Skip to content

Commit e3f168b

Browse files
committed
add ctrl+p to merge with recipe in clipboard
1 parent c84fb4e commit e3f168b

File tree

1 file changed

+190
-16
lines changed

1 file changed

+190
-16
lines changed

src/smgui.rs

Lines changed: 190 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
cli::Arguments,
3-
recipe::{export_recipe, Recipe, WidgetMetadata},
3+
recipe::{export_recipe, parse_recipe, Recipe, WidgetMetadata},
44
};
55
use std::{
66
fs::File, io::Write,
@@ -10,6 +10,7 @@ use std::{
1010
use copypasta::{ClipboardContext, ClipboardProvider};
1111
use eframe::egui;
1212
use winit::raw_window_handle::HasWindowHandle;
13+
use indexmap::map::IndexMap;
1314

1415
struct SmApp {
1516
first_frame: bool,
@@ -19,13 +20,17 @@ struct SmApp {
1920
metadata: WidgetMetadata,
2021
selected_files: Vec<PathBuf>,
2122
show_confirmation_dialog: bool,
23+
show_merge_dialog: bool,
24+
staging_merge: Option<(Recipe, IndexMap<String, IndexMap<String, bool>>)>,
2225
allowed_to_close: bool,
2326
show_about: bool,
2427
args: Arguments,
2528
start_rendering: bool,
2629
// yeah that's the damn typename
2730
recipe_saved: String,
28-
sender: Sender<(Recipe, Arguments, Option<windows::Win32::Foundation::HWND>)>
31+
sender: Sender<(Recipe, Arguments, Option<windows::Win32::Foundation::HWND>)>,
32+
make_new_recipe: bool,
33+
new_recipe_filename: String,
2934
}
3035

3136
pub const WINDOW_NAME: &str = "smoothie-app";
@@ -41,7 +46,7 @@ pub fn save_recipe(recipe: &Recipe, recipe_filename: &PathBuf, metadata: &Widget
4146
None => panic!("Could not resolve Smoothie's binary directory `{exe:?}`"),
4247
};
4348

44-
let recipe_path = if PathBuf::from(recipe_filename.clone()).exists() {
49+
let recipe_path = if recipe_filename.clone().exists() {
4550
PathBuf::from(recipe_filename)
4651
} else {
4752
let cur_dir_rc = bin_dir.join(recipe_filename);
@@ -73,6 +78,7 @@ pub fn save_recipe(recipe: &Recipe, recipe_filename: &PathBuf, metadata: &Widget
7378
println!("{}", &content);
7479
}
7580

81+
#[allow(clippy::extra_unused_lifetimes)]
7682
pub fn sm_gui<'gui>(
7783
recipe: Recipe,
7884
metadata: WidgetMetadata,
@@ -91,13 +97,16 @@ pub fn sm_gui<'gui>(
9197
..Default::default()
9298
};
9399

100+
94101
eframe::run_native(
95102
WINDOW_NAME,
96103
options,
97104
Box::new(|_cc|{
98105

99106
Ok(Box::new(
100107
SmApp {
108+
show_merge_dialog: false,
109+
staging_merge: None,
101110
first_frame: true,
102111
save_new_recipe: false,
103112
recipe_change_request: None,
@@ -110,7 +119,9 @@ pub fn sm_gui<'gui>(
110119
show_about: false,
111120
args,
112121
start_rendering: false,
113-
sender: sender
122+
sender,
123+
make_new_recipe: false,
124+
new_recipe_filename: String::new(),
114125
}
115126
))
116127
}),
@@ -160,6 +171,7 @@ impl eframe::App for SmApp {
160171
// self.allowed_to_close = true;
161172
ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close);
162173
}
174+
163175
let ctrl_s = egui::KeyboardShortcut {
164176
modifiers: egui::Modifiers {
165177
ctrl: true,
@@ -172,6 +184,19 @@ impl eframe::App for SmApp {
172184
};
173185
let ctrl_s_pressed = ctx.input_mut(|i| i.consume_shortcut(&ctrl_s));
174186

187+
let ctrl_p = egui::KeyboardShortcut {
188+
modifiers: egui::Modifiers {
189+
ctrl: true,
190+
alt: false,
191+
shift: false,
192+
mac_cmd: false,
193+
command: false,
194+
},
195+
logical_key: egui::Key::P,
196+
};
197+
let ctrl_p_pressed = ctx.input_mut(|i| i.consume_shortcut(&ctrl_p));
198+
199+
175200
egui::menu::bar(ui, |ui| {
176201
egui::widgets::global_theme_preference_switch(ui);
177202
if ui.button("README").clicked() {
@@ -257,14 +282,14 @@ impl eframe::App for SmApp {
257282
ctx.set_contents(recipe_txt).unwrap();
258283
}
259284
});
260-
egui::menu::bar(ui, |ui| {
285+
//egui::menu::bar(ui, |ui| {
261286

262-
let binding = PathBuf::from(self.args.recipe.clone());
263-
let selected_recipe = binding
264-
.file_name().expect("Failed unwrapping file name from args.recipe")
265-
.to_str().expect("Failed unwrapping string from filename from args.recipe");
287+
let binding = PathBuf::from(self.args.recipe.clone());
288+
let selected_recipe = binding
289+
.file_name().expect("Failed unwrapping file name from args.recipe")
290+
.to_str().expect("Failed unwrapping string from filename from args.recipe");
266291

267-
egui::ComboBox::from_label("")
292+
egui::ComboBox::from_label("")
268293
.selected_text(selected_recipe)
269294
.show_ui(ui, |ui| {
270295
let enum_values = crate::portable::get_config_filepaths();
@@ -281,16 +306,21 @@ impl eframe::App for SmApp {
281306
selected_value,
282307
enum_value.file_name().to_owned().unwrap().to_str().unwrap()
283308
);
309+
284310
}
285-
if binding.to_str().unwrap().to_string() != self.args.recipe {
311+
if binding.to_str().unwrap() != self.args.recipe.as_str() {
286312
self.recipe_change_request = Some(binding.to_str().unwrap().to_string());
287313
// let (recipe, metadata) = crate::recipe::get_recipe(&mut self.args);
288314
// self.recipe = recipe;
289315
// self.metadata = metadata;
290316
}
291-
317+
ui.selectable_value(
318+
&mut self.make_new_recipe,
319+
true,
320+
"New recipe"
321+
);
292322
});
293-
});
323+
//});
294324
egui::menu::bar(ui, |_| {}); // <br>
295325
egui::ScrollArea::vertical().show(ui, |ui| {
296326
for cat in &mut self.metadata.keys() {
@@ -320,7 +350,7 @@ impl eframe::App for SmApp {
320350
&cat.clone().replace(" ", "-")
321351
);
322352

323-
let _ = if ui.hyperlink_to(cat, &url).secondary_clicked() {
353+
if ui.hyperlink_to(cat, &url).secondary_clicked() {
324354
dbg!(&url);
325355
println!("Copied `{}` to clipboard", &url);
326356
let mut ctx = ClipboardContext::new().unwrap();
@@ -469,7 +499,7 @@ impl eframe::App for SmApp {
469499
.to_ascii_lowercase()
470500
.as_os_str()
471501
.to_str()
472-
.expect("Failed "),
502+
.expect("Failed convertin file extension to string"),
473503
) {
474504
self.selected_files.push(path)
475505
} else {
@@ -489,6 +519,150 @@ impl eframe::App for SmApp {
489519
}
490520
});
491521

522+
if self.make_new_recipe {
523+
let mut open = true;
524+
egui::Window::new("new recipe").open(&mut open).show(ctx, |ui|{
525+
ui.label(format!("it will use current recipe ({}) as base", selected_recipe));
526+
ui.horizontal(|ui| {
527+
ui.label("file name: ");
528+
ui.add(egui::TextEdit::singleline(&mut self.new_recipe_filename).desired_width(200.0)).request_focus();
529+
ui.label(".ini")
530+
});
531+
if ui.button("create").clicked() {
532+
}
533+
});
534+
if !open {
535+
self.make_new_recipe = false;
536+
}
537+
}
538+
539+
if ctrl_p_pressed {
540+
let clipboard = ClipboardContext::new().unwrap().get_contents().expect("Failed reading system clipboard");
541+
let lines = clipboard.split("\n");
542+
let mut cleaned: Vec<String> = vec![];
543+
544+
#[allow(non_camel_case_types)]
545+
enum _RecipeTypes {
546+
smoothie_rs,
547+
smoothie_py,
548+
teres,
549+
blur_18,
550+
blur_19,
551+
blur_20,
552+
}
553+
554+
for line in lines {
555+
if line.is_empty() || line.starts_with("#") || line.starts_with("//") || line.starts_with(";") {
556+
continue
557+
}
558+
cleaned.push(line.to_owned());
559+
};
560+
561+
if !cleaned.is_empty() {
562+
let mut to_merge = Recipe::new();
563+
564+
parse_recipe(
565+
PathBuf::from(self.args.recipe.clone()),
566+
Some(cleaned.join("\n")), &mut to_merge,
567+
&mut None,
568+
false
569+
);
570+
571+
let mut toggled: IndexMap<String, IndexMap<String, bool>> = IndexMap::new();
572+
573+
for section in to_merge.keys() {
574+
toggled.insert(section.to_owned(), IndexMap::new());
575+
}
576+
577+
for section in toggled.to_owned().keys() {
578+
for key in to_merge.get_section(section){
579+
toggled
580+
.entry(section.to_owned())
581+
.or_default()
582+
.insert(key.0.to_owned(), true);
583+
}
584+
}
585+
586+
self.staging_merge = Some((to_merge, toggled));
587+
self.show_merge_dialog = true;
588+
}
589+
590+
}
591+
592+
if self.show_merge_dialog {
593+
594+
egui::Window::new("merge pasted config").show(ctx, |ui|{
595+
596+
let mut cancel = false;
597+
let mut merge = false;
598+
let mut invert_selection = false;
599+
ui.horizontal(|ui| {
600+
cancel = ui.button("cancel").clicked();
601+
merge = ui.button("merge").clicked();
602+
invert_selection = ui.button("invert").clicked();
603+
});
604+
let staging_recipe = self.staging_merge.as_mut().unwrap();
605+
for section in staging_recipe.0.to_owned().keys() {
606+
607+
ui.horizontal(|ui| {
608+
609+
let section_selection: Vec<bool> = staging_recipe.1.entry(section.to_owned()).or_default().values().cloned().collect();
610+
611+
let mut select = !section_selection.contains(&false);
612+
613+
let toggle_section = ui.checkbox(&mut select, section);
614+
615+
let section = staging_recipe.1.entry(section.to_owned()).or_default();
616+
617+
618+
for (key, value) in section.to_owned().into_iter() {
619+
620+
if toggle_section.clicked() {
621+
section.insert(key.to_owned(), select);
622+
} else if invert_selection {
623+
624+
section.insert(key.to_owned(), !value);
625+
}
626+
}
627+
});
628+
629+
for (key , value) in staging_recipe.0.get_section_mut(section){
630+
631+
ui.horizontal(|ui| {
632+
633+
let enabled = staging_recipe.1
634+
.entry(section.to_owned())
635+
.or_default()
636+
.entry(key.to_owned())
637+
.or_insert(false);
638+
639+
ui.checkbox(enabled, key);
640+
*enabled = enabled.to_owned();
641+
ui.add(egui::TextEdit::singleline(&mut *value));
642+
});
643+
}
644+
}
645+
if merge {
646+
647+
self.show_merge_dialog = false;
648+
for section in staging_recipe.0.to_owned().keys() {
649+
for (key, value) in staging_recipe.0.get_section(section){
650+
let enabled =
651+
staging_recipe.1.entry(section.to_owned()).or_default().entry(key.to_owned()).or_insert(false);
652+
653+
if !enabled.to_owned() { continue }
654+
self.recipe.insert_value(section, key.to_owned(), value.to_owned());
655+
}
656+
}
657+
658+
}
659+
if cancel || merge {
660+
self.staging_merge = None;
661+
self.show_merge_dialog = false;
662+
}
663+
});
664+
}
665+
492666
if self.show_about {
493667
egui::Window::new("about smoothie app")
494668
.collapsible(false)
@@ -570,7 +744,7 @@ impl eframe::App for SmApp {
570744
// the recipe isn't formatted yet, let it go through a frame
571745
// to normalize bools and int slider increments
572746
//self.recipe_saved = format!("{:?}", recipe);
573-
self.save_new_recipe;
747+
//self.save_new_recipe;
574748
}
575749
if ui.button("Don't Save").clicked() {
576750
self.recipe_change_request = None;

0 commit comments

Comments
 (0)