diff --git a/src/draw_thread.rs b/src/draw_thread.rs index de6c3cd..aaf08d9 100644 --- a/src/draw_thread.rs +++ b/src/draw_thread.rs @@ -6,7 +6,8 @@ use crate::{ AppMessage, }; use fltk::{ - app, + app, enums, + frame::Frame, input::{Input, MultilineInput}, menu, misc::Spinner, @@ -34,6 +35,8 @@ pub(crate) enum DrawMessage { Flush, /// Save to file Save, + /// Clone file + Clone, /// Delete file Delete, } @@ -59,6 +62,8 @@ pub(crate) fn spawn_image_thread( let mut tag_position_slider = main_win.tag_position_slider.clone(); let mut page = main_win.page.clone(); let mut status = main_win.status.clone(); + let mut count = main_win.count.clone(); + let mut dimension = main_win.dimension.clone(); let images_path = Arc::clone(&main_win.images_path); let mut _container: Option = None; @@ -82,6 +87,8 @@ pub(crate) fn spawn_image_thread( &mut quote_position_slider, &mut tag_position_slider, &mut page, + &mut count, + &mut dimension, &app_sender, &properties, &mut _container, @@ -108,6 +115,8 @@ pub(crate) fn spawn_image_thread( &mut quote_position_slider, &mut tag_position_slider, &mut page, + &mut count, + &mut dimension, &app_sender, &properties, &mut _container, @@ -132,6 +141,25 @@ pub(crate) fn spawn_image_thread( status.set_label(""); } } + DrawMessage::Clone => { + if let Some(cont) = &mut _container { + status.set_label("Cloning..."); + if let Some(path) = cont.clone_img() { + images_path + .write() + .unwrap() + .insert(file_choice.value() as usize, path.clone()); + file_choice.insert( + file_choice.value(), + path.file_name().unwrap().to_str().unwrap(), + enums::Shortcut::None, + menu::MenuFlag::Normal, + |_| {}, + ); + } + status.set_label(""); + } + } DrawMessage::Delete => { if let Some(cont) = &mut _container { status.set_label("Deleting to trash..."); @@ -169,6 +197,8 @@ fn load_image( quote_position_slider: &mut Slider, tag_position_slider: &mut Slider, page: &mut Page, + count: &mut Frame, + dimension: &mut Frame, app_sender: &app::Sender, properties: &Arc>, container: &mut Option, @@ -179,6 +209,7 @@ fn load_image( flush_buffer(app_sender, container); return; } + count.set_label(&format!("[{}/{}]", file_choice.value() + 1, imgs.len())); let file = imgs.get(file_choice.value() as usize).unwrap(); *container = Some(ImageContainer::new(&file, Arc::clone(properties))); @@ -207,6 +238,10 @@ fn load_image( quote_position_slider.set_value(saved_prop.quote_position); tag_position_slider.set_range(0.0, prop.original_dimension.1); tag_position_slider.set_value(saved_prop.tag_position); + dimension.set_label(&format!( + "[{}x{}]", + prop.original_dimension.0, prop.original_dimension.1 + )); prop.quote = saved_prop.quote; prop.tag = saved_prop.tag; diff --git a/src/main_window.rs b/src/main_window.rs index 0c35395..9a86367 100644 --- a/src/main_window.rs +++ b/src/main_window.rs @@ -45,8 +45,11 @@ pub(crate) struct MainWindow { pub(crate) reset_tag_position_btn: Button, pub(crate) reset_file_choice: Button, pub(crate) crop_btn: Button, + pub(crate) clone_btn: Button, pub(crate) delete_btn: Button, pub(crate) status: Frame, + pub(crate) count: Frame, + pub(crate) dimension: Frame, pub(crate) page: Page, pub(crate) images_path: Arc>>, pub(crate) draw_buff: Arc>>>, @@ -66,7 +69,7 @@ impl MainWindow { sender: app::Sender, draw_buff: Arc>>>, ) -> Self { - let mut win = Window::new(0, 0, 1000, 600, "Post Maker").center_screen(); + let mut win = Window::new(0, 0, 1000, 650, "Post Maker").center_screen(); win.set_icon(Some( SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(), )); @@ -178,6 +181,8 @@ impl MainWindow { Frame::default(); let delete_btn = Button::default().with_label("Delete"); actions_flex.set_size(&delete_btn, 100); + let clone_btn = Button::default().with_label("Clone"); + actions_flex.set_size(&clone_btn, 100); let crop_btn = Button::default().with_label("Crop"); actions_flex.set_size(&crop_btn, 100); Frame::default(); @@ -186,8 +191,12 @@ impl MainWindow { Frame::default(); + let info_flex = Flex::default().row(); + let count = Frame::default().with_align(enums::Align::Left | enums::Align::Inside); let status = Frame::default(); - controls_flex.set_size(&status, 30); + let dimension = Frame::default().with_align(enums::Align::Right | enums::Align::Inside); + info_flex.end(); + controls_flex.set_size(&info_flex, 30); controls_flex.end(); workspace_flex.set_size(&controls_flex, 360); @@ -204,6 +213,7 @@ impl MainWindow { Frame::default(); center_row_flex.set_size(¢er_col_flex, 400); center_row_flex.end(); + workspace_flex.end(); main_flex.end(); @@ -236,8 +246,11 @@ impl MainWindow { reset_tag_position_btn, reset_file_choice, crop_btn, + clone_btn, delete_btn, status, + count, + dimension, images_path: Arc::new(RwLock::new(vec![])), draw_buff, properties: Arc::clone(&properties), @@ -310,6 +323,17 @@ impl MainWindow { } }, ); + + self.menubar.add( + "&Help/About...\t", + Shortcut::None, + menu::MenuFlag::Normal, + move |_| { + dialog::message_default( + "Created with <3 by PiyushXCoder\nhttps://github.com/PiyushXCoder", + ); + }, + ); } fn draw(&mut self) { @@ -410,6 +434,19 @@ impl MainWindow { sender.send(DrawMessage::Save).unwrap() }); + let mut image = self.page.image.clone(); + let mut file_choice = self.file_choice.clone(); + let sender = self.sender.clone(); + self.clone_btn.set_callback(move |_| { + let ch = dialog::choice_default("Do you want to clone??", "Yes", "No", ""); + if ch == 0 { + sender.send(DrawMessage::Clone).unwrap(); + sender.send(DrawMessage::Open).unwrap(); + image.redraw(); + file_choice.redraw(); + } + }); + let mut image = self.page.image.clone(); let mut file_choice = self.file_choice.clone(); let sender = self.sender.clone(); diff --git a/src/utils.rs b/src/utils.rs index 89acb3c..47fee0b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -201,6 +201,32 @@ impl ImageContainer { } } + pub(crate) fn clone_img(&self) -> Option { + let prop = self.properties.read().unwrap(); + + match &prop.path { + Some(path) => { + let name = path.file_stem().unwrap().to_string_lossy(); + let ext = path.extension().unwrap().to_string_lossy(); + let new_file = format!("{}_copy.{}", name, ext); + let new_path = path.with_file_name(&new_file); + let path_conf = path.with_extension("conf"); + let path_conf_new = new_path.with_extension("conf"); + + if fs::copy(path, &new_path).is_err() { + dialog::message_default("Failed to clone image!"); + return None; + } + + if fs::copy(path_conf, &path_conf_new).is_err() { + dialog::message_default("Failed to clone image conf!"); + } + Some(new_path) + } + None => None, + } + } + pub(crate) fn delete(&self) { let prop = self.properties.read().unwrap();