Skip to content

Commit 023a87f

Browse files
committed
Merge branch 'master' into favourited-apps
2 parents 1e2c978 + be27ca0 commit 023a87f

5 files changed

Lines changed: 363 additions & 28 deletions

File tree

src/app.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::HashMap;
33

44
use crate::app::apps::{App, AppCommand, ICNS_ICON};
55
use crate::commands::Function;
6-
use crate::config::{Config, MainPage};
6+
use crate::config::{Config, MainPage, Shelly};
77
use crate::debounce::DebouncePolicy;
88
use crate::utils::icns_data_to_handle;
99
use crate::{app::tile::ExtSender, clipboard::ClipBoardContentType};
@@ -129,7 +129,8 @@ pub enum SetConfigFields {
129129
SetPage(MainPage),
130130
Modes(Editable<(String, String)>),
131131
Aliases(Editable<(String, String)>),
132-
SearchDirs(Editable<Vec<String>>),
132+
SearchDirs(Editable<String>),
133+
ShellCommands(Editable<Shelly>),
133134
DebounceDelay(u64),
134135
SetThemeFields(SetConfigThemeFields),
135136
SetBufferFields(SetConfigBufferFields),

src/app/pages/settings.rs

Lines changed: 295 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::collections::HashMap;
44

55
use iced::widget::Slider;
6+
use iced::widget::Space;
67
use iced::widget::TextInput;
78
use iced::widget::checkbox;
89
use iced::widget::radio;
@@ -11,7 +12,9 @@ use iced::widget::text_input;
1112
use crate::app::Editable;
1213
use crate::app::SetConfigBufferFields;
1314
use crate::app::SetConfigThemeFields;
15+
use crate::commands::Function;
1416
use crate::config::MainPage;
17+
use crate::config::Shelly;
1518
use crate::styles::delete_button_style;
1619
use crate::styles::settings_add_button_style;
1720
use crate::styles::settings_checkbox_style;
@@ -231,16 +234,19 @@ pub fn settings_page(config: Config) -> Element<'static, Message> {
231234
let theme_clone = theme.clone();
232235
let font_family = settings_item_column([
233236
settings_hint_text(theme.clone(), "Set Font family"),
234-
text_input("Font family", &config.theme.font.unwrap_or("".to_string()))
235-
.on_input(move |input: String| {
236-
Message::SetConfig(SetConfigFields::SetThemeFields(SetConfigThemeFields::Font(
237-
input,
238-
)))
239-
})
240-
.on_submit(Message::WriteConfig(false))
241-
.width(Length::Fill)
242-
.style(move |_, _| settings_text_input_item_style(&theme_clone))
243-
.into(),
237+
text_input(
238+
"Font family",
239+
&config.theme.font.clone().unwrap_or("".to_string()),
240+
)
241+
.on_input(move |input: String| {
242+
Message::SetConfig(SetConfigFields::SetThemeFields(SetConfigThemeFields::Font(
243+
input,
244+
)))
245+
})
246+
.on_submit(Message::WriteConfig(false))
247+
.width(Length::Fill)
248+
.style(move |_, _| settings_text_input_item_style(&theme_clone))
249+
.into(),
244250
notice_item(theme.clone(), "What font rustcast should use"),
245251
]);
246252

@@ -399,12 +405,18 @@ pub fn settings_page(config: Config) -> Element<'static, Message> {
399405
text_clr.into(),
400406
bg_clr.into(),
401407
settings_hint_text(theme.clone(), "Aliases"),
402-
aliases_item(config.aliases, &theme),
408+
aliases_item(config.aliases.clone(), &theme),
403409
settings_hint_text(theme.clone(), "Modes"),
404-
modes_item(config.modes, &theme),
410+
modes_item(config.modes.clone(), &theme),
411+
settings_hint_text(theme.clone(), "Search Directories"),
412+
search_dirs_item(&theme, config.search_dirs.clone()),
413+
Space::new().height(30).into(),
414+
settings_hint_text(theme.clone(), "Shell commands"),
415+
shell_commands_item(config.shells.clone(), theme.clone()),
405416
Row::from_iter([
406417
savebutton(theme.clone()),
407418
default_button(theme.clone()),
419+
copy_config_button(config),
408420
wiki_button(theme.clone()),
409421
])
410422
.spacing(5)
@@ -450,18 +462,34 @@ fn default_button(theme: Theme) -> Element<'static, Message> {
450462

451463
fn wiki_button(theme: Theme) -> Element<'static, Message> {
452464
Button::new(
453-
Text::new("Open the wiki")
465+
Text::new("Open file")
454466
.align_x(Alignment::Center)
455467
.width(Length::Fill)
456468
.font(theme.font()),
457469
)
458470
.style(move |_, _| settings_save_button_style(&theme))
459471
.width(Length::Fill)
460-
.on_press(Message::RunFunction(
461-
crate::commands::Function::OpenWebsite(
462-
"https://github.com/RustCastLabs/rustcast/wiki".to_string(),
472+
.on_press(Message::RunFunction(crate::commands::Function::OpenApp(
473+
std::env::var("HOME").unwrap_or("".to_string()) + "/.config/rustcast/config.toml",
474+
)))
475+
.into()
476+
}
477+
478+
fn copy_config_button(config: Box<Config>) -> Element<'static, Message> {
479+
let theme = config.theme.clone();
480+
Button::new(
481+
Text::new("Copy config")
482+
.align_x(Alignment::Center)
483+
.width(Length::Fill)
484+
.font(theme.font()),
485+
)
486+
.style(move |_, _| settings_save_button_style(&theme))
487+
.width(Length::Fill)
488+
.on_press(Message::RunFunction(Function::CopyToClipboard(
489+
crate::clipboard::ClipBoardContentType::Text(
490+
toml::to_string(&config).unwrap_or("".to_string()),
463491
),
464-
))
492+
)))
465493
.into()
466494
}
467495

