diff --git a/Rajdhani-Regular.ttf b/Rajdhani-Regular.ttf new file mode 100644 index 0000000..37663a5 Binary files /dev/null and b/Rajdhani-Regular.ttf differ diff --git a/src/config.rs b/src/config.rs index 7d5fb74..72e3f47 100644 --- a/src/config.rs +++ b/src/config.rs @@ -79,10 +79,13 @@ impl Into for Themes { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConfigFile { pub quote_font_ttf: String, + pub subquote_font_ttf: String, pub tag_font_ttf: String, pub quote_font_ratio: f64, + pub subquote_font_ratio: f64, pub tag_font_ratio: f64, pub quote_position_ratio: f64, + pub subquote_position_ratio: f64, pub tag_position_ratio: f64, pub image_ratio: (f64, f64), pub color_layer: [u8; 4], @@ -92,10 +95,13 @@ impl Default for ConfigFile { fn default() -> Self { Self { quote_font_ttf: String::new(), + subquote_font_ttf: String::new(), tag_font_ttf: String::new(), quote_font_ratio: 230.0, + subquote_font_ratio: 230.0, tag_font_ratio: 150.0, quote_position_ratio: 0.7, + subquote_position_ratio: 0.8, tag_position_ratio: 0.5, image_ratio: (4.0, 5.0), color_layer: [20, 22, 25, 197], @@ -115,13 +121,14 @@ impl ConfigFile { }; let default_config = (&*globals::CONFIG_NAME.read().unwrap()).to_string(); - let config_name = if map.len() > 1 || !map.contains_key(&default_config) { - ConfigPicker::new(map.keys().map(|a| a.to_owned()).collect()) - .selected() - .unwrap_or(default_config) - } else { - default_config - }; + let config_name = + if map.len() > 1 && map.len() != 0 || !map.contains_key(&default_config) { + ConfigPicker::new(map.keys().map(|a| a.to_owned()).collect()) + .selected() + .unwrap_or(default_config) + } else { + default_config + }; if let Some(config) = map.get(&config_name) { *globals::CONFIG_NAME.write().unwrap() = config_name; diff --git a/src/config_window.rs b/src/config_window.rs index 43c0455..2d5c4f5 100644 --- a/src/config_window.rs +++ b/src/config_window.rs @@ -31,11 +31,15 @@ pub(crate) struct ConfigWindow { pub(crate) del_config_btn: Button, pub(crate) quote_font_ttf: Output, pub(crate) quote_font_ttf_browse: Button, + pub(crate) subquote_font_ttf: Output, + pub(crate) subquote_font_ttf_browse: Button, pub(crate) tag_font_ttf: Output, pub(crate) tag_font_ttf_browse: Button, pub(crate) quote_font_ratio: ValueInput, + pub(crate) subquote_font_ratio: ValueInput, pub(crate) tag_font_ratio: ValueInput, pub(crate) quote_position_ratio: ValueInput, + pub(crate) subquote_position_ratio: ValueInput, pub(crate) tag_position_ratio: ValueInput, pub(crate) image_ratio_width: ValueInput, pub(crate) image_ratio_height: ValueInput, @@ -53,11 +57,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, 700, 450, "Config").center_screen(); + let mut win = Window::new(0, 0, 730, 530, "Config").center_screen(); win.set_icon(Some( SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(), )); - let mut row = Flex::default().with_size(690, 440).with_pos(5, 5).row(); + let mut row = Flex::default().with_size(720, 520).with_pos(5, 5).row(); let mut config_picker_flex = Flex::default().column(); // Picker let browse = Browser::default().with_type(BrowserType::Hold); @@ -87,7 +91,7 @@ impl ConfigWindow { &Frame::default() .with_label("Font for quote (ttf)") .with_align(Align::Right | Align::Inside), - 170, + 190, ); let quote_font_ttf = Output::default(); let quote_font_ttf_browse = Button::default().with_label("Pick"); @@ -95,12 +99,25 @@ impl ConfigWindow { quote_font_ttf_grp.end(); col.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_align(Align::Right | Align::Inside), + 190, + ); + 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); + let mut tag_font_ttf_grp = Flex::default().row(); tag_font_ttf_grp.set_size( &Frame::default() .with_label("Font for tag (ttf)") .with_align(Align::Right | Align::Inside), - 170, + 190, ); let tag_font_ttf = Output::default(); let tag_font_ttf_browse = Button::default().with_label("Pick"); @@ -113,14 +130,35 @@ impl ConfigWindow { &Frame::default() .with_label("Quote text size ratio") .with_align(Align::Right | Align::Inside), - 170, + 190, ); 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(), 170); + 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 subquote_font_ratio_grp = Flex::default().row(); + subquote_font_ratio_grp.set_size( + &Frame::default() + .with_label("Subquote text size ratio") + .with_align(Align::Right | Align::Inside), + 190, + ); + let subquote_font_ratio = ValueInput::default(); + subquote_font_ratio_grp.end(); + col.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); @@ -134,14 +172,14 @@ impl ConfigWindow { &Frame::default() .with_label("Tag text size ratio") .with_align(Align::Right | Align::Inside), - 170, + 190, ); let tag_font_ratio = ValueInput::default(); tag_font_ratio_grp.end(); col.set_size(&tag_font_ratio_grp, 30); let mut grp = Flex::default().row(); - grp.set_size(&Frame::default(), 170); + 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); @@ -155,18 +193,29 @@ impl ConfigWindow { &Frame::default() .with_label("Quote text position ratio") .with_align(Align::Right | Align::Inside), - 170, + 190, ); let quote_position_ratio = ValueInput::default(); quote_position_ratio_grp.end(); col.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_align(Align::Right | Align::Inside), + 190, + ); + let subquote_position_ratio = ValueInput::default(); + subquote_position_ratio_grp.end(); + col.set_size(&subquote_position_ratio_grp, 30); + let mut tag_position_ratio_grp = Flex::default().row(); tag_position_ratio_grp.set_size( &Frame::default() .with_label("Tag text position ratio") .with_align(Align::Right | Align::Inside), - 170, + 190, ); let tag_position_ratio = ValueInput::default(); tag_position_ratio_grp.end(); @@ -177,7 +226,7 @@ impl ConfigWindow { &Frame::default() .with_label("Image size ratio") .with_align(Align::Right | Align::Inside), - 170, + 190, ); let image_ratio_width = ValueInput::default(); image_ratio_grp.set_size(&Frame::default().with_label("x"), 30); @@ -239,11 +288,15 @@ impl ConfigWindow { del_config_btn, quote_font_ttf, quote_font_ttf_browse, + subquote_font_ttf, + subquote_font_ttf_browse, tag_font_ttf, tag_font_ttf_browse, quote_font_ratio, + subquote_font_ratio, tag_font_ratio, quote_position_ratio, + subquote_position_ratio, tag_position_ratio, image_ratio_width, image_ratio_height, @@ -275,11 +328,17 @@ impl ConfigWindow { let config = globals::CONFIG.read().unwrap(); self.quote_font_ttf .set_value(config.quote_font_ttf.as_str()); + self.subquote_font_ttf + .set_value(config.subquote_font_ttf.as_str()); self.tag_font_ttf.set_value(config.tag_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.tag_font_ratio.set_value(config.tag_font_ratio); self.quote_position_ratio .set_value(config.quote_position_ratio); + self.subquote_position_ratio + .set_value(config.subquote_position_ratio); self.tag_position_ratio.set_value(config.tag_position_ratio); self.image_ratio_width.set_value(config.image_ratio.0); self.image_ratio_height.set_value(config.image_ratio.1); @@ -298,10 +357,13 @@ 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 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(); @@ -337,10 +399,13 @@ impl ConfigWindow { .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 = [ @@ -353,10 +418,13 @@ impl ConfigWindow { 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); @@ -371,10 +439,13 @@ impl ConfigWindow { }); 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(); @@ -406,10 +477,13 @@ 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); 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); @@ -421,10 +495,13 @@ impl ConfigWindow { }); 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(); @@ -449,10 +526,13 @@ impl ConfigWindow { .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 = [ @@ -465,10 +545,13 @@ impl ConfigWindow { 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); 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); @@ -492,6 +575,17 @@ impl ConfigWindow { quote_font_ttf.set_value(path.to_str().unwrap()); }); + 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); + chooser.set_option(FileDialogOptions::UseFilterExt); + chooser.set_filter("*.ttf"); + 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 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); @@ -508,10 +602,13 @@ impl ConfigWindow { }); 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(); @@ -522,10 +619,13 @@ impl ConfigWindow { 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); @@ -536,10 +636,13 @@ impl ConfigWindow { }); 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(); @@ -557,10 +660,13 @@ impl ConfigWindow { .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 = [ diff --git a/src/draw_thread.rs b/src/draw_thread.rs index 34e51c8..9f20e21 100644 --- a/src/draw_thread.rs +++ b/src/draw_thread.rs @@ -50,14 +50,17 @@ pub(crate) fn spawn_image_thread( let mut win = main_win.win.clone(); 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 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 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 tag_position = main_win.tag_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 tag_position_slider = main_win.tag_position_slider.clone(); let mut page = main_win.page.clone(); let mut status = main_win.status.clone(); @@ -76,14 +79,17 @@ pub(crate) fn spawn_image_thread( Arc::clone(&images_path), None, &mut quote, + &mut subquote, &mut tag, &mut layer_red, &mut layer_green, &mut layer_blue, &mut layer_alpha, &mut quote_position, + &mut subquote_position, &mut tag_position, &mut quote_position_slider, + &mut subquote_position_slider, &mut tag_position_slider, &mut page, &mut count, @@ -102,14 +108,17 @@ pub(crate) fn spawn_image_thread( Arc::clone(&images_path), Some((x, y)), &mut quote, + &mut subquote, &mut tag, &mut layer_red, &mut layer_green, &mut layer_blue, &mut layer_alpha, &mut quote_position, + &mut subquote_position, &mut tag_position, &mut quote_position_slider, + &mut subquote_position_slider, &mut tag_position_slider, &mut page, &mut count, @@ -185,14 +194,17 @@ fn load_image( images_path: Arc>>, crop: Option<(f64, f64)>, quote: &mut MultilineInput, + subquote: &mut MultilineInput, tag: &mut Input, layer_red: &mut Spinner, layer_green: &mut Spinner, layer_blue: &mut Spinner, layer_alpha: &mut Spinner, quote_position: &mut Spinner, + subquote_position: &mut Spinner, tag_position: &mut Spinner, quote_position_slider: &mut Slider, + subquote_position_slider: &mut Slider, tag_position_slider: &mut Slider, page: &mut Page, count: &mut Frame, @@ -227,13 +239,18 @@ fn load_image( layer_blue.set_value(saved_prop.rgba[2] as f64); layer_alpha.set_value(saved_prop.rgba[3] as f64); quote.set_value(&saved_prop.quote); + subquote.set_value(&saved_prop.subquote); tag.set_value(&saved_prop.tag); 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); tag_position.set_range(0.0, prop.original_dimension.1); tag_position.set_value(saved_prop.tag_position); quote_position_slider.set_range(0.0, prop.original_dimension.1); + subquote_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); tag_position_slider.set_range(0.0, prop.original_dimension.1); tag_position_slider.set_value(saved_prop.tag_position); dimension.set_label(&format!( @@ -242,8 +259,10 @@ fn load_image( )); prop.quote = saved_prop.quote; + prop.subquote = saved_prop.subquote; prop.tag = saved_prop.tag; prop.quote_position = saved_prop.quote_position; + prop.subquote_position = saved_prop.subquote_position; prop.tag_position = saved_prop.tag_position; prop.rgba = saved_prop.rgba; prop.is_saved = true; @@ -265,13 +284,19 @@ fn load_image( if crop.is_none() { quote.set_value(""); prop.quote = "".to_owned(); + subquote.set_value(""); + prop.subquote = "".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); tag_position.set_range(0.0, prop.original_dimension.1); tag_position.set_value(prop.tag_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); tag_position_slider.set_range(0.0, prop.original_dimension.1); tag_position_slider.set_value(prop.tag_position); diff --git a/src/globals.rs b/src/globals.rs index 8cdc2ab..a2d348b 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -7,12 +7,6 @@ lazy_static! { pub static ref THEME: config::Themes = config::config().theme.unwrap_or(config::Themes::System); pub static ref CONFIG_NAME: RwLock = RwLock::new("default".to_owned()); pub static ref CONFIG: RwLock = RwLock::new(config::ConfigFile::load()); - // pub static ref IMAGE_RATIO: RwLock<(f64, f64)> = - // RwLock::new(CONFIG.read().unwrap().image_ratio); - // pub static ref QUOTE_POSITION_RATIO: RwLock = - // RwLock::new(CONFIG.read().unwrap().quote_position_ratio); - // pub static ref TAG_POSITION_RATIO: RwLock = - // RwLock::new(CONFIG.read().unwrap().tag_position_ratio); pub static ref FONT_QUOTE: Font<'static> = { let mut buffer = Vec::new(); if let Ok(mut file) = std::fs::File::open(CONFIG.read().unwrap().quote_font_ttf.as_str()) { @@ -25,6 +19,18 @@ lazy_static! { rusttype::Font::try_from_vec(include_bytes!("../ReenieBeanie-Regular.ttf").to_vec()) .unwrap() }; + pub static ref FONT_SUBQUOTE: Font<'static> = { + let mut buffer = Vec::new(); + if let Ok(mut file) = std::fs::File::open(CONFIG.read().unwrap().subquote_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()) { diff --git a/src/main_window.rs b/src/main_window.rs index d41c4e2..41b6745 100644 --- a/src/main_window.rs +++ b/src/main_window.rs @@ -31,17 +31,21 @@ pub(crate) struct MainWindow { pub(crate) save_btn: Button, pub(crate) file_choice: menu::Choice, pub(crate) quote: MultilineInput, + pub(crate) subquote: MultilineInput, pub(crate) tag: Input, pub(crate) layer_red: Spinner, pub(crate) layer_green: Spinner, pub(crate) layer_blue: Spinner, pub(crate) layer_alpha: Spinner, pub(crate) quote_position: Spinner, + pub(crate) subquote_position: Spinner, pub(crate) tag_position: Spinner, pub(crate) quote_position_slider: Slider, + pub(crate) subquote_position_slider: Slider, pub(crate) tag_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_tag_position_btn: Button, pub(crate) reset_file_choice: Button, pub(crate) crop_btn: Button, @@ -69,7 +73,7 @@ impl MainWindow { sender: app::Sender, draw_buff: Arc>>>, ) -> Self { - let mut win = Window::new(0, 0, 1000, 650, "Post Maker").center_screen(); + let mut win = Window::new(0, 0, 1000, 700, "Post Maker").center_screen(); win.set_icon(Some( SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(), )); @@ -101,15 +105,23 @@ impl MainWindow { &Frame::default() .with_label("Quote:") .with_align(enums::Align::Left | enums::Align::Inside), - 30, + 25, ); let quote = MultilineInput::default(); - controls_flex.set_size("e, 90); + controls_flex.set_size("e, 70); + 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( &Frame::default() .with_label("Tag:") .with_align(enums::Align::Left | enums::Align::Inside), - 30, + 25, ); let tag = Input::default(); controls_flex.set_size(&tag, 30); @@ -161,6 +173,22 @@ impl MainWindow { 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:") @@ -232,17 +260,21 @@ impl MainWindow { save_btn, file_choice, quote, + subquote, tag, layer_red, layer_green, layer_blue, layer_alpha, quote_position, + subquote_position, tag_position, quote_position_slider, + subquote_position_slider, tag_position_slider, reset_darklayer_btn, reset_quote_position_btn, + reset_subquote_position_btn, reset_tag_position_btn, reset_file_choice, crop_btn, @@ -396,7 +428,7 @@ impl MainWindow { self.reset_quote_position_btn.set_callback(move |_| { let mut prop = properties.write().unwrap(); let height = prop.original_dimension.1; - let pos = (height * 2.0) / 3.0; + let pos = height * globals::CONFIG.read().unwrap().quote_position_ratio; prop.quote_position = pos; prop.is_saved = false; quote_position.set_value(pos); @@ -407,6 +439,25 @@ impl MainWindow { image.redraw(); }); + let mut subquote_position = self.subquote_position.clone(); + let mut subquote_position_slider = self.subquote_position_slider.clone(); + let mut image = self.page.image.clone(); + let sender = self.sender.clone(); + let properties = Arc::clone(&self.properties); + self.reset_subquote_position_btn.set_callback(move |_| { + let mut prop = properties.write().unwrap(); + let height = prop.original_dimension.1; + let pos = height * globals::CONFIG.read().unwrap().subquote_position_ratio; + prop.subquote_position = pos; + prop.is_saved = false; + subquote_position.set_value(pos); + subquote_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(); @@ -415,7 +466,7 @@ impl MainWindow { self.reset_tag_position_btn.set_callback(move |_| { let mut prop = properties.write().unwrap(); let height = prop.original_dimension.1; - let pos = height / 2.0; + let pos = height * globals::CONFIG.read().unwrap().tag_position_ratio; prop.tag_position = pos; prop.is_saved = false; tag_position.set_value(pos); @@ -547,6 +598,21 @@ impl MainWindow { true }); + let mut image = self.page.image.clone(); + let properties = Arc::clone(&self.properties); + let sender = self.sender.clone(); + self.subquote.handle(move |f, ev| { + if ev == enums::Event::KeyUp { + let mut prop = properties.write().unwrap(); + prop.subquote = 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(); @@ -590,6 +656,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 subquote_position_slider = self.subquote_position_slider.clone(); + self.subquote_position.set_callback(move |f| { + let mut prop = properties.write().unwrap(); + prop.subquote_position = f.value(); + subquote_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 subquote_position = self.subquote_position.clone(); + self.subquote_position_slider.set_callback(move |f| { + let mut prop = properties.write().unwrap(); + prop.subquote_position = f.value(); + subquote_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(); diff --git a/src/utils.rs b/src/utils.rs index eeea3d0..4056159 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -74,6 +74,7 @@ impl ImageContainer { prop.path = Some(path.to_owned()); prop.original_dimension = (width, height); prop.quote_position = height * config.quote_position_ratio; + prop.subquote_position = height * config.subquote_position_ratio; prop.tag_position = height * config.tag_position_ratio; Self { @@ -144,7 +145,9 @@ impl ImageContainer { &mut tmp, &prop.rgba, &prop.quote, + &prop.subquote, prop.quote_position, + prop.subquote_position, &prop.tag, prop.tag_position, prop.original_dimension.1, @@ -191,7 +194,9 @@ impl ImageContainer { &mut img, &prop.rgba, &prop.quote, + &prop.subquote, prop.quote_position, + prop.subquote_position, &prop.tag, prop.tag_position, prop.original_dimension.1, @@ -276,9 +281,11 @@ pub(crate) struct ImageProperties { pub(crate) original_dimension: (f64, f64), pub(crate) crop_position: Option<(f64, f64)>, pub(crate) quote: String, + pub(crate) subquote: String, pub(crate) tag: String, - pub(crate) quote_position: f64, // as per original - pub(crate) tag_position: f64, // as per original + 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) rgba: [u8; 4], pub(crate) is_saved: bool, } @@ -291,8 +298,10 @@ impl ImageProperties { original_dimension: (0.0, 0.0), crop_position: None, quote: "".to_owned(), + subquote: "".to_owned(), tag: "".to_owned(), quote_position: 0.0, + subquote_position: 0.0, tag_position: 0.0, rgba: [0; 4], is_saved: true, @@ -304,7 +313,9 @@ fn draw_layer_and_text( tmp: &mut DynamicImage, rgba: &[u8; 4], quote: &str, + subquote: &str, quote_position: f64, + subquote_position: f64, tag: &str, tag_position: f64, original_height: f64, @@ -328,7 +339,7 @@ fn draw_layer_and_text( 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.2)) + ((quote_position * height) / original_height + index as f64 * (text_height * 1.15)) as u32, rusttype::Scale::uniform(size as f32), &globals::FONT_QUOTE, @@ -336,6 +347,26 @@ fn draw_layer_and_text( ); } + 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), + ); + + 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 = tag_from_height(height); for (index, line) in tag.lines().enumerate() { let (text_width, text_height) = measure_line( @@ -378,6 +409,10 @@ pub(crate) fn quote_from_height(height: f64) -> f64 { (height * globals::CONFIG.read().unwrap().quote_font_ratio) / 5000.0 } +pub(crate) fn subquote_from_height(height: f64) -> f64 { + (height * globals::CONFIG.read().unwrap().subquote_font_ratio) / 5000.0 +} + pub(crate) fn tag_from_height(height: f64) -> f64 { (height * globals::CONFIG.read().unwrap().tag_font_ratio) / 5000.0 }