mirror of
https://github.com/djibux/BoilR.git
synced 2026-09-01 05:53:41 +02:00
Image UI optimize (#259)
* Show images in grids * Start of columns in image select * Redo image selection ui * Update to version 1.7.3
This commit is contained in:
Generated
+1
-1
@@ -192,7 +192,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "boilr"
|
name = "boilr"
|
||||||
version = "1.7.2"
|
version = "1.7.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
+18
-7
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
name = "boilr"
|
name = "boilr"
|
||||||
version = "1.7.2"
|
version = "1.7.3"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "^0.13.0"
|
base64 = "^0.13.0"
|
||||||
@@ -13,7 +13,7 @@ is_executable = "^1.0.1"
|
|||||||
nom = "^7.1.1"
|
nom = "^7.1.1"
|
||||||
rusty-leveldb = "^1.0.4"
|
rusty-leveldb = "^1.0.4"
|
||||||
serde_json = "^1.0.83"
|
serde_json = "^1.0.83"
|
||||||
sqlite = "^0.27.0"
|
|
||||||
steam_shortcuts_util = "^1.1.8"
|
steam_shortcuts_util = "^1.1.8"
|
||||||
steamgriddb_api = "^0.3.1"
|
steamgriddb_api = "^0.3.1"
|
||||||
sysinfo = "^0.26.4"
|
sysinfo = "^0.26.4"
|
||||||
@@ -21,6 +21,9 @@ eyre = "^0.6.8"
|
|||||||
color-eyre = "^0.6"
|
color-eyre = "^0.6"
|
||||||
dyn-clone = "^1.0.9"
|
dyn-clone = "^1.0.9"
|
||||||
|
|
||||||
|
[dependencies.sqlite]
|
||||||
|
version = "^0.27.0"
|
||||||
|
|
||||||
[dependencies.dashmap]
|
[dependencies.dashmap]
|
||||||
features = ["serde"]
|
features = ["serde"]
|
||||||
version = "^5.3.4"
|
version = "^5.3.4"
|
||||||
@@ -66,8 +69,16 @@ winreg = "^0.10.1"
|
|||||||
# This feature is enabled when building for a flatpak environment
|
# This feature is enabled when building for a flatpak environment
|
||||||
flatpak = []
|
flatpak = []
|
||||||
|
|
||||||
[profile.release]
|
# [profile.release]
|
||||||
strip = true # Automatically strip symbols from the binary.
|
# strip = true # Automatically strip symbols from the binary.
|
||||||
opt-level = "z" # Optimize for size.
|
# opt-level = "z" # Optimize for size.
|
||||||
lto = true
|
# lto = true
|
||||||
codegen-units = 1
|
# codegen-units = 1
|
||||||
|
|
||||||
|
# # Enable a small amount of optimization in debug mode
|
||||||
|
# [profile.dev]
|
||||||
|
# opt-level = 1
|
||||||
|
|
||||||
|
# # # Enable high optimizations for dependencies but not for BoilR code:
|
||||||
|
# # [profile.dev.package."*"]
|
||||||
|
# # opt-level = 3
|
||||||
|
|||||||
+149
-36
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
steamgriddb::{get_image_extension, get_query_type, CachedSearch, ImageType, ToDownload},
|
steamgriddb::{get_image_extension, get_query_type, CachedSearch, ImageType, ToDownload},
|
||||||
};
|
};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use egui::{ImageButton, ScrollArea};
|
use egui::{Button, ImageButton, ScrollArea};
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
use steam_shortcuts_util::shortcut::ShortcutOwned;
|
use steam_shortcuts_util::shortcut::ShortcutOwned;
|
||||||
use steamgriddb_api::images::MimeTypes;
|
use steamgriddb_api::images::MimeTypes;
|
||||||
@@ -188,32 +188,33 @@ impl MyEguiApp {
|
|||||||
fn render_shortcut_select(&self, ui: &mut egui::Ui) -> Option<UserAction> {
|
fn render_shortcut_select(&self, ui: &mut egui::Ui) -> Option<UserAction> {
|
||||||
let shortcuts = &self.image_selected_state.user_shortcuts;
|
let shortcuts = &self.image_selected_state.user_shortcuts;
|
||||||
|
|
||||||
|
let width = ui.available_size().x;
|
||||||
|
let column_width = 100.;
|
||||||
|
let column_padding = 23.;
|
||||||
|
let columns = (width / (column_width + column_padding)).floor() as u32;
|
||||||
|
let mut cur_column = 0;
|
||||||
match shortcuts {
|
match shortcuts {
|
||||||
Some(shortcuts) => {
|
Some(shortcuts) => {
|
||||||
let user_info = &self.image_selected_state.steam_user.as_ref().unwrap();
|
let user_info = &self.image_selected_state.steam_user.as_ref().unwrap();
|
||||||
for shortcut in shortcuts {
|
if let Some(action) = egui::Grid::new("ui_images")
|
||||||
let (_, key) = shortcut.key(
|
.show(ui, |ui| {
|
||||||
&ImageType::Grid,
|
for shortcut in shortcuts {
|
||||||
Path::new(&user_info.steam_user_data_folder),
|
let action = self.render_image(shortcut, user_info, column_width, ui);
|
||||||
);
|
if action.is_some() {
|
||||||
let texture = self.image_selected_state.image_handles.get(&key);
|
return action;
|
||||||
let mut clicked = false;
|
}
|
||||||
if let Some(texture) = texture {
|
cur_column += 1;
|
||||||
if let TextureState::Loaded(texture) = &texture.value() {
|
if cur_column >= columns {
|
||||||
let mut size = texture.size_vec2();
|
cur_column = 0;
|
||||||
clamp_to_width(&mut size, 100.);
|
ui.end_row();
|
||||||
let image_button = ImageButton::new(texture, size);
|
}
|
||||||
clicked = clicked || ui.add(image_button).clicked();
|
|
||||||
}
|
}
|
||||||
}
|
ui.end_row();
|
||||||
|
None
|
||||||
let button = ui.button(&shortcut.app_name);
|
})
|
||||||
clicked = clicked || button.clicked();
|
.inner
|
||||||
if clicked {
|
{
|
||||||
return Some(UserAction::ShortcutSelected(GameType::Shortcut(
|
return action;
|
||||||
shortcut.clone(),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@@ -223,6 +224,46 @@ impl MyEguiApp {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_image(
|
||||||
|
&self,
|
||||||
|
shortcut: &ShortcutOwned,
|
||||||
|
user_info: &&SteamUsersInfo,
|
||||||
|
column_width: f32,
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
) -> Option<Option<UserAction>> {
|
||||||
|
let (_, key) = shortcut.key(
|
||||||
|
&ImageType::Grid,
|
||||||
|
Path::new(&user_info.steam_user_data_folder),
|
||||||
|
);
|
||||||
|
let mut clicked = false;
|
||||||
|
|
||||||
|
let texture = self.image_selected_state.image_handles.get(&key);
|
||||||
|
if let Some(texture) = texture {
|
||||||
|
if let TextureState::Loaded(texture) = &texture.value() {
|
||||||
|
let mut size = texture.size_vec2();
|
||||||
|
clamp_to_width(&mut size, column_width);
|
||||||
|
let image_button = ImageButton::new(texture, size);
|
||||||
|
clicked = ui
|
||||||
|
.add(image_button)
|
||||||
|
.on_hover_text(&shortcut.app_name)
|
||||||
|
.clicked();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let button = ui.add_sized(
|
||||||
|
[column_width, column_width * 1.6],
|
||||||
|
Button::new(&shortcut.app_name).wrap(true),
|
||||||
|
);
|
||||||
|
clicked = clicked || button.clicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
if clicked {
|
||||||
|
return Some(Some(UserAction::ShortcutSelected(GameType::Shortcut(
|
||||||
|
shortcut.clone(),
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn render_possible_images(
|
fn render_possible_images(
|
||||||
&self,
|
&self,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
@@ -732,21 +773,94 @@ fn render_shortcut_images(ui: &mut egui::Ui, state: &ImageSelectState) -> Option
|
|||||||
|
|
||||||
let shortcut = state.selected_shortcut.as_ref().unwrap();
|
let shortcut = state.selected_shortcut.as_ref().unwrap();
|
||||||
let user_path = &state.steam_user.as_ref().unwrap().steam_user_data_folder;
|
let user_path = &state.steam_user.as_ref().unwrap().steam_user_data_folder;
|
||||||
for image_type in ImageType::all() {
|
|
||||||
ui.label(image_type.name());
|
if ui.available_width() > MAX_WIDTH * 3. {
|
||||||
let (_path, key) = shortcut.key(image_type, Path::new(&user_path));
|
ui.horizontal(|ui| {
|
||||||
let texture = state.image_handles.get(&key).and_then(|k| match k.value() {
|
let x = ui.vertical(|ui| {
|
||||||
TextureState::Loaded(texture) => Some(texture.clone()),
|
let texture = texture_from_iamge_type(shortcut, &ImageType::Grid, user_path, state);
|
||||||
_ => None,
|
ui.label(ImageType::Grid.name());
|
||||||
});
|
if render_thumbnail(ui, texture).clicked(){
|
||||||
let clicked = render_thumbnail(ui, texture);
|
return Some(UserAction::ImageTypeSelected(ImageType::Grid));
|
||||||
if clicked {
|
}
|
||||||
|
None
|
||||||
|
}).inner;
|
||||||
|
if x.is_some(){
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
let x = ui.vertical(|ui| {
|
||||||
|
let texture = texture_from_iamge_type(shortcut, &ImageType::Hero, user_path, state);
|
||||||
|
ui.label(ImageType::Hero.name());
|
||||||
|
if render_thumbnail(ui, texture).clicked(){
|
||||||
|
return Some(UserAction::ImageTypeSelected(ImageType::Hero));
|
||||||
|
}
|
||||||
|
let texture =
|
||||||
|
texture_from_iamge_type(shortcut, &ImageType::WideGrid, user_path, state);
|
||||||
|
ui.label(ImageType::WideGrid.name());
|
||||||
|
if render_thumbnail(ui, texture).clicked(){
|
||||||
|
return Some(UserAction::ImageTypeSelected(ImageType::WideGrid));
|
||||||
|
}
|
||||||
|
|
||||||
|
let texture = texture_from_iamge_type(shortcut, &ImageType::Logo, user_path, state);
|
||||||
|
ui.label(ImageType::Logo.name());
|
||||||
|
if render_thumbnail(ui, texture).clicked(){
|
||||||
|
return Some(UserAction::ImageTypeSelected(ImageType::Logo));
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}).inner;
|
||||||
|
if x.is_some(){
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
let texture = texture_from_iamge_type(shortcut, &ImageType::Icon, user_path, state);
|
||||||
|
ui.label(ImageType::Icon.name());
|
||||||
|
if render_thumbnail(ui, texture).clicked(){
|
||||||
|
return Some(UserAction::ImageTypeSelected(ImageType::Icon));
|
||||||
|
}
|
||||||
|
|
||||||
|
let texture =
|
||||||
|
texture_from_iamge_type(shortcut, &ImageType::BigPicture, user_path, state);
|
||||||
|
ui.label(ImageType::BigPicture.name());
|
||||||
|
if render_thumbnail(ui, texture).clicked(){
|
||||||
|
return Some(UserAction::ImageTypeSelected(ImageType::BigPicture));
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}).inner
|
||||||
|
}).inner
|
||||||
|
} else {
|
||||||
|
render_image_types_as_list(shortcut, user_path, state, ui)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_image_types_as_list(shortcut: &GameType, user_path: &String, state: &ImageSelectState, ui: &mut egui::Ui) -> Option<UserAction> {
|
||||||
|
let types = ImageType::all();
|
||||||
|
for image_type in types {
|
||||||
|
let texture = texture_from_iamge_type(shortcut, image_type, user_path, state);
|
||||||
|
let response = ui
|
||||||
|
.vertical(|ui| {
|
||||||
|
ui.label(image_type.name());
|
||||||
|
render_thumbnail(ui, texture)
|
||||||
|
})
|
||||||
|
.inner;
|
||||||
|
if response.clicked() {
|
||||||
return Some(UserAction::ImageTypeSelected(*image_type));
|
return Some(UserAction::ImageTypeSelected(*image_type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn texture_from_iamge_type(
|
||||||
|
shortcut: &GameType,
|
||||||
|
image_type: &ImageType,
|
||||||
|
user_path: &String,
|
||||||
|
state: &ImageSelectState,
|
||||||
|
) -> Option<egui::TextureHandle> {
|
||||||
|
let (_path, key) = shortcut.key(image_type, Path::new(&user_path));
|
||||||
|
state.image_handles.get(&key).and_then(|k| match k.value() {
|
||||||
|
TextureState::Loaded(texture) => Some(texture.clone()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn render_user_select(state: &ImageSelectState, ui: &mut egui::Ui) -> UserAction {
|
fn render_user_select(state: &ImageSelectState, ui: &mut egui::Ui) -> UserAction {
|
||||||
let users = state.steam_users.as_ref().unwrap();
|
let users = state.steam_users.as_ref().unwrap();
|
||||||
if users.len() == 1 {
|
if users.len() == 1 {
|
||||||
@@ -762,15 +876,14 @@ fn render_user_select(state: &ImageSelectState, ui: &mut egui::Ui) -> UserAction
|
|||||||
|
|
||||||
const MAX_WIDTH: f32 = 300.;
|
const MAX_WIDTH: f32 = 300.;
|
||||||
|
|
||||||
fn render_thumbnail(ui: &mut egui::Ui, image: Option<egui::TextureHandle>) -> bool {
|
fn render_thumbnail(ui: &mut egui::Ui, image: Option<egui::TextureHandle>) -> egui::Response {
|
||||||
if let Some(texture) = image {
|
if let Some(texture) = image {
|
||||||
let mut size = texture.size_vec2();
|
let mut size = texture.size_vec2();
|
||||||
clamp_to_width(&mut size, MAX_WIDTH);
|
clamp_to_width(&mut size, MAX_WIDTH);
|
||||||
let image_button = ImageButton::new(&texture, size);
|
let image_button = ImageButton::new(&texture, size);
|
||||||
let added = ui.add(image_button);
|
ui.add(image_button)
|
||||||
added.on_hover_text("Click to change image").clicked()
|
|
||||||
} else {
|
} else {
|
||||||
ui.button("Pick an image").clicked()
|
ui.button("Pick an image")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user