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 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],
}

File diff suppressed because it is too large Load Diff

View File

@ -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::<ImageProperties>(&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);

View File

@ -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");

View File

@ -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<crate::AppMessage>,
draw_buff: Arc<RwLock<Option<Vec<u8>>>>,
) -> 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(&quote, 70);
controls_flex.set_size(
left_controls_flex.set_size(&quote, 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(&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);
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(&center_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(&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();
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();

View File

@ -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,