@@ -567,6 +595,47 @@ fn aliases_item(aliases: HashMap<String, String>, theme: &Theme) -> Element<'sta
567595
.into()
568596
}
569597

598+
fn search_dirs_item(theme: &Theme, search_dirs: Vec<String>) -> Element<'static, Message> {
599+
let theme_clone = theme.clone();
600+
let search_dirs = search_dirs.clone();
601+
Column::from_iter([
602+
container(
603+
Column::from_iter(search_dirs.iter().map(|dir| {
604+
let theme_clone_2 = theme.clone();
605+
let directory = dir.clone();
606+
container(
607+
Row::from_iter([
608+
dir_picker_button(directory, dir, theme_clone.clone()).into(),
609+
Button::new("Delete")
610+
.on_press(Message::SetConfig(SetConfigFields::SearchDirs(
611+
Editable::Delete(dir.clone()),
612+
)))
613+
.style(move |_, _| delete_button_style(&theme_clone_2))
614+
.into(),
615+
])
616+
.spacing(10)
617+
.align_y(Alignment::Center),
618+
)
619+
.width(Length::Fill)
620+
.align_x(Alignment::Center)
621+
.into()
622+
}))
623+
.spacing(10),
624+
)
625+
.height(Length::Fill)
626+
.width(Length::Fill)
627+
.align_x(Alignment::Center)
628+
.align_y(Alignment::Center)
629+
.into(),
630+
dir_adder_button("+", theme.to_owned()).into(),
631+
])
632+
.spacing(10)
633+
.height(Length::Fill)
634+
.width(Length::Fill)
635+
.align_x(Alignment::Center)
636+
.into()
637+
}
638+
570639
fn text_input_cell(text: String, theme: &Theme, placeholder: &str) -> TextInput<'static, Message> {
571640
text_input(placeholder, &text)
572641
.font(theme.font())
@@ -637,3 +706,212 @@ fn modes_item(modes: HashMap<String, String>, theme: &Theme) -> Element<'static,
637706
.align_x(Alignment::Center)
638707
.into()
639708
}
709+
710+
fn dir_picker_button(directory: String, dir: &str, theme: Theme) -> Button<'static, Message> {
711+
let home = std::env::var("HOME").unwrap_or("/".to_string());
712+
Button::new(Text::new(dir.to_owned().replace(&home, "~")))
713+
.on_press_with(move || {
714+
rfd::FileDialog::new()
715+
.set_directory(home.clone())
716+
.set_can_create_directories(false)
717+
.pick_folder()
718+
.map(|path| {
719+
let new = path.to_str().unwrap_or("").to_string();
720+
Message::SetConfig(SetConfigFields::SearchDirs(Editable::Update {
721+
old: directory.clone(),
722+
new,
723+
}))
724+
})
725+
.unwrap_or(Message::SetConfig(SetConfigFields::SearchDirs(
726+
Editable::Update {
727+
old: directory.clone(),
728+
new: directory.clone(),
729+
},
730+
)))
731+
})
732+
.style(move |_, _| settings_add_button_style(&theme.clone()))
733+
}
734+
735+
fn dir_adder_button(dir: &str, theme: Theme) -> Button<'static, Message> {
736+
Button::new(Text::new(dir.to_owned()))
737+
.on_press_with(move || {
738+
rfd::FileDialog::new()
739+
.set_directory(std::env::var("HOME").unwrap_or("/".to_string()))
740+
.set_can_create_directories(false)
741+
.pick_folder()
742+
.map(|path| {
743+
let new = path.to_str().unwrap_or("").to_string();
744+
Message::SetConfig(SetConfigFields::SearchDirs(Editable::Create(new)))
745+
})
746+
.unwrap_or(Message::SetConfig(SetConfigFields::SearchDirs(
747+
Editable::Create(String::new()),
748+
)))
749+
})
750+
.style(move |_, _| settings_add_button_style(&theme.clone()))
751+
}
752+
753+
fn shell_commands_item(shells: Vec<Shelly>, theme: Theme) -> Element<'static, Message> {
754+
let mut col =
755+
Column::from_iter(shells.iter().map(|x| x.editable_render(theme.clone()))).spacing(30);
756+
757+
let theme_clone = theme.clone();
758+
759+
col = col
760+
.push(
761+
Button::new(
762+
Text::new("+")
763+
.align_x(Alignment::Center)
764+
.align_y(Alignment::Center),
765+
)
766+
.style(move |_, _| settings_add_button_style(&theme_clone.clone()))
767+
.on_press(Message::SetConfig(SetConfigFields::ShellCommands(
768+
Editable::Create(Shelly::default()),
769+
))),
770+
)
771+
.width(Length::Fill)
772+
.align_x(Alignment::Center);
773+
774+
col.into()
775+
}
776+
777+
impl Shelly {
778+
pub fn editable_render(&self, theme: Theme) -> Element<'static, Message> {
779+
let shell = self.to_owned();
780+
Column::from_iter([
781+
tuple_row(
782+
shellcommand_hint_text(theme.clone(), "Display name"),
783+
text_input_cell(self.alias.clone(), &theme, "Display Name")
784+
.on_input({
785+
let shell = shell.clone();
786+
move |input| {
787+
let old = shell.clone();
788+
let mut new = old.clone();
789+
new.alias = input;
790+
Message::SetConfig(SetConfigFields::ShellCommands(Editable::Update {
791+
old,
792+
new,
793+
}))
794+
}
795+
})
796+
.into(),
797+
)
798+
.into(),
799+
tuple_row(
800+
shellcommand_hint_text(theme.clone(), "Search name"),
801+
text_input_cell(self.alias_lc.clone(), &theme, "Search Name")
802+
.on_input({
803+
let shell = shell.clone();
804+
move |input| {
805+
let old = shell.clone();
806+
let mut new = old.clone();
807+
new.alias_lc = input;
808+
Message::SetConfig(SetConfigFields::ShellCommands(Editable::Update {
809+
old,
810+
new,
811+
}))
812+
}
813+
})
814+
.into(),
815+
)
816+
.into(),
817+
tuple_row(
818+
shellcommand_hint_text(theme.clone(), "Command"),
819+
text_input_cell(self.command.clone(), &theme, "Command")
820+
.on_input({
821+
let shell = shell.clone();
822+
move |input| {
823+
let old = shell.clone();
824+
let mut new = old.clone();
825+
new.command = input;
826+
Message::SetConfig(SetConfigFields::ShellCommands(Editable::Update {
827+
old,
828+
new,
829+
}))
830+
}
831+
})
832+
.into(),
833+
)
834+
.into(),
835+
tuple_row(
836+
shellcommand_hint_text(theme.clone(), "Icon File"),
837+
text_input_cell(
838+
self.icon_path.clone().unwrap_or("".to_string()),
839+
&theme,
840+
"Icon path",
841+
)
842+
.on_input({
843+
let shell = shell.clone();
844+
move |input| {
845+
let old = shell.clone();
846+
let mut new = old.clone();
847+
new.icon_path = if input.is_empty() { None } else { Some(input) };
848+
Message::SetConfig(SetConfigFields::ShellCommands(Editable::Update {
849+
old,
850+
new,
851+
}))
852+
}
853+
})
854+
.into(),
855+
)
856+
.into(),
857+
tuple_row(
858+
shellcommand_hint_text(theme.clone(), "Hotkey"),
859+
text_input_cell(
860+
self.hotkey.clone().unwrap_or("".to_string()),
861+
&theme,
862+
"Hotkey",
863+
)
864+
.on_input({
865+
let shell = shell.clone();
866+
move |input| {
867+
let old = shell.clone();
868+
let mut new = old.clone();
869+
new.hotkey = Some(input);
870+
Message::SetConfig(SetConfigFields::ShellCommands(Editable::Update {
871+
old,
872+
new,
873+
}))
874+
}
875+
})
876+
.into(),
877+
)
878+
.into(),
879+
tuple_row(
880+
Button::new("Delete")
881+
.on_press(Message::SetConfig(SetConfigFields::ShellCommands(
882+
Editable::Delete(self.clone()),
883+
)))
884+
.style({
885+
let theme = theme.clone();
886+
move |_, _| delete_button_style(&theme)
887+
})
888+
.into(),
889+
notice_item(theme.clone(), "Icon path and hotkey are optional"),
890+
)
891+
.into(),
892+
])
893+
.spacing(10)
894+
.height(Length::Fill)
895+
.width(Length::Fill)
896+
.into()
897+
}
898+
}
899+
900+
fn tuple_row(
901+
left: Element<'static, Message>,
902+
right: Element<'static, Message>,
903+
) -> Row<'static, Message> {
904+
Row::from_iter([left, right])
905+
.spacing(10)
906+
.width(Length::Fill)
907+
}
908+
909+
fn shellcommand_hint_text(theme: Theme, text: impl ToString) -> Element<'static, Message> {
910+
let text = text.to_string();
911+
912+
Text::new(text)
913+
.font(theme.font())
914+
.color(theme.text_color(0.7))
915+
.width(WINDOW_WIDTH * 0.3)
916+
.into()
917+
}

src/app/tile/elm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ pub fn view(tile: &Tile, wid: window::Id) -> Element<'_, Message> {
189189
.height(height as u32);
190190

191191
let text = if tile.query_lc.is_empty() {
192-
if tile.page == Page::Main {
192+
if tile.config.auto_suggest && tile.page == Page::Main {
193193
"Frequently used".to_string()
194194
} else {
195195
tile.page.to_string()

0 commit comments

Comments
 (0)