diff --git a/icon.svg b/icon.svg
new file mode 100644
index 0000000..a24bc2b
--- /dev/null
+++ b/icon.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/src/config.rs b/src/config.rs
index 3451846..a14f0f3 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,6 +1,5 @@
-use std::path::Path;
-
use clap::{ArgEnum, Parser};
+use fltk::dialog;
use fltk_theme::ThemeType;
use serde::{Deserialize, Serialize};
@@ -100,10 +99,27 @@ impl ConfigFile {
let config = Self::default();
if let Err(_) = std::fs::write(&conf, serde_json::to_string(&config).unwrap()) {
+ dialog::message_default("Can't write config!");
eprintln!("Can't write config!");
}
config
}
+
+ pub(crate) fn save(&self) {
+ let conf = match dirs::config_dir() {
+ Some(path) => path.join("post_maker.config"),
+ None => std::env::current_exe()
+ .unwrap()
+ .parent()
+ .unwrap()
+ .join("post_maker.config"),
+ };
+
+ if let Err(_) = std::fs::write(&conf, serde_json::to_string(self).unwrap()) {
+ dialog::message_default("Can't write config!");
+ eprintln!("Can't write config!");
+ }
+ }
}
pub(crate) fn config() -> Args {
diff --git a/src/config_window.rs b/src/config_window.rs
new file mode 100644
index 0000000..1fad536
--- /dev/null
+++ b/src/config_window.rs
@@ -0,0 +1,278 @@
+use std::{cell::RefCell, rc::Rc};
+
+use fltk::{
+ app,
+ button::Button,
+ dialog::{self, FileDialogOptions, NativeFileChooser},
+ enums::{Align, Font},
+ frame::Frame,
+ group::Flex,
+ image::SvgImage,
+ misc::Spinner,
+ output::Output,
+ prelude::*,
+ valuator::ValueInput,
+ window::Window,
+};
+
+use crate::{config::ConfigFile, globals};
+
+pub(crate) struct ConfigWindow {
+ pub(crate) win: Window,
+ pub(crate) quote_font_ttf: Output,
+ pub(crate) quote_font_ttf_browse: Button,
+ pub(crate) tag_font_ttf: Output,
+ pub(crate) tag_font_ttf_browse: Button,
+ pub(crate) quote_font_ratio: ValueInput,
+ pub(crate) tag_font_ratio: ValueInput,
+ pub(crate) layer_red: Spinner,
+ pub(crate) layer_green: Spinner,
+ pub(crate) layer_blue: Spinner,
+ pub(crate) layer_alpha: Spinner,
+ pub(crate) defaults_btn: Button,
+ pub(crate) save_btn: Button,
+ pub(crate) cancel_btn: Button,
+ did_save: Rc>,
+}
+
+impl ConfigWindow {
+ pub(crate) fn new() -> Self {
+ let mut win = Window::new(0, 0, 500, 300, "Config").center_screen();
+ if let Ok(image) = SvgImage::from_data(&globals::ICON) {
+ win.set_icon(Some(image));
+ }
+
+ let mut col = Flex::default().with_size(490, 290).with_pos(5, 5).column();
+
+ let mut quote_font_ttf_grp = Flex::default().row();
+ quote_font_ttf_grp.set_size(
+ &Frame::default()
+ .with_label("Font for quote (ttf)")
+ .with_align(Align::Right | Align::Inside),
+ 160,
+ );
+ let quote_font_ttf = Output::default();
+ let quote_font_ttf_browse = Button::default().with_label("Pick");
+ quote_font_ttf_grp.set_size("e_font_ttf_browse, 50);
+ quote_font_ttf_grp.end();
+ col.set_size("e_font_ttf_grp, 30);
+
+ let mut tag_font_ttf_grp = Flex::default().row();
+ tag_font_ttf_grp.set_size(
+ &Frame::default()
+ .with_label("Font for tag (ttf)")
+ .with_align(Align::Right | Align::Inside),
+ 160,
+ );
+ let tag_font_ttf = Output::default();
+ let tag_font_ttf_browse = Button::default().with_label("Pick");
+ tag_font_ttf_grp.set_size(&tag_font_ttf_browse, 50);
+ tag_font_ttf_grp.end();
+ col.set_size(&tag_font_ttf_grp, 30);
+
+ let mut quote_font_ratio_grp = Flex::default().row();
+ quote_font_ratio_grp.set_size(
+ &Frame::default()
+ .with_label("Quote text size ratio")
+ .with_align(Align::Right | Align::Inside),
+ 160,
+ );
+ let quote_font_ratio = ValueInput::default();
+ quote_font_ratio_grp.end();
+ col.set_size("e_font_ratio_grp, 30);
+
+ let mut grp = Flex::default().row();
+ grp.set_size(&Frame::default(), 160);
+ let mut hint = Frame::default()
+ .with_label("Font size in image of resolution 4000x5000")
+ .with_align(Align::Left | Align::Inside);
+ hint.set_label_font(Font::CourierItalic);
+ hint.set_label_size(12);
+ grp.end();
+ col.set_size(&grp, 13);
+
+ let mut tag_font_ratio_grp = Flex::default().row();
+ tag_font_ratio_grp.set_size(
+ &Frame::default()
+ .with_label("Tag text size ratio")
+ .with_align(Align::Right | Align::Inside),
+ 160,
+ );
+ let tag_font_ratio = ValueInput::default();
+ tag_font_ratio_grp.end();
+ col.set_size(&tag_font_ratio_grp, 30);
+
+ let mut grp = Flex::default().row();
+ grp.set_size(&Frame::default(), 160);
+ let mut hint = Frame::default()
+ .with_label("Font size in image of resolution 4000x5000")
+ .with_align(Align::Left | Align::Inside);
+ hint.set_label_font(Font::CourierItalic);
+ hint.set_label_size(12);
+ grp.end();
+ col.set_size(&grp, 13);
+
+ col.set_size(
+ &Frame::default().with_label("Default colour shader to use with new images:"),
+ 30,
+ );
+
+ let mut darklayer_grp = Flex::default().row();
+ darklayer_grp.set_pad(2);
+ darklayer_grp.set_size(&Frame::default().with_label("Red"), 30);
+ let mut layer_red = Spinner::default();
+ layer_red.set_range(0.0, 255.0);
+ // darklayer_flex.set_size(&layer_red, 50);
+ darklayer_grp.set_size(&Frame::default().with_label("Green"), 40);
+ let mut layer_green = Spinner::default();
+ layer_green.set_range(0.0, 255.0);
+ // darklayer_flex.set_size(&layer_green, 50);
+ darklayer_grp.set_size(&Frame::default().with_label("Blue"), 30);
+ let mut layer_blue = Spinner::default();
+ layer_blue.set_range(0.0, 255.0);
+ // darklayer_flex.set_size(&layer_blue, 50);
+ darklayer_grp.set_size(&Frame::default().with_label("Alpha"), 40);
+ let mut layer_alpha = Spinner::default();
+ layer_alpha.set_range(0.0, 255.0);
+ // darklayer_flex.set_size(&layer_alpha, 50);
+ darklayer_grp.end();
+ col.set_size(&darklayer_grp, 30);
+
+ Frame::default();
+
+ let mut panel_grp = Flex::default().row();
+ Frame::default();
+ let defaults_btn = Button::default().with_label("Defaults");
+ let save_btn = Button::default().with_label("Save");
+ let cancel_btn = Button::default().with_label("Cancel");
+ panel_grp.set_size(&defaults_btn, 100);
+ panel_grp.set_size(&save_btn, 100);
+ panel_grp.set_size(&cancel_btn, 100);
+ panel_grp.end();
+
+ col.set_size(&panel_grp, 30);
+
+ col.end();
+ win.end();
+ win.make_modal(true);
+ win.make_resizable(true);
+
+ let mut config_window = Self {
+ win,
+ quote_font_ttf,
+ quote_font_ttf_browse,
+ tag_font_ttf,
+ tag_font_ttf_browse,
+ quote_font_ratio,
+ tag_font_ratio,
+ layer_red,
+ layer_green,
+ layer_blue,
+ layer_alpha,
+ defaults_btn,
+ save_btn,
+ cancel_btn,
+ did_save: Rc::new(RefCell::new(false)),
+ };
+ config_window.event();
+
+ config_window
+ }
+
+ pub(crate) fn show(&mut self) -> bool {
+ let glob = globals::CONFIG.read().unwrap();
+ self.quote_font_ttf.set_value(glob.quote_font_ttf.as_str());
+ self.tag_font_ttf.set_value(glob.tag_font_ttf.as_str());
+ self.quote_font_ratio.set_value(glob.quote_font_ratio);
+ self.tag_font_ratio.set_value(glob.tag_font_ratio);
+ self.layer_red.set_value(glob.color_layer[0] as f64);
+ self.layer_green.set_value(glob.color_layer[1] as f64);
+ self.layer_blue.set_value(glob.color_layer[2] as f64);
+ self.layer_alpha.set_value(glob.color_layer[3] as f64);
+ *self.did_save.borrow_mut() = false;
+ drop(glob);
+ self.win.show();
+ while self.win.shown() {
+ app::wait();
+ }
+ *self.did_save.borrow()
+ }
+
+ fn event(&mut self) {
+ let mut quote_font_ttf = self.quote_font_ttf.clone();
+ self.quote_font_ttf_browse.set_callback(move |_| {
+ let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseFile);
+ chooser.set_option(FileDialogOptions::UseFilterExt);
+ chooser.set_filter("*.ttf");
+ chooser.show();
+ let path = chooser.filename();
+ quote_font_ttf.set_value(path.to_str().unwrap());
+ });
+
+ let mut tag_font_ttf = self.tag_font_ttf.clone();
+ self.tag_font_ttf_browse.set_callback(move |_| {
+ let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseFile);
+ chooser.set_option(FileDialogOptions::UseFilterExt);
+ chooser.set_filter("*.ttf");
+ chooser.show();
+ let path = chooser.filename();
+ tag_font_ttf.set_value(path.to_str().unwrap());
+ });
+
+ let mut win = self.win.clone();
+ self.cancel_btn.set_callback(move |_| {
+ win.hide();
+ });
+
+ let mut quote_font_ttf = self.quote_font_ttf.clone();
+ let mut tag_font_ttf = self.tag_font_ttf.clone();
+ let mut quote_font_ratio = self.quote_font_ratio.clone();
+ let mut tag_font_ratio = self.tag_font_ratio.clone();
+ let mut layer_red = self.layer_red.clone();
+ let mut layer_green = self.layer_green.clone();
+ let mut layer_blue = self.layer_blue.clone();
+ let mut layer_alpha = self.layer_alpha.clone();
+ self.defaults_btn.set_callback(move |_| {
+ let conf = ConfigFile::default();
+ quote_font_ttf.set_value(&conf.quote_font_ttf);
+ tag_font_ttf.set_value(&conf.tag_font_ttf);
+ quote_font_ratio.set_value(conf.quote_font_ratio);
+ tag_font_ratio.set_value(conf.tag_font_ratio);
+ layer_red.set_value(conf.color_layer[0] as f64);
+ layer_green.set_value(conf.color_layer[1] as f64);
+ layer_blue.set_value(conf.color_layer[2] as f64);
+ layer_alpha.set_value(conf.color_layer[3] as f64);
+ });
+
+ let mut win = self.win.clone();
+ let quote_font_ttf = self.quote_font_ttf.clone();
+ let tag_font_ttf = self.tag_font_ttf.clone();
+ let quote_font_ratio = self.quote_font_ratio.clone();
+ let tag_font_ratio = self.tag_font_ratio.clone();
+ let layer_red = self.layer_red.clone();
+ let layer_green = self.layer_green.clone();
+ let layer_blue = self.layer_blue.clone();
+ let layer_alpha = self.layer_alpha.clone();
+ let did_save = Rc::clone(&self.did_save);
+ self.save_btn.set_callback(move |_| {
+ let conf = ConfigFile {
+ quote_font_ttf: quote_font_ttf.value(),
+ tag_font_ttf: tag_font_ttf.value(),
+ quote_font_ratio: quote_font_ratio.value(),
+ tag_font_ratio: tag_font_ratio.value(),
+ color_layer: [
+ layer_red.value() as u8,
+ layer_green.value() as u8,
+ layer_blue.value() as u8,
+ layer_alpha.value() as u8,
+ ],
+ };
+
+ conf.save();
+ *globals::CONFIG.write().unwrap() = conf;
+ *did_save.borrow_mut() = true;
+ win.hide();
+ dialog::message_default("Re-open Post Maker to see changes!")
+ });
+ }
+}
diff --git a/src/crop_window.rs b/src/crop_window.rs
index b128e1b..4c3ae33 100644
--- a/src/crop_window.rs
+++ b/src/crop_window.rs
@@ -61,6 +61,7 @@ impl CropWindow {
main_flex.end();
win.end();
+ win.make_modal(true);
win.make_resizable(true);
let mut crop_win = Self {
@@ -119,7 +120,6 @@ impl CropWindow {
self.page.image_view.redraw();
self.win.show();
- self.win.make_modal(true);
while self.win.shown() {
app::wait();
}
diff --git a/src/draw_thread.rs b/src/draw_thread.rs
index 79c4279..2c3a251 100644
--- a/src/draw_thread.rs
+++ b/src/draw_thread.rs
@@ -188,11 +188,13 @@ fn load_image(
tag_position.set_range(0.0, prop.original_dimension.1);
tag_position.set_value(prop.tag_position);
- layer_red.set_value(globals::CONFIG.color_layer[0] as f64);
- layer_green.set_value(globals::CONFIG.color_layer[1] as f64);
- layer_blue.set_value(globals::CONFIG.color_layer[2] as f64);
- layer_alpha.set_value(globals::CONFIG.color_layer[3] as f64);
- prop.rgba = globals::CONFIG.color_layer;
+ 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);
+ layer_alpha.set_value(glob.color_layer[3] as f64);
+ prop.rgba = glob.color_layer;
+ drop(glob);
match crop {
Some((x, y)) => {
diff --git a/src/globals.rs b/src/globals.rs
index ce20dcc..2944faa 100644
--- a/src/globals.rs
+++ b/src/globals.rs
@@ -1,13 +1,13 @@
use crate::config;
use lazy_static::lazy_static;
use rusttype::Font;
-use std::io::Read;
+use std::{io::Read, sync::RwLock};
lazy_static! {
- pub static ref CONFIG: config::ConfigFile = config::ConfigFile::load();
+ pub static ref CONFIG: RwLock = RwLock::new(config::ConfigFile::load());
pub static ref FONT_QUOTE: Font<'static> = {
let mut buffer = Vec::new();
- if let Ok(mut file) = std::fs::File::open(&CONFIG.quote_font_ttf) {
+ if let Ok(mut file) = std::fs::File::open(CONFIG.read().unwrap().quote_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;
@@ -19,7 +19,7 @@ lazy_static! {
};
pub static ref FONT_TAG: Font<'static> = {
let mut buffer = Vec::new();
- if let Ok(mut file) = std::fs::File::open(&CONFIG.quote_font_ttf) {
+ if let Ok(mut file) = std::fs::File::open(&CONFIG.read().unwrap().tag_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;
@@ -28,4 +28,5 @@ lazy_static! {
}
rusttype::Font::try_from_vec(include_bytes!("../Kalam-Regular.ttf").to_vec()).unwrap()
};
+ pub static ref ICON: &'static str = include_str!("../icon.svg");
}
diff --git a/src/main.rs b/src/main.rs
index 44c1846..c01d656 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
mod config;
+mod config_window;
mod crop_window;
mod draw_thread;
mod globals;
diff --git a/src/main_window.rs b/src/main_window.rs
index 4ae7028..db720e4 100644
--- a/src/main_window.rs
+++ b/src/main_window.rs
@@ -1,3 +1,4 @@
+use crate::config_window::ConfigWindow;
use crate::crop_window::CropWindow;
use crate::draw_thread::*;
use crate::utils::ImageProperties;
@@ -53,8 +54,6 @@ impl MainWindow {
sender: app::Sender,
draw_buff: Arc>>,
) -> Self {
- let color = [25, 29, 34, 190];
-
let mut win = Window::new(0, 0, 1000, 600, "Post Maker").center_screen();
let mut main_flex = Flex::default().size_of_parent().column();
@@ -102,22 +101,18 @@ impl MainWindow {
darklayer_flex.set_size(&Frame::default().with_label("Red"), 30);
let mut layer_red = Spinner::default();
layer_red.set_range(0.0, 255.0);
- layer_red.set_value(color[0] as f64);
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);
- layer_green.set_value(color[1] as f64);
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);
- layer_blue.set_value(color[2] as f64);
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);
- layer_alpha.set_value(color[3] as f64);
darklayer_flex.set_size(&layer_alpha, 50);
darklayer_flex.end();
controls_flex.set_size(&darklayer_flex, 30);
@@ -262,12 +257,16 @@ impl MainWindow {
move |_| sender.send(DrawMessage::Save).unwrap(),
);
+ let mut config_window = ConfigWindow::new();
+ let sender = self.sender.clone();
self.menubar.add(
"&Edit/Configure...\t",
Shortcut::None,
menu::MenuFlag::Normal,
- |_| {
- println!("wow");
+ move |_| {
+ if config_window.show() {
+ sender.send(DrawMessage::Recalc).unwrap();
+ }
},
);
}
diff --git a/src/utils.rs b/src/utils.rs
index 02f75d9..f158eae 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -394,11 +394,11 @@ pub(crate) fn height_from_width(width: f64) -> f64 {
}
pub(crate) fn quote_from_height(height: f64) -> f64 {
- (height * globals::CONFIG.quote_font_ratio) / 5000.0
+ (height * globals::CONFIG.read().unwrap().quote_font_ratio) / 5000.0
}
pub(crate) fn tag_from_height(height: f64) -> f64 {
- (height * globals::CONFIG.tag_font_ratio) / 5000.0
+ (height * globals::CONFIG.read().unwrap().tag_font_ratio) / 5000.0
}
pub(crate) fn measure_line(