From 386c0bc2677f8051f5d883facad19065a092ec19 Mon Sep 17 00:00:00 2001 From: Piyush Mishra Date: Sun, 23 Jan 2022 21:02:49 +0530 Subject: [PATCH] added: 1) subquote 2, tag 2 2) combined rgb 3) colour rgb button 4) new layout to config 5) lots of fixes --- src/config.rs | 12 + src/config_window.rs | 803 +++++++++++++++++++++++++++++++------------ src/draw_thread.rs | 78 +++-- src/globals.rs | 24 ++ src/main_window.rs | 403 ++++++++++++++++------ src/utils.rs | 142 +++++--- 6 files changed, 1063 insertions(+), 399 deletions(-) diff --git a/src/config.rs b/src/config.rs index 72e3f47..a3b136a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -80,13 +80,19 @@ impl Into for Themes { pub struct ConfigFile { pub quote_font_ttf: String, pub subquote_font_ttf: String, + pub subquote2_font_ttf: String, pub tag_font_ttf: String, + pub tag2_font_ttf: String, pub quote_font_ratio: f64, pub subquote_font_ratio: f64, + pub subquote2_font_ratio: f64, pub tag_font_ratio: f64, + pub tag2_font_ratio: f64, pub quote_position_ratio: f64, pub subquote_position_ratio: f64, + pub subquote2_position_ratio: f64, pub tag_position_ratio: f64, + pub tag2_position_ratio: f64, pub image_ratio: (f64, f64), pub color_layer: [u8; 4], } @@ -96,13 +102,19 @@ impl Default for ConfigFile { Self { quote_font_ttf: String::new(), subquote_font_ttf: String::new(), + subquote2_font_ttf: String::new(), tag_font_ttf: String::new(), + tag2_font_ttf: String::new(), quote_font_ratio: 230.0, subquote_font_ratio: 230.0, + subquote2_font_ratio: 230.0, tag_font_ratio: 150.0, + tag2_font_ratio: 150.0, quote_position_ratio: 0.7, subquote_position_ratio: 0.8, + subquote2_position_ratio: 0.8, tag_position_ratio: 0.5, + tag2_position_ratio: 0.5, image_ratio: (4.0, 5.0), color_layer: [20, 22, 25, 197], } diff --git a/src/config_window.rs b/src/config_window.rs index 2d5c4f5..4ef9a40 100644 --- a/src/config_window.rs +++ b/src/config_window.rs @@ -7,11 +7,10 @@ use fltk::{ browser::{Browser, BrowserType}, button::Button, dialog::{self, FileDialogOptions, NativeFileChooser}, - enums::{Align, Font}, + enums::{self, Align, Event, Font}, frame::Frame, group::Flex, image::SvgImage, - misc::Spinner, output::Output, prelude::*, valuator::ValueInput, @@ -20,7 +19,7 @@ use fltk::{ use crate::{ config::{self, ConfigFile}, - globals, + globals, utils, }; pub(crate) struct ConfigWindow { @@ -33,20 +32,26 @@ pub(crate) struct ConfigWindow { pub(crate) quote_font_ttf_browse: Button, pub(crate) subquote_font_ttf: Output, pub(crate) subquote_font_ttf_browse: Button, + pub(crate) subquote2_font_ttf: Output, + pub(crate) subquote2_font_ttf_browse: Button, pub(crate) tag_font_ttf: Output, pub(crate) tag_font_ttf_browse: Button, + pub(crate) tag2_font_ttf: Output, + pub(crate) tag2_font_ttf_browse: Button, pub(crate) quote_font_ratio: ValueInput, pub(crate) subquote_font_ratio: ValueInput, + pub(crate) subquote2_font_ratio: ValueInput, pub(crate) tag_font_ratio: ValueInput, + pub(crate) tag2_font_ratio: ValueInput, pub(crate) quote_position_ratio: ValueInput, pub(crate) subquote_position_ratio: ValueInput, + pub(crate) subquote2_position_ratio: ValueInput, pub(crate) tag_position_ratio: ValueInput, + pub(crate) tag2_position_ratio: ValueInput, pub(crate) image_ratio_width: ValueInput, pub(crate) image_ratio_height: ValueInput, - pub(crate) layer_red: Spinner, - pub(crate) layer_green: Spinner, - pub(crate) layer_blue: Spinner, - pub(crate) layer_alpha: Spinner, + pub(crate) layer_rgb: Button, + pub(crate) layer_alpha: ValueInput, pub(crate) defaults_btn: Button, pub(crate) save_btn: Button, pub(crate) cancel_btn: Button, @@ -57,11 +62,11 @@ pub(crate) struct ConfigWindow { impl ConfigWindow { pub(crate) fn new() -> Self { let configs = config::get_configs().unwrap_or(HashMap::new()); - let mut win = Window::new(0, 0, 730, 530, "Config").center_screen(); + let mut win = Window::new(0, 0, 900, 680, "Config").center_screen(); win.set_icon(Some( SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(), )); - let mut row = Flex::default().with_size(720, 520).with_pos(5, 5).row(); + let mut row = Flex::default().with_size(890, 670).with_pos(5, 5).row(); let mut config_picker_flex = Flex::default().column(); // Picker let browse = Browser::default().with_type(BrowserType::Hold); @@ -86,147 +91,240 @@ impl ConfigWindow { let mut col = Flex::default().column(); + let mut label = Frame::default().with_label("Fonts:"); + label.set_label_font(enums::Font::HelveticaBold); + col.set_size(&label, 30); + // Fonts Group + let row_grp = Flex::default().row(); + // column 1 + let mut col_grp = Flex::default().column(); let mut quote_font_ttf_grp = Flex::default().row(); quote_font_ttf_grp.set_size( &Frame::default() - .with_label("Font for quote (ttf)") + .with_label("Quote") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let quote_font_ttf = Output::default(); let quote_font_ttf_browse = Button::default().with_label("Pick"); quote_font_ttf_grp.set_size("e_font_ttf_browse, 50); quote_font_ttf_grp.end(); - col.set_size("e_font_ttf_grp, 30); + col_grp.set_size("e_font_ttf_grp, 30); let mut subquote_font_ttf_grp = Flex::default().row(); subquote_font_ttf_grp.set_size( &Frame::default() - .with_label("Font for Subquote (ttf)") + .with_label("Subquote") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let subquote_font_ttf = Output::default(); let subquote_font_ttf_browse = Button::default().with_label("Pick"); subquote_font_ttf_grp.set_size(&subquote_font_ttf_browse, 50); subquote_font_ttf_grp.end(); - col.set_size(&subquote_font_ttf_grp, 30); + col_grp.set_size(&subquote_font_ttf_grp, 30); + let mut subquote2_font_ttf_grp = Flex::default().row(); + subquote2_font_ttf_grp.set_size( + &Frame::default() + .with_label("Subquote 2") + .with_align(Align::Right | Align::Inside), + 130, + ); + let subquote2_font_ttf = Output::default(); + let subquote2_font_ttf_browse = Button::default().with_label("Pick"); + subquote2_font_ttf_grp.set_size(&subquote2_font_ttf_browse, 50); + subquote2_font_ttf_grp.end(); + col_grp.set_size(&subquote2_font_ttf_grp, 30); + col_grp.end(); + + // column 2 + let mut col_grp = Flex::default().column(); let mut tag_font_ttf_grp = Flex::default().row(); tag_font_ttf_grp.set_size( &Frame::default() - .with_label("Font for tag (ttf)") + .with_label("Tag") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let tag_font_ttf = Output::default(); let tag_font_ttf_browse = Button::default().with_label("Pick"); tag_font_ttf_grp.set_size(&tag_font_ttf_browse, 50); tag_font_ttf_grp.end(); - col.set_size(&tag_font_ttf_grp, 30); + col_grp.set_size(&tag_font_ttf_grp, 30); + let mut tag2_font_ttf_grp = Flex::default().row(); + tag2_font_ttf_grp.set_size( + &Frame::default() + .with_label("Tag 2") + .with_align(Align::Right | Align::Inside), + 130, + ); + let tag2_font_ttf = Output::default(); + let tag2_font_ttf_browse = Button::default().with_label("Pick"); + tag2_font_ttf_grp.set_size(&tag2_font_ttf_browse, 50); + tag2_font_ttf_grp.end(); + col_grp.set_size(&tag2_font_ttf_grp, 30); + col_grp.end(); + row_grp.end(); + col.set_size(&row_grp, 110); + + let mut label = Frame::default().with_label("Ratio of size of text:"); + label.set_label_font(enums::Font::HelveticaBold); + col.set_size(&label, 15); + let mut hint = Frame::default().with_label("Font size in image of resolution 4000x5000"); + hint.set_label_font(Font::CourierItalic); + hint.set_label_size(12); + col.set_size(&hint, 20); + // Size Ratio Group + let row_grp = Flex::default().row(); + // column 1 + let mut col_grp = Flex::default().column(); let mut quote_font_ratio_grp = Flex::default().row(); quote_font_ratio_grp.set_size( &Frame::default() - .with_label("Quote text size ratio") + .with_label("Quote") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let quote_font_ratio = ValueInput::default(); quote_font_ratio_grp.end(); - col.set_size("e_font_ratio_grp, 30); - - let mut grp = Flex::default().row(); - grp.set_size(&Frame::default(), 190); - let mut hint = Frame::default() - .with_label("Font size in image of resolution 4000x5000") - .with_align(Align::Left | Align::Inside); - hint.set_label_font(Font::CourierItalic); - hint.set_label_size(12); - grp.end(); - col.set_size(&grp, 13); + col_grp.set_size("e_font_ratio_grp, 30); let mut subquote_font_ratio_grp = Flex::default().row(); subquote_font_ratio_grp.set_size( &Frame::default() - .with_label("Subquote text size ratio") + .with_label("Subquote") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let subquote_font_ratio = ValueInput::default(); subquote_font_ratio_grp.end(); - col.set_size(&subquote_font_ratio_grp, 30); + col_grp.set_size(&subquote_font_ratio_grp, 30); - let mut grp = Flex::default().row(); - grp.set_size(&Frame::default(), 190); - let mut hint = Frame::default() - .with_label("Font size in image of resolution 4000x5000") - .with_align(Align::Left | Align::Inside); - hint.set_label_font(Font::CourierItalic); - hint.set_label_size(12); - grp.end(); - col.set_size(&grp, 13); + let mut subquote2_font_ratio_grp = Flex::default().row(); + subquote2_font_ratio_grp.set_size( + &Frame::default() + .with_label("Subquote 2") + .with_align(Align::Right | Align::Inside), + 130, + ); + let subquote2_font_ratio = ValueInput::default(); + subquote2_font_ratio_grp.end(); + col_grp.set_size(&subquote2_font_ratio_grp, 30); + col_grp.end(); + // column 2 + let mut col_grp = Flex::default().column(); let mut tag_font_ratio_grp = Flex::default().row(); tag_font_ratio_grp.set_size( &Frame::default() - .with_label("Tag text size ratio") + .with_label("Tag") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let tag_font_ratio = ValueInput::default(); tag_font_ratio_grp.end(); - col.set_size(&tag_font_ratio_grp, 30); + col_grp.set_size(&tag_font_ratio_grp, 30); - let mut grp = Flex::default().row(); - grp.set_size(&Frame::default(), 190); - let mut hint = Frame::default() - .with_label("Font size in image of resolution 4000x5000") - .with_align(Align::Left | Align::Inside); + let mut tag2_font_ratio_grp = Flex::default().row(); + tag2_font_ratio_grp.set_size( + &Frame::default() + .with_label("Tag 2") + .with_align(Align::Right | Align::Inside), + 130, + ); + let tag2_font_ratio = ValueInput::default(); + tag2_font_ratio_grp.end(); + col_grp.set_size(&tag2_font_ratio_grp, 30); + + col_grp.end(); + row_grp.end(); + col.set_size(&row_grp, 110); + + let mut label = Frame::default().with_label("Position percentage of text:"); + label.set_label_font(enums::Font::HelveticaBold); + col.set_size(&label, 15); + let mut hint = + Frame::default().with_label("Percentage of height at which text to be place"); hint.set_label_font(Font::CourierItalic); hint.set_label_size(12); - grp.end(); - col.set_size(&grp, 13); - + col.set_size(&hint, 20); + // Size Ratio Group + let row_grp = Flex::default().row(); + // column 1 + let mut col_grp = Flex::default().column(); let mut quote_position_ratio_grp = Flex::default().row(); quote_position_ratio_grp.set_size( &Frame::default() - .with_label("Quote text position ratio") + .with_label("Quote") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let quote_position_ratio = ValueInput::default(); quote_position_ratio_grp.end(); - col.set_size("e_position_ratio_grp, 30); + col_grp.set_size("e_position_ratio_grp, 30); let mut subquote_position_ratio_grp = Flex::default().row(); subquote_position_ratio_grp.set_size( &Frame::default() - .with_label("Subquote text position ratio") + .with_label("Subquote") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let subquote_position_ratio = ValueInput::default(); subquote_position_ratio_grp.end(); - col.set_size(&subquote_position_ratio_grp, 30); + col_grp.set_size(&subquote_position_ratio_grp, 30); + let mut subquote2_position_ratio_grp = Flex::default().row(); + subquote2_position_ratio_grp.set_size( + &Frame::default() + .with_label("Subquote 2") + .with_align(Align::Right | Align::Inside), + 130, + ); + let subquote2_position_ratio = ValueInput::default(); + subquote2_position_ratio_grp.end(); + col_grp.set_size(&subquote2_position_ratio_grp, 30); + col_grp.end(); + + // column 2 + let mut col_grp = Flex::default().column(); let mut tag_position_ratio_grp = Flex::default().row(); tag_position_ratio_grp.set_size( &Frame::default() - .with_label("Tag text position ratio") + .with_label("Tag") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let tag_position_ratio = ValueInput::default(); tag_position_ratio_grp.end(); - col.set_size(&tag_position_ratio_grp, 30); + col_grp.set_size(&tag_position_ratio_grp, 30); + + let mut tag2_position_ratio_grp = Flex::default().row(); + tag2_position_ratio_grp.set_size( + &Frame::default() + .with_label("Tag 2") + .with_align(Align::Right | Align::Inside), + 130, + ); + let tag2_position_ratio = ValueInput::default(); + tag2_position_ratio_grp.end(); + col_grp.set_size(&tag2_position_ratio_grp, 30); + col_grp.end(); + row_grp.end(); + col.set_size(&row_grp, 100); + + let mut label = Frame::default().with_label("Image:"); + label.set_label_font(enums::Font::HelveticaBold); + col.set_size(&label, 30); let mut image_ratio_grp = Flex::default().row(); image_ratio_grp.set_size( &Frame::default() .with_label("Image size ratio") .with_align(Align::Right | Align::Inside), - 190, + 130, ); let image_ratio_width = ValueInput::default(); image_ratio_grp.set_size(&Frame::default().with_label("x"), 30); @@ -234,31 +332,25 @@ impl ConfigWindow { image_ratio_grp.end(); col.set_size(&image_ratio_grp, 30); - col.set_size( - &Frame::default().with_label("Default colour shader to use with new images:"), - 30, - ); + let mut label = Frame::default().with_label("Colour for dark layer:"); + label.set_label_font(enums::Font::HelveticaBold); + col.set_size(&label, 15); + let mut hint = + Frame::default().with_label("Alpha should be between (0-255), Alpha mean opacity"); + hint.set_label_font(Font::CourierItalic); + hint.set_label_size(12); + col.set_size(&hint, 20); - let mut darklayer_grp = Flex::default().row(); - darklayer_grp.set_pad(2); - darklayer_grp.set_size(&Frame::default().with_label("Red"), 30); - let mut layer_red = Spinner::default(); - layer_red.set_range(0.0, 255.0); - // darklayer_flex.set_size(&layer_red, 50); - darklayer_grp.set_size(&Frame::default().with_label("Green"), 40); - let mut layer_green = Spinner::default(); - layer_green.set_range(0.0, 255.0); - // darklayer_flex.set_size(&layer_green, 50); - darklayer_grp.set_size(&Frame::default().with_label("Blue"), 30); - let mut layer_blue = Spinner::default(); - layer_blue.set_range(0.0, 255.0); - // darklayer_flex.set_size(&layer_blue, 50); - darklayer_grp.set_size(&Frame::default().with_label("Alpha"), 40); - let mut layer_alpha = Spinner::default(); - layer_alpha.set_range(0.0, 255.0); - // darklayer_flex.set_size(&layer_alpha, 50); - darklayer_grp.end(); - col.set_size(&darklayer_grp, 30); + let mut darklayer_flex = Flex::default().row(); + darklayer_flex.set_pad(2); + darklayer_flex.set_size(&Frame::default().with_label("Colour"), 50); + let mut layer_rgb = Button::default(); + layer_rgb.set_frame(enums::FrameType::BorderBox); + + darklayer_flex.set_size(&Frame::default().with_label("Alpha"), 50); + let layer_alpha = ValueInput::default(); + darklayer_flex.end(); + col.set_size(&darklayer_flex, 30); Frame::default(); @@ -290,19 +382,25 @@ impl ConfigWindow { quote_font_ttf_browse, subquote_font_ttf, subquote_font_ttf_browse, + subquote2_font_ttf, + subquote2_font_ttf_browse, tag_font_ttf, tag_font_ttf_browse, + tag2_font_ttf, + tag2_font_ttf_browse, quote_font_ratio, subquote_font_ratio, + subquote2_font_ratio, tag_font_ratio, + tag2_font_ratio, quote_position_ratio, subquote_position_ratio, + subquote2_position_ratio, tag_position_ratio, + tag2_position_ratio, image_ratio_width, image_ratio_height, - layer_red, - layer_green, - layer_blue, + layer_rgb, layer_alpha, defaults_btn, save_btn, @@ -330,21 +428,29 @@ impl ConfigWindow { .set_value(config.quote_font_ttf.as_str()); self.subquote_font_ttf .set_value(config.subquote_font_ttf.as_str()); + self.subquote2_font_ttf + .set_value(config.subquote2_font_ttf.as_str()); self.tag_font_ttf.set_value(config.tag_font_ttf.as_str()); + self.tag2_font_ttf.set_value(config.tag2_font_ttf.as_str()); self.quote_font_ratio.set_value(config.quote_font_ratio); self.subquote_font_ratio .set_value(config.subquote_font_ratio); + self.subquote2_font_ratio + .set_value(config.subquote2_font_ratio); self.tag_font_ratio.set_value(config.tag_font_ratio); + self.tag2_font_ratio.set_value(config.tag2_font_ratio); self.quote_position_ratio .set_value(config.quote_position_ratio); self.subquote_position_ratio .set_value(config.subquote_position_ratio); + self.subquote2_position_ratio + .set_value(config.subquote2_position_ratio); self.tag_position_ratio.set_value(config.tag_position_ratio); + self.tag2_position_ratio + .set_value(config.tag2_position_ratio); self.image_ratio_width.set_value(config.image_ratio.0); self.image_ratio_height.set_value(config.image_ratio.1); - self.layer_red.set_value(config.color_layer[0] as f64); - self.layer_green.set_value(config.color_layer[1] as f64); - self.layer_blue.set_value(config.color_layer[2] as f64); + utils::set_color_btn_rgba(config.color_layer, &mut self.layer_rgb); self.layer_alpha.set_value(config.color_layer[3] as f64); *self.did_save.borrow_mut() = false; drop(config); @@ -358,18 +464,22 @@ impl ConfigWindow { fn event(&mut self) { let mut quote_font_ttf = self.quote_font_ttf.clone(); let mut subquote_font_ttf = self.subquote_font_ttf.clone(); + let mut subquote2_font_ttf = self.subquote2_font_ttf.clone(); let mut tag_font_ttf = self.tag_font_ttf.clone(); + let mut tag2_font_ttf = self.tag2_font_ttf.clone(); let mut quote_font_ratio = self.quote_font_ratio.clone(); let mut subquote_font_ratio = self.subquote_font_ratio.clone(); + let mut subquote2_font_ratio = self.subquote2_font_ratio.clone(); let mut tag_font_ratio = self.tag_font_ratio.clone(); + let mut tag2_font_ratio = self.tag2_font_ratio.clone(); let mut quote_position_ratio = self.quote_position_ratio.clone(); let mut subquote_position_ratio = self.subquote_position_ratio.clone(); + let mut subquote2_position_ratio = self.subquote2_position_ratio.clone(); let mut tag_position_ratio = self.tag_position_ratio.clone(); + let mut tag2_position_ratio = self.tag2_position_ratio.clone(); let mut image_ratio_width = self.image_ratio_width.clone(); let mut image_ratio_height = self.image_ratio_height.clone(); - let mut layer_red = self.layer_red.clone(); - let mut layer_green = self.layer_green.clone(); - let mut layer_blue = self.layer_blue.clone(); + let mut layer_rgb = self.layer_rgb.clone(); let mut layer_alpha = self.layer_alpha.clone(); let mut browse = self.browse.clone(); let configs = Rc::clone(&self.configs); @@ -394,64 +504,51 @@ impl ConfigWindow { } }; - if let Some(conf) = configs - .borrow_mut() - .get_mut(&browse.selected_text().unwrap()) - { - conf.quote_font_ttf = quote_font_ttf.value(); - conf.subquote_font_ttf = subquote_font_ttf.value(); - conf.tag_font_ttf = tag_font_ttf.value(); - conf.quote_font_ratio = quote_font_ratio.value(); - conf.subquote_font_ratio = subquote_font_ratio.value(); - conf.tag_font_ratio = tag_font_ratio.value(); - conf.quote_position_ratio = quote_position_ratio.value(); - conf.subquote_position_ratio = subquote_position_ratio.value(); - conf.tag_position_ratio = tag_position_ratio.value(); - conf.image_ratio = (image_ratio_width.value(), image_ratio_height.value()); - conf.color_layer = [ - layer_red.value() as u8, - layer_green.value() as u8, - layer_blue.value() as u8, - layer_alpha.value() as u8, - ]; - } - let conf = ConfigFile::default(); quote_font_ttf.set_value(&conf.quote_font_ttf); subquote_font_ttf.set_value(&conf.subquote_font_ttf); + subquote2_font_ttf.set_value(&conf.subquote2_font_ttf); tag_font_ttf.set_value(&conf.tag_font_ttf); + tag2_font_ttf.set_value(&conf.tag2_font_ttf); quote_font_ratio.set_value(conf.quote_font_ratio); subquote_font_ratio.set_value(conf.subquote_font_ratio); + subquote2_font_ratio.set_value(conf.subquote2_font_ratio); tag_font_ratio.set_value(conf.tag_font_ratio); + tag2_font_ratio.set_value(conf.tag2_font_ratio); quote_position_ratio.set_value(conf.quote_position_ratio); subquote_position_ratio.set_value(conf.subquote_position_ratio); + subquote2_position_ratio.set_value(conf.subquote2_position_ratio); tag_position_ratio.set_value(conf.tag_position_ratio); + tag2_position_ratio.set_value(conf.tag2_position_ratio); image_ratio_width.set_value(conf.image_ratio.0); image_ratio_height.set_value(conf.image_ratio.1); - layer_red.set_value(conf.color_layer[0] as f64); - layer_green.set_value(conf.color_layer[1] as f64); - layer_blue.set_value(conf.color_layer[2] as f64); + utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb); layer_alpha.set_value(conf.color_layer[3] as f64); browse.add(&name); configs.borrow_mut().insert(name.clone(), conf); browse.select(browse.size()); *selected_browse_line.borrow_mut() = browse.value(); + layer_rgb.redraw(); }); let mut quote_font_ttf = self.quote_font_ttf.clone(); let mut subquote_font_ttf = self.subquote_font_ttf.clone(); + let mut subquote2_font_ttf = self.subquote2_font_ttf.clone(); let mut tag_font_ttf = self.tag_font_ttf.clone(); + let mut tag2_font_ttf = self.tag2_font_ttf.clone(); let mut quote_font_ratio = self.quote_font_ratio.clone(); let mut subquote_font_ratio = self.subquote_font_ratio.clone(); + let mut subquote2_font_ratio = self.subquote2_font_ratio.clone(); let mut tag_font_ratio = self.tag_font_ratio.clone(); + let mut tag2_font_ratio = self.tag2_font_ratio.clone(); let mut quote_position_ratio = self.quote_position_ratio.clone(); let mut subquote_position_ratio = self.subquote_position_ratio.clone(); + let mut subquote2_position_ratio = self.subquote2_position_ratio.clone(); let mut tag_position_ratio = self.tag_position_ratio.clone(); + let mut tag2_position_ratio = self.tag2_position_ratio.clone(); let mut image_ratio_width = self.image_ratio_width.clone(); let mut image_ratio_height = self.image_ratio_height.clone(); - let mut layer_red = self.layer_red.clone(); - let mut layer_green = self.layer_green.clone(); - let mut layer_blue = self.layer_blue.clone(); + let mut layer_rgb = self.layer_rgb.clone(); let mut layer_alpha = self.layer_alpha.clone(); let mut browse = self.browse.clone(); let configs = Rc::clone(&self.configs); @@ -478,36 +575,45 @@ impl ConfigWindow { if let Some(conf) = configs.borrow().get(&browse.selected_text().unwrap()) { quote_font_ttf.set_value(&conf.quote_font_ttf); subquote_font_ttf.set_value(&conf.subquote_font_ttf); + subquote2_font_ttf.set_value(&conf.subquote2_font_ttf); tag_font_ttf.set_value(&conf.tag_font_ttf); + tag2_font_ttf.set_value(&conf.tag2_font_ttf); quote_font_ratio.set_value(conf.quote_font_ratio); subquote_font_ratio.set_value(conf.subquote_font_ratio); + subquote2_font_ratio.set_value(conf.subquote2_font_ratio); tag_font_ratio.set_value(conf.tag_font_ratio); + tag2_font_ratio.set_value(conf.tag2_font_ratio); quote_position_ratio.set_value(conf.quote_position_ratio); subquote_position_ratio.set_value(conf.subquote_position_ratio); + subquote2_position_ratio.set_value(conf.subquote2_position_ratio); tag_position_ratio.set_value(conf.tag_position_ratio); + tag2_position_ratio.set_value(conf.tag2_position_ratio); image_ratio_width.set_value(conf.image_ratio.0); image_ratio_height.set_value(conf.image_ratio.1); - layer_red.set_value(conf.color_layer[0] as f64); - layer_green.set_value(conf.color_layer[1] as f64); - layer_blue.set_value(conf.color_layer[2] as f64); + utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb); layer_alpha.set_value(conf.color_layer[3] as f64); + layer_rgb.redraw(); } }); let mut quote_font_ttf = self.quote_font_ttf.clone(); let mut subquote_font_ttf = self.subquote_font_ttf.clone(); + let mut subquote2_font_ttf = self.subquote2_font_ttf.clone(); let mut tag_font_ttf = self.tag_font_ttf.clone(); + let mut tag2_font_ttf = self.tag2_font_ttf.clone(); let mut quote_font_ratio = self.quote_font_ratio.clone(); let mut subquote_font_ratio = self.subquote_font_ratio.clone(); + let mut subquote2_font_ratio = self.subquote2_font_ratio.clone(); let mut tag_font_ratio = self.tag_font_ratio.clone(); + let mut tag2_font_ratio = self.tag2_font_ratio.clone(); let mut quote_position_ratio = self.quote_position_ratio.clone(); let mut subquote_position_ratio = self.subquote_position_ratio.clone(); + let mut subquote2_position_ratio = self.subquote2_position_ratio.clone(); let mut tag_position_ratio = self.tag_position_ratio.clone(); + let mut tag2_position_ratio = self.tag2_position_ratio.clone(); let mut image_ratio_width = self.image_ratio_width.clone(); let mut image_ratio_height = self.image_ratio_height.clone(); - let mut layer_red = self.layer_red.clone(); - let mut layer_green = self.layer_green.clone(); - let mut layer_blue = self.layer_blue.clone(); + let mut layer_rgb = self.layer_rgb.clone(); let mut layer_alpha = self.layer_alpha.clone(); let configs = Rc::clone(&self.configs); let selected_browse_line = Rc::clone(&self.selected_browse_line); @@ -521,49 +627,33 @@ impl ConfigWindow { return; } - if let Some(conf) = configs - .borrow_mut() - .get_mut(&f.text(*selected_browse_line.borrow()).unwrap()) - { - conf.quote_font_ttf = quote_font_ttf.value(); - conf.subquote_font_ttf = subquote_font_ttf.value(); - conf.tag_font_ttf = tag_font_ttf.value(); - conf.quote_font_ratio = quote_font_ratio.value(); - conf.subquote_font_ratio = subquote_font_ratio.value(); - conf.tag_font_ratio = tag_font_ratio.value(); - conf.quote_position_ratio = quote_position_ratio.value(); - conf.subquote_position_ratio = subquote_position_ratio.value(); - conf.tag_position_ratio = tag_position_ratio.value(); - conf.image_ratio = (image_ratio_width.value(), image_ratio_height.value()); - conf.color_layer = [ - layer_red.value() as u8, - layer_green.value() as u8, - layer_blue.value() as u8, - layer_alpha.value() as u8, - ]; - } - if let Some(conf) = configs.borrow().get(&f.selected_text().unwrap()) { quote_font_ttf.set_value(&conf.quote_font_ttf); subquote_font_ttf.set_value(&conf.subquote_font_ttf); + subquote2_font_ttf.set_value(&conf.subquote2_font_ttf); tag_font_ttf.set_value(&conf.tag_font_ttf); + tag2_font_ttf.set_value(&conf.tag2_font_ttf); quote_font_ratio.set_value(conf.quote_font_ratio); subquote_font_ratio.set_value(conf.subquote_font_ratio); + subquote2_font_ratio.set_value(conf.subquote2_font_ratio); tag_font_ratio.set_value(conf.tag_font_ratio); + tag2_font_ratio.set_value(conf.tag2_font_ratio); quote_position_ratio.set_value(conf.quote_position_ratio); subquote_position_ratio.set_value(conf.subquote_position_ratio); + subquote2_position_ratio.set_value(conf.subquote2_position_ratio); tag_position_ratio.set_value(conf.tag_position_ratio); + tag2_position_ratio.set_value(conf.tag2_position_ratio); image_ratio_width.set_value(conf.image_ratio.0); image_ratio_height.set_value(conf.image_ratio.1); - layer_red.set_value(conf.color_layer[0] as f64); - layer_green.set_value(conf.color_layer[1] as f64); - layer_blue.set_value(conf.color_layer[2] as f64); + utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb); layer_alpha.set_value(conf.color_layer[3] as f64); + layer_rgb.redraw(); } *selected_browse_line.borrow_mut() = f.value(); - // println!("browse {:?}", selected_config_name); }); + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); let mut quote_font_ttf = self.quote_font_ttf.clone(); self.quote_font_ttf_browse.set_callback(move |_| { let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseFile); @@ -572,9 +662,18 @@ impl ConfigWindow { chooser.show(); let path = chooser.filename(); let path = std::fs::canonicalize(&path).unwrap_or(path); - quote_font_ttf.set_value(path.to_str().unwrap()); + let path = path.to_str().unwrap(); + quote_font_ttf.set_value(path); + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.quote_font_ttf = path.to_owned(); + } }); + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); let mut subquote_font_ttf = self.subquote_font_ttf.clone(); self.subquote_font_ttf_browse.set_callback(move |_| { let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseFile); @@ -583,9 +682,38 @@ impl ConfigWindow { chooser.show(); let path = chooser.filename(); let path = std::fs::canonicalize(&path).unwrap_or(path); - subquote_font_ttf.set_value(path.to_str().unwrap()); + let path = path.to_str().unwrap(); + subquote_font_ttf.set_value(path); + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.subquote_font_ttf = path.to_owned(); + } }); + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + let mut subquote2_font_ttf = self.subquote2_font_ttf.clone(); + self.subquote2_font_ttf_browse.set_callback(move |_| { + let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseFile); + chooser.set_option(FileDialogOptions::UseFilterExt); + chooser.set_filter("*.ttf"); + chooser.show(); + let path = chooser.filename(); + let path = std::fs::canonicalize(&path).unwrap_or(path); + let path = path.to_str().unwrap(); + subquote2_font_ttf.set_value(path); + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.subquote2_font_ttf = path.to_owned(); + } + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); let mut tag_font_ttf = self.tag_font_ttf.clone(); self.tag_font_ttf_browse.set_callback(move |_| { let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseFile); @@ -593,7 +721,35 @@ impl ConfigWindow { chooser.set_filter("*.ttf"); chooser.show(); let path = chooser.filename(); - tag_font_ttf.set_value(path.to_str().unwrap()); + let path = std::fs::canonicalize(&path).unwrap_or(path); + let path = path.to_str().unwrap(); + tag_font_ttf.set_value(path); + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.tag_font_ttf = path.to_owned(); + } + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + let mut tag2_font_ttf = self.tag2_font_ttf.clone(); + self.tag2_font_ttf_browse.set_callback(move |_| { + let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseFile); + chooser.set_option(FileDialogOptions::UseFilterExt); + chooser.set_filter("*.ttf"); + chooser.show(); + let path = chooser.filename(); + let path = std::fs::canonicalize(&path).unwrap_or(path); + let path = path.to_str().unwrap(); + tag2_font_ttf.set_value(path); + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.tag2_font_ttf = path.to_owned(); + } }); let mut win = self.win.clone(); @@ -601,82 +757,275 @@ impl ConfigWindow { win.hide(); }); - let mut quote_font_ttf = self.quote_font_ttf.clone(); - let mut subquote_font_ttf = self.subquote_font_ttf.clone(); - let mut tag_font_ttf = self.tag_font_ttf.clone(); - let mut quote_font_ratio = self.quote_font_ratio.clone(); - let mut subquote_font_ratio = self.subquote_font_ratio.clone(); - let mut tag_font_ratio = self.tag_font_ratio.clone(); - let mut quote_position_ratio = self.quote_position_ratio.clone(); - let mut subquote_position_ratio = self.subquote_position_ratio.clone(); - let mut tag_position_ratio = self.tag_position_ratio.clone(); - let mut image_ratio_width = self.image_ratio_width.clone(); - let mut image_ratio_height = self.image_ratio_height.clone(); - let mut layer_red = self.layer_red.clone(); - let mut layer_green = self.layer_green.clone(); - let mut layer_blue = self.layer_blue.clone(); - let mut layer_alpha = self.layer_alpha.clone(); - self.defaults_btn.set_callback(move |_| { - let conf = ConfigFile::default(); - quote_font_ttf.set_value(&conf.quote_font_ttf); - subquote_font_ttf.set_value(&conf.subquote_font_ttf); - tag_font_ttf.set_value(&conf.tag_font_ttf); - quote_font_ratio.set_value(conf.quote_font_ratio); - subquote_font_ratio.set_value(conf.subquote_font_ratio); - tag_font_ratio.set_value(conf.tag_font_ratio); - quote_position_ratio.set_value(conf.quote_position_ratio); - subquote_position_ratio.set_value(conf.subquote_position_ratio); - tag_position_ratio.set_value(conf.tag_position_ratio); - image_ratio_width.set_value(conf.image_ratio.0); - image_ratio_height.set_value(conf.image_ratio.1); - layer_red.set_value(conf.color_layer[0] as f64); - layer_green.set_value(conf.color_layer[1] as f64); - layer_blue.set_value(conf.color_layer[2] as f64); - layer_alpha.set_value(conf.color_layer[3] as f64); - }); + // Font size ratio - let quote_font_ttf = self.quote_font_ttf.clone(); - let subquote_font_ttf = self.subquote_font_ttf.clone(); - let tag_font_ttf = self.tag_font_ttf.clone(); - let quote_font_ratio = self.quote_font_ratio.clone(); - let subquote_font_ratio = self.subquote_font_ratio.clone(); - let tag_font_ratio = self.tag_font_ratio.clone(); - let quote_position_ratio = self.quote_position_ratio.clone(); - let subquote_position_ratio = self.subquote_position_ratio.clone(); - let tag_position_ratio = self.tag_position_ratio.clone(); - let image_ratio_width = self.image_ratio_width.clone(); - let image_ratio_height = self.image_ratio_height.clone(); - let layer_red = self.layer_red.clone(); - let layer_green = self.layer_green.clone(); - let layer_blue = self.layer_blue.clone(); - let layer_alpha = self.layer_alpha.clone(); let browse = self.browse.clone(); let configs = Rc::clone(&self.configs); - let did_save = Rc::clone(&self.did_save); - let mut win = self.win.clone(); - self.save_btn.set_callback(move |_| { + self.quote_font_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.quote_font_ratio = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.subquote_font_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.subquote_font_ratio = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.subquote2_font_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.subquote2_font_ratio = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.tag_font_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.tag_font_ratio = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.tag2_font_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.tag2_font_ratio = f.value(); + } + } + true + }); + + // text Position + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.quote_position_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.quote_position_ratio = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.subquote_position_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.subquote_position_ratio = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.subquote2_position_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.subquote2_position_ratio = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.tag_position_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.tag_position_ratio = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.tag2_position_ratio.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.tag2_position_ratio = f.value(); + } + } + true + }); + + // iamge ratio + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.image_ratio_width.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.image_ratio.0 = f.value(); + } + } + true + }); + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.image_ratio_height.handle(move |f, ev| { + if ev == Event::KeyUp { + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.image_ratio.1 = f.value(); + } + } + true + }); + + // Color + + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.layer_rgb.set_callback(move |mut f| { if let Some(conf) = configs .borrow_mut() .get_mut(&browse.selected_text().unwrap()) { - conf.quote_font_ttf = quote_font_ttf.value(); - conf.subquote_font_ttf = subquote_font_ttf.value(); - conf.tag_font_ttf = tag_font_ttf.value(); - conf.quote_font_ratio = quote_font_ratio.value(); - conf.subquote_font_ratio = subquote_font_ratio.value(); - conf.tag_font_ratio = tag_font_ratio.value(); - conf.quote_position_ratio = quote_position_ratio.value(); - conf.subquote_position_ratio = subquote_position_ratio.value(); - conf.tag_position_ratio = tag_position_ratio.value(); - conf.image_ratio = (image_ratio_width.value(), image_ratio_height.value()); - conf.color_layer = [ - layer_red.value() as u8, - layer_green.value() as u8, - layer_blue.value() as u8, - layer_alpha.value() as u8, - ]; + let (r, g, b) = dialog::color_chooser_with_default( + "Pick a colour", + dialog::ColorMode::Byte, + ( + conf.color_layer[0], + conf.color_layer[1], + conf.color_layer[2], + ), + ); + conf.color_layer = [r, g, b, conf.color_layer[3]]; + utils::set_color_btn_rgba(conf.color_layer, &mut f); + f.redraw(); } + }); + let browse = self.browse.clone(); + let configs = Rc::clone(&self.configs); + self.layer_alpha.handle(move |f, ev| { + if ev == Event::KeyUp { + if f.value() > 255.0 { + f.set_value(255.0); + } else if f.value() < 0.0 { + f.set_value(0.0); + } + + if let Some(conf) = configs + .borrow_mut() + .get_mut(&browse.selected_text().unwrap()) + { + conf.color_layer[3] = f.value() as u8; + } + } + true + }); + + let mut quote_font_ttf = self.quote_font_ttf.clone(); + let mut subquote_font_ttf = self.subquote_font_ttf.clone(); + let mut subquote2_font_ttf = self.subquote2_font_ttf.clone(); + let mut tag_font_ttf = self.tag_font_ttf.clone(); + let mut tag2_font_ttf = self.tag2_font_ttf.clone(); + let mut quote_font_ratio = self.quote_font_ratio.clone(); + let mut subquote_font_ratio = self.subquote_font_ratio.clone(); + let mut subquote2_font_ratio = self.subquote2_font_ratio.clone(); + let mut tag_font_ratio = self.tag_font_ratio.clone(); + let mut tag2_font_ratio = self.tag2_font_ratio.clone(); + let mut quote_position_ratio = self.quote_position_ratio.clone(); + let mut subquote_position_ratio = self.subquote_position_ratio.clone(); + let mut subquote2_position_ratio = self.subquote2_position_ratio.clone(); + let mut tag_position_ratio = self.tag_position_ratio.clone(); + let mut tag2_position_ratio = self.tag2_position_ratio.clone(); + let mut image_ratio_width = self.image_ratio_width.clone(); + let mut image_ratio_height = self.image_ratio_height.clone(); + let mut layer_rgb = self.layer_rgb.clone(); + let mut layer_alpha = self.layer_alpha.clone(); + let configs = Rc::clone(&self.configs); + let browse = self.browse.clone(); + self.defaults_btn.set_callback(move |_| { + let conf = ConfigFile::default(); + quote_font_ttf.set_value(&conf.quote_font_ttf); + subquote_font_ttf.set_value(&conf.subquote_font_ttf); + subquote2_font_ttf.set_value(&conf.subquote2_font_ttf); + tag_font_ttf.set_value(&conf.tag_font_ttf); + tag2_font_ttf.set_value(&conf.tag2_font_ttf); + quote_font_ratio.set_value(conf.quote_font_ratio); + subquote_font_ratio.set_value(conf.subquote_font_ratio); + subquote2_font_ratio.set_value(conf.subquote2_font_ratio); + tag_font_ratio.set_value(conf.tag_font_ratio); + tag2_font_ratio.set_value(conf.tag2_font_ratio); + quote_position_ratio.set_value(conf.quote_position_ratio); + subquote_position_ratio.set_value(conf.subquote_position_ratio); + subquote2_position_ratio.set_value(conf.subquote2_position_ratio); + tag_position_ratio.set_value(conf.tag_position_ratio); + tag2_position_ratio.set_value(conf.tag2_position_ratio); + image_ratio_width.set_value(conf.image_ratio.0); + image_ratio_height.set_value(conf.image_ratio.1); + utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb); + layer_rgb.redraw(); + layer_alpha.set_value(conf.color_layer[3] as f64); + configs + .borrow_mut() + .insert(browse.selected_text().unwrap(), conf); + }); + + let configs = Rc::clone(&self.configs); + let did_save = Rc::clone(&self.did_save); + let mut win = self.win.clone(); + self.save_btn.set_callback(move |_| { config::save_configs((*configs.borrow()).clone()); if let Some(c) = configs.borrow().get(&*globals::CONFIG_NAME.read().unwrap()) { diff --git a/src/draw_thread.rs b/src/draw_thread.rs index 9f20e21..ac9bded 100644 --- a/src/draw_thread.rs +++ b/src/draw_thread.rs @@ -3,10 +3,12 @@ use crate::{ globals, main_window::{MainWindow, Page}, - AppMessage, + utils, AppMessage, }; use fltk::{ - app, enums, + app, + button::Button, + enums, frame::Frame, input::{Input, MultilineInput}, menu, @@ -51,17 +53,21 @@ pub(crate) fn spawn_image_thread( let mut file_choice = main_win.file_choice.clone(); let mut quote = main_win.quote.clone(); let mut subquote = main_win.subquote.clone(); + let mut subquote2 = main_win.subquote2.clone(); let mut tag = main_win.tag.clone(); - let mut layer_red = main_win.layer_red.clone(); - let mut layer_green = main_win.layer_green.clone(); - let mut layer_blue = main_win.layer_blue.clone(); + let mut tag2 = main_win.tag2.clone(); + let mut layer_rgb = main_win.layer_rgb.clone(); let mut layer_alpha = main_win.layer_alpha.clone(); let mut quote_position = main_win.quote_position.clone(); let mut subquote_position = main_win.subquote_position.clone(); + let mut subquote2_position = main_win.subquote2_position.clone(); let mut tag_position = main_win.tag_position.clone(); + let mut tag2_position = main_win.tag2_position.clone(); let mut quote_position_slider = main_win.quote_position_slider.clone(); let mut subquote_position_slider = main_win.subquote_position_slider.clone(); + let mut subquote2_position_slider = main_win.subquote2_position_slider.clone(); let mut tag_position_slider = main_win.tag_position_slider.clone(); + let mut tag2_position_slider = main_win.tag2_position_slider.clone(); let mut page = main_win.page.clone(); let mut status = main_win.status.clone(); let mut count = main_win.count.clone(); @@ -80,17 +86,21 @@ pub(crate) fn spawn_image_thread( None, &mut quote, &mut subquote, + &mut subquote2, &mut tag, - &mut layer_red, - &mut layer_green, - &mut layer_blue, + &mut tag2, + &mut layer_rgb, &mut layer_alpha, &mut quote_position, &mut subquote_position, + &mut subquote2_position, &mut tag_position, + &mut tag2_position, &mut quote_position_slider, &mut subquote_position_slider, + &mut subquote2_position_slider, &mut tag_position_slider, + &mut tag2_position_slider, &mut page, &mut count, &mut dimension, @@ -109,17 +119,21 @@ pub(crate) fn spawn_image_thread( Some((x, y)), &mut quote, &mut subquote, + &mut subquote2, &mut tag, - &mut layer_red, - &mut layer_green, - &mut layer_blue, + &mut tag2, + &mut layer_rgb, &mut layer_alpha, &mut quote_position, &mut subquote_position, + &mut subquote2_position, &mut tag_position, + &mut tag2_position, &mut quote_position_slider, &mut subquote_position_slider, + &mut subquote2_position_slider, &mut tag_position_slider, + &mut tag2_position_slider, &mut page, &mut count, &mut dimension, @@ -195,17 +209,21 @@ fn load_image( crop: Option<(f64, f64)>, quote: &mut MultilineInput, subquote: &mut MultilineInput, + subquote2: &mut MultilineInput, tag: &mut Input, - layer_red: &mut Spinner, - layer_green: &mut Spinner, - layer_blue: &mut Spinner, + tag2: &mut Input, + layer_rgb: &mut Button, layer_alpha: &mut Spinner, quote_position: &mut Spinner, subquote_position: &mut Spinner, + subquote2_position: &mut Spinner, tag_position: &mut Spinner, + tag2_position: &mut Spinner, quote_position_slider: &mut Slider, subquote_position_slider: &mut Slider, + subquote2_position_slider: &mut Slider, tag_position_slider: &mut Slider, + tag2_position_slider: &mut Slider, page: &mut Page, count: &mut Frame, dimension: &mut Frame, @@ -234,25 +252,33 @@ fn load_image( let mut prop = properties.write().unwrap(); let read = fs::read_to_string(&conf).unwrap(); if let Ok(saved_prop) = serde_json::from_str::(&read) { - layer_red.set_value(saved_prop.rgba[0] as f64); - layer_green.set_value(saved_prop.rgba[1] as f64); - layer_blue.set_value(saved_prop.rgba[2] as f64); + utils::set_color_btn_rgba(saved_prop.rgba, layer_rgb); layer_alpha.set_value(saved_prop.rgba[3] as f64); quote.set_value(&saved_prop.quote); subquote.set_value(&saved_prop.subquote); + subquote2.set_value(&saved_prop.subquote2); tag.set_value(&saved_prop.tag); + tag2.set_value(&saved_prop.tag2); quote_position.set_range(0.0, prop.original_dimension.1); quote_position.set_value(saved_prop.quote_position); subquote_position.set_range(0.0, prop.original_dimension.1); subquote_position.set_value(saved_prop.subquote_position); + subquote2_position.set_range(0.0, prop.original_dimension.1); + subquote2_position.set_value(saved_prop.subquote2_position); tag_position.set_range(0.0, prop.original_dimension.1); tag_position.set_value(saved_prop.tag_position); + tag2_position.set_range(0.0, prop.original_dimension.1); + tag2_position.set_value(saved_prop.tag2_position); quote_position_slider.set_range(0.0, prop.original_dimension.1); subquote_position_slider.set_range(0.0, prop.original_dimension.1); + subquote2_position_slider.set_range(0.0, prop.original_dimension.1); quote_position_slider.set_value(saved_prop.quote_position); subquote_position_slider.set_value(saved_prop.subquote_position); + subquote2_position_slider.set_value(saved_prop.subquote2_position); tag_position_slider.set_range(0.0, prop.original_dimension.1); tag_position_slider.set_value(saved_prop.tag_position); + tag2_position_slider.set_range(0.0, prop.original_dimension.1); + tag2_position_slider.set_value(saved_prop.tag2_position); dimension.set_label(&format!( "[{}x{}]", prop.original_dimension.0, prop.original_dimension.1 @@ -260,10 +286,14 @@ fn load_image( prop.quote = saved_prop.quote; prop.subquote = saved_prop.subquote; + prop.subquote2 = saved_prop.subquote2; prop.tag = saved_prop.tag; + prop.tag2 = saved_prop.tag2; prop.quote_position = saved_prop.quote_position; prop.subquote_position = saved_prop.subquote_position; + prop.subquote2_position = saved_prop.subquote2_position; prop.tag_position = saved_prop.tag_position; + prop.tag2_position = saved_prop.tag2_position; prop.rgba = saved_prop.rgba; prop.is_saved = true; use_defaults = false; @@ -286,24 +316,32 @@ fn load_image( prop.quote = "".to_owned(); subquote.set_value(""); prop.subquote = "".to_owned(); + subquote2.set_value(""); + prop.subquote2 = "".to_owned(); } quote_position.set_range(0.0, prop.original_dimension.1); quote_position.set_value(prop.quote_position); subquote_position.set_range(0.0, prop.original_dimension.1); subquote_position.set_value(prop.subquote_position); + subquote2_position.set_range(0.0, prop.original_dimension.1); + subquote2_position.set_value(prop.subquote2_position); tag_position.set_range(0.0, prop.original_dimension.1); tag_position.set_value(prop.tag_position); + tag2_position.set_range(0.0, prop.original_dimension.1); + tag2_position.set_value(prop.tag2_position); quote_position_slider.set_range(0.0, prop.original_dimension.1); quote_position_slider.set_value(prop.quote_position); subquote_position_slider.set_range(0.0, prop.original_dimension.1); subquote_position_slider.set_value(prop.subquote_position); + subquote2_position_slider.set_range(0.0, prop.original_dimension.1); + subquote2_position_slider.set_value(prop.subquote2_position); tag_position_slider.set_range(0.0, prop.original_dimension.1); tag_position_slider.set_value(prop.tag_position); + tag2_position_slider.set_range(0.0, prop.original_dimension.1); + tag2_position_slider.set_value(prop.tag2_position); let glob = &globals::CONFIG.read().unwrap(); - layer_red.set_value(glob.color_layer[0] as f64); - layer_green.set_value(glob.color_layer[1] as f64); - layer_blue.set_value(glob.color_layer[2] as f64); + utils::set_color_btn_rgba(glob.color_layer, layer_rgb); layer_alpha.set_value(glob.color_layer[3] as f64); prop.rgba = glob.color_layer; drop(glob); diff --git a/src/globals.rs b/src/globals.rs index a2d348b..e17098d 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -31,6 +31,19 @@ lazy_static! { } rusttype::Font::try_from_vec(include_bytes!("../Rajdhani-Regular.ttf").to_vec()).unwrap() }; + pub static ref FONT_SUBQUOTE2: Font<'static> = { + let mut buffer = Vec::new(); + if let Ok(mut file) = + std::fs::File::open(CONFIG.read().unwrap().subquote2_font_ttf.as_str()) + { + if let Ok(_) = file.read_to_end(&mut buffer) { + if let Some(out) = rusttype::Font::try_from_vec(buffer) { + return out; + } + } + } + rusttype::Font::try_from_vec(include_bytes!("../Rajdhani-Regular.ttf").to_vec()).unwrap() + }; pub static ref FONT_TAG: Font<'static> = { let mut buffer = Vec::new(); if let Ok(mut file) = std::fs::File::open(&CONFIG.read().unwrap().tag_font_ttf.as_str()) { @@ -42,6 +55,17 @@ lazy_static! { } rusttype::Font::try_from_vec(include_bytes!("../Kalam-Regular.ttf").to_vec()).unwrap() }; + pub static ref FONT_TAG2: Font<'static> = { + let mut buffer = Vec::new(); + if let Ok(mut file) = std::fs::File::open(&CONFIG.read().unwrap().tag2_font_ttf.as_str()) { + if let Ok(_) = file.read_to_end(&mut buffer) { + if let Some(out) = rusttype::Font::try_from_vec(buffer) { + return out; + } + } + } + rusttype::Font::try_from_vec(include_bytes!("../Kalam-Regular.ttf").to_vec()).unwrap() + }; pub static ref ICON: OsString = include_str!("../icon.svg").into(); pub static ref RELOAD_ICON: OsString = { let img = include_str!("../reload.svg"); diff --git a/src/main_window.rs b/src/main_window.rs index 41b6745..656560c 100644 --- a/src/main_window.rs +++ b/src/main_window.rs @@ -1,12 +1,12 @@ use crate::crop_window::CropWindow; use crate::draw_thread::*; +use crate::utils; use crate::utils::ImageProperties; use crate::{config_window::ConfigWindow, globals}; -use fltk::dialog; -use fltk::valuator::{Slider, SliderType}; use fltk::{ app, button::Button, + dialog, dialog::NativeFileChooser, draw as dr, enums, enums::Shortcut, @@ -17,6 +17,7 @@ use fltk::{ menu, misc::Spinner, prelude::*, + valuator::{Slider, SliderType}, window::Window, }; use std::path::PathBuf; @@ -32,21 +33,27 @@ pub(crate) struct MainWindow { pub(crate) file_choice: menu::Choice, pub(crate) quote: MultilineInput, pub(crate) subquote: MultilineInput, + pub(crate) subquote2: MultilineInput, pub(crate) tag: Input, - pub(crate) layer_red: Spinner, - pub(crate) layer_green: Spinner, - pub(crate) layer_blue: Spinner, + pub(crate) tag2: Input, + pub(crate) layer_rgb: Button, pub(crate) layer_alpha: Spinner, pub(crate) quote_position: Spinner, pub(crate) subquote_position: Spinner, + pub(crate) subquote2_position: Spinner, pub(crate) tag_position: Spinner, + pub(crate) tag2_position: Spinner, pub(crate) quote_position_slider: Slider, pub(crate) subquote_position_slider: Slider, + pub(crate) subquote2_position_slider: Slider, pub(crate) tag_position_slider: Slider, + pub(crate) tag2_position_slider: Slider, pub(crate) reset_darklayer_btn: Button, pub(crate) reset_quote_position_btn: Button, pub(crate) reset_subquote_position_btn: Button, + pub(crate) reset_subquote2_position_btn: Button, pub(crate) reset_tag_position_btn: Button, + pub(crate) reset_tag2_position_btn: Button, pub(crate) reset_file_choice: Button, pub(crate) crop_btn: Button, pub(crate) clone_btn: Button, @@ -73,7 +80,7 @@ impl MainWindow { sender: app::Sender, draw_buff: Arc>>>, ) -> Self { - let mut win = Window::new(0, 0, 1000, 700, "Post Maker").center_screen(); + let mut win = Window::new(0, 0, 1100, 700, "Post Maker").center_screen(); win.set_icon(Some( SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(), )); @@ -99,111 +106,52 @@ impl MainWindow { main_flex.set_size(&toolbar_flex, 30); let mut workspace_flex = Flex::default().row(); - // Controls - let mut controls_flex = Flex::default().column(); - controls_flex.set_size( + // Controls Left + let mut left_controls_flex = Flex::default().column(); + left_controls_flex.set_size( &Frame::default() .with_label("Quote:") .with_align(enums::Align::Left | enums::Align::Inside), 25, ); let quote = MultilineInput::default(); - controls_flex.set_size("e, 70); - controls_flex.set_size( + left_controls_flex.set_size("e, 70); + + left_controls_flex.set_size( &Frame::default() .with_label("Subquote:") .with_align(enums::Align::Left | enums::Align::Inside), 25, ); let subquote = MultilineInput::default(); - controls_flex.set_size(&subquote, 70); - controls_flex.set_size( + left_controls_flex.set_size(&subquote, 70); + + left_controls_flex.set_size( + &Frame::default() + .with_label("Subquote 2:") + .with_align(enums::Align::Left | enums::Align::Inside), + 25, + ); + let subquote2 = MultilineInput::default(); + left_controls_flex.set_size(&subquote2, 70); + + left_controls_flex.set_size( &Frame::default() .with_label("Tag:") .with_align(enums::Align::Left | enums::Align::Inside), 25, ); let tag = Input::default(); - controls_flex.set_size(&tag, 30); + left_controls_flex.set_size(&tag, 30); - let mut darklayer_head_flex = Flex::default().row(); - Frame::default() - .with_label("Dark Layer (RGBA):") - .with_align(enums::Align::Left | enums::Align::Inside); - let mut reset_darklayer_btn = Button::default(); - reset_darklayer_btn.set_image(Some(reload_image.clone())); - darklayer_head_flex.set_size(&reset_darklayer_btn, 30); - darklayer_head_flex.end(); - controls_flex.set_size(&darklayer_head_flex, 30); - - let mut darklayer_flex = Flex::default().row(); - darklayer_flex.set_pad(2); - darklayer_flex.set_size(&Frame::default().with_label("Red"), 30); - let mut layer_red = Spinner::default(); - layer_red.set_range(0.0, 255.0); - // darklayer_flex.set_size(&layer_red, 50); - darklayer_flex.set_size(&Frame::default().with_label("Green"), 40); - let mut layer_green = Spinner::default(); - layer_green.set_range(0.0, 255.0); - // darklayer_flex.set_size(&layer_green, 50); - darklayer_flex.set_size(&Frame::default().with_label("Blue"), 30); - let mut layer_blue = Spinner::default(); - layer_blue.set_range(0.0, 255.0); - // darklayer_flex.set_size(&layer_blue, 50); - darklayer_flex.set_size(&Frame::default().with_label("Alpha"), 40); - let mut layer_alpha = Spinner::default(); - layer_alpha.set_range(0.0, 255.0); - // darklayer_flex.set_size(&layer_alpha, 50); - darklayer_flex.end(); - controls_flex.set_size(&darklayer_flex, 30); - - let mut quote_position_flex = Flex::default().row(); - Frame::default() - .with_label("Quote Position:") - .with_align(enums::Align::Left | enums::Align::Inside); - let quote_position = fltk::misc::Spinner::default(); - let mut reset_quote_position_btn = Button::default(); - reset_quote_position_btn.set_image(Some(reload_image.clone())); - quote_position_flex.set_size(&reset_quote_position_btn, 30); - quote_position_flex.end(); - controls_flex.set_size("e_position_flex, 30); - - let mut quote_position_slider = Slider::default().with_type(SliderType::HorizontalNice); - quote_position_slider.set_step(1.0, 1); - quote_position_slider.set_frame(enums::FrameType::NoBox); - controls_flex.set_size("e_position_slider, 30); - - let mut subquote_position_flex = Flex::default().row(); - Frame::default() - .with_label("Subquote Position:") - .with_align(enums::Align::Left | enums::Align::Inside); - let subquote_position = fltk::misc::Spinner::default(); - let mut reset_subquote_position_btn = Button::default(); - reset_subquote_position_btn.set_image(Some(reload_image.clone())); - subquote_position_flex.set_size(&reset_subquote_position_btn, 30); - subquote_position_flex.end(); - controls_flex.set_size(&subquote_position_flex, 30); - - let mut subquote_position_slider = Slider::default().with_type(SliderType::HorizontalNice); - subquote_position_slider.set_step(1.0, 1); - subquote_position_slider.set_frame(enums::FrameType::NoBox); - controls_flex.set_size(&subquote_position_slider, 30); - - let mut tag_position_flex = Flex::default().row(); - Frame::default() - .with_label("Tag Position:") - .with_align(enums::Align::Left | enums::Align::Inside); - let tag_position = fltk::misc::Spinner::default(); - let mut reset_tag_position_btn = Button::default(); - reset_tag_position_btn.set_image(Some(reload_image.clone())); - tag_position_flex.set_size(&reset_tag_position_btn, 30); - tag_position_flex.end(); - controls_flex.set_size(&tag_position_flex, 30); - - let mut tag_position_slider = Slider::default().with_type(SliderType::HorizontalNice); - tag_position_slider.set_step(1.0, 1); - tag_position_slider.set_frame(enums::FrameType::NoBox); - controls_flex.set_size(&tag_position_slider, 30); + left_controls_flex.set_size( + &Frame::default() + .with_label("Tag 2:") + .with_align(enums::Align::Left | enums::Align::Inside), + 25, + ); + let tag2 = Input::default(); + left_controls_flex.set_size(&tag2, 30); let mut actions_flex = Flex::default().row(); Frame::default(); @@ -215,7 +163,7 @@ impl MainWindow { actions_flex.set_size(&crop_btn, 100); Frame::default(); actions_flex.end(); - controls_flex.set_size(&actions_flex, 30); + left_controls_flex.set_size(&actions_flex, 30); Frame::default(); @@ -224,10 +172,10 @@ impl MainWindow { let status = Frame::default(); let dimension = Frame::default().with_align(enums::Align::Right | enums::Align::Inside); info_flex.end(); - controls_flex.set_size(&info_flex, 30); + left_controls_flex.set_size(&info_flex, 30); - controls_flex.end(); - workspace_flex.set_size(&controls_flex, 360); + left_controls_flex.end(); + workspace_flex.set_size(&left_controls_flex, 310); // Page let mut center_row_flex = Flex::default().row(); @@ -242,6 +190,129 @@ impl MainWindow { center_row_flex.set_size(¢er_col_flex, 400); center_row_flex.end(); + // Controls right + let mut right_controls_flex = Flex::default().column(); + let mut darklayer_head_flex = Flex::default().row(); + Frame::default() + .with_label("Dark Layer (RGBA):") + .with_align(enums::Align::Left | enums::Align::Inside); + let mut reset_darklayer_btn = Button::default(); + reset_darklayer_btn.set_image(Some(reload_image.clone())); + darklayer_head_flex.set_size(&reset_darklayer_btn, 30); + darklayer_head_flex.end(); + right_controls_flex.set_size(&darklayer_head_flex, 30); + + let mut darklayer_flex = Flex::default().row(); + darklayer_flex.set_pad(2); + darklayer_flex.set_size(&Frame::default().with_label("Colour"), 50); + let mut layer_rgb = Button::default(); + layer_rgb.set_frame(enums::FrameType::BorderBox); + + darklayer_flex.set_size(&Frame::default().with_label("Alpha"), 50); + let mut layer_alpha = Spinner::default(); + layer_alpha.set_range(0.0, 255.0); + darklayer_flex.end(); + right_controls_flex.set_size(&darklayer_flex, 30); + + let mut quote_position_flex = Flex::default().row(); + quote_position_flex.set_size( + &Frame::default() + .with_label("Quote Position") + .with_align(enums::Align::Left | enums::Align::Inside), + 140, + ); + let quote_position = fltk::misc::Spinner::default(); + let mut reset_quote_position_btn = Button::default(); + reset_quote_position_btn.set_image(Some(reload_image.clone())); + quote_position_flex.set_size(&reset_quote_position_btn, 30); + quote_position_flex.end(); + right_controls_flex.set_size("e_position_flex, 30); + + let mut quote_position_slider = Slider::default().with_type(SliderType::HorizontalNice); + quote_position_slider.set_step(1.0, 1); + quote_position_slider.set_frame(enums::FrameType::NoBox); + right_controls_flex.set_size("e_position_slider, 30); + + let mut subquote_position_flex = Flex::default().row(); + subquote_position_flex.set_size( + &Frame::default() + .with_label("Subquote Position") + .with_align(enums::Align::Left | enums::Align::Inside), + 140, + ); + let subquote_position = fltk::misc::Spinner::default(); + let mut reset_subquote_position_btn = Button::default(); + reset_subquote_position_btn.set_image(Some(reload_image.clone())); + subquote_position_flex.set_size(&reset_subquote_position_btn, 30); + subquote_position_flex.end(); + right_controls_flex.set_size(&subquote_position_flex, 30); + + let mut subquote_position_slider = Slider::default().with_type(SliderType::HorizontalNice); + subquote_position_slider.set_step(1.0, 1); + subquote_position_slider.set_frame(enums::FrameType::NoBox); + right_controls_flex.set_size(&subquote_position_slider, 30); + + let mut subquote2_position_flex = Flex::default().row(); + subquote2_position_flex.set_size( + &Frame::default() + .with_label("Subquote 2 Position") + .with_align(enums::Align::Left | enums::Align::Inside), + 140, + ); + let subquote2_position = fltk::misc::Spinner::default(); + let mut reset_subquote2_position_btn = Button::default(); + reset_subquote2_position_btn.set_image(Some(reload_image.clone())); + subquote2_position_flex.set_size(&reset_subquote2_position_btn, 30); + subquote2_position_flex.end(); + right_controls_flex.set_size(&subquote2_position_flex, 30); + + let mut subquote2_position_slider = Slider::default().with_type(SliderType::HorizontalNice); + subquote2_position_slider.set_step(1.0, 1); + subquote2_position_slider.set_frame(enums::FrameType::NoBox); + right_controls_flex.set_size(&subquote2_position_slider, 30); + + let mut tag_position_flex = Flex::default().row(); + tag_position_flex.set_size( + &Frame::default() + .with_label("Tag Position") + .with_align(enums::Align::Left | enums::Align::Inside), + 140, + ); + let tag_position = fltk::misc::Spinner::default(); + let mut reset_tag_position_btn = Button::default(); + reset_tag_position_btn.set_image(Some(reload_image.clone())); + tag_position_flex.set_size(&reset_tag_position_btn, 30); + tag_position_flex.end(); + right_controls_flex.set_size(&tag_position_flex, 30); + + let mut tag_position_slider = Slider::default().with_type(SliderType::HorizontalNice); + tag_position_slider.set_step(1.0, 1); + tag_position_slider.set_frame(enums::FrameType::NoBox); + right_controls_flex.set_size(&tag_position_slider, 30); + + let mut tag2_position_flex = Flex::default().row(); + tag2_position_flex.set_size( + &Frame::default() + .with_label("Tag 2 Position") + .with_align(enums::Align::Left | enums::Align::Inside), + 140, + ); + let tag2_position = fltk::misc::Spinner::default(); + let mut reset_tag2_position_btn = Button::default(); + reset_tag2_position_btn.set_image(Some(reload_image.clone())); + tag2_position_flex.set_size(&reset_tag2_position_btn, 30); + tag2_position_flex.end(); + right_controls_flex.set_size(&tag2_position_flex, 30); + + let mut tag2_position_slider = Slider::default().with_type(SliderType::HorizontalNice); + tag2_position_slider.set_step(1.0, 1); + tag2_position_slider.set_frame(enums::FrameType::NoBox); + right_controls_flex.set_size(&tag2_position_slider, 30); + + Frame::default(); + right_controls_flex.end(); + workspace_flex.set_size(&right_controls_flex, 270); + workspace_flex.end(); main_flex.end(); @@ -261,21 +332,27 @@ impl MainWindow { file_choice, quote, subquote, + subquote2, tag, - layer_red, - layer_green, - layer_blue, + tag2, + layer_rgb, layer_alpha, quote_position, subquote_position, + subquote2_position, tag_position, + tag2_position, quote_position_slider, subquote_position_slider, + subquote2_position_slider, tag_position_slider, + tag2_position_slider, reset_darklayer_btn, reset_quote_position_btn, reset_subquote_position_btn, + reset_subquote2_position_btn, reset_tag_position_btn, + reset_tag2_position_btn, reset_file_choice, crop_btn, clone_btn, @@ -399,9 +476,7 @@ impl MainWindow { load_dir(&path, Arc::clone(&imgs), &mut file_choice, &sender); }); - let mut layer_red = self.layer_red.clone(); - let mut layer_green = self.layer_green.clone(); - let mut layer_blue = self.layer_blue.clone(); + let mut layer_rgb = self.layer_rgb.clone(); let mut layer_alpha = self.layer_alpha.clone(); let mut image = self.page.image.clone(); let sender = self.sender.clone(); @@ -411,9 +486,7 @@ impl MainWindow { let color = globals::CONFIG.read().unwrap().color_layer; prop.rgba = color; prop.is_saved = false; - layer_red.set_value(color[0] as f64); - layer_green.set_value(color[1] as f64); - layer_blue.set_value(color[2] as f64); + utils::set_color_btn_rgba(color, &mut layer_rgb); layer_alpha.set_value(color[3] as f64); sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Flush).unwrap(); @@ -458,6 +531,25 @@ impl MainWindow { image.redraw(); }); + let mut subquote2_position = self.subquote2_position.clone(); + let mut subquote2_position_slider = self.subquote2_position_slider.clone(); + let mut image = self.page.image.clone(); + let sender = self.sender.clone(); + let properties = Arc::clone(&self.properties); + self.reset_subquote2_position_btn.set_callback(move |_| { + let mut prop = properties.write().unwrap(); + let height = prop.original_dimension.1; + let pos = height * globals::CONFIG.read().unwrap().subquote2_position_ratio; + prop.subquote2_position = pos; + prop.is_saved = false; + subquote2_position.set_value(pos); + subquote2_position_slider.set_value(pos); + + sender.send(DrawMessage::Recalc).unwrap(); + sender.send(DrawMessage::Flush).unwrap(); + image.redraw(); + }); + let mut tag_position = self.tag_position.clone(); let mut tag_position_slider = self.tag_position_slider.clone(); let mut image = self.page.image.clone(); @@ -477,6 +569,25 @@ impl MainWindow { image.redraw(); }); + let mut tag2_position = self.tag2_position.clone(); + let mut tag2_position_slider = self.tag2_position_slider.clone(); + let mut image = self.page.image.clone(); + let sender = self.sender.clone(); + let properties = Arc::clone(&self.properties); + self.reset_tag2_position_btn.set_callback(move |_| { + let mut prop = properties.write().unwrap(); + let height = prop.original_dimension.1; + let pos = height * globals::CONFIG.read().unwrap().tag2_position_ratio; + prop.tag2_position = pos; + prop.is_saved = false; + tag2_position.set_value(pos); + tag2_position_slider.set_value(pos); + + sender.send(DrawMessage::Recalc).unwrap(); + sender.send(DrawMessage::Flush).unwrap(); + image.redraw(); + }); + let sender = self.sender.clone(); let properties = Arc::clone(&self.properties); self.save_btn.set_callback(move |_| { @@ -613,6 +724,21 @@ impl MainWindow { true }); + let mut image = self.page.image.clone(); + let properties = Arc::clone(&self.properties); + let sender = self.sender.clone(); + self.subquote2.handle(move |f, ev| { + if ev == enums::Event::KeyUp { + let mut prop = properties.write().unwrap(); + prop.subquote2 = f.value(); + prop.is_saved = false; + sender.send(DrawMessage::Recalc).unwrap(); + sender.send(DrawMessage::Flush).unwrap(); + image.redraw(); + } + true + }); + let mut image = self.page.image.clone(); let properties = Arc::clone(&self.properties); let sender = self.sender.clone(); @@ -628,6 +754,21 @@ impl MainWindow { true }); + let mut image = self.page.image.clone(); + let properties = Arc::clone(&self.properties); + let sender = self.sender.clone(); + self.tag2.handle(move |f, ev| { + if ev == enums::Event::KeyUp { + let mut prop = properties.write().unwrap(); + prop.tag2 = f.value(); + prop.is_saved = false; + sender.send(DrawMessage::Recalc).unwrap(); + sender.send(DrawMessage::Flush).unwrap(); + image.redraw(); + } + true + }); + let mut image = self.page.image.clone(); let properties = Arc::clone(&self.properties); let sender = self.sender.clone(); @@ -684,6 +825,34 @@ impl MainWindow { image.redraw(); }); + let mut image = self.page.image.clone(); + let properties = Arc::clone(&self.properties); + let sender = self.sender.clone(); + let mut subquote2_position_slider = self.subquote2_position_slider.clone(); + self.subquote2_position.set_callback(move |f| { + let mut prop = properties.write().unwrap(); + prop.subquote2_position = f.value(); + subquote2_position_slider.set_value(f.value()); + prop.is_saved = false; + sender.send(DrawMessage::Recalc).unwrap(); + sender.send(DrawMessage::Flush).unwrap(); + image.redraw(); + }); + + let mut image = self.page.image.clone(); + let properties = Arc::clone(&self.properties); + let sender = self.sender.clone(); + let mut subquote2_position = self.subquote2_position.clone(); + self.subquote2_position_slider.set_callback(move |f| { + let mut prop = properties.write().unwrap(); + prop.subquote2_position = f.value(); + subquote2_position.set_value(f.value()); + prop.is_saved = false; + sender.send(DrawMessage::Recalc).unwrap(); + sender.send(DrawMessage::Flush).unwrap(); + image.redraw(); + }); + let mut image = self.page.image.clone(); let properties = Arc::clone(&self.properties); let sender = self.sender.clone(); @@ -715,9 +884,11 @@ impl MainWindow { let mut image = self.page.image.clone(); let properties = Arc::clone(&self.properties); let sender = self.sender.clone(); - self.layer_red.set_callback(move |f| { + let mut tag2_position_slider = self.tag2_position_slider.clone(); + self.tag2_position.set_callback(move |f| { let mut prop = properties.write().unwrap(); - prop.rgba[0] = f.value() as u8; + prop.tag2_position = f.value(); + tag2_position_slider.set_value(f.value()); prop.is_saved = false; sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Flush).unwrap(); @@ -727,21 +898,29 @@ impl MainWindow { let mut image = self.page.image.clone(); let properties = Arc::clone(&self.properties); let sender = self.sender.clone(); - self.layer_green.set_callback(move |f| { + let mut tag2_position = self.tag2_position.clone(); + self.tag2_position_slider.set_callback(move |f| { let mut prop = properties.write().unwrap(); - prop.rgba[1] = f.value() as u8; + prop.tag2_position = f.value(); + tag2_position.set_value(f.value()); prop.is_saved = false; sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Flush).unwrap(); image.redraw(); }); - let mut image = self.page.image.clone(); let properties = Arc::clone(&self.properties); let sender = self.sender.clone(); - self.layer_blue.set_callback(move |f| { + self.layer_rgb.set_callback(move |mut f| { let mut prop = properties.write().unwrap(); - prop.rgba[2] = f.value() as u8; + let (r, g, b) = dialog::color_chooser_with_default( + "Pick a colour", + dialog::ColorMode::Byte, + (prop.rgba[0], prop.rgba[1], prop.rgba[2]), + ); + prop.rgba = [r, g, b, prop.rgba[3]]; + utils::set_color_btn_rgba(prop.rgba, &mut f); + f.redraw(); prop.is_saved = false; sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Flush).unwrap(); diff --git a/src/utils.rs b/src/utils.rs index 4056159..10c9353 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,7 +4,7 @@ use std::{ sync::{Arc, RwLock}, }; -use fltk::dialog; +use fltk::{button::Button, dialog, enums, prelude::*}; use image::{DynamicImage, GenericImageView, ImageBuffer}; use serde::{Deserialize, Serialize}; @@ -75,7 +75,9 @@ impl ImageContainer { prop.original_dimension = (width, height); prop.quote_position = height * config.quote_position_ratio; prop.subquote_position = height * config.subquote_position_ratio; + prop.subquote2_position = height * config.subquote2_position_ratio; prop.tag_position = height * config.tag_position_ratio; + prop.tag2_position = height * config.tag2_position_ratio; Self { image: img.clone(), @@ -146,10 +148,14 @@ impl ImageContainer { &prop.rgba, &prop.quote, &prop.subquote, + &prop.subquote2, prop.quote_position, prop.subquote_position, + prop.subquote2_position, &prop.tag, + &prop.tag2, prop.tag_position, + prop.tag2_position, prop.original_dimension.1, ); @@ -195,10 +201,14 @@ impl ImageContainer { &prop.rgba, &prop.quote, &prop.subquote, + &prop.subquote2, prop.quote_position, prop.subquote_position, + prop.subquote2_position, &prop.tag, + &prop.tag2, prop.tag_position, + prop.tag2_position, prop.original_dimension.1, ); @@ -282,10 +292,14 @@ pub(crate) struct ImageProperties { pub(crate) crop_position: Option<(f64, f64)>, pub(crate) quote: String, pub(crate) subquote: String, + pub(crate) subquote2: String, pub(crate) tag: String, - pub(crate) quote_position: f64, // as per original - pub(crate) subquote_position: f64, // as per original - pub(crate) tag_position: f64, // as per original + pub(crate) tag2: String, + pub(crate) quote_position: f64, // as per original + pub(crate) subquote_position: f64, // as per original + pub(crate) subquote2_position: f64, // as per original + pub(crate) tag_position: f64, // as per original + pub(crate) tag2_position: f64, // as per original pub(crate) rgba: [u8; 4], pub(crate) is_saved: bool, } @@ -299,10 +313,14 @@ impl ImageProperties { crop_position: None, quote: "".to_owned(), subquote: "".to_owned(), + subquote2: "".to_owned(), tag: "".to_owned(), + tag2: "".to_owned(), quote_position: 0.0, subquote_position: 0.0, + subquote2_position: 0.0, tag_position: 0.0, + tag2_position: 0.0, rgba: [0; 4], is_saved: true, } @@ -314,10 +332,14 @@ fn draw_layer_and_text( rgba: &[u8; 4], quote: &str, subquote: &str, + subquote2: &str, quote_position: f64, subquote_position: f64, + subquote2_position: f64, tag: &str, + tag2: &str, tag_position: f64, + tag2_position: f64, original_height: f64, ) { let (width, height): (f64, f64) = Coord::from(tmp.dimensions()).into(); @@ -328,44 +350,42 @@ fn draw_layer_and_text( image::imageops::overlay(tmp, &layer, 0, 0); let size = quote_from_height(height); - for (index, line) in quote.lines().enumerate() { - let (text_width, text_height) = measure_line( - &globals::FONT_QUOTE, - line, - rusttype::Scale::uniform(size as f32), - ); - - imageproc::drawing::draw_text_mut( - tmp, - image::Rgba([255, 255, 255, 255]), - ((width - text_width) / 2.0) as u32, - ((quote_position * height) / original_height + index as f64 * (text_height * 1.15)) - as u32, - rusttype::Scale::uniform(size as f32), - &globals::FONT_QUOTE, - line, - ); - } - + draw_multiline_mid_string( + tmp, + &globals::FONT_QUOTE, + size, + quote_position, + original_height, + quote, + ); let size = subquote_from_height(height); - for (index, line) in subquote.lines().enumerate() { - let (text_width, text_height) = measure_line( - &globals::FONT_SUBQUOTE, - line, - rusttype::Scale::uniform(size as f32), - ); + draw_multiline_mid_string( + tmp, + &globals::FONT_SUBQUOTE, + size, + subquote_position, + original_height, + subquote, + ); + let size = subquote2_from_height(height); + draw_multiline_mid_string( + tmp, + &globals::FONT_SUBQUOTE2, + size, + subquote2_position, + original_height, + subquote2, + ); - imageproc::drawing::draw_text_mut( - tmp, - image::Rgba([255, 255, 255, 255]), - ((width - text_width) / 2.0) as u32, - ((subquote_position * height) / original_height + index as f64 * (text_height * 1.15)) - as u32, - rusttype::Scale::uniform(size as f32), - &globals::FONT_SUBQUOTE, - line, - ); - } + let size = tag2_from_height(height); + draw_multiline_mid_string( + tmp, + &globals::FONT_TAG2, + size, + tag2_position, + original_height, + tag2, + ); let size = tag_from_height(height); for (index, line) in tag.lines().enumerate() { @@ -387,6 +407,40 @@ fn draw_layer_and_text( } } +pub(crate) fn draw_multiline_mid_string( + tmp: &mut DynamicImage, + font: &rusttype::Font, + size: f64, + position: f64, + original_height: f64, + text: &str, +) { + let (width, height): (f64, f64) = Coord::from(tmp.dimensions()).into(); + for (index, line) in text.lines().enumerate() { + let (text_width, text_height) = + measure_line(font, line, rusttype::Scale::uniform(size as f32)); + + imageproc::drawing::draw_text_mut( + tmp, + image::Rgba([255, 255, 255, 255]), + ((width - text_width) / 2.0) as u32, + ((position * height) / original_height + index as f64 * (text_height * 1.15)) as u32, + rusttype::Scale::uniform(size as f32), + font, + line, + ); + } +} + +// small hack because 0,0,0 rgb can't be set on theme +pub(crate) fn set_color_btn_rgba(rgba: [u8; 4], btn: &mut Button) { + let [mut r, g, b, _] = rgba; + if r == 0 && g == 0 && b == 0 { + r = 1; + } + btn.set_color(enums::Color::from_rgb(r, g, b)); +} + pub(crate) fn croped_ratio(width: f64, height: f64) -> (f64, f64) { if width > width_from_height(height) { (width_from_height(height), height) @@ -413,10 +467,18 @@ pub(crate) fn subquote_from_height(height: f64) -> f64 { (height * globals::CONFIG.read().unwrap().subquote_font_ratio) / 5000.0 } +pub(crate) fn subquote2_from_height(height: f64) -> f64 { + (height * globals::CONFIG.read().unwrap().subquote2_font_ratio) / 5000.0 +} + pub(crate) fn tag_from_height(height: f64) -> f64 { (height * globals::CONFIG.read().unwrap().tag_font_ratio) / 5000.0 } +pub(crate) fn tag2_from_height(height: f64) -> f64 { + (height * globals::CONFIG.read().unwrap().tag2_font_ratio) / 5000.0 +} + pub(crate) fn measure_line( font: &rusttype::Font, text: &str,