From b35967d6dc97da861d65884be3f40f3b101b3070 Mon Sep 17 00:00:00 2001 From: Jaby Date: Thu, 13 Feb 2025 22:33:52 +0100 Subject: [PATCH] Clean-up ui code --- src/Tools/tim_tool/src/gui/file_tab.rs | 19 +++++ src/Tools/tim_tool/src/gui/gui_elements.rs | 76 ++--------------- src/Tools/tim_tool/src/gui/main_tab.rs | 98 ++++++++++++++++++++++ src/Tools/tim_tool/src/gui/mod.rs | 9 +- src/Tools/tim_tool/src/main.rs | 56 ++++++------- 5 files changed, 162 insertions(+), 96 deletions(-) create mode 100644 src/Tools/tim_tool/src/gui/file_tab.rs create mode 100644 src/Tools/tim_tool/src/gui/main_tab.rs diff --git a/src/Tools/tim_tool/src/gui/file_tab.rs b/src/Tools/tim_tool/src/gui/file_tab.rs new file mode 100644 index 00000000..49c29a87 --- /dev/null +++ b/src/Tools/tim_tool/src/gui/file_tab.rs @@ -0,0 +1,19 @@ +use crate::MainWindow; +use super::MainWindowRef; + +pub struct FileTab { + main_window: MainWindowRef +} + +impl FileTab { + pub fn new(main_window: MainWindowRef) -> FileTab { + FileTab{main_window} + } + + pub fn on_browse_file(&self, mut function: impl FnMut(&MainWindow) + 'static) { + let main_window_cloned = self.main_window.clone(); + self.main_window.borrow().on_file_tab_browse_convert_image(move || { + function(&main_window_cloned.borrow()); + }); + } +} \ No newline at end of file diff --git a/src/Tools/tim_tool/src/gui/gui_elements.rs b/src/Tools/tim_tool/src/gui/gui_elements.rs index d26ec7bd..da0036e2 100644 --- a/src/Tools/tim_tool/src/gui/gui_elements.rs +++ b/src/Tools/tim_tool/src/gui/gui_elements.rs @@ -1,78 +1,20 @@ -use crate::{gui::{VRAM_HEIGHT, VRAM_WIDTH, create_vram_bg}, MainWindow, VRAMImage}; +use super::create_vram_bg; -use slint::Model; -use std::{cell::RefCell, ffi::OsStr, path::PathBuf, rc::Rc}; -use tool_helper::Error; +use super::MainWindowRef; +use super::{file_tab::FileTab, main_tab::MainTab}; pub struct GUIElements { - pub main_window: Rc>, - vram_file_list: Rc>, - vram_image_list: Rc>, + pub file_tab: FileTab, + pub main_tab: MainTab, } impl GUIElements { - pub fn new(main_window: Rc>) -> GUIElements { - let vram_file_list:Vec = main_window.borrow().get_main_tab_vram_file_list().iter().collect(); - let vram_file_list = Rc::new(slint::VecModel::from(vram_file_list)); - - let vram_image_list = Rc::new(slint::VecModel::from(Vec::::new())); - - main_window.borrow().set_main_tab_vram_file_list(vram_file_list.clone().into()); - main_window.borrow().set_main_tab_vram_images(vram_image_list.clone().into()); - - GUIElements{main_window, vram_file_list, vram_image_list} + pub fn new(main_window: MainWindowRef) -> Result { + main_window.borrow().set_main_tab_vram_bg(GUIElements::create_bg()?); + Ok(GUIElements{file_tab: FileTab::new(main_window.clone()), main_tab: MainTab::new(main_window.clone())}) } - pub fn add_new_vram_file(&mut self, file: PathBuf) -> Result<(), Error> { - let vram_image = VRAMImage{ - img: slint::Image::load_from_path(&file).or_else(|_| {Err(Error::from_str("Failed loading image"))})?, - x: 0, - y: 0 - }; - - let img_size = vram_image.img.size(); - if img_size.width > VRAM_WIDTH as u32 || img_size.height > VRAM_HEIGHT as u32 { - return Err(Error::from_text(format!("Image size ({}; {}) is to big for VRAM ({}, {})", img_size.width, img_size.height, VRAM_WIDTH, VRAM_HEIGHT))); - } - - let file_name = file.file_name().get_or_insert(OsStr::new("")).to_string_lossy().to_string(); - self.vram_file_list.push(slint::StandardListViewItem::from(file_name.as_str())); - self.vram_image_list.push(vram_image); - Ok(()) - } - - pub fn remove_vram_file(&mut self, idx: usize) { - self.vram_file_list.remove(idx); - self.vram_image_list.remove(idx); - } - - pub fn move_vram_image(&mut self, idx: usize, dx: i32, dy: i32) { - if let Some(mut vram_info) = self.vram_image_list.row_data(idx) { - vram_info.x += dx; - vram_info.y += dy; - - if vram_info.x < 0 { - vram_info.x = 0; - } - - if vram_info.y < 0 { - vram_info.y = 0; - } - - let (vram_img_width, vram_img_height) = (vram_info.img.size().width as i32, vram_info.img.size().height as i32); - if (vram_info.x + vram_img_width) > VRAM_WIDTH as i32 { - vram_info.x = VRAM_WIDTH as i32 - vram_img_width; - } - - if (vram_info.y + vram_img_height) > VRAM_HEIGHT as i32 { - vram_info.y = VRAM_HEIGHT as i32 - vram_img_height; - } - - self.vram_image_list.set_row_data(idx, vram_info); - } - } - - pub fn create_bg() -> Result { + fn create_bg() -> Result { Ok(slint::Image::from_rgba8_premultiplied(create_vram_bg(320, 256).ok_or(slint::PlatformError::Other("Failed creating VRAM background image".to_string()))?)) } } \ No newline at end of file diff --git a/src/Tools/tim_tool/src/gui/main_tab.rs b/src/Tools/tim_tool/src/gui/main_tab.rs new file mode 100644 index 00000000..5c45adc3 --- /dev/null +++ b/src/Tools/tim_tool/src/gui/main_tab.rs @@ -0,0 +1,98 @@ +use crate::{gui::{VRAM_HEIGHT, VRAM_WIDTH}, MainWindow, VRAMImage}; +use super::{GUIElementsRef, MainWindowRef}; + +use slint::Model; +use std::{ffi::OsStr, path::PathBuf, rc::Rc}; +use tool_helper::Error; + +pub struct MainTab { + main_window: MainWindowRef, + vram_file_list: Rc>, + vram_image_list: Rc>, +} + +impl MainTab { + pub fn new(main_window: MainWindowRef) -> MainTab { + let vram_file_list:Vec = main_window.borrow().get_main_tab_vram_file_list().iter().collect(); + let vram_file_list = Rc::new(slint::VecModel::from(vram_file_list)); + let vram_image_list = Rc::new(slint::VecModel::from(Vec::::new())); + + main_window.borrow().set_main_tab_vram_file_list(vram_file_list.clone().into()); + main_window.borrow().set_main_tab_vram_images(vram_image_list.clone().into()); + + MainTab{main_window, vram_file_list, vram_image_list} + } + + pub fn add_new_vram_file(&mut self, file: PathBuf) -> Result<(), Error> { + let vram_image = VRAMImage{ + img: slint::Image::load_from_path(&file).or_else(|_| {Err(Error::from_str("Failed loading image"))})?, + x: 0, + y: 0 + }; + + let img_size = vram_image.img.size(); + if img_size.width > VRAM_WIDTH as u32 || img_size.height > VRAM_HEIGHT as u32 { + return Err(Error::from_text(format!("Image size ({}; {}) is to big for VRAM ({}, {})", img_size.width, img_size.height, VRAM_WIDTH, VRAM_HEIGHT))); + } + + let file_name = file.file_name().get_or_insert(OsStr::new("")).to_string_lossy().to_string(); + self.vram_file_list.push(slint::StandardListViewItem::from(file_name.as_str())); + self.vram_image_list.push(vram_image); + Ok(()) + } + + pub fn remove_vram_file(&mut self, idx: usize) { + self.vram_file_list.remove(idx); + self.vram_image_list.remove(idx); + } + + pub fn move_vram_image(&mut self, idx: usize, dx: i32, dy: i32) { + if let Some(mut vram_info) = self.vram_image_list.row_data(idx) { + vram_info.x += dx; + vram_info.y += dy; + + if vram_info.x < 0 { + vram_info.x = 0; + } + + if vram_info.y < 0 { + vram_info.y = 0; + } + + let (vram_img_width, vram_img_height) = (vram_info.img.size().width as i32, vram_info.img.size().height as i32); + if (vram_info.x + vram_img_width) > VRAM_WIDTH as i32 { + vram_info.x = VRAM_WIDTH as i32 - vram_img_width; + } + + if (vram_info.y + vram_img_height) > VRAM_HEIGHT as i32 { + vram_info.y = VRAM_HEIGHT as i32 - vram_img_height; + } + + self.vram_image_list.set_row_data(idx, vram_info); + } + } + + pub fn on_move_vram_image(&self, gui_elements: GUIElementsRef, mut function: impl FnMut(&mut MainTab, &MainWindow, i32, i32, i32) + 'static) { + let main_window_cloned = self.main_window.clone(); + let gui_cloned = gui_elements.clone(); + self.main_window.borrow().on_move_vram_image(move |idx, dx, dy| { + function(&mut gui_cloned.borrow_mut().main_tab, &main_window_cloned.borrow(), idx, dx, dy); + }); + } + + pub fn on_remove_file(&self, gui_elements: GUIElementsRef, mut function: impl FnMut(&mut MainTab, &MainWindow, i32) + 'static) { + let main_window_cloned = self.main_window.clone(); + let gui_cloned = gui_elements.clone(); + self.main_window.borrow().on_main_tab_remove_file_clicked(move |idx| { + function(&mut gui_cloned.borrow_mut().main_tab, &main_window_cloned.borrow(), idx); + }); + } + + pub fn on_add_file(&self, gui_elements: GUIElementsRef, mut function: impl FnMut(&mut MainTab, &MainWindow) + 'static) { + let main_window_cloned = self.main_window.clone(); + let gui_cloned = gui_elements.clone(); + self.main_window.borrow().on_main_tab_add_file_clicked(move || { + function(&mut gui_cloned.borrow_mut().main_tab, &main_window_cloned.borrow()); + }); + } +} \ No newline at end of file diff --git a/src/Tools/tim_tool/src/gui/mod.rs b/src/Tools/tim_tool/src/gui/mod.rs index 82b6483c..163db6ce 100644 --- a/src/Tools/tim_tool/src/gui/mod.rs +++ b/src/Tools/tim_tool/src/gui/mod.rs @@ -1,5 +1,9 @@ +mod file_tab; mod gui_elements; +mod main_tab; +use crate::MainWindow; +use std::{cell::RefCell, rc::Rc}; use slint::{Rgba8Pixel, SharedPixelBuffer}; use tiny_skia::{Rect, Transform}; @@ -8,7 +12,10 @@ pub use gui_elements::GUIElements; pub const VRAM_WIDTH:usize = 1024; pub const VRAM_HEIGHT:usize = 512; -pub fn create_vram_bg(rect_width: u32, rect_height: u32) -> Option> { +type MainWindowRef = Rc>; +type GUIElementsRef = Rc>; + +fn create_vram_bg(rect_width: u32, rect_height: u32) -> Option> { let mut pixel_buffer = SharedPixelBuffer::::new(VRAM_WIDTH as u32, VRAM_HEIGHT as u32); let width = pixel_buffer.width(); let height = pixel_buffer.height(); diff --git a/src/Tools/tim_tool/src/main.rs b/src/Tools/tim_tool/src/main.rs index 1464fb5b..65c6861b 100644 --- a/src/Tools/tim_tool/src/main.rs +++ b/src/Tools/tim_tool/src/main.rs @@ -10,45 +10,48 @@ use slint::SharedString; slint::include_modules!(); fn main() -> Result<(), slint::PlatformError> { - let main_window = Rc::new(RefCell::new(MainWindow::new()?)); - let gui_elements = Rc::new(RefCell::new(GUIElements::new(main_window.clone()))); - let main_window = main_window.borrow(); + let main_window_ref = Rc::new(RefCell::new(MainWindow::new()?)); + let gui_elements_ref = Rc::new(RefCell::new(GUIElements::new(main_window_ref.clone())?)); - main_window.set_main_tab_vram_bg(GUIElements::create_bg()?); + setup_main_tab(gui_elements_ref.clone()); + setup_file_tab(gui_elements_ref.clone()); - let gui_elements_cloned = gui_elements.clone(); - main_window.on_main_tab_add_file_clicked(move || { - let mut gui_elements = gui_elements_cloned.borrow_mut(); - let file = FileDialog::new() + let main_window = main_window_ref.borrow(); + main_window.run() +} + +fn setup_main_tab(gui_elements_ref: Rc>) { + let gui_elements = gui_elements_ref.borrow(); + + gui_elements.main_tab.on_move_vram_image(gui_elements_ref.clone(), move |main_tab, _main_window, idx, dx, dy| { + main_tab.move_vram_image(idx as usize, dx, dy); + }); + + gui_elements.main_tab.on_remove_file(gui_elements_ref.clone(), move |main_tab, _main_window, idx| { + if idx >= 0 { + main_tab.remove_vram_file(idx as usize); + } + }); + + gui_elements.main_tab.on_add_file(gui_elements_ref.clone(), move |main_tab, _main_window| { + let file = FileDialog::new() .add_filter("Images", &["png", "bmp", "jpeg"]) .add_filter("All", &[""]) .set_title("Add TIM image") .pick_file(); if let Some(file) = file { - if let Result::Err(error) = gui_elements.add_new_vram_file(file) { + if let Result::Err(error) = main_tab.add_new_vram_file(file) { MessageDialog::new().set_title("Loading Image failed").set_level(rfd::MessageLevel::Error).set_description(error.to_string()).show(); } } }); +} - let gui_elements_cloned = gui_elements.clone(); - main_window.on_main_tab_remove_file_clicked(move |idx: i32| { - let mut gui_elements = gui_elements_cloned.borrow_mut(); - if idx >= 0 { - gui_elements.remove_vram_file(idx as usize); - } - }); +fn setup_file_tab(gui_elements_ref: Rc>) { + let gui_elements = gui_elements_ref.borrow(); - let gui_elements_cloned = gui_elements.clone(); - main_window.on_move_vram_image(move |idx: i32, dx: i32, dy: i32| { - let mut gui_elements = gui_elements_cloned.borrow_mut(); - gui_elements.move_vram_image(idx as usize, dx, dy); - }); - - let gui_elements_cloned = gui_elements.clone(); - main_window.on_file_tab_browse_convert_image(move || { - let gui_elements = gui_elements_cloned.borrow_mut(); + gui_elements.file_tab.on_browse_file(move |main_window| { let file = FileDialog::new() .add_filter("Images", &["png", "bmp", "jpeg"]) .add_filter("All", &[""]) @@ -56,12 +59,9 @@ fn main() -> Result<(), slint::PlatformError> { .pick_file(); if let Some(file) = file { - let main_window = gui_elements.main_window.borrow(); if let Some(file_path) = file.to_str() { main_window.set_file_tab_browse_path(SharedString::from(file_path)); } } }); - - main_window.run() } \ No newline at end of file