mirror of
https://github.com/djibux/BoilR.git
synced 2026-09-01 14:03:42 +02:00
Pick image component (#295)
* Extract render_possible_image into function * Seperate render_image into reusable functions * Seperate game image into component * Use image component in shortcut overview * Reuse image pick component in type select * Reuse component across select_image_type * Use image type to scale image buttons Use image type to scale * Remove old functions
This commit is contained in:
@@ -22,6 +22,17 @@ impl ImageType {
|
|||||||
&ALL_TYPES
|
&ALL_TYPES
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ratio(&self) -> f32{
|
||||||
|
match self {
|
||||||
|
ImageType::Hero => 0.3,
|
||||||
|
ImageType::Grid => 1.6,
|
||||||
|
ImageType::WideGrid => 0.5,
|
||||||
|
ImageType::Logo => 0.2,
|
||||||
|
ImageType::BigPicture => 0.5,
|
||||||
|
ImageType::Icon => 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
ImageType::Hero => "Hero",
|
ImageType::Hero => "Hero",
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use egui::{Button, ImageButton};
|
||||||
|
use futures::executor::block_on;
|
||||||
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
|
use crate::steamgriddb::{ImageType, ToDownload};
|
||||||
|
use crate::ui::images::{clamp_to_width, ImageHandles, TextureDownloadState};
|
||||||
|
use crate::ui::ui_images::load_image_from_path;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn render_image_from_path(
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
image_handles: &ImageHandles,
|
||||||
|
path: &Path,
|
||||||
|
max_width: f32,
|
||||||
|
text: &str,
|
||||||
|
) -> bool {
|
||||||
|
render_possible_image(ui, image_handles, path, max_width, text, &ImageType::Grid, None, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_image_from_path_image_type(
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
image_handles: &ImageHandles,
|
||||||
|
path: &Path,
|
||||||
|
max_width: f32,
|
||||||
|
text: &str,
|
||||||
|
image_type: &ImageType,
|
||||||
|
) -> bool {
|
||||||
|
render_possible_image(ui, image_handles, path, max_width, text, image_type, None, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn render_image_from_path_or_url(
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
image_handles: &ImageHandles,
|
||||||
|
path: &Path,
|
||||||
|
max_width: f32,
|
||||||
|
text: &str,
|
||||||
|
image_type: &ImageType,
|
||||||
|
rt: &Runtime,
|
||||||
|
url: &str,
|
||||||
|
) -> bool {
|
||||||
|
render_possible_image(
|
||||||
|
ui,
|
||||||
|
image_handles,
|
||||||
|
path,
|
||||||
|
max_width,
|
||||||
|
text,
|
||||||
|
image_type,
|
||||||
|
Some(rt),
|
||||||
|
Some(url),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_possible_image(
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
image_handles: &ImageHandles,
|
||||||
|
path: &Path,
|
||||||
|
max_width: f32,
|
||||||
|
text: &str,
|
||||||
|
image_type: &ImageType,
|
||||||
|
rt: Option<&Runtime>,
|
||||||
|
url: Option<&str>,
|
||||||
|
) -> bool {
|
||||||
|
let image_key = path.to_string_lossy().to_string();
|
||||||
|
|
||||||
|
match image_handles.get_mut(&image_key) {
|
||||||
|
Some(mut state) => {
|
||||||
|
match state.value() {
|
||||||
|
TextureDownloadState::Downloading => {
|
||||||
|
ui.ctx().request_repaint();
|
||||||
|
//nothing to do,just wait
|
||||||
|
ui.spinner();
|
||||||
|
}
|
||||||
|
TextureDownloadState::Downloaded => {
|
||||||
|
//Need to load
|
||||||
|
let image_data = load_image_from_path(&path);
|
||||||
|
match image_data {
|
||||||
|
Ok(image_data) => {
|
||||||
|
let handle = ui.ctx().load_texture(
|
||||||
|
&image_key,
|
||||||
|
image_data,
|
||||||
|
egui::TextureOptions::LINEAR,
|
||||||
|
);
|
||||||
|
*state.value_mut() = TextureDownloadState::Loaded(handle);
|
||||||
|
ui.spinner();
|
||||||
|
}
|
||||||
|
Err(_) => *state.value_mut() = TextureDownloadState::Failed,
|
||||||
|
}
|
||||||
|
ui.ctx().request_repaint();
|
||||||
|
}
|
||||||
|
TextureDownloadState::Loaded(texture_handle) => {
|
||||||
|
//need to show
|
||||||
|
let mut size = texture_handle.size_vec2();
|
||||||
|
clamp_to_width(&mut size, max_width);
|
||||||
|
let image_button = ImageButton::new(texture_handle, size);
|
||||||
|
if ui
|
||||||
|
.add_sized(size, image_button)
|
||||||
|
.on_hover_text(text)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextureDownloadState::Failed => {
|
||||||
|
let button =
|
||||||
|
ui.add_sized([max_width, max_width * image_type.ratio()], Button::new(text).wrap(true));
|
||||||
|
if button.clicked() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if !path.exists() && url.is_none() {
|
||||||
|
image_handles.insert(image_key, TextureDownloadState::Failed);
|
||||||
|
} else {
|
||||||
|
//We need to start a download
|
||||||
|
//Redownload if file is too small
|
||||||
|
if !path.exists()
|
||||||
|
|| std::fs::metadata(path).map(|m| m.len()).unwrap_or_default() < 2
|
||||||
|
{
|
||||||
|
image_handles.insert(image_key.clone(), TextureDownloadState::Downloading);
|
||||||
|
let to_download = ToDownload {
|
||||||
|
path: path.to_path_buf(),
|
||||||
|
url: url.unwrap().to_string(),
|
||||||
|
app_name: "Thumbnail".to_string(),
|
||||||
|
image_type: *image_type,
|
||||||
|
};
|
||||||
|
let image_handles = image_handles.clone();
|
||||||
|
let image_key = image_key.clone();
|
||||||
|
if let Some(rt) = rt {
|
||||||
|
rt.spawn_blocking(move || {
|
||||||
|
block_on(crate::steamgriddb::download_to_download(&to_download))
|
||||||
|
.unwrap();
|
||||||
|
image_handles.insert(image_key, TextureDownloadState::Downloaded);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
image_handles.insert(image_key.clone(), TextureDownloadState::Downloaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
mod steam_user_select;
|
mod steam_user_select;
|
||||||
|
mod game_image_button;
|
||||||
|
|
||||||
pub use steam_user_select::render_user_select;
|
pub use steam_user_select::render_user_select;
|
||||||
|
pub use game_image_button::render_image_from_path;
|
||||||
|
pub use game_image_button::render_image_from_path_or_url;
|
||||||
|
pub use game_image_button::render_image_from_path_image_type;
|
||||||
@@ -8,6 +8,9 @@ use crate::{steam::SteamUsersInfo, steamgriddb::ImageType, ui::FetcStatus};
|
|||||||
use super::{ gamemode::GameMode, possible_image::PossibleImage, texturestate::TextureDownloadState, gametype::GameType};
|
use super::{ gamemode::GameMode, possible_image::PossibleImage, texturestate::TextureDownloadState, gametype::GameType};
|
||||||
|
|
||||||
use tokio::sync::watch::{self, Receiver};
|
use tokio::sync::watch::{self, Receiver};
|
||||||
|
|
||||||
|
pub type ImageHandles = std::sync::Arc<DashMap<String, TextureDownloadState>>;
|
||||||
|
|
||||||
pub struct ImageSelectState {
|
pub struct ImageSelectState {
|
||||||
pub selected_shortcut: Option<GameType>,
|
pub selected_shortcut: Option<GameType>,
|
||||||
pub grid_id: Option<usize>,
|
pub grid_id: Option<usize>,
|
||||||
@@ -20,7 +23,7 @@ pub struct ImageSelectState {
|
|||||||
pub image_type_selected: Option<ImageType>,
|
pub image_type_selected: Option<ImageType>,
|
||||||
pub image_options: Receiver<FetcStatus<Vec<PossibleImage>>>,
|
pub image_options: Receiver<FetcStatus<Vec<PossibleImage>>>,
|
||||||
pub steam_games: Option<Vec<crate::steam::SteamGameInfo>>,
|
pub steam_games: Option<Vec<crate::steam::SteamGameInfo>>,
|
||||||
pub image_handles: std::sync::Arc<DashMap<String, TextureDownloadState>>,
|
pub image_handles: ImageHandles,
|
||||||
|
|
||||||
pub possible_names: Option<Vec<steamgriddb_api::search::SearchResult>>,
|
pub possible_names: Option<Vec<steamgriddb_api::search::SearchResult>>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,3 +12,6 @@ mod constants;
|
|||||||
mod pages;
|
mod pages;
|
||||||
|
|
||||||
pub use image_select_state::ImageSelectState;
|
pub use image_select_state::ImageSelectState;
|
||||||
|
pub use image_select_state::ImageHandles;
|
||||||
|
pub use texturestate::TextureDownloadState;
|
||||||
|
pub use image_resize::clamp_to_width;
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use egui::{Grid, ImageButton};
|
use egui::{Grid, };
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
use tokio::sync::watch;
|
use tokio::{ sync::watch};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
steamgriddb::{get_image_extension, ImageType, ToDownload},
|
steamgriddb::{get_image_extension, ImageType, ToDownload},
|
||||||
ui::{
|
ui::{
|
||||||
images::{
|
images::{
|
||||||
constants::MAX_WIDTH, image_resize::clamp_to_width,
|
constants::MAX_WIDTH,
|
||||||
image_select_state::ImageSelectState, possible_image::PossibleImage,
|
hasimagekey::HasImageKey,
|
||||||
texturestate::TextureDownloadState, useraction::UserAction, hasimagekey::HasImageKey,
|
image_select_state::{ ImageSelectState},
|
||||||
|
possible_image::PossibleImage,
|
||||||
|
useraction::UserAction,
|
||||||
},
|
},
|
||||||
ui_images::load_image_from_path,
|
FetcStatus, MyEguiApp, components::render_image_from_path_or_url,
|
||||||
FetcStatus, MyEguiApp,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,88 +60,18 @@ pub fn render_page_pick_image(
|
|||||||
.spacing([column_padding, column_padding])
|
.spacing([column_padding, column_padding])
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
for image in images {
|
for image in images {
|
||||||
let image_key =
|
let path = image.thumbnail_path.as_path();
|
||||||
image.thumbnail_path.as_path().to_string_lossy().to_string();
|
if render_image_from_path_or_url(
|
||||||
|
ui,
|
||||||
match state.image_handles.get_mut(&image_key) {
|
&state.image_handles,
|
||||||
Some(mut state) => {
|
&path,
|
||||||
match state.value() {
|
column_width,
|
||||||
TextureDownloadState::Downloading => {
|
&image.full_url,
|
||||||
ui.ctx().request_repaint();
|
image_type,
|
||||||
//nothing to do,just wait
|
&app.rt,
|
||||||
ui.spinner();
|
&image.thumbnail_url,
|
||||||
}
|
) {
|
||||||
TextureDownloadState::Downloaded => {
|
return Some(image.clone());
|
||||||
//Need to load
|
|
||||||
let image_data =
|
|
||||||
load_image_from_path(&image.thumbnail_path);
|
|
||||||
match image_data {
|
|
||||||
Ok(image_data) => {
|
|
||||||
let handle = ui.ctx().load_texture(
|
|
||||||
&image_key,
|
|
||||||
image_data,
|
|
||||||
egui::TextureOptions::LINEAR,
|
|
||||||
);
|
|
||||||
*state.value_mut() =
|
|
||||||
TextureDownloadState::Loaded(handle);
|
|
||||||
ui.spinner();
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
*state.value_mut() = TextureDownloadState::Failed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui.ctx().request_repaint();
|
|
||||||
}
|
|
||||||
TextureDownloadState::Loaded(texture_handle) => {
|
|
||||||
//need to show
|
|
||||||
let mut size = texture_handle.size_vec2();
|
|
||||||
clamp_to_width(&mut size, column_width);
|
|
||||||
let image_button = ImageButton::new(texture_handle, size);
|
|
||||||
if ui.add_sized(size, image_button).clicked() {
|
|
||||||
return Some(UserAction::ImageSelected(image.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TextureDownloadState::Failed => {
|
|
||||||
ui.label("Failed to load image");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
//We need to start a download
|
|
||||||
let image_handles = &app.image_selected_state.image_handles;
|
|
||||||
let path = &image.thumbnail_path;
|
|
||||||
//Redownload if file is too small
|
|
||||||
if !path.exists()
|
|
||||||
|| std::fs::metadata(path).map(|m| m.len()).unwrap_or_default()
|
|
||||||
< 2
|
|
||||||
{
|
|
||||||
image_handles.insert(
|
|
||||||
image_key.clone(),
|
|
||||||
TextureDownloadState::Downloading,
|
|
||||||
);
|
|
||||||
let to_download = ToDownload {
|
|
||||||
path: path.clone(),
|
|
||||||
url: image.thumbnail_url.clone(),
|
|
||||||
app_name: "Thumbnail".to_string(),
|
|
||||||
image_type: *image_type,
|
|
||||||
};
|
|
||||||
let image_handles = image_handles.clone();
|
|
||||||
let image_key = image_key.clone();
|
|
||||||
app.rt.spawn_blocking(move || {
|
|
||||||
block_on(crate::steamgriddb::download_to_download(
|
|
||||||
&to_download,
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
image_handles
|
|
||||||
.insert(image_key, TextureDownloadState::Downloaded);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
image_handles.insert(
|
|
||||||
image_key.clone(),
|
|
||||||
TextureDownloadState::Downloaded,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
column += 1;
|
column += 1;
|
||||||
if column >= columns {
|
if column >= columns {
|
||||||
@@ -148,12 +79,11 @@ pub fn render_page_pick_image(
|
|||||||
ui.end_row();
|
ui.end_row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
.inner;
|
.inner;
|
||||||
if x.is_some() {
|
if let Some(x) = x {
|
||||||
return x;
|
return Some(UserAction::ImageSelected(x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
@@ -1,78 +1,61 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use egui::ImageButton;
|
use crate::ui::images::{
|
||||||
|
gametype::GameType, hasimagekey::HasImageKey, image_select_state::ImageSelectState,
|
||||||
use crate::{ui::images::{image_select_state::ImageSelectState, useraction::UserAction, gametype::GameType, texturestate::TextureDownloadState, hasimagekey::HasImageKey, image_resize::clamp_to_width}, steamgriddb::ImageType};
|
useraction::UserAction, ImageHandles,
|
||||||
|
};
|
||||||
|
use crate::{steamgriddb::ImageType, ui::components::render_image_from_path_image_type};
|
||||||
|
|
||||||
const MAX_WIDTH: f32 = 300.;
|
const MAX_WIDTH: f32 = 300.;
|
||||||
|
|
||||||
|
pub fn render_page_shortcut_select_image_type(
|
||||||
pub fn render_page_shortcut_select_image_type(ui: &mut egui::Ui, state: &ImageSelectState) -> Option<UserAction> {
|
ui: &mut egui::Ui,
|
||||||
|
state: &ImageSelectState,
|
||||||
|
) -> Option<UserAction> {
|
||||||
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;
|
||||||
|
|
||||||
|
let thumbnail = |ui: &mut egui::Ui, image_type: &ImageType| {
|
||||||
|
if render_thumbnail(ui, &state.image_handles, shortcut, image_type, user_path) {
|
||||||
|
Some(UserAction::ImageTypeSelected(*image_type))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
let x = if ui.available_width() > MAX_WIDTH * 3. {
|
let x = if ui.available_width() > MAX_WIDTH * 3. {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let x = ui
|
let x = ui.vertical(|ui| thumbnail(ui, &ImageType::Grid)).inner;
|
||||||
.vertical(|ui| {
|
|
||||||
let texture =
|
|
||||||
texture_from_iamge_type(shortcut, &ImageType::Grid, user_path, state);
|
|
||||||
ui.label(ImageType::Grid.name());
|
|
||||||
if render_thumbnail(ui, texture).clicked() {
|
|
||||||
return Some(UserAction::ImageTypeSelected(ImageType::Grid));
|
|
||||||
}
|
|
||||||
None
|
|
||||||
})
|
|
||||||
.inner;
|
|
||||||
if x.is_some() {
|
if x.is_some() {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
let x = ui
|
let x = ui
|
||||||
.vertical(|ui| {
|
.vertical(|ui| {
|
||||||
let texture =
|
let types = &[ImageType::Hero, ImageType::WideGrid, ImageType::Logo];
|
||||||
texture_from_iamge_type(shortcut, &ImageType::Hero, user_path, state);
|
types
|
||||||
ui.label(ImageType::Hero.name());
|
.iter()
|
||||||
if render_thumbnail(ui, texture).clicked() {
|
.flat_map(|image_type| thumbnail(ui, image_type))
|
||||||
return Some(UserAction::ImageTypeSelected(ImageType::Hero));
|
.next()
|
||||||
}
|
|
||||||
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;
|
.inner;
|
||||||
if x.is_some() {
|
if x.is_some() {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
let texture = texture_from_iamge_type(shortcut, &ImageType::Icon, user_path, state);
|
let types = &[ImageType::Icon, ImageType::BigPicture];
|
||||||
ui.label(ImageType::Icon.name());
|
types
|
||||||
if render_thumbnail(ui, texture).clicked() {
|
.iter()
|
||||||
return Some(UserAction::ImageTypeSelected(ImageType::Icon));
|
.flat_map(|image_type| thumbnail(ui, image_type))
|
||||||
}
|
.next()
|
||||||
|
|
||||||
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
|
||||||
})
|
})
|
||||||
.inner
|
.inner
|
||||||
} else {
|
} else {
|
||||||
render_image_types_as_list(shortcut, user_path, state, ui)
|
let types = ImageType::all();
|
||||||
|
types
|
||||||
|
.iter()
|
||||||
|
.flat_map(|image_type| thumbnail(ui, image_type))
|
||||||
|
.next()
|
||||||
};
|
};
|
||||||
|
|
||||||
if ui
|
if ui
|
||||||
@@ -84,48 +67,21 @@ pub fn render_page_shortcut_select_image_type(ui: &mut egui::Ui, state: &ImageSe
|
|||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_image_types_as_list(
|
fn render_thumbnail(
|
||||||
shortcut: &GameType,
|
|
||||||
user_path: &String,
|
|
||||||
state: &ImageSelectState,
|
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
) -> Option<UserAction> {
|
image_handles: &ImageHandles,
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn texture_from_iamge_type(
|
|
||||||
shortcut: &GameType,
|
shortcut: &GameType,
|
||||||
image_type: &ImageType,
|
image_type: &ImageType,
|
||||||
user_path: &String,
|
user_path: &String,
|
||||||
state: &ImageSelectState,
|
) -> bool {
|
||||||
) -> Option<egui::TextureHandle> {
|
let (path, _key) = shortcut.key(image_type, Path::new(&user_path));
|
||||||
let (_path, key) = shortcut.key(image_type, Path::new(&user_path));
|
let text = format!("Pick {} image", image_type.name());
|
||||||
state.image_handles.get(&key).and_then(|k| match k.value() {
|
render_image_from_path_image_type(
|
||||||
TextureDownloadState::Loaded(texture) => Some(texture.clone()),
|
ui,
|
||||||
_ => None,
|
image_handles,
|
||||||
})
|
path.as_path(),
|
||||||
}
|
MAX_WIDTH,
|
||||||
|
&text,
|
||||||
fn render_thumbnail(ui: &mut egui::Ui, image: Option<egui::TextureHandle>) -> egui::Response {
|
image_type,
|
||||||
if let Some(texture) = image {
|
)
|
||||||
let mut size = texture.size_vec2();
|
|
||||||
clamp_to_width(&mut size, MAX_WIDTH);
|
|
||||||
let image_button = ImageButton::new(&texture, size);
|
|
||||||
ui.add(image_button)
|
|
||||||
} else {
|
|
||||||
ui.button("Pick an image")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use egui::{Button, ImageButton};
|
|
||||||
use steam_shortcuts_util::shortcut::ShortcutOwned;
|
use steam_shortcuts_util::shortcut::ShortcutOwned;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -8,10 +7,10 @@ use crate::{
|
|||||||
steamgriddb::{ImageType, CachedSearch},
|
steamgriddb::{ImageType, CachedSearch},
|
||||||
ui::{
|
ui::{
|
||||||
images::{
|
images::{
|
||||||
gametype::GameType, hasimagekey::HasImageKey, image_resize::clamp_to_width,
|
gametype::GameType, hasimagekey::HasImageKey,
|
||||||
texturestate::TextureDownloadState, useraction::UserAction,
|
texturestate::TextureDownloadState, useraction::UserAction,
|
||||||
},
|
},
|
||||||
MyEguiApp, ui_images::load_image_from_path,
|
MyEguiApp, ui_images::load_image_from_path, components::render_image_from_path,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,27 +64,8 @@ fn render_image(
|
|||||||
&ImageType::Grid,
|
&ImageType::Grid,
|
||||||
Path::new(&user_info.steam_user_data_folder),
|
Path::new(&user_info.steam_user_data_folder),
|
||||||
);
|
);
|
||||||
let mut clicked = false;
|
|
||||||
|
|
||||||
let texture = app.image_selected_state.image_handles.get(&key);
|
|
||||||
if let Some(texture) = texture {
|
|
||||||
if let TextureDownloadState::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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let clicked= render_image_from_path(ui, &app.image_selected_state.image_handles, Path::new(&key), column_width, &shortcut.app_name);
|
||||||
if clicked {
|
if clicked {
|
||||||
return Some(Some(UserAction::ShortcutSelected(GameType::Shortcut(
|
return Some(Some(UserAction::ShortcutSelected(GameType::Shortcut(
|
||||||
shortcut.clone(),
|
shortcut.clone(),
|
||||||
|
|||||||
Reference in New Issue
Block a user