1) subquote 2, tag 2
2) combined rgb
3) colour rgb button
4) new layout to config
5) lots of fixes
This commit is contained in:
Piyush मिश्रः 2022-01-23 21:02:49 +05:30
parent b4e47eb96e
commit 386c0bc267
6 changed files with 1063 additions and 399 deletions

View File

@ -80,13 +80,19 @@ impl Into<ThemeType> for Themes {
pub struct ConfigFile { pub struct ConfigFile {
pub quote_font_ttf: String, pub quote_font_ttf: String,
pub subquote_font_ttf: String, pub subquote_font_ttf: String,
pub subquote2_font_ttf: String,
pub tag_font_ttf: String, pub tag_font_ttf: String,
pub tag2_font_ttf: String,
pub quote_font_ratio: f64, pub quote_font_ratio: f64,
pub subquote_font_ratio: f64, pub subquote_font_ratio: f64,
pub subquote2_font_ratio: f64,
pub tag_font_ratio: f64, pub tag_font_ratio: f64,
pub tag2_font_ratio: f64,
pub quote_position_ratio: f64, pub quote_position_ratio: f64,
pub subquote_position_ratio: f64, pub subquote_position_ratio: f64,
pub subquote2_position_ratio: f64,
pub tag_position_ratio: f64, pub tag_position_ratio: f64,
pub tag2_position_ratio: f64,
pub image_ratio: (f64, f64), pub image_ratio: (f64, f64),
pub color_layer: [u8; 4], pub color_layer: [u8; 4],
} }
@ -96,13 +102,19 @@ impl Default for ConfigFile {
Self { Self {
quote_font_ttf: String::new(), quote_font_ttf: String::new(),
subquote_font_ttf: String::new(), subquote_font_ttf: String::new(),
subquote2_font_ttf: String::new(),
tag_font_ttf: String::new(), tag_font_ttf: String::new(),
tag2_font_ttf: String::new(),
quote_font_ratio: 230.0, quote_font_ratio: 230.0,
subquote_font_ratio: 230.0, subquote_font_ratio: 230.0,
subquote2_font_ratio: 230.0,
tag_font_ratio: 150.0, tag_font_ratio: 150.0,
tag2_font_ratio: 150.0,
quote_position_ratio: 0.7, quote_position_ratio: 0.7,
subquote_position_ratio: 0.8, subquote_position_ratio: 0.8,
subquote2_position_ratio: 0.8,
tag_position_ratio: 0.5, tag_position_ratio: 0.5,
tag2_position_ratio: 0.5,
image_ratio: (4.0, 5.0), image_ratio: (4.0, 5.0),
color_layer: [20, 22, 25, 197], color_layer: [20, 22, 25, 197],
} }

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,12 @@
use crate::{ use crate::{
globals, globals,
main_window::{MainWindow, Page}, main_window::{MainWindow, Page},
AppMessage, utils, AppMessage,
}; };
use fltk::{ use fltk::{
app, enums, app,
button::Button,
enums,
frame::Frame, frame::Frame,
input::{Input, MultilineInput}, input::{Input, MultilineInput},
menu, menu,
@ -51,17 +53,21 @@ pub(crate) fn spawn_image_thread(
let mut file_choice = main_win.file_choice.clone(); let mut file_choice = main_win.file_choice.clone();
let mut quote = main_win.quote.clone(); let mut quote = main_win.quote.clone();
let mut subquote = main_win.subquote.clone(); let mut subquote = main_win.subquote.clone();
let mut subquote2 = main_win.subquote2.clone();
let mut tag = main_win.tag.clone(); let mut tag = main_win.tag.clone();
let mut layer_red = main_win.layer_red.clone(); let mut tag2 = main_win.tag2.clone();
let mut layer_green = main_win.layer_green.clone(); let mut layer_rgb = main_win.layer_rgb.clone();
let mut layer_blue = main_win.layer_blue.clone();
let mut layer_alpha = main_win.layer_alpha.clone(); let mut layer_alpha = main_win.layer_alpha.clone();
let mut quote_position = main_win.quote_position.clone(); let mut quote_position = main_win.quote_position.clone();
let mut subquote_position = main_win.subquote_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 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 quote_position_slider = main_win.quote_position_slider.clone();
let mut subquote_position_slider = main_win.subquote_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 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 page = main_win.page.clone();
let mut status = main_win.status.clone(); let mut status = main_win.status.clone();
let mut count = main_win.count.clone(); let mut count = main_win.count.clone();
@ -80,17 +86,21 @@ pub(crate) fn spawn_image_thread(
None, None,
&mut quote, &mut quote,
&mut subquote, &mut subquote,
&mut subquote2,
&mut tag, &mut tag,
&mut layer_red, &mut tag2,
&mut layer_green, &mut layer_rgb,
&mut layer_blue,
&mut layer_alpha, &mut layer_alpha,
&mut quote_position, &mut quote_position,
&mut subquote_position, &mut subquote_position,
&mut subquote2_position,
&mut tag_position, &mut tag_position,
&mut tag2_position,
&mut quote_position_slider, &mut quote_position_slider,
&mut subquote_position_slider, &mut subquote_position_slider,
&mut subquote2_position_slider,
&mut tag_position_slider, &mut tag_position_slider,
&mut tag2_position_slider,
&mut page, &mut page,
&mut count, &mut count,
&mut dimension, &mut dimension,
@ -109,17 +119,21 @@ pub(crate) fn spawn_image_thread(
Some((x, y)), Some((x, y)),
&mut quote, &mut quote,
&mut subquote, &mut subquote,
&mut subquote2,
&mut tag, &mut tag,
&mut layer_red, &mut tag2,
&mut layer_green, &mut layer_rgb,
&mut layer_blue,
&mut layer_alpha, &mut layer_alpha,
&mut quote_position, &mut quote_position,
&mut subquote_position, &mut subquote_position,
&mut subquote2_position,
&mut tag_position, &mut tag_position,
&mut tag2_position,
&mut quote_position_slider, &mut quote_position_slider,
&mut subquote_position_slider, &mut subquote_position_slider,
&mut subquote2_position_slider,
&mut tag_position_slider, &mut tag_position_slider,
&mut tag2_position_slider,
&mut page, &mut page,
&mut count, &mut count,
&mut dimension, &mut dimension,
@ -195,17 +209,21 @@ fn load_image(
crop: Option<(f64, f64)>, crop: Option<(f64, f64)>,
quote: &mut MultilineInput, quote: &mut MultilineInput,
subquote: &mut MultilineInput, subquote: &mut MultilineInput,
subquote2: &mut MultilineInput,
tag: &mut Input, tag: &mut Input,
layer_red: &mut Spinner, tag2: &mut Input,
layer_green: &mut Spinner, layer_rgb: &mut Button,
layer_blue: &mut Spinner,
layer_alpha: &mut Spinner, layer_alpha: &mut Spinner,
quote_position: &mut Spinner, quote_position: &mut Spinner,
subquote_position: &mut Spinner, subquote_position: &mut Spinner,
subquote2_position: &mut Spinner,
tag_position: &mut Spinner, tag_position: &mut Spinner,
tag2_position: &mut Spinner,
quote_position_slider: &mut Slider, quote_position_slider: &mut Slider,
subquote_position_slider: &mut Slider, subquote_position_slider: &mut Slider,
subquote2_position_slider: &mut Slider,
tag_position_slider: &mut Slider, tag_position_slider: &mut Slider,
tag2_position_slider: &mut Slider,
page: &mut Page, page: &mut Page,
count: &mut Frame, count: &mut Frame,
dimension: &mut Frame, dimension: &mut Frame,
@ -234,25 +252,33 @@ fn load_image(
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
let read = fs::read_to_string(&conf).unwrap(); let read = fs::read_to_string(&conf).unwrap();
if let Ok(saved_prop) = serde_json::from_str::<ImageProperties>(&read) { if let Ok(saved_prop) = serde_json::from_str::<ImageProperties>(&read) {
layer_red.set_value(saved_prop.rgba[0] as f64); utils::set_color_btn_rgba(saved_prop.rgba, layer_rgb);
layer_green.set_value(saved_prop.rgba[1] as f64);
layer_blue.set_value(saved_prop.rgba[2] as f64);
layer_alpha.set_value(saved_prop.rgba[3] as f64); layer_alpha.set_value(saved_prop.rgba[3] as f64);
quote.set_value(&saved_prop.quote); quote.set_value(&saved_prop.quote);
subquote.set_value(&saved_prop.subquote); subquote.set_value(&saved_prop.subquote);
subquote2.set_value(&saved_prop.subquote2);
tag.set_value(&saved_prop.tag); 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_range(0.0, prop.original_dimension.1);
quote_position.set_value(saved_prop.quote_position); quote_position.set_value(saved_prop.quote_position);
subquote_position.set_range(0.0, prop.original_dimension.1); subquote_position.set_range(0.0, prop.original_dimension.1);
subquote_position.set_value(saved_prop.subquote_position); 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_range(0.0, prop.original_dimension.1);
tag_position.set_value(saved_prop.tag_position); 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); quote_position_slider.set_range(0.0, prop.original_dimension.1);
subquote_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); quote_position_slider.set_value(saved_prop.quote_position);
subquote_position_slider.set_value(saved_prop.subquote_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_range(0.0, prop.original_dimension.1);
tag_position_slider.set_value(saved_prop.tag_position); 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!( dimension.set_label(&format!(
"[{}x{}]", "[{}x{}]",
prop.original_dimension.0, prop.original_dimension.1 prop.original_dimension.0, prop.original_dimension.1
@ -260,10 +286,14 @@ fn load_image(
prop.quote = saved_prop.quote; prop.quote = saved_prop.quote;
prop.subquote = saved_prop.subquote; prop.subquote = saved_prop.subquote;
prop.subquote2 = saved_prop.subquote2;
prop.tag = saved_prop.tag; prop.tag = saved_prop.tag;
prop.tag2 = saved_prop.tag2;
prop.quote_position = saved_prop.quote_position; prop.quote_position = saved_prop.quote_position;
prop.subquote_position = saved_prop.subquote_position; prop.subquote_position = saved_prop.subquote_position;
prop.subquote2_position = saved_prop.subquote2_position;
prop.tag_position = saved_prop.tag_position; prop.tag_position = saved_prop.tag_position;
prop.tag2_position = saved_prop.tag2_position;
prop.rgba = saved_prop.rgba; prop.rgba = saved_prop.rgba;
prop.is_saved = true; prop.is_saved = true;
use_defaults = false; use_defaults = false;
@ -286,24 +316,32 @@ fn load_image(
prop.quote = "".to_owned(); prop.quote = "".to_owned();
subquote.set_value(""); subquote.set_value("");
prop.subquote = "".to_owned(); prop.subquote = "".to_owned();
subquote2.set_value("");
prop.subquote2 = "".to_owned();
} }
quote_position.set_range(0.0, prop.original_dimension.1); quote_position.set_range(0.0, prop.original_dimension.1);
quote_position.set_value(prop.quote_position); quote_position.set_value(prop.quote_position);
subquote_position.set_range(0.0, prop.original_dimension.1); subquote_position.set_range(0.0, prop.original_dimension.1);
subquote_position.set_value(prop.subquote_position); 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_range(0.0, prop.original_dimension.1);
tag_position.set_value(prop.tag_position); 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_range(0.0, prop.original_dimension.1);
quote_position_slider.set_value(prop.quote_position); quote_position_slider.set_value(prop.quote_position);
subquote_position_slider.set_range(0.0, prop.original_dimension.1); subquote_position_slider.set_range(0.0, prop.original_dimension.1);
subquote_position_slider.set_value(prop.subquote_position); 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_range(0.0, prop.original_dimension.1);
tag_position_slider.set_value(prop.tag_position); 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(); let glob = &globals::CONFIG.read().unwrap();
layer_red.set_value(glob.color_layer[0] as f64); utils::set_color_btn_rgba(glob.color_layer, layer_rgb);
layer_green.set_value(glob.color_layer[1] as f64);
layer_blue.set_value(glob.color_layer[2] as f64);
layer_alpha.set_value(glob.color_layer[3] as f64); layer_alpha.set_value(glob.color_layer[3] as f64);
prop.rgba = glob.color_layer; prop.rgba = glob.color_layer;
drop(glob); drop(glob);

View File

@ -31,6 +31,19 @@ lazy_static! {
} }
rusttype::Font::try_from_vec(include_bytes!("../Rajdhani-Regular.ttf").to_vec()).unwrap() 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> = { pub static ref FONT_TAG: Font<'static> = {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
if let Ok(mut file) = std::fs::File::open(&CONFIG.read().unwrap().tag_font_ttf.as_str()) { 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() 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 ICON: OsString = include_str!("../icon.svg").into();
pub static ref RELOAD_ICON: OsString = { pub static ref RELOAD_ICON: OsString = {
let img = include_str!("../reload.svg"); let img = include_str!("../reload.svg");

View File

@ -1,12 +1,12 @@
use crate::crop_window::CropWindow; use crate::crop_window::CropWindow;
use crate::draw_thread::*; use crate::draw_thread::*;
use crate::utils;
use crate::utils::ImageProperties; use crate::utils::ImageProperties;
use crate::{config_window::ConfigWindow, globals}; use crate::{config_window::ConfigWindow, globals};
use fltk::dialog;
use fltk::valuator::{Slider, SliderType};
use fltk::{ use fltk::{
app, app,
button::Button, button::Button,
dialog,
dialog::NativeFileChooser, dialog::NativeFileChooser,
draw as dr, enums, draw as dr, enums,
enums::Shortcut, enums::Shortcut,
@ -17,6 +17,7 @@ use fltk::{
menu, menu,
misc::Spinner, misc::Spinner,
prelude::*, prelude::*,
valuator::{Slider, SliderType},
window::Window, window::Window,
}; };
use std::path::PathBuf; use std::path::PathBuf;
@ -32,21 +33,27 @@ pub(crate) struct MainWindow {
pub(crate) file_choice: menu::Choice, pub(crate) file_choice: menu::Choice,
pub(crate) quote: MultilineInput, pub(crate) quote: MultilineInput,
pub(crate) subquote: MultilineInput, pub(crate) subquote: MultilineInput,
pub(crate) subquote2: MultilineInput,
pub(crate) tag: Input, pub(crate) tag: Input,
pub(crate) layer_red: Spinner, pub(crate) tag2: Input,
pub(crate) layer_green: Spinner, pub(crate) layer_rgb: Button,
pub(crate) layer_blue: Spinner,
pub(crate) layer_alpha: Spinner, pub(crate) layer_alpha: Spinner,
pub(crate) quote_position: Spinner, pub(crate) quote_position: Spinner,
pub(crate) subquote_position: Spinner, pub(crate) subquote_position: Spinner,
pub(crate) subquote2_position: Spinner,
pub(crate) tag_position: Spinner, pub(crate) tag_position: Spinner,
pub(crate) tag2_position: Spinner,
pub(crate) quote_position_slider: Slider, pub(crate) quote_position_slider: Slider,
pub(crate) subquote_position_slider: Slider, pub(crate) subquote_position_slider: Slider,
pub(crate) subquote2_position_slider: Slider,
pub(crate) tag_position_slider: Slider, pub(crate) tag_position_slider: Slider,
pub(crate) tag2_position_slider: Slider,
pub(crate) reset_darklayer_btn: Button, pub(crate) reset_darklayer_btn: Button,
pub(crate) reset_quote_position_btn: Button, pub(crate) reset_quote_position_btn: Button,
pub(crate) reset_subquote_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_tag_position_btn: Button,
pub(crate) reset_tag2_position_btn: Button,
pub(crate) reset_file_choice: Button, pub(crate) reset_file_choice: Button,
pub(crate) crop_btn: Button, pub(crate) crop_btn: Button,
pub(crate) clone_btn: Button, pub(crate) clone_btn: Button,
@ -73,7 +80,7 @@ impl MainWindow {
sender: app::Sender<crate::AppMessage>, sender: app::Sender<crate::AppMessage>,
draw_buff: Arc<RwLock<Option<Vec<u8>>>>, draw_buff: Arc<RwLock<Option<Vec<u8>>>>,
) -> Self { ) -> 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( win.set_icon(Some(
SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(), SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(),
)); ));
@ -99,111 +106,52 @@ impl MainWindow {
main_flex.set_size(&toolbar_flex, 30); main_flex.set_size(&toolbar_flex, 30);
let mut workspace_flex = Flex::default().row(); let mut workspace_flex = Flex::default().row();
// Controls // Controls Left
let mut controls_flex = Flex::default().column(); let mut left_controls_flex = Flex::default().column();
controls_flex.set_size( left_controls_flex.set_size(
&Frame::default() &Frame::default()
.with_label("Quote:") .with_label("Quote:")
.with_align(enums::Align::Left | enums::Align::Inside), .with_align(enums::Align::Left | enums::Align::Inside),
25, 25,
); );
let quote = MultilineInput::default(); let quote = MultilineInput::default();
controls_flex.set_size(&quote, 70); left_controls_flex.set_size(&quote, 70);
controls_flex.set_size(
left_controls_flex.set_size(
&Frame::default() &Frame::default()
.with_label("Subquote:") .with_label("Subquote:")
.with_align(enums::Align::Left | enums::Align::Inside), .with_align(enums::Align::Left | enums::Align::Inside),
25, 25,
); );
let subquote = MultilineInput::default(); let subquote = MultilineInput::default();
controls_flex.set_size(&subquote, 70); left_controls_flex.set_size(&subquote, 70);
controls_flex.set_size(
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() &Frame::default()
.with_label("Tag:") .with_label("Tag:")
.with_align(enums::Align::Left | enums::Align::Inside), .with_align(enums::Align::Left | enums::Align::Inside),
25, 25,
); );
let tag = Input::default(); 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(); left_controls_flex.set_size(
Frame::default() &Frame::default()
.with_label("Dark Layer (RGBA):") .with_label("Tag 2:")
.with_align(enums::Align::Left | enums::Align::Inside); .with_align(enums::Align::Left | enums::Align::Inside),
let mut reset_darklayer_btn = Button::default(); 25,
reset_darklayer_btn.set_image(Some(reload_image.clone())); );
darklayer_head_flex.set_size(&reset_darklayer_btn, 30); let tag2 = Input::default();
darklayer_head_flex.end(); left_controls_flex.set_size(&tag2, 30);
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(&quote_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(&quote_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);
let mut actions_flex = Flex::default().row(); let mut actions_flex = Flex::default().row();
Frame::default(); Frame::default();
@ -215,7 +163,7 @@ impl MainWindow {
actions_flex.set_size(&crop_btn, 100); actions_flex.set_size(&crop_btn, 100);
Frame::default(); Frame::default();
actions_flex.end(); actions_flex.end();
controls_flex.set_size(&actions_flex, 30); left_controls_flex.set_size(&actions_flex, 30);
Frame::default(); Frame::default();
@ -224,10 +172,10 @@ impl MainWindow {
let status = Frame::default(); let status = Frame::default();
let dimension = Frame::default().with_align(enums::Align::Right | enums::Align::Inside); let dimension = Frame::default().with_align(enums::Align::Right | enums::Align::Inside);
info_flex.end(); info_flex.end();
controls_flex.set_size(&info_flex, 30); left_controls_flex.set_size(&info_flex, 30);
controls_flex.end(); left_controls_flex.end();
workspace_flex.set_size(&controls_flex, 360); workspace_flex.set_size(&left_controls_flex, 310);
// Page // Page
let mut center_row_flex = Flex::default().row(); let mut center_row_flex = Flex::default().row();
@ -242,6 +190,129 @@ impl MainWindow {
center_row_flex.set_size(&center_col_flex, 400); center_row_flex.set_size(&center_col_flex, 400);
center_row_flex.end(); 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(&quote_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(&quote_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(); workspace_flex.end();
main_flex.end(); main_flex.end();
@ -261,21 +332,27 @@ impl MainWindow {
file_choice, file_choice,
quote, quote,
subquote, subquote,
subquote2,
tag, tag,
layer_red, tag2,
layer_green, layer_rgb,
layer_blue,
layer_alpha, layer_alpha,
quote_position, quote_position,
subquote_position, subquote_position,
subquote2_position,
tag_position, tag_position,
tag2_position,
quote_position_slider, quote_position_slider,
subquote_position_slider, subquote_position_slider,
subquote2_position_slider,
tag_position_slider, tag_position_slider,
tag2_position_slider,
reset_darklayer_btn, reset_darklayer_btn,
reset_quote_position_btn, reset_quote_position_btn,
reset_subquote_position_btn, reset_subquote_position_btn,
reset_subquote2_position_btn,
reset_tag_position_btn, reset_tag_position_btn,
reset_tag2_position_btn,
reset_file_choice, reset_file_choice,
crop_btn, crop_btn,
clone_btn, clone_btn,
@ -399,9 +476,7 @@ impl MainWindow {
load_dir(&path, Arc::clone(&imgs), &mut file_choice, &sender); load_dir(&path, Arc::clone(&imgs), &mut file_choice, &sender);
}); });
let mut layer_red = self.layer_red.clone(); let mut layer_rgb = self.layer_rgb.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(); let mut layer_alpha = self.layer_alpha.clone();
let mut image = self.page.image.clone(); let mut image = self.page.image.clone();
let sender = self.sender.clone(); let sender = self.sender.clone();
@ -411,9 +486,7 @@ impl MainWindow {
let color = globals::CONFIG.read().unwrap().color_layer; let color = globals::CONFIG.read().unwrap().color_layer;
prop.rgba = color; prop.rgba = color;
prop.is_saved = false; prop.is_saved = false;
layer_red.set_value(color[0] as f64); utils::set_color_btn_rgba(color, &mut layer_rgb);
layer_green.set_value(color[1] as f64);
layer_blue.set_value(color[2] as f64);
layer_alpha.set_value(color[3] as f64); layer_alpha.set_value(color[3] as f64);
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
@ -458,6 +531,25 @@ impl MainWindow {
image.redraw(); 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 = self.tag_position.clone();
let mut tag_position_slider = self.tag_position_slider.clone(); let mut tag_position_slider = self.tag_position_slider.clone();
let mut image = self.page.image.clone(); let mut image = self.page.image.clone();
@ -477,6 +569,25 @@ impl MainWindow {
image.redraw(); 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 sender = self.sender.clone();
let properties = Arc::clone(&self.properties); let properties = Arc::clone(&self.properties);
self.save_btn.set_callback(move |_| { self.save_btn.set_callback(move |_| {
@ -613,6 +724,21 @@ impl MainWindow {
true 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 mut image = self.page.image.clone();
let properties = Arc::clone(&self.properties); let properties = Arc::clone(&self.properties);
let sender = self.sender.clone(); let sender = self.sender.clone();
@ -628,6 +754,21 @@ impl MainWindow {
true 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 mut image = self.page.image.clone();
let properties = Arc::clone(&self.properties); let properties = Arc::clone(&self.properties);
let sender = self.sender.clone(); let sender = self.sender.clone();
@ -684,6 +825,34 @@ impl MainWindow {
image.redraw(); 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 mut image = self.page.image.clone();
let properties = Arc::clone(&self.properties); let properties = Arc::clone(&self.properties);
let sender = self.sender.clone(); let sender = self.sender.clone();
@ -715,9 +884,11 @@ impl MainWindow {
let mut image = self.page.image.clone(); let mut image = self.page.image.clone();
let properties = Arc::clone(&self.properties); let properties = Arc::clone(&self.properties);
let sender = self.sender.clone(); 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(); 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; prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
@ -727,21 +898,29 @@ impl MainWindow {
let mut image = self.page.image.clone(); let mut image = self.page.image.clone();
let properties = Arc::clone(&self.properties); let properties = Arc::clone(&self.properties);
let sender = self.sender.clone(); 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(); 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; prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();
}); });
let mut image = self.page.image.clone(); let mut image = self.page.image.clone();
let properties = Arc::clone(&self.properties); let properties = Arc::clone(&self.properties);
let sender = self.sender.clone(); 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(); 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; prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();

View File

@ -4,7 +4,7 @@ use std::{
sync::{Arc, RwLock}, sync::{Arc, RwLock},
}; };
use fltk::dialog; use fltk::{button::Button, dialog, enums, prelude::*};
use image::{DynamicImage, GenericImageView, ImageBuffer}; use image::{DynamicImage, GenericImageView, ImageBuffer};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -75,7 +75,9 @@ impl ImageContainer {
prop.original_dimension = (width, height); prop.original_dimension = (width, height);
prop.quote_position = height * config.quote_position_ratio; prop.quote_position = height * config.quote_position_ratio;
prop.subquote_position = height * config.subquote_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.tag_position = height * config.tag_position_ratio;
prop.tag2_position = height * config.tag2_position_ratio;
Self { Self {
image: img.clone(), image: img.clone(),
@ -146,10 +148,14 @@ impl ImageContainer {
&prop.rgba, &prop.rgba,
&prop.quote, &prop.quote,
&prop.subquote, &prop.subquote,
&prop.subquote2,
prop.quote_position, prop.quote_position,
prop.subquote_position, prop.subquote_position,
prop.subquote2_position,
&prop.tag, &prop.tag,
&prop.tag2,
prop.tag_position, prop.tag_position,
prop.tag2_position,
prop.original_dimension.1, prop.original_dimension.1,
); );
@ -195,10 +201,14 @@ impl ImageContainer {
&prop.rgba, &prop.rgba,
&prop.quote, &prop.quote,
&prop.subquote, &prop.subquote,
&prop.subquote2,
prop.quote_position, prop.quote_position,
prop.subquote_position, prop.subquote_position,
prop.subquote2_position,
&prop.tag, &prop.tag,
&prop.tag2,
prop.tag_position, prop.tag_position,
prop.tag2_position,
prop.original_dimension.1, prop.original_dimension.1,
); );
@ -282,10 +292,14 @@ pub(crate) struct ImageProperties {
pub(crate) crop_position: Option<(f64, f64)>, pub(crate) crop_position: Option<(f64, f64)>,
pub(crate) quote: String, pub(crate) quote: String,
pub(crate) subquote: String, pub(crate) subquote: String,
pub(crate) subquote2: String,
pub(crate) tag: String, pub(crate) tag: String,
pub(crate) tag2: String,
pub(crate) quote_position: f64, // as per original pub(crate) quote_position: f64, // as per original
pub(crate) subquote_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) tag_position: f64, // as per original
pub(crate) tag2_position: f64, // as per original
pub(crate) rgba: [u8; 4], pub(crate) rgba: [u8; 4],
pub(crate) is_saved: bool, pub(crate) is_saved: bool,
} }
@ -299,10 +313,14 @@ impl ImageProperties {
crop_position: None, crop_position: None,
quote: "".to_owned(), quote: "".to_owned(),
subquote: "".to_owned(), subquote: "".to_owned(),
subquote2: "".to_owned(),
tag: "".to_owned(), tag: "".to_owned(),
tag2: "".to_owned(),
quote_position: 0.0, quote_position: 0.0,
subquote_position: 0.0, subquote_position: 0.0,
subquote2_position: 0.0,
tag_position: 0.0, tag_position: 0.0,
tag2_position: 0.0,
rgba: [0; 4], rgba: [0; 4],
is_saved: true, is_saved: true,
} }
@ -314,10 +332,14 @@ fn draw_layer_and_text(
rgba: &[u8; 4], rgba: &[u8; 4],
quote: &str, quote: &str,
subquote: &str, subquote: &str,
subquote2: &str,
quote_position: f64, quote_position: f64,
subquote_position: f64, subquote_position: f64,
subquote2_position: f64,
tag: &str, tag: &str,
tag2: &str,
tag_position: f64, tag_position: f64,
tag2_position: f64,
original_height: f64, original_height: f64,
) { ) {
let (width, height): (f64, f64) = Coord::from(tmp.dimensions()).into(); 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); image::imageops::overlay(tmp, &layer, 0, 0);
let size = quote_from_height(height); let size = quote_from_height(height);
for (index, line) in quote.lines().enumerate() { draw_multiline_mid_string(
let (text_width, text_height) = measure_line(
&globals::FONT_QUOTE,
line,
rusttype::Scale::uniform(size as f32),
);
imageproc::drawing::draw_text_mut(
tmp, 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, &globals::FONT_QUOTE,
line, size,
quote_position,
original_height,
quote,
); );
}
let size = subquote_from_height(height); let size = subquote_from_height(height);
for (index, line) in subquote.lines().enumerate() { draw_multiline_mid_string(
let (text_width, text_height) = measure_line( tmp,
&globals::FONT_SUBQUOTE, &globals::FONT_SUBQUOTE,
line, size,
rusttype::Scale::uniform(size as f32), 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( let size = tag2_from_height(height);
draw_multiline_mid_string(
tmp, tmp,
image::Rgba([255, 255, 255, 255]), &globals::FONT_TAG2,
((width - text_width) / 2.0) as u32, size,
((subquote_position * height) / original_height + index as f64 * (text_height * 1.15)) tag2_position,
as u32, original_height,
rusttype::Scale::uniform(size as f32), tag2,
&globals::FONT_SUBQUOTE,
line,
); );
}
let size = tag_from_height(height); let size = tag_from_height(height);
for (index, line) in tag.lines().enumerate() { 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) { pub(crate) fn croped_ratio(width: f64, height: f64) -> (f64, f64) {
if width > width_from_height(height) { if width > width_from_height(height) {
(width_from_height(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 (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 { pub(crate) fn tag_from_height(height: f64) -> f64 {
(height * globals::CONFIG.read().unwrap().tag_font_ratio) / 5000.0 (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( pub(crate) fn measure_line(
font: &rusttype::Font, font: &rusttype::Font,
text: &str, text: &str,