* Added support for blured box around quotes
* Removed useless ttf and added opensans * Cleaned global and grouped all fonts together in one function
This commit is contained in:
parent
55d394380d
commit
90d72f9d4e
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "post_maker"
|
name = "post_maker"
|
||||||
version = "0.5.0-alpha.1"
|
version = "0.6.0-alpha.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Post Maker helps you to make post for Instagram and other Social Media apps easily."
|
description = "Post Maker helps you to make post for Instagram and other Social Media apps easily."
|
||||||
authors = ["PiyushXCoder <https://piyushxcoder.in>"]
|
authors = ["PiyushXCoder <https://piyushxcoder.in>"]
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -132,6 +132,7 @@ pub(crate) struct ConfigFile {
|
||||||
pub(crate) color_layer: [u8; 4],
|
pub(crate) color_layer: [u8; 4],
|
||||||
pub(crate) minimum_width_limit: f64, // for export of image
|
pub(crate) minimum_width_limit: f64, // for export of image
|
||||||
pub(crate) maximum_width_limit: f64, // for export of image
|
pub(crate) maximum_width_limit: f64, // for export of image
|
||||||
|
pub(crate) draw_box_around_quote: bool,
|
||||||
pub(crate) image_format: ImageType,
|
pub(crate) image_format: ImageType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,10 +156,11 @@ impl Default for ConfigFile {
|
||||||
tag_y_position_ratio: 0.5,
|
tag_y_position_ratio: 0.5,
|
||||||
tag2_position_ratio: 0.95,
|
tag2_position_ratio: 0.95,
|
||||||
image_ratio: (4.0, 5.0),
|
image_ratio: (4.0, 5.0),
|
||||||
color_layer: [20, 22, 25, 197],
|
color_layer: [20, 22, 25, 80],
|
||||||
minimum_width_limit: 650.0,
|
minimum_width_limit: 650.0,
|
||||||
maximum_width_limit: 1080.0,
|
maximum_width_limit: 1080.0,
|
||||||
image_format: ImageType::Png,
|
draw_box_around_quote: true,
|
||||||
|
image_format: ImageType::Jpeg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ use crate::{
|
||||||
use fltk::{
|
use fltk::{
|
||||||
app,
|
app,
|
||||||
browser::{Browser, BrowserType},
|
browser::{Browser, BrowserType},
|
||||||
button::{Button, RadioRoundButton},
|
button::{Button, CheckButton, RadioRoundButton},
|
||||||
dialog::{FileDialogOptions, NativeFileChooser},
|
dialog::{FileDialogOptions, NativeFileChooser},
|
||||||
enums::{self, Align, Event, Font},
|
enums::{self, Align, Event, Font},
|
||||||
frame::Frame,
|
frame::Frame,
|
||||||
|
|
@ -65,6 +65,7 @@ pub(crate) struct ConfigWindow {
|
||||||
pub(crate) tag2_position_ratio: ValueInput,
|
pub(crate) tag2_position_ratio: ValueInput,
|
||||||
pub(crate) image_ratio_width: ValueInput,
|
pub(crate) image_ratio_width: ValueInput,
|
||||||
pub(crate) image_ratio_height: ValueInput,
|
pub(crate) image_ratio_height: ValueInput,
|
||||||
|
pub(crate) draw_box_around_quote: CheckButton,
|
||||||
pub(crate) minimum_width_limit: ValueInput,
|
pub(crate) minimum_width_limit: ValueInput,
|
||||||
pub(crate) maximum_width_limit: ValueInput,
|
pub(crate) maximum_width_limit: ValueInput,
|
||||||
/// RGB value of top translucent layer
|
/// RGB value of top translucent layer
|
||||||
|
|
@ -389,6 +390,18 @@ impl ConfigWindow {
|
||||||
image_ratio_grp.end();
|
image_ratio_grp.end();
|
||||||
col.set_size(&image_ratio_grp, 30);
|
col.set_size(&image_ratio_grp, 30);
|
||||||
|
|
||||||
|
// Draw box around Quote
|
||||||
|
let mut label = Frame::default().with_label("Draw Box:");
|
||||||
|
label.set_label_font(enums::Font::HelveticaBold);
|
||||||
|
col.set_size(&label, 15);
|
||||||
|
|
||||||
|
let mut draw_box_around_quote_flex = Flex::default().row();
|
||||||
|
draw_box_around_quote_flex.set_size(&Frame::default(), 20);
|
||||||
|
let mut draw_box_around_quote = CheckButton::default().with_label("Draw box around text");
|
||||||
|
draw_box_around_quote.set_value(true);
|
||||||
|
draw_box_around_quote_flex.end();
|
||||||
|
col.set_size(&draw_box_around_quote_flex, 30);
|
||||||
|
|
||||||
let mut label = Frame::default().with_label("Image with limits:");
|
let mut label = Frame::default().with_label("Image with limits:");
|
||||||
label.set_label_font(enums::Font::HelveticaBold);
|
label.set_label_font(enums::Font::HelveticaBold);
|
||||||
col.set_size(&label, 15);
|
col.set_size(&label, 15);
|
||||||
|
|
@ -505,6 +518,7 @@ impl ConfigWindow {
|
||||||
tag2_position_ratio,
|
tag2_position_ratio,
|
||||||
image_ratio_width,
|
image_ratio_width,
|
||||||
image_ratio_height,
|
image_ratio_height,
|
||||||
|
draw_box_around_quote,
|
||||||
minimum_width_limit,
|
minimum_width_limit,
|
||||||
maximum_width_limit,
|
maximum_width_limit,
|
||||||
translucent_layer_rgb,
|
translucent_layer_rgb,
|
||||||
|
|
@ -561,6 +575,8 @@ impl ConfigWindow {
|
||||||
.set_value(config.tag2_position_ratio);
|
.set_value(config.tag2_position_ratio);
|
||||||
self.image_ratio_width.set_value(config.image_ratio.0);
|
self.image_ratio_width.set_value(config.image_ratio.0);
|
||||||
self.image_ratio_height.set_value(config.image_ratio.1);
|
self.image_ratio_height.set_value(config.image_ratio.1);
|
||||||
|
self.draw_box_around_quote
|
||||||
|
.set_checked(config.draw_box_around_quote);
|
||||||
self.minimum_width_limit
|
self.minimum_width_limit
|
||||||
.set_value(config.minimum_width_limit);
|
.set_value(config.minimum_width_limit);
|
||||||
self.maximum_width_limit
|
self.maximum_width_limit
|
||||||
|
|
@ -611,6 +627,7 @@ impl ConfigWindow {
|
||||||
let mut tag2_position_ratio = self.tag2_position_ratio.clone();
|
let mut tag2_position_ratio = self.tag2_position_ratio.clone();
|
||||||
let mut image_ratio_width = self.image_ratio_width.clone();
|
let mut image_ratio_width = self.image_ratio_width.clone();
|
||||||
let mut image_ratio_height = self.image_ratio_height.clone();
|
let mut image_ratio_height = self.image_ratio_height.clone();
|
||||||
|
let draw_box_around_quote = self.draw_box_around_quote.clone();
|
||||||
let mut minimum_width_limit = self.minimum_width_limit.clone();
|
let mut minimum_width_limit = self.minimum_width_limit.clone();
|
||||||
let mut maximum_width_limit = self.maximum_width_limit.clone();
|
let mut maximum_width_limit = self.maximum_width_limit.clone();
|
||||||
let mut layer_rgb = self.translucent_layer_rgb.clone();
|
let mut layer_rgb = self.translucent_layer_rgb.clone();
|
||||||
|
|
@ -657,6 +674,7 @@ impl ConfigWindow {
|
||||||
tag2_position_ratio.set_value(conf.tag2_position_ratio);
|
tag2_position_ratio.set_value(conf.tag2_position_ratio);
|
||||||
image_ratio_width.set_value(conf.image_ratio.0);
|
image_ratio_width.set_value(conf.image_ratio.0);
|
||||||
image_ratio_height.set_value(conf.image_ratio.1);
|
image_ratio_height.set_value(conf.image_ratio.1);
|
||||||
|
draw_box_around_quote.set_checked(conf.draw_box_around_quote);
|
||||||
minimum_width_limit.set_value(conf.minimum_width_limit);
|
minimum_width_limit.set_value(conf.minimum_width_limit);
|
||||||
maximum_width_limit.set_value(conf.maximum_width_limit);
|
maximum_width_limit.set_value(conf.maximum_width_limit);
|
||||||
utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb);
|
utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb);
|
||||||
|
|
@ -687,6 +705,7 @@ impl ConfigWindow {
|
||||||
let mut tag2_position_ratio = self.tag2_position_ratio.clone();
|
let mut tag2_position_ratio = self.tag2_position_ratio.clone();
|
||||||
let mut image_ratio_width = self.image_ratio_width.clone();
|
let mut image_ratio_width = self.image_ratio_width.clone();
|
||||||
let mut image_ratio_height = self.image_ratio_height.clone();
|
let mut image_ratio_height = self.image_ratio_height.clone();
|
||||||
|
let draw_box_around_quote = self.draw_box_around_quote.clone();
|
||||||
let mut minimum_width_limit = self.minimum_width_limit.clone();
|
let mut minimum_width_limit = self.minimum_width_limit.clone();
|
||||||
let mut maximum_width_limit = self.maximum_width_limit.clone();
|
let mut maximum_width_limit = self.maximum_width_limit.clone();
|
||||||
let mut layer_rgb = self.translucent_layer_rgb.clone();
|
let mut layer_rgb = self.translucent_layer_rgb.clone();
|
||||||
|
|
@ -732,6 +751,7 @@ impl ConfigWindow {
|
||||||
tag2_position_ratio.set_value(conf.tag2_position_ratio);
|
tag2_position_ratio.set_value(conf.tag2_position_ratio);
|
||||||
image_ratio_width.set_value(conf.image_ratio.0);
|
image_ratio_width.set_value(conf.image_ratio.0);
|
||||||
image_ratio_height.set_value(conf.image_ratio.1);
|
image_ratio_height.set_value(conf.image_ratio.1);
|
||||||
|
draw_box_around_quote.set_checked(conf.draw_box_around_quote);
|
||||||
minimum_width_limit.set_value(conf.minimum_width_limit);
|
minimum_width_limit.set_value(conf.minimum_width_limit);
|
||||||
maximum_width_limit.set_value(conf.maximum_width_limit);
|
maximum_width_limit.set_value(conf.maximum_width_limit);
|
||||||
utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb);
|
utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb);
|
||||||
|
|
@ -759,6 +779,7 @@ impl ConfigWindow {
|
||||||
let mut tag2_position_ratio = self.tag2_position_ratio.clone();
|
let mut tag2_position_ratio = self.tag2_position_ratio.clone();
|
||||||
let mut image_ratio_width = self.image_ratio_width.clone();
|
let mut image_ratio_width = self.image_ratio_width.clone();
|
||||||
let mut image_ratio_height = self.image_ratio_height.clone();
|
let mut image_ratio_height = self.image_ratio_height.clone();
|
||||||
|
let draw_box_around_quote = self.draw_box_around_quote.clone();
|
||||||
let mut minimum_width_limit = self.minimum_width_limit.clone();
|
let mut minimum_width_limit = self.minimum_width_limit.clone();
|
||||||
let mut maximum_width_limit = self.maximum_width_limit.clone();
|
let mut maximum_width_limit = self.maximum_width_limit.clone();
|
||||||
let mut layer_rgb = self.translucent_layer_rgb.clone();
|
let mut layer_rgb = self.translucent_layer_rgb.clone();
|
||||||
|
|
@ -794,6 +815,7 @@ impl ConfigWindow {
|
||||||
tag2_position_ratio.set_value(conf.tag2_position_ratio);
|
tag2_position_ratio.set_value(conf.tag2_position_ratio);
|
||||||
image_ratio_width.set_value(conf.image_ratio.0);
|
image_ratio_width.set_value(conf.image_ratio.0);
|
||||||
image_ratio_height.set_value(conf.image_ratio.1);
|
image_ratio_height.set_value(conf.image_ratio.1);
|
||||||
|
draw_box_around_quote.set_checked(conf.draw_box_around_quote);
|
||||||
minimum_width_limit.set_value(conf.minimum_width_limit);
|
minimum_width_limit.set_value(conf.minimum_width_limit);
|
||||||
maximum_width_limit.set_value(conf.maximum_width_limit);
|
maximum_width_limit.set_value(conf.maximum_width_limit);
|
||||||
utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb);
|
utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb);
|
||||||
|
|
@ -1108,6 +1130,18 @@ impl ConfigWindow {
|
||||||
true
|
true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let browse = self.browse.clone();
|
||||||
|
let configs = Rc::clone(&self.configs);
|
||||||
|
self.draw_box_around_quote.handle(move |f, _| {
|
||||||
|
if let Some(conf) = configs
|
||||||
|
.borrow_mut()
|
||||||
|
.get_mut(&browse.selected_text().unwrap())
|
||||||
|
{
|
||||||
|
conf.draw_box_around_quote = f.value();
|
||||||
|
}
|
||||||
|
true
|
||||||
|
});
|
||||||
|
|
||||||
// Minimum Width Limit
|
// Minimum Width Limit
|
||||||
let browse = self.browse.clone();
|
let browse = self.browse.clone();
|
||||||
let configs = Rc::clone(&self.configs);
|
let configs = Rc::clone(&self.configs);
|
||||||
|
|
@ -1225,6 +1259,7 @@ impl ConfigWindow {
|
||||||
let mut tag2_position_ratio = self.tag2_position_ratio.clone();
|
let mut tag2_position_ratio = self.tag2_position_ratio.clone();
|
||||||
let mut image_ratio_width = self.image_ratio_width.clone();
|
let mut image_ratio_width = self.image_ratio_width.clone();
|
||||||
let mut image_ratio_height = self.image_ratio_height.clone();
|
let mut image_ratio_height = self.image_ratio_height.clone();
|
||||||
|
let draw_box_around_quote = self.draw_box_around_quote.clone();
|
||||||
let mut minimum_width_limit = self.minimum_width_limit.clone();
|
let mut minimum_width_limit = self.minimum_width_limit.clone();
|
||||||
let mut maximum_width_limit = self.maximum_width_limit.clone();
|
let mut maximum_width_limit = self.maximum_width_limit.clone();
|
||||||
let mut layer_rgb = self.translucent_layer_rgb.clone();
|
let mut layer_rgb = self.translucent_layer_rgb.clone();
|
||||||
|
|
@ -1253,13 +1288,23 @@ impl ConfigWindow {
|
||||||
tag2_position_ratio.set_value(conf.tag2_position_ratio);
|
tag2_position_ratio.set_value(conf.tag2_position_ratio);
|
||||||
image_ratio_width.set_value(conf.image_ratio.0);
|
image_ratio_width.set_value(conf.image_ratio.0);
|
||||||
image_ratio_height.set_value(conf.image_ratio.1);
|
image_ratio_height.set_value(conf.image_ratio.1);
|
||||||
|
draw_box_around_quote.set_checked(conf.draw_box_around_quote);
|
||||||
minimum_width_limit.set_value(conf.minimum_width_limit);
|
minimum_width_limit.set_value(conf.minimum_width_limit);
|
||||||
maximum_width_limit.set_value(conf.maximum_width_limit);
|
maximum_width_limit.set_value(conf.maximum_width_limit);
|
||||||
utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb);
|
utils::set_color_btn_rgba(conf.color_layer, &mut layer_rgb);
|
||||||
layer_rgb.redraw();
|
layer_rgb.redraw();
|
||||||
layer_alpha.set_value(conf.color_layer[3] as f64);
|
layer_alpha.set_value(conf.color_layer[3] as f64);
|
||||||
|
match conf.image_format {
|
||||||
|
ImageType::Png => {
|
||||||
png_format.set_value(true);
|
png_format.set_value(true);
|
||||||
jpeg_format.set_value(false);
|
jpeg_format.set_value(false);
|
||||||
|
}
|
||||||
|
ImageType::Jpeg => {
|
||||||
|
png_format.set_value(false);
|
||||||
|
jpeg_format.set_value(true);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
configs
|
configs
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.insert(browse.selected_text().unwrap(), conf);
|
.insert(browse.selected_text().unwrap(), conf);
|
||||||
|
|
|
||||||
|
|
@ -18,5 +18,5 @@ pub(crate) fn message_default(txt: &str) {
|
||||||
|
|
||||||
pub(crate) fn choice_default(txt: &str, b0: &str, b1: &str) -> i32 {
|
pub(crate) fn choice_default(txt: &str, b0: &str, b1: &str) -> i32 {
|
||||||
let (x, y) = get_mouse();
|
let (x, y) = get_mouse();
|
||||||
dialog::choice(x, y, txt, b0, b1, "")
|
dialog::choice2(x, y, txt, b0, b1, "").unwrap_or(-1)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,85 +33,19 @@ lazy_static! {
|
||||||
pub(crate) static ref MAIN_SENDER: RwLock<Option<fltk::app::Sender<crate::AppMessage>>> = RwLock::new(None);
|
pub(crate) static ref MAIN_SENDER: RwLock<Option<fltk::app::Sender<crate::AppMessage>>> = RwLock::new(None);
|
||||||
|
|
||||||
/// TTF Font for Quote
|
/// TTF Font for Quote
|
||||||
pub(crate) static ref FONT_QUOTE: Font<'static> = {
|
pub(crate) static ref FONT_QUOTE: Font<'static> = load_font(rw_read!(CONFIG).quote_font.as_str());
|
||||||
let mut buffer = Vec::new();
|
|
||||||
if let Ok(mut file) = std::fs::File::open(rw_read!(CONFIG).quote_font.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!("../assets/fonts/ReenieBeanie-Regular.ttf").to_vec(),
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
/// TTF Font for Subquote
|
/// TTF Font for Subquote
|
||||||
pub(crate) static ref FONT_SUBQUOTE: Font<'static> = {
|
pub(crate) static ref FONT_SUBQUOTE: Font<'static> = load_font(rw_read!(CONFIG).subquote_font.as_str());
|
||||||
let mut buffer = Vec::new();
|
|
||||||
if let Ok(mut file) = std::fs::File::open(rw_read!(CONFIG).subquote_font.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!("../assets/fonts/ReenieBeanie-Regular.ttf").to_vec(),
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
/// TTF Font for Subquote 2
|
/// TTF Font for Subquote 2
|
||||||
pub(crate) static ref FONT_SUBQUOTE2: Font<'static> = {
|
pub(crate) static ref FONT_SUBQUOTE2: Font<'static> = load_font(rw_read!(CONFIG).subquote2_font.as_str());
|
||||||
let mut buffer = Vec::new();
|
|
||||||
if let Ok(mut file) =
|
|
||||||
std::fs::File::open(rw_read!(CONFIG).subquote2_font.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!("../assets/fonts/Rajdhani-Regular.ttf").to_vec(),
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
/// TTF Font for Tag
|
/// TTF Font for Tag
|
||||||
pub(crate) static ref FONT_TAG: Font<'static> = {
|
pub(crate) static ref FONT_TAG: Font<'static> = load_font(rw_read!(CONFIG).tag_font.as_str());
|
||||||
let mut buffer = Vec::new();
|
|
||||||
if let Ok(mut file) = std::fs::File::open(&rw_read!(CONFIG).tag_font.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!("../assets/fonts/Kalam-Regular.ttf").to_vec())
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
/// TTF Font for Tag 2
|
/// TTF Font for Tag 2
|
||||||
pub(crate) static ref FONT_TAG2: Font<'static> = {
|
pub(crate) static ref FONT_TAG2: Font<'static> = load_font(rw_read!(CONFIG).tag2_font.as_str());
|
||||||
let mut buffer = Vec::new();
|
|
||||||
if let Ok(mut file) = std::fs::File::open(&rw_read!(CONFIG).tag2_font.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!("../assets/fonts/Rajdhani-Regular.ttf").to_vec(),
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Image to use for Window
|
/// Image to use for Window
|
||||||
pub(crate) static ref ICON: OsString = include_str!("../assets/icon.svg").into();
|
pub(crate) static ref ICON: OsString = include_str!("../assets/icon.svg").into();
|
||||||
|
|
@ -128,3 +62,15 @@ lazy_static! {
|
||||||
img.into()
|
img.into()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_font(path: &str) -> Font<'static> {
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
if let Ok(mut file) = std::fs::File::open(path) {
|
||||||
|
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!("../assets/OpenSans-Regular.ttf").to_vec()).unwrap()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -777,8 +777,8 @@ impl MainWindow {
|
||||||
self.next_btn.set_callback(move |_| {
|
self.next_btn.set_callback(move |_| {
|
||||||
let prop = rw_read!(properties);
|
let prop = rw_read!(properties);
|
||||||
if !prop.is_saved {
|
if !prop.is_saved {
|
||||||
let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
|
let save = fltk::dialog::choice2_default("Save?", "yes", "no", "cancel");
|
||||||
match save {
|
match save.unwrap_or(-1) {
|
||||||
0 => sender.send_it(DrawMessage::Save),
|
0 => sender.send_it(DrawMessage::Save),
|
||||||
1 => {}
|
1 => {}
|
||||||
_ => return,
|
_ => return,
|
||||||
|
|
@ -801,8 +801,8 @@ impl MainWindow {
|
||||||
self.back_btn.set_callback(move |_| {
|
self.back_btn.set_callback(move |_| {
|
||||||
let prop = rw_read!(properties);
|
let prop = rw_read!(properties);
|
||||||
if !prop.is_saved {
|
if !prop.is_saved {
|
||||||
let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
|
let save = fltk::dialog::choice2_default("Save?", "yes", "no", "cancel");
|
||||||
match save {
|
match save.unwrap_or(-1) {
|
||||||
0 => sender.send_it(DrawMessage::Save),
|
0 => sender.send_it(DrawMessage::Save),
|
||||||
1 => {}
|
1 => {}
|
||||||
_ => return,
|
_ => return,
|
||||||
|
|
@ -824,8 +824,8 @@ impl MainWindow {
|
||||||
self.file_choice.set_callback(move |_| {
|
self.file_choice.set_callback(move |_| {
|
||||||
let prop = rw_read!(properties);
|
let prop = rw_read!(properties);
|
||||||
if !prop.is_saved {
|
if !prop.is_saved {
|
||||||
let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
|
let save = fltk::dialog::choice2_default("Save?", "yes", "no", "cancel");
|
||||||
match save {
|
match save.unwrap_or(-1) {
|
||||||
0 => sender.send_it(DrawMessage::Save),
|
0 => sender.send_it(DrawMessage::Save),
|
||||||
1 => {}
|
1 => {}
|
||||||
_ => return,
|
_ => return,
|
||||||
|
|
|
||||||
134
src/utils.rs
134
src/utils.rs
|
|
@ -20,7 +20,8 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use fltk::{button::Button, enums, prelude::*};
|
use fltk::{button::Button, enums, prelude::*};
|
||||||
use image::{DynamicImage, GenericImageView, ImageBuffer, ImageEncoder};
|
use image::{DynamicImage, GenericImageView, ImageBuffer, ImageEncoder, Pixel};
|
||||||
|
use imageproc::rect::Rect;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::globals;
|
use crate::globals;
|
||||||
|
|
@ -211,6 +212,7 @@ impl ImageContainer {
|
||||||
&prop.tag2,
|
&prop.tag2,
|
||||||
prop.tag_position,
|
prop.tag_position,
|
||||||
prop.tag2_position,
|
prop.tag2_position,
|
||||||
|
prop.original_dimension.0,
|
||||||
prop.original_dimension.1,
|
prop.original_dimension.1,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -275,6 +277,7 @@ impl ImageContainer {
|
||||||
&prop.tag2,
|
&prop.tag2,
|
||||||
prop.tag_position,
|
prop.tag_position,
|
||||||
prop.tag2_position,
|
prop.tag2_position,
|
||||||
|
prop.original_dimension.0,
|
||||||
prop.original_dimension.1,
|
prop.original_dimension.1,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -571,6 +574,7 @@ fn draw_layer_and_text(
|
||||||
tag2: &str,
|
tag2: &str,
|
||||||
tag_y_position: f64,
|
tag_y_position: f64,
|
||||||
tag2_position: f64,
|
tag2_position: f64,
|
||||||
|
original_width: 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();
|
||||||
|
|
@ -586,16 +590,21 @@ fn draw_layer_and_text(
|
||||||
&globals::FONT_QUOTE,
|
&globals::FONT_QUOTE,
|
||||||
size,
|
size,
|
||||||
quote_position,
|
quote_position,
|
||||||
|
original_width,
|
||||||
original_height,
|
original_height,
|
||||||
|
true,
|
||||||
quote,
|
quote,
|
||||||
);
|
);
|
||||||
|
|
||||||
let size = subquote_from_height(height);
|
let size = subquote_from_height(height);
|
||||||
draw_multiline_mid_string(
|
draw_multiline_mid_string(
|
||||||
tmp,
|
tmp,
|
||||||
&globals::FONT_SUBQUOTE,
|
&globals::FONT_SUBQUOTE,
|
||||||
size,
|
size,
|
||||||
subquote_position,
|
subquote_position,
|
||||||
|
original_width,
|
||||||
original_height,
|
original_height,
|
||||||
|
true,
|
||||||
subquote,
|
subquote,
|
||||||
);
|
);
|
||||||
let size = subquote2_from_height(height);
|
let size = subquote2_from_height(height);
|
||||||
|
|
@ -604,7 +613,9 @@ fn draw_layer_and_text(
|
||||||
&globals::FONT_SUBQUOTE2,
|
&globals::FONT_SUBQUOTE2,
|
||||||
size,
|
size,
|
||||||
subquote2_position,
|
subquote2_position,
|
||||||
|
original_width,
|
||||||
original_height,
|
original_height,
|
||||||
|
true,
|
||||||
subquote2,
|
subquote2,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -614,7 +625,9 @@ fn draw_layer_and_text(
|
||||||
&globals::FONT_TAG2,
|
&globals::FONT_TAG2,
|
||||||
size,
|
size,
|
||||||
tag2_position,
|
tag2_position,
|
||||||
|
original_width,
|
||||||
original_height,
|
original_height,
|
||||||
|
false,
|
||||||
tag2,
|
tag2,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -645,24 +658,137 @@ pub(crate) fn draw_multiline_mid_string(
|
||||||
font: &rusttype::Font,
|
font: &rusttype::Font,
|
||||||
size: f64,
|
size: f64,
|
||||||
position: f64,
|
position: f64,
|
||||||
|
original_width: f64,
|
||||||
original_height: f64,
|
original_height: f64,
|
||||||
|
boxed: bool,
|
||||||
text: &str,
|
text: &str,
|
||||||
) {
|
) {
|
||||||
|
let (mut box_width, mut box_height) = (0.0, 0.0);
|
||||||
|
|
||||||
let (width, height): (f64, f64) = Coord::from(tmp.dimensions()).into();
|
let (width, height): (f64, f64) = Coord::from(tmp.dimensions()).into();
|
||||||
for (index, line) in text.lines().enumerate() {
|
for (index, line) in text.lines().enumerate() {
|
||||||
let (text_width, text_height) =
|
let (text_width, text_height) =
|
||||||
measure_line(font, line, rusttype::Scale::uniform(size as f32));
|
measure_line(font, line, rusttype::Scale::uniform(size as f32));
|
||||||
|
|
||||||
|
if text_width > box_width {
|
||||||
|
box_width = text_width;
|
||||||
|
}
|
||||||
|
box_height += text_height * 1.15;
|
||||||
|
|
||||||
|
let (x, y) = (
|
||||||
|
(width - text_width) / 2.0,
|
||||||
|
(position * height) / original_height + index as f64 * (text_height * 1.15),
|
||||||
|
);
|
||||||
|
|
||||||
|
if !boxed || !rw_read!(globals::CONFIG).draw_box_around_quote {
|
||||||
imageproc::drawing::draw_text_mut(
|
imageproc::drawing::draw_text_mut(
|
||||||
tmp,
|
tmp,
|
||||||
image::Rgba([255, 255, 255, 255]),
|
image::Rgba([255, 255, 255, 100]),
|
||||||
((width - text_width) / 2.0) as i32,
|
x as i32,
|
||||||
((position * height) / original_height + index as f64 * (text_height * 1.15)) as i32,
|
y as i32,
|
||||||
rusttype::Scale::uniform(size as f32),
|
rusttype::Scale::uniform(size as f32),
|
||||||
font,
|
font,
|
||||||
line,
|
line,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if boxed && rw_read!(globals::CONFIG).draw_box_around_quote {
|
||||||
|
draw_box(
|
||||||
|
tmp,
|
||||||
|
box_width,
|
||||||
|
box_height,
|
||||||
|
position,
|
||||||
|
original_width,
|
||||||
|
original_height,
|
||||||
|
);
|
||||||
|
|
||||||
|
let size = quote_from_height(height);
|
||||||
|
draw_multiline_mid_string(
|
||||||
|
tmp,
|
||||||
|
font,
|
||||||
|
size,
|
||||||
|
position,
|
||||||
|
original_width,
|
||||||
|
original_height,
|
||||||
|
false,
|
||||||
|
text,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draws box around text.
|
||||||
|
fn draw_box(
|
||||||
|
tmp: &mut DynamicImage,
|
||||||
|
box_width: f64,
|
||||||
|
box_height: f64,
|
||||||
|
position: f64,
|
||||||
|
original_width: f64,
|
||||||
|
original_height: f64,
|
||||||
|
) {
|
||||||
|
if box_width <= 0.0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (width, height): (f64, f64) = Coord::from(tmp.dimensions()).into();
|
||||||
|
let (delta_x, delta_y) = (width / original_width, height / original_height);
|
||||||
|
|
||||||
|
let (x_gap, y_gap) = (8.0 * delta_x, 5.0 * delta_y);
|
||||||
|
let (x, y) = (
|
||||||
|
((width - box_width) / 2.0 - x_gap) as u32,
|
||||||
|
((position * height) / original_height - y_gap) as u32,
|
||||||
|
);
|
||||||
|
let (w, h) = (
|
||||||
|
(box_width + x_gap * 2.0) as u32,
|
||||||
|
(box_height + y_gap * 2.0) as u32,
|
||||||
|
);
|
||||||
|
|
||||||
|
if x >= width as u32 || y >= height as u32 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut buff = tmp.crop(x, y, w, h);
|
||||||
|
let layer = DynamicImage::ImageRgba8(ImageBuffer::from_fn(w, h, |_, _| {
|
||||||
|
image::Rgba([20, 22, 25, 80])
|
||||||
|
}));
|
||||||
|
image::imageops::overlay(&mut buff, &layer, 0, 0);
|
||||||
|
buff = buff.blur(15.0);
|
||||||
|
|
||||||
|
let (dx, dy) = (20.0 * delta_x, 20.0 * delta_y);
|
||||||
|
let mut shadow = DynamicImage::new_rgba8(w + (dx * 2.0) as u32, h + (dy * 2.0) as u32);
|
||||||
|
imageproc::drawing::draw_hollow_rect_mut(
|
||||||
|
&mut shadow,
|
||||||
|
Rect::at(dx as i32, dy as i32).of_size(w, h),
|
||||||
|
image::Rgba([30, 30, 30, 255]),
|
||||||
|
);
|
||||||
|
shadow = shadow.blur(5.0 * delta_x as f32);
|
||||||
|
|
||||||
|
image::imageops::overlay(tmp, &shadow, x as i64 - dx as i64, y as i64 - dy as i64);
|
||||||
|
image::imageops::overlay(tmp, &buff, x as i64, y as i64);
|
||||||
|
|
||||||
|
let mut color = buff.get_pixel(0, 0).to_rgba();
|
||||||
|
color.blend(&buff.get_pixel(0, buff.height() - 1).to_rgba());
|
||||||
|
color.blend(
|
||||||
|
&buff
|
||||||
|
.get_pixel(buff.width() - 1, buff.height() - 1)
|
||||||
|
.to_rgba(),
|
||||||
|
);
|
||||||
|
color.blend(&buff.get_pixel(buff.width() - 1, 0).to_rgba());
|
||||||
|
imageproc::drawing::draw_hollow_rect_mut(
|
||||||
|
tmp,
|
||||||
|
Rect::at(
|
||||||
|
x as i32 - (delta_x * 1.0) as i32,
|
||||||
|
y as i32 - (delta_x * 1.0) as i32,
|
||||||
|
)
|
||||||
|
.of_size(w + (delta_x * 2.0) as u32, h + (delta_x * 2.0) as u32),
|
||||||
|
color.clone(),
|
||||||
|
);
|
||||||
|
color.blend(&image::Rgba([0, 0, 0, 2]));
|
||||||
|
imageproc::drawing::draw_hollow_rect_mut(
|
||||||
|
tmp,
|
||||||
|
Rect::at(x as i32, y as i32).of_size(w, h),
|
||||||
|
color.clone(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get size of text to draw on image
|
/// Get size of text to draw on image
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue