diff --git a/src/Tools/tim_tool/src/gui/file_tab/callbacks.rs b/src/Tools/tim_tool/src/gui/file_tab/callbacks.rs index 2cfdb929..d4033bfa 100644 --- a/src/Tools/tim_tool/src/gui/file_tab/callbacks.rs +++ b/src/Tools/tim_tool/src/gui/file_tab/callbacks.rs @@ -4,7 +4,7 @@ use crate::{gui::{self, main_tab::{MainTab, NewVRAMImageInfo}, MutexTIMManager, use super::FileTab; use rfd::FileDialog; use slint::SharedString; -use tim_tool::logic::{project::{ImagePosition, Job, PaletteRect, Project}, tim::types::Encoding, TIMManager}; +use tim_tool::logic::{project::{FileSettings, ImagePosition, Job, PaletteRect, Project, Transparency}, tim::types::Encoding, TIMManager}; use tool_helper::Error; pub(super) fn on_browse_file(tim_manager: MutexTIMManager) -> impl FnMut(&mut FileTab, &MainWindow) -> Result<(), Error> + 'static { @@ -46,7 +46,7 @@ pub(super) fn on_add_image(tim_manager: MutexTIMManager) -> impl FnMut(&mut File let file_name = file_tab.get_file_name(); let encoding = file_tab.get_encoding()?; - add_unadded_tim(main_tab, &mut tim_manager.lock().expect("VRAM already locked"), UnaddedTIM::new(&file_name, encoding))?; + add_unadded_tim(main_tab, &mut tim_manager.lock().expect("VRAM already locked"), UnaddedTIM::new(&file_name, encoding), FileSettings::from_encoding(encoding))?; file_tab.clear_load(); main_window.invoke_change_to_main(); @@ -77,20 +77,20 @@ pub(super) fn on_load_project_clicked(tim_manager: MutexTIMManager) -> impl FnMu } for job in new_project.jobs { - let file_path = Job::create_file_path(job.file_path, open_location.as_str()); - let (_, _) = tim_manager.load_unadded_tim(&file_path)?; - let (pal_width, pal_height) = job.palette_rect.size.into(); + let file_path = Job::create_file_path(job.file_path, open_location.as_str()); + let (_, _) = tim_manager.load_unadded_tim(&file_path)?; + let (pal_x, pal_y, pal_width, pal_height) = if let Some(palette_rect) = job.palette_rect {palette_rect.into()} else {(0, 0, 0, 0)}; tim_manager.change_unadded_tim_palette_size(pal_width, pal_height)?; let unadded_tim = UnaddedTIM{ file_name: &job.name, image_x: job.image_pos.x, image_y: job.image_pos.y, - palette_x: job.palette_rect.pos.x, - palette_y: job.palette_rect.pos.y, - encoding: job.encoding + palette_x: pal_x, + palette_y: pal_y, + encoding: job.settings.encoding }; - add_unadded_tim(main_tab, &mut tim_manager, unadded_tim)?; + add_unadded_tim(main_tab, &mut tim_manager, unadded_tim, job.settings)?; } main_window.invoke_change_to_main(); @@ -126,7 +126,7 @@ pub(super) fn on_save_project_clicked(tim_manager: MutexTIMManager) -> impl FnMu if let Some(mut cur_palette) = cur_palette { cur_palette.pos = ImagePosition::new(vram.x as u16, vram.y as u16); if let Some(cur_job) = &mut cur_job { - cur_job.palette_rect = cur_palette; + cur_job.palette_rect = Some(cur_palette); } } None @@ -149,7 +149,11 @@ pub(super) fn on_save_project_clicked(tim_manager: MutexTIMManager) -> impl FnMu } } } else {tim.get_path()}; - cur_job = Some(Job::new(name, file_path, (vram.x as u16, vram.y as u16), Encoding::from_str(vram.encoding_str.as_str()))); + cur_job = Some(Job::new(name, file_path, (vram.x as u16, vram.y as u16), FileSettings::new( + vram.use_compression, + Transparency::from(vram.trans_setting), + Encoding::from_str(vram.encoding_str.as_str()) + ))); } prev_job } @@ -220,11 +224,11 @@ impl<'a> UnaddedTIM<'a> { } } -fn add_unadded_tim(main_tab: &mut MainTab, tim_manager: &mut TIMManager, unadded_tim: UnaddedTIM) -> Result<(), Error> { +fn add_unadded_tim(main_tab: &mut MainTab, tim_manager: &mut TIMManager, unadded_tim: UnaddedTIM, settings: FileSettings) -> Result<(), Error> { let (image, palette_image) = tim_manager.get_converted_unadded_tim_image(unadded_tim.encoding)?; let (full_image, _) = tim_manager.get_converted_unadded_tim_image(Encoding::FullColor)?; - let image = NewVRAMImageInfo::new(image, unadded_tim.image_x, unadded_tim.image_y, unadded_tim.encoding); - let palette_image = if let Some(palette_image) = palette_image { Some(NewVRAMImageInfo::new(palette_image, unadded_tim.palette_x, unadded_tim.palette_y, Encoding::FullColor)) } else { None }; + let image = NewVRAMImageInfo::new(image, unadded_tim.image_x, unadded_tim.image_y, settings); + let palette_image = if let Some(palette_image) = palette_image { Some(NewVRAMImageInfo::new(palette_image, unadded_tim.palette_x, unadded_tim.palette_y, FileSettings::from_encoding(Encoding::FullColor))) } else { None }; let images_created = main_tab.add_new_vram_file(unadded_tim.file_name, full_image, image, palette_image); if let Err(error) = tim_manager.add_unadded_tim(images_created) { diff --git a/src/Tools/tim_tool/src/gui/main_tab/mod.rs b/src/Tools/tim_tool/src/gui/main_tab/mod.rs index a4cf8087..0fec418e 100644 --- a/src/Tools/tim_tool/src/gui/main_tab/mod.rs +++ b/src/Tools/tim_tool/src/gui/main_tab/mod.rs @@ -4,18 +4,18 @@ use crate::{gui::{MutexTIMManager, VRAM_HEIGHT, VRAM_WIDTH}, VRAMImgData, VRAMIn use super::MainWindowRef; use slint::{Model, SharedString}; use std::{cell::RefCell, ops::RangeInclusive, rc::Rc, sync::{Arc, Mutex}}; -use tim_tool::logic::tim::types::Encoding; +use tim_tool::logic::project::FileSettings; pub struct NewVRAMImageInfo { - pub image: slint::Image, - pub x: u16, - pub y: u16, - pub encoding: Encoding, + pub image: slint::Image, + pub x: u16, + pub y: u16, + pub settings: FileSettings, } impl NewVRAMImageInfo { - pub fn new(image: slint::Image, x: u16, y: u16, encoding: Encoding) -> NewVRAMImageInfo { - NewVRAMImageInfo{image, x, y, encoding} + pub fn new(image: slint::Image, x: u16, y: u16, settings: FileSettings) -> NewVRAMImageInfo { + NewVRAMImageInfo{image, x, y, settings} } } @@ -84,16 +84,18 @@ impl MainTab { pub fn add_new_vram_file(&mut self, file_name: &String, full_image: slint::Image, texture: NewVRAMImageInfo, image_palette: Option) -> usize { let mut vram_data = self.vram.lock().expect("VRAM already locked"); let mut add_new_image = |file_name: &String, full_image: slint::Image, vram_image: NewVRAMImageInfo, palette_count: i32, is_palette: bool| { - let encoding_str = if is_palette {""} else {vram_image.encoding.to_str()}; + let encoding_str = if is_palette {""} else {vram_image.settings.encoding.to_str()}; let vram_image = VRAMData { images: VRAMImgData { full_image, image: vram_image.image, }, info: VRAMInfo { - x: vram_image.x as i32, - y: vram_image.y as i32, - encoding_str: SharedString::from(encoding_str), + x: vram_image.x as i32, + y: vram_image.y as i32, + encoding_str: SharedString::from(encoding_str), + use_compression: vram_image.settings.compress, + trans_setting: vram_image.settings.transparency.as_idx(), palette_count, is_palette, } diff --git a/src/Tools/tim_tool/src/logic/project/mod.rs b/src/Tools/tim_tool/src/logic/project/mod.rs index ab120cc1..c53f8633 100644 --- a/src/Tools/tim_tool/src/logic/project/mod.rs +++ b/src/Tools/tim_tool/src/logic/project/mod.rs @@ -2,6 +2,72 @@ use super::tim::types::Encoding; use serde::{Deserialize, Serialize}; use std::path::PathBuf; +#[derive(Serialize, Deserialize)] +pub struct FileSettings { + pub compress: bool, + pub transparency: Transparency, + pub encoding: Encoding, +} + +impl FileSettings { + pub fn new(compress: bool, transparency: Transparency, encoding: Encoding) -> FileSettings { + FileSettings{compress, transparency, encoding} + } + + pub fn from_encoding(encoding: Encoding) -> FileSettings { + let mut new_type = FileSettings::default(); + + new_type.encoding = encoding; + new_type + } +} + +impl std::default::Default for FileSettings { + fn default() -> Self { + Self{compress: Default::default(), transparency: Transparency::None, encoding: Encoding::FullColor} + } +} + +#[derive(Serialize, Deserialize)] +pub struct Job { + pub name: String, + pub file_path: PathBuf, + pub image_pos: ImagePosition, + pub palette_rect: Option, + pub settings: FileSettings, +} + +impl Job { + pub fn new(name: String, file_path: PathBuf, image_pos: (u16, u16), settings: FileSettings) -> Job { + Job{name, file_path, image_pos: ImagePosition{x: image_pos.0, y: image_pos.1}, palette_rect: None, settings} + } + + pub fn create_file_path>(file_path: PathBuf, location_path: &T) -> PathBuf { + if file_path.is_file() { + file_path + } + + else { + let mut new_file_path = PathBuf::from(location_path); + + new_file_path.pop(); + new_file_path.push(file_path); + new_file_path + } + } +} + +#[derive(Serialize, Deserialize)] +pub struct Project { + pub jobs: Vec +} + +impl Project { + pub fn new(jobs: Vec) -> Project { + Project{jobs} + } +} + #[derive(Serialize, Deserialize)] pub struct ImagePosition { pub x: u16, @@ -56,6 +122,12 @@ impl PaletteRect { } } +impl From for (u16, u16, u16, u16) { + fn from(value: PaletteRect) -> Self { + (value.pos.x, value.pos.y, value.size.width, value.size.height) + } +} + impl std::default::Default for PaletteRect { fn default() -> Self { PaletteRect{pos: ImagePosition::default(), size: ImageSize::default()} @@ -63,41 +135,30 @@ impl std::default::Default for PaletteRect { } #[derive(Serialize, Deserialize)] -pub struct Job { - pub name: String, - pub file_path: PathBuf, - pub image_pos: ImagePosition, - pub palette_rect: PaletteRect, - pub encoding: Encoding, +pub enum Transparency { + None, + FirstColor, + PSXSemi, + Both, } -impl Job { - pub fn new(name: String, file_path: PathBuf, image_pos: (u16, u16), encoding: Encoding) -> Job { - Job{name, file_path, image_pos: ImagePosition{x: image_pos.0, y: image_pos.1}, palette_rect: PaletteRect::default(), encoding} - } - - pub fn create_file_path>(file_path: PathBuf, location_path: &T) -> PathBuf { - if file_path.is_file() { - file_path - } - - else { - let mut new_file_path = PathBuf::from(location_path); - - new_file_path.pop(); - new_file_path.push(file_path); - new_file_path +impl Transparency { + pub fn from(selection: i32) -> Transparency { + match selection { + 0 => Transparency::None, + 1 => Transparency::FirstColor, + 2 => Transparency::PSXSemi, + 3 => Transparency::Both, + _ => Transparency::None, } } -} -#[derive(Serialize, Deserialize)] -pub struct Project { - pub jobs: Vec -} - -impl Project { - pub fn new(jobs: Vec) -> Project { - Project{jobs} + pub fn as_idx(&self) -> i32 { + match self { + Transparency::None => 0, + Transparency::FirstColor => 1, + Transparency::PSXSemi => 2, + Transparency::Both => 3, + } } } \ No newline at end of file diff --git a/src/Tools/tim_tool/ui/tab/main-tab.slint b/src/Tools/tim_tool/ui/tab/main-tab.slint index 5ae87712..1682ad58 100644 --- a/src/Tools/tim_tool/ui/tab/main-tab.slint +++ b/src/Tools/tim_tool/ui/tab/main-tab.slint @@ -1,5 +1,5 @@ import { VRAMArea } from "../vram-components.slint"; -import { Button, ComboBox, GroupBox, StandardListView, LineEdit, ScrollView, Slider } from "std-widgets.slint"; +import { Button, CheckBox, ComboBox, GroupBox, StandardListView, LineEdit, ScrollView, Slider } from "std-widgets.slint"; struct VRAMImgData { full_image: image, @@ -7,11 +7,13 @@ struct VRAMImgData { } struct VRAMInfo { - x: int, - y: int, - encoding_str: string, - palette_count: int, - is_palette: bool, // < Can we combine the palette into this, instead of having it separate? + x: int, + y: int, + encoding_str: string, + use_compression: bool, + trans_setting: int, + palette_count: int, + is_palette: bool, // < Can we combine the palette into this, instead of having it separate? } struct VRAMData { @@ -96,6 +98,14 @@ export component MainTab inherits Rectangle { encoding_text.encoding_str = vram_data.info.encoding_str; cur_sel_img.visible = true; + if !vram-data.info.is_palette { + file_settings_box.set_active(i); + } + + else { + file_settings_box.set_inactive(); + } + vram_files_list.current-item = i; } } @@ -171,6 +181,14 @@ export component MainTab inherits Rectangle { cur_sel_img.source = root.vram_data[current-item].images.full_image; encoding_text.encoding_str = root.vram_data[current-item].info.encoding_str; cur_sel_img.visible = true; + + if !root.vram_data[current-item].info.is_palette { + file_settings_box.set_active(current-item); + } + + else { + file_settings_box.set_inactive(); + } } item-pointer-event(item, event, position) => { @@ -279,6 +297,54 @@ export component MainTab inherits Rectangle { } } } + file_settings_box := GroupBox { + title: "File settings"; + enabled: false; + + VerticalLayout { + alignment: start; + lz4_check_box := CheckBox { + text: "Compress (lz4)"; + enabled: file_settings_box.enabled; + + toggled => { + if(vram_files_list.current-item != -1) { + root.vram_data[vram_files_list.current-item].info.use_compression = self.checked; + } + } + } + + GroupBox { + title: "Transparency:"; + enabled: file_settings_box.enabled; + VerticalLayout { + alignment: start; + trans_combo_box := ComboBox { + model: ["No transparency", "First color transparent", "PSX semi-transparency", "Both"]; + enabled: file_settings_box.enabled; + + selected(current-value) => { + if(vram_files_list.current-item != -1) { + root.vram_data[vram_files_list.current-item].info.trans_setting = self.current-index; + } + } + } + } + } + } + + public function set_active(current-item: int) { + lz4_check_box.checked = root.vram_data[current-item].info.use_compression; + trans_combo_box.current-index = root.vram_data[current-item].info.trans_setting; + self.enabled = true; + } + + public function set_inactive() { + lz4_check_box.checked = false; + trans_combo_box.current-index = 0; + self.enabled = false; + } + } } } }