Support for multiple congifs

This commit is contained in:
Piyush मिश्रः 2022-01-23 13:26:03 +05:30
parent a780e50235
commit 75d093e5df
8 changed files with 535 additions and 102 deletions

45
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,45 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'post_maker'",
"cargo": {
"args": [
"build",
"--bin=post_maker",
"--package=post_maker"
],
"filter": {
"name": "post_maker",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'post_maker'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=post_maker",
"--package=post_maker"
],
"filter": {
"name": "post_maker",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

View File

@ -1,13 +1,25 @@
//! load, save configuration and parse cli args
use std::collections::HashMap;
use crate::{config_picker::ConfigPicker, globals};
use clap::{ArgEnum, Parser};
use fltk::dialog;
use fltk_theme::ThemeType;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, path::PathBuf};
use crate::globals;
lazy_static! {
pub static ref CONFIG_PATH: PathBuf = {
match dirs::config_dir() {
Some(path) => path.join("post_maker.config"),
None => std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("post_maker.config"),
}
};
}
/// Simple program calculate size of stuff in quote image
#[derive(Parser, Debug)]
@ -85,7 +97,7 @@ impl Default for ConfigFile {
tag_font_ratio: 150.0,
quote_position_ratio: 0.7,
tag_position_ratio: 0.5,
image_ratio: (4.0, 4.0),
image_ratio: (4.0, 5.0),
color_layer: [20, 22, 25, 197],
}
}
@ -93,63 +105,52 @@ impl Default for ConfigFile {
impl ConfigFile {
pub(crate) fn load() -> 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 conf.exists() {
let map = match std::fs::read_to_string(&conf) {
Ok(r) => serde_json::from_str::<HashMap<String, Self>>(&r).ok(),
Err(_) => None,
};
// config_picker::ConfigPicker::new();
if CONFIG_PATH.exists() {
let map = get_configs();
let map = match map {
Some(m) => m,
None => HashMap::new(),
};
if let Some(config) = map.get(&*globals::CONFIG_NAME.read().unwrap()) {
let default_config = (&*globals::CONFIG_NAME.read().unwrap()).to_string();
let config_name = if map.len() > 1 || !map.contains_key(&default_config) {
ConfigPicker::new(map.keys().map(|a| a.to_owned()).collect())
.selected()
.unwrap_or(default_config)
} else {
default_config
};
if let Some(config) = map.get(&config_name) {
*globals::CONFIG_NAME.write().unwrap() = config_name;
return config.to_owned();
}
}
let config = Self::default();
config.save();
let mut configs = HashMap::new();
configs.insert(
(&*globals::CONFIG_NAME.read().unwrap()).to_owned(),
config.clone(),
);
save_configs(configs);
config
}
}
pub(crate) fn save(&self) {
let config_name = &*globals::CONFIG_NAME.read().unwrap();
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"),
};
pub(crate) fn get_configs() -> Option<HashMap<String, ConfigFile>> {
match std::fs::read_to_string(&*CONFIG_PATH) {
Ok(r) => serde_json::from_str::<HashMap<String, ConfigFile>>(&r).ok(),
Err(_) => None,
}
}
let map = match std::fs::read_to_string(&conf) {
Ok(r) => serde_json::from_str::<HashMap<String, Self>>(&r).ok(),
Err(_) => None,
};
let mut map = match map {
Some(m) => m,
None => HashMap::new(),
};
map.insert(config_name.to_owned(), (*self).clone());
if let Err(_) = std::fs::write(&conf, serde_json::to_string(&map).unwrap()) {
dialog::message_default("Can't write config!");
eprintln!("Can't write config!");
}
pub(crate) fn save_configs(configs: HashMap<String, ConfigFile>) {
if let Err(_) = std::fs::write(&*CONFIG_PATH, serde_json::to_string(&configs).unwrap()) {
dialog::alert_default("Can't write config!");
eprintln!("Can't write config!");
}
}

84
src/config_picker.rs Normal file
View File

@ -0,0 +1,84 @@
use crate::globals;
use fltk::{
app,
browser::{Browser, BrowserType},
button::Button,
frame::Frame,
group::Flex,
image::SvgImage,
prelude::*,
window::Window,
};
pub(crate) struct ConfigPicker {
pub(crate) win: Window,
pub(crate) browse: Browser,
pub(crate) apply_btn: Button,
pub(crate) configs: Vec<String>,
}
impl ConfigPicker {
pub(crate) fn new(configs: Vec<String>) -> Self {
let mut win = Window::new(0, 0, 500, 400, "Configurations").center_screen();
win.set_icon(Some(
SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(),
));
let mut main_flex = Flex::default().size_of_parent().column();
// Work area
let mut browse = Browser::default().with_type(BrowserType::Hold);
for name in &configs {
browse.add(&name);
}
browse.select(1);
// Panel
let top_padding_btn = Frame::default();
let mut panel_flex = Flex::default().row();
Frame::default();
let apply_btn = Button::default().with_label("apply");
Frame::default();
panel_flex.set_size(&apply_btn, 100);
panel_flex.end();
let bottom_padding_btn = Frame::default();
main_flex.set_size(&top_padding_btn, 5);
main_flex.set_size(&panel_flex, 30);
main_flex.set_size(&bottom_padding_btn, 5);
main_flex.end();
win.end();
win.make_resizable(true);
let mut config_picker = Self {
win,
browse,
apply_btn,
configs,
};
config_picker.event();
config_picker.win.show();
while config_picker.win.shown() {
app::wait();
}
config_picker
}
fn event(&mut self) {
let mut win = self.win.clone();
self.apply_btn.set_callback(move |_| {
win.hide();
});
}
pub(crate) fn selected(&self) -> Option<String> {
let idx = self.browse.value();
if idx == 0 {
None
} else {
self.configs.get(idx as usize - 1).map(|a| a.to_owned())
}
}
}

View File

@ -1,9 +1,10 @@
//! Window to edit configuration
use std::{cell::RefCell, rc::Rc};
use std::{cell::RefCell, collections::HashMap, rc::Rc};
use fltk::{
app,
browser::{Browser, BrowserType},
button::Button,
dialog::{self, FileDialogOptions, NativeFileChooser},
enums::{Align, Font},
@ -17,16 +18,27 @@ use fltk::{
window::Window,
};
use crate::{config::ConfigFile, globals};
use crate::{
config::{self, ConfigFile},
globals,
};
pub(crate) struct ConfigWindow {
pub(crate) win: Window,
pub(crate) browse: Browser,
pub(crate) selected_browse_line: Rc<RefCell<i32>>,
pub(crate) add_config_btn: Button,
pub(crate) del_config_btn: Button,
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) quote_position_ratio: ValueInput,
pub(crate) tag_position_ratio: ValueInput,
pub(crate) image_ratio_width: ValueInput,
pub(crate) image_ratio_height: ValueInput,
pub(crate) layer_red: Spinner,
pub(crate) layer_green: Spinner,
pub(crate) layer_blue: Spinner,
@ -34,24 +46,48 @@ pub(crate) struct ConfigWindow {
pub(crate) defaults_btn: Button,
pub(crate) save_btn: Button,
pub(crate) cancel_btn: Button,
pub(crate) configs: Rc<RefCell<HashMap<String, ConfigFile>>>,
did_save: Rc<RefCell<bool>>,
}
impl ConfigWindow {
pub(crate) fn new() -> Self {
let mut win = Window::new(0, 0, 500, 300, "Config").center_screen();
let configs = config::get_configs().unwrap_or(HashMap::new());
let mut win = Window::new(0, 0, 700, 450, "Config").center_screen();
win.set_icon(Some(
SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(),
));
let mut row = Flex::default().with_size(690, 440).with_pos(5, 5).row();
let mut config_picker_flex = Flex::default().column();
// Picker
let browse = Browser::default().with_type(BrowserType::Hold);
let mut col = Flex::default().with_size(490, 290).with_pos(5, 5).column();
// Panel
let top_padding_btn = Frame::default();
let mut panel_flex = Flex::default().row();
Frame::default();
let add_config_btn = Button::default().with_label("add");
let del_config_btn = Button::default().with_label("delete");
Frame::default();
panel_flex.set_size(&add_config_btn, 50);
panel_flex.set_size(&del_config_btn, 50);
panel_flex.end();
let bottom_padding_btn = Frame::default();
config_picker_flex.set_size(&top_padding_btn, 5);
config_picker_flex.set_size(&panel_flex, 30);
config_picker_flex.set_size(&bottom_padding_btn, 5);
config_picker_flex.end();
row.set_size(&config_picker_flex, 200);
let mut col = Flex::default().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,
170,
);
let quote_font_ttf = Output::default();
let quote_font_ttf_browse = Button::default().with_label("Pick");
@ -64,7 +100,7 @@ impl ConfigWindow {
&Frame::default()
.with_label("Font for tag (ttf)")
.with_align(Align::Right | Align::Inside),
160,
170,
);
let tag_font_ttf = Output::default();
let tag_font_ttf_browse = Button::default().with_label("Pick");
@ -77,14 +113,14 @@ impl ConfigWindow {
&Frame::default()
.with_label("Quote text size ratio")
.with_align(Align::Right | Align::Inside),
160,
170,
);
let quote_font_ratio = ValueInput::default();
quote_font_ratio_grp.end();
col.set_size(&quote_font_ratio_grp, 30);
let mut grp = Flex::default().row();
grp.set_size(&Frame::default(), 160);
grp.set_size(&Frame::default(), 170);
let mut hint = Frame::default()
.with_label("Font size in image of resolution 4000x5000")
.with_align(Align::Left | Align::Inside);
@ -98,14 +134,14 @@ impl ConfigWindow {
&Frame::default()
.with_label("Tag text size ratio")
.with_align(Align::Right | Align::Inside),
160,
170,
);
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);
grp.set_size(&Frame::default(), 170);
let mut hint = Frame::default()
.with_label("Font size in image of resolution 4000x5000")
.with_align(Align::Left | Align::Inside);
@ -114,6 +150,41 @@ impl ConfigWindow {
grp.end();
col.set_size(&grp, 13);
let mut quote_position_ratio_grp = Flex::default().row();
quote_position_ratio_grp.set_size(
&Frame::default()
.with_label("Quote text position ratio")
.with_align(Align::Right | Align::Inside),
170,
);
let quote_position_ratio = ValueInput::default();
quote_position_ratio_grp.end();
col.set_size(&quote_position_ratio_grp, 30);
let mut tag_position_ratio_grp = Flex::default().row();
tag_position_ratio_grp.set_size(
&Frame::default()
.with_label("Tag text position ratio")
.with_align(Align::Right | Align::Inside),
170,
);
let tag_position_ratio = ValueInput::default();
tag_position_ratio_grp.end();
col.set_size(&tag_position_ratio_grp, 30);
let mut image_ratio_grp = Flex::default().row();
image_ratio_grp.set_size(
&Frame::default()
.with_label("Image size ratio")
.with_align(Align::Right | Align::Inside),
170,
);
let image_ratio_width = ValueInput::default();
image_ratio_grp.set_size(&Frame::default().with_label("x"), 30);
let image_ratio_height = ValueInput::default();
image_ratio_grp.end();
col.set_size(&image_ratio_grp, 30);
col.set_size(
&Frame::default().with_label("Default colour shader to use with new images:"),
30,
@ -155,18 +226,27 @@ impl ConfigWindow {
col.set_size(&panel_grp, 30);
col.end();
row.end();
win.end();
win.make_modal(true);
win.make_resizable(true);
let mut config_window = Self {
win,
browse,
selected_browse_line: Rc::new(RefCell::new(0)),
add_config_btn,
del_config_btn,
quote_font_ttf,
quote_font_ttf_browse,
tag_font_ttf,
tag_font_ttf_browse,
quote_font_ratio,
tag_font_ratio,
quote_position_ratio,
tag_position_ratio,
image_ratio_width,
image_ratio_height,
layer_red,
layer_green,
layer_blue,
@ -174,6 +254,7 @@ impl ConfigWindow {
defaults_btn,
save_btn,
cancel_btn,
configs: Rc::new(RefCell::new(configs)),
did_save: Rc::new(RefCell::new(false)),
};
config_window.event();
@ -182,17 +263,32 @@ impl ConfigWindow {
}
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);
let config_name = &*globals::CONFIG_NAME.read().unwrap();
self.browse.clear();
for (idx, name) in self.configs.borrow().keys().enumerate() {
self.browse.add(name);
if name == config_name {
self.browse.select(idx as i32 + 1);
}
}
*self.selected_browse_line.borrow_mut() = self.browse.value();
let config = globals::CONFIG.read().unwrap();
self.quote_font_ttf
.set_value(config.quote_font_ttf.as_str());
self.tag_font_ttf.set_value(config.tag_font_ttf.as_str());
self.quote_font_ratio.set_value(config.quote_font_ratio);
self.tag_font_ratio.set_value(config.tag_font_ratio);
self.quote_position_ratio
.set_value(config.quote_position_ratio);
self.tag_position_ratio.set_value(config.tag_position_ratio);
self.image_ratio_width.set_value(config.image_ratio.0);
self.image_ratio_height.set_value(config.image_ratio.1);
self.layer_red.set_value(config.color_layer[0] as f64);
self.layer_green.set_value(config.color_layer[1] as f64);
self.layer_blue.set_value(config.color_layer[2] as f64);
self.layer_alpha.set_value(config.color_layer[3] as f64);
*self.did_save.borrow_mut() = false;
drop(glob);
drop(config);
self.win.show();
while self.win.shown() {
app::wait();
@ -201,6 +297,190 @@ impl ConfigWindow {
}
fn event(&mut self) {
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 quote_position_ratio = self.quote_position_ratio.clone();
let mut tag_position_ratio = self.tag_position_ratio.clone();
let mut image_ratio_width = self.image_ratio_width.clone();
let mut image_ratio_height = self.image_ratio_height.clone();
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();
let mut browse = self.browse.clone();
let configs = Rc::clone(&self.configs);
let selected_browse_line = Rc::clone(&self.selected_browse_line);
self.add_config_btn.set_callback(move |_| {
let name = loop {
let name = dialog::input_default("Enter new config's name", "");
match name {
Some(name) => {
let name = name.trim();
if name == "" {
dialog::alert_default("Name is empty!");
} else if !configs.borrow().contains_key(name) {
break name.to_owned();
} else {
dialog::alert_default("Name is already used!");
}
}
None => {
return;
}
}
};
if let Some(conf) = configs
.borrow_mut()
.get_mut(&browse.selected_text().unwrap())
{
conf.quote_font_ttf = quote_font_ttf.value();
conf.tag_font_ttf = tag_font_ttf.value();
conf.quote_font_ratio = quote_font_ratio.value();
conf.tag_font_ratio = tag_font_ratio.value();
conf.quote_position_ratio = quote_position_ratio.value();
conf.tag_position_ratio = tag_position_ratio.value();
conf.image_ratio = (image_ratio_width.value(), image_ratio_height.value());
conf.color_layer = [
layer_red.value() as u8,
layer_green.value() as u8,
layer_blue.value() as u8,
layer_alpha.value() as u8,
];
}
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);
quote_position_ratio.set_value(conf.quote_position_ratio);
tag_position_ratio.set_value(conf.tag_position_ratio);
image_ratio_width.set_value(conf.image_ratio.0);
image_ratio_height.set_value(conf.image_ratio.1);
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);
browse.add(&name);
configs.borrow_mut().insert(name.clone(), conf);
browse.select(browse.size());
*selected_browse_line.borrow_mut() = browse.value();
});
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 quote_position_ratio = self.quote_position_ratio.clone();
let mut tag_position_ratio = self.tag_position_ratio.clone();
let mut image_ratio_width = self.image_ratio_width.clone();
let mut image_ratio_height = self.image_ratio_height.clone();
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();
let mut browse = self.browse.clone();
let configs = Rc::clone(&self.configs);
let selected_browse_line = Rc::clone(&self.selected_browse_line);
self.del_config_btn.set_callback(move |_| {
let ch = dialog::choice_default("Do you want to delete??", "Yes", "No", "");
if ch == 1 {
return;
}
if browse.size() == 1 {
dialog::alert_default("Atleast one config should exist!");
return;
}
let line = browse.value();
configs
.borrow_mut()
.remove(&browse.selected_text().unwrap());
browse.remove(browse.value());
let line = if browse.size() < line { line - 1 } else { line };
browse.select(line);
*selected_browse_line.borrow_mut() = browse.value();
if let Some(conf) = configs.borrow().get(&browse.selected_text().unwrap()) {
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);
quote_position_ratio.set_value(conf.quote_position_ratio);
tag_position_ratio.set_value(conf.tag_position_ratio);
image_ratio_width.set_value(conf.image_ratio.0);
image_ratio_height.set_value(conf.image_ratio.1);
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 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 quote_position_ratio = self.quote_position_ratio.clone();
let mut tag_position_ratio = self.tag_position_ratio.clone();
let mut image_ratio_width = self.image_ratio_width.clone();
let mut image_ratio_height = self.image_ratio_height.clone();
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();
let configs = Rc::clone(&self.configs);
let selected_browse_line = Rc::clone(&self.selected_browse_line);
self.browse.set_callback(move |f| {
if f.value() == 0 {
f.select(*selected_browse_line.borrow());
return;
}
if *selected_browse_line.borrow() == f.value() {
return;
}
if let Some(conf) = configs
.borrow_mut()
.get_mut(&f.text(*selected_browse_line.borrow()).unwrap())
{
conf.quote_font_ttf = quote_font_ttf.value();
conf.tag_font_ttf = tag_font_ttf.value();
conf.quote_font_ratio = quote_font_ratio.value();
conf.tag_font_ratio = tag_font_ratio.value();
conf.quote_position_ratio = quote_position_ratio.value();
conf.tag_position_ratio = tag_position_ratio.value();
conf.image_ratio = (image_ratio_width.value(), image_ratio_height.value());
conf.color_layer = [
layer_red.value() as u8,
layer_green.value() as u8,
layer_blue.value() as u8,
layer_alpha.value() as u8,
];
}
if let Some(conf) = configs.borrow().get(&f.selected_text().unwrap()) {
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);
quote_position_ratio.set_value(conf.quote_position_ratio);
tag_position_ratio.set_value(conf.tag_position_ratio);
image_ratio_width.set_value(conf.image_ratio.0);
image_ratio_height.set_value(conf.image_ratio.1);
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);
}
*selected_browse_line.borrow_mut() = f.value();
// println!("browse {:?}", selected_config_name);
});
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);
@ -208,6 +488,7 @@ impl ConfigWindow {
chooser.set_filter("*.ttf");
chooser.show();
let path = chooser.filename();
let path = std::fs::canonicalize(&path).unwrap_or(path);
quote_font_ttf.set_value(path.to_str().unwrap());
});
@ -230,6 +511,10 @@ impl ConfigWindow {
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 quote_position_ratio = self.quote_position_ratio.clone();
let mut tag_position_ratio = self.tag_position_ratio.clone();
let mut image_ratio_width = self.image_ratio_width.clone();
let mut image_ratio_height = self.image_ratio_height.clone();
let mut layer_red = self.layer_red.clone();
let mut layer_green = self.layer_green.clone();
let mut layer_blue = self.layer_blue.clone();
@ -240,44 +525,60 @@ impl ConfigWindow {
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);
quote_position_ratio.set_value(conf.quote_position_ratio);
tag_position_ratio.set_value(conf.tag_position_ratio);
image_ratio_width.set_value(conf.image_ratio.0);
image_ratio_height.set_value(conf.image_ratio.1);
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 quote_position_ratio = self.quote_position_ratio.clone();
let tag_position_ratio = self.tag_position_ratio.clone();
let image_ratio_width = self.image_ratio_width.clone();
let image_ratio_height = self.image_ratio_height.clone();
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 browse = self.browse.clone();
let configs = Rc::clone(&self.configs);
let did_save = Rc::clone(&self.did_save);
let mut win = self.win.clone();
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(),
quote_position_ratio: *globals::QUOTE_POSITION_RATIO.read().unwrap(),
tag_position_ratio: *globals::TAG_POSITION_RATIO.read().unwrap(),
image_ratio: *globals::IMAGE_RATIO.read().unwrap(),
color_layer: [
if let Some(conf) = configs
.borrow_mut()
.get_mut(&browse.selected_text().unwrap())
{
conf.quote_font_ttf = quote_font_ttf.value();
conf.tag_font_ttf = tag_font_ttf.value();
conf.quote_font_ratio = quote_font_ratio.value();
conf.tag_font_ratio = tag_font_ratio.value();
conf.quote_position_ratio = quote_position_ratio.value();
conf.tag_position_ratio = tag_position_ratio.value();
conf.image_ratio = (image_ratio_width.value(), image_ratio_height.value());
conf.color_layer = [
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;
config::save_configs((*configs.borrow()).clone());
if let Some(c) = configs.borrow().get(&*globals::CONFIG_NAME.read().unwrap()) {
*globals::CONFIG.write().unwrap() = c.to_owned();
}
*did_save.borrow_mut() = true;
win.hide();
dialog::message_default("Re-open Post Maker to see changes!")
dialog::message_default("Re-open Post Maker to see changes properly!")
});
}
}

View File

@ -7,12 +7,12 @@ lazy_static! {
pub static ref THEME: config::Themes = config::config().theme.unwrap_or(config::Themes::System);
pub static ref CONFIG_NAME: RwLock<String> = RwLock::new("default".to_owned());
pub static ref CONFIG: RwLock<config::ConfigFile> = RwLock::new(config::ConfigFile::load());
pub static ref IMAGE_RATIO: RwLock<(f64, f64)> =
RwLock::new(CONFIG.read().unwrap().image_ratio);
pub static ref QUOTE_POSITION_RATIO: RwLock<f64> =
RwLock::new(CONFIG.read().unwrap().quote_position_ratio);
pub static ref TAG_POSITION_RATIO: RwLock<f64> =
RwLock::new(CONFIG.read().unwrap().tag_position_ratio);
// pub static ref IMAGE_RATIO: RwLock<(f64, f64)> =
// RwLock::new(CONFIG.read().unwrap().image_ratio);
// pub static ref QUOTE_POSITION_RATIO: RwLock<f64> =
// RwLock::new(CONFIG.read().unwrap().quote_position_ratio);
// pub static ref TAG_POSITION_RATIO: RwLock<f64> =
// RwLock::new(CONFIG.read().unwrap().tag_position_ratio);
pub static ref FONT_QUOTE: Font<'static> = {
let mut buffer = Vec::new();
if let Ok(mut file) = std::fs::File::open(CONFIG.read().unwrap().quote_font_ttf.as_str()) {

View File

@ -1,6 +1,7 @@
#![windows_subsystem = "windows"]
mod config;
mod config_picker;
mod config_window;
mod crop_window;
mod draw_thread;
@ -25,8 +26,8 @@ pub(crate) enum AppMessage {
fn main() {
let app = App::default();
WidgetTheme::new(globals::THEME.clone().into()).apply();
lazy_static::initialize(&globals::CONFIG);
let draw_buff: Arc<RwLock<Option<Vec<u8>>>> = Arc::new(RwLock::new(None));
let (main_sender, main_receiver) = channel::<AppMessage>();

View File

@ -287,7 +287,7 @@ impl MainWindow {
let expost_dir = path.join("export");
if !expost_dir.exists() {
if let Err(_) = fs::create_dir(expost_dir) {
fltk::dialog::message_default("Failed: Readonly folder!");
fltk::dialog::alert_default("Failed: create export folder!");
return;
}
}
@ -329,7 +329,7 @@ impl MainWindow {
Shortcut::None,
menu::MenuFlag::Normal,
move |_| {
dialog::message_default(
dialog::alert_default(
"Created with <3 by PiyushXCoder\nhttps://github.com/PiyushXCoder",
);
},

View File

@ -60,7 +60,7 @@ impl ImageContainer {
let img = match image::open(path) {
Ok(i) => i,
Err(_) => {
dialog::message_default("Failed to open image");
dialog::alert_default("Failed to open image!");
panic!("Failed to open image");
}
};
@ -69,11 +69,12 @@ impl ImageContainer {
let (width, height): (f64, f64) = Coord::from(img.dimensions()).into();
let (width, height) = (width, height);
let config = globals::CONFIG.read().unwrap();
let mut prop = properties.write().unwrap();
prop.path = Some(path.to_owned());
prop.original_dimension = (width, height);
prop.quote_position = height * &*globals::QUOTE_POSITION_RATIO.read().unwrap();
prop.tag_position = height * &*globals::TAG_POSITION_RATIO.read().unwrap();
prop.quote_position = height * config.quote_position_ratio;
prop.tag_position = height * config.tag_position_ratio;
Self {
image: img.clone(),
@ -172,7 +173,7 @@ impl ImageContainer {
let mut prop = prop.clone();
prop.path = None;
if fs::write(&path_conf, serde_json::to_string(&prop).unwrap()).is_err() {
dialog::message_default("Failed to save conf!");
dialog::alert_default("Failed to save conf!");
}
let mut img = image::open(&path_original).unwrap();
@ -200,7 +201,7 @@ impl ImageContainer {
.save_with_format(&export, image::ImageFormat::Png)
.is_err()
{
dialog::message_default("Failed to export png!");
dialog::alert_default("Failed to export png!");
}
}
@ -223,12 +224,12 @@ impl ImageContainer {
let path_conf_new = new_path.with_extension("conf");
if path.exists() && fs::copy(path, &new_path).is_err() {
dialog::message_default("Failed to clone image!");
dialog::alert_default("Failed to clone image!");
return None;
}
if path_conf.exists() && fs::copy(path_conf, &path_conf_new).is_err() {
dialog::message_default("Failed to clone image!");
dialog::alert_default("Failed to clone image!");
return None;
}
Some(new_path)
@ -255,15 +256,15 @@ impl ImageContainer {
);
if path_original.exists() && fs::remove_file(path_original).is_err() {
dialog::message_default("Failed to delete image!");
dialog::alert_default("Failed to delete image!");
}
if path_conf.exists() && fs::remove_file(path_conf).is_err() {
dialog::message_default("Failed to delete image conf!");
dialog::alert_default("Failed to delete image conf!");
}
if export.exists() && fs::remove_file(export).is_err() {
dialog::message_default("Failed to delete exported image!");
dialog::alert_default("Failed to delete exported image!");
}
}
}
@ -364,12 +365,12 @@ pub(crate) fn croped_ratio(width: f64, height: f64) -> (f64, f64) {
}
pub(crate) fn width_from_height(height: f64) -> f64 {
let (w, h) = &*globals::IMAGE_RATIO.read().unwrap();
let (w, h) = globals::CONFIG.read().unwrap().image_ratio;
(w * height) / h
}
pub(crate) fn height_from_width(width: f64) -> f64 {
let (w, h) = &*globals::IMAGE_RATIO.read().unwrap();
let (w, h) = globals::CONFIG.read().unwrap().image_ratio;
(h * width) / w
}