Skip to content

Commit b9d4148

Browse files
authored
Merge pull request #217 from unsecretised/settings-page-finish
Improve settings page
2 parents 7662a64 + f73963a commit b9d4148

File tree

6 files changed

+259
-9
lines changed

6 files changed

+259
-9
lines changed

Cargo.lock

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ objc2-foundation = { version = "0.3.2", features = ["NSString"] }
3030
once_cell = "1.21.3"
3131
rand = "0.9.2"
3232
rayon = "1.11.0"
33+
rfd = "0.17.2"
3334
serde = { version = "1.0.228", features = ["derive"] }
3435
serde_json = "1.0.149"
3536
tokio = { version = "1.48.0", features = ["full"] }

src/app.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ pub enum Message {
9191
RunFunction(Function),
9292
OpenFocused,
9393
SetConfig(SetConfigFields),
94+
OpenFileDialogue(String),
9495
ReturnFocus,
9596
EscKeyPressed(Id),
9697
ClearSearchResults,
@@ -112,6 +113,7 @@ pub enum Message {
112113
}
113114

114115
#[derive(Debug, Clone)]
116+
#[allow(unused)]
115117
pub enum SetConfigFields {
116118
ToDefault,
117119
ToggleHotkey(String),
@@ -120,9 +122,9 @@ pub enum SetConfigFields {
120122
SearchUrl(String),
121123
HapticFeedback(bool),
122124
ShowMenubarIcon(bool),
123-
// Modes(HashMap<String, String>),
124-
// Aliases(HashMap<String, String>),
125-
// SearchDirs(Vec<String>),
125+
Modes(Editable<(String, String)>),
126+
Aliases(Editable<(String, String)>),
127+
SearchDirs(Editable<Vec<String>>),
126128
DebounceDelay(u64),
127129
SetThemeFields(SetConfigThemeFields),
128130
SetBufferFields(SetConfigBufferFields),

src/app/pages/settings.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
//! The settings page UI
22
3+
use std::collections::HashMap;
4+
35
use iced::widget::Slider;
6+
use iced::widget::TextInput;
47
use iced::widget::checkbox;
58
use iced::widget::text_input;
69

10+
use crate::app::Editable;
711
use crate::app::SetConfigBufferFields;
812
use crate::app::SetConfigThemeFields;
13+
use crate::styles::delete_button_style;
14+
use crate::styles::settings_add_button_style;
915
use crate::styles::settings_checkbox_style;
1016
use crate::styles::settings_save_button_style;
1117
use crate::styles::settings_slider_style;
@@ -351,6 +357,10 @@ pub fn settings_page(config: Config) -> Element<'static, Message> {
351357
font_family.into(),
352358
text_clr.into(),
353359
bg_clr.into(),
360+
settings_hint_text(theme.clone(), "Aliases"),
361+
aliases_item(config.aliases, &theme),
362+
settings_hint_text(theme.clone(), "Rustcast modes"),
363+
modes_item(config.modes, &theme),
354364
Row::from_iter([
355365
savebutton(theme.clone()),
356366
default_button(theme.clone()),
@@ -451,3 +461,138 @@ fn notice_item(theme: Theme, notice: impl ToString) -> Element<'static, Message>
451461
.align_x(Alignment::End)
452462
.into()
453463
}
464+
465+
fn aliases_item(aliases: HashMap<String, String>, theme: &Theme) -> Element<'static, Message> {
466+
let theme_clone = theme.clone();
467+
let mut aliases = aliases
468+
.iter()
469+
.map(|(k, v)| (k.to_owned(), v.to_owned()))
470+
.collect::<Vec<(String, String)>>();
471+
aliases.sort_by_key(|x| x.0.len());
472+
Column::from_iter([
473+
container(
474+
Column::from_iter(aliases.iter().map(|(key, value)| {
475+
let key_clone = key.clone();
476+
let val_clone = value.clone();
477+
let key_clone_2 = key.clone();
478+
let val_clone_2 = value.clone();
479+
let theme_clone_2 = theme.clone();
480+
Row::from_iter([
481+
text_input_cell(key.to_owned(), &theme_clone, "Shorthand")
482+
.on_input(move |input| {
483+
Message::SetConfig(SetConfigFields::Aliases(Editable::Update {
484+
old: (key_clone.clone(), val_clone.clone()),
485+
new: (input.clone(), val_clone.clone()),
486+
}))
487+
})
488+
.into(),
489+
text_input_cell(value.to_owned(), &theme_clone, "Term")
490+
.on_input(move |input| {
491+
Message::SetConfig(SetConfigFields::Aliases(Editable::Update {
492+
old: (key_clone_2.clone(), val_clone_2.clone()),
493+
new: (key_clone_2.clone(), input.clone()),
494+
}))
495+
})
496+
.into(),
497+
Button::new("Delete")
498+
.on_press(Message::SetConfig(SetConfigFields::Aliases(
499+
Editable::Delete((key.clone(), value.clone())),
500+
)))
501+
.style(move |_, _| delete_button_style(&theme_clone_2))
502+
.into(),
503+
])
504+
.spacing(10)
505+
.into()
506+
}))
507+
.spacing(10),
508+
)
509+
.height(Length::Fill)
510+
.width(Length::Fill)
511+
.into(),
512+
Button::new(
513+
Text::new("+")
514+
.align_x(Alignment::Center)
515+
.align_y(Alignment::Center),
516+
)
517+
.style(move |_, _| settings_add_button_style(&theme_clone.clone()))
518+
.on_press(Message::SetConfig(SetConfigFields::Aliases(
519+
Editable::Create((String::new(), String::new())),
520+
)))
521+
.into(),
522+
])
523+
.spacing(10)
524+
.width(Length::Fill)
525+
.align_x(Alignment::Center)
526+
.into()
527+
}
528+
529+
fn text_input_cell(text: String, theme: &Theme, placeholder: &str) -> TextInput<'static, Message> {
530+
text_input(placeholder, &text)
531+
.font(theme.font())
532+
.padding(5)
533+
.on_submit(Message::WriteConfig(false))
534+
}
535+
536+
fn modes_item(modes: HashMap<String, String>, theme: &Theme) -> Element<'static, Message> {
537+
let theme_clone = theme.clone();
538+
let mut modes = modes
539+
.iter()
540+
.map(|(k, v)| (k.to_owned(), v.to_owned()))
541+
.collect::<Vec<(String, String)>>();
542+
modes.sort_by_key(|x| x.0.len());
543+
Column::from_iter([
544+
container(
545+
Column::from_iter(modes.iter().map(|(key, value)| {
546+
let theme_clone_1 = theme_clone.clone();
547+
let display_val = if value.is_empty() {
548+
"Pick a file".to_string()
549+
} else {
550+
value.replace(&std::env::var("HOME").unwrap_or("".to_string()), "~")
551+
};
552+
let key_clone = key.clone();
553+
let val_clone = value.clone();
554+
let theme_clone_2 = theme.clone();
555+
Row::from_iter([
556+
text_input_cell(key.to_owned(), &theme_clone, "Shorthand")
557+
.on_input(move |input| {
558+
Message::SetConfig(SetConfigFields::Modes(Editable::Update {
559+
old: (key_clone.clone(), val_clone.clone()),
560+
new: (input.clone(), val_clone.clone()),
561+
}))
562+
})
563+
.into(),
564+
Button::new(Text::new(display_val))
565+
.on_press(Message::OpenFileDialogue(key.to_owned()))
566+
.style(move |_, _| settings_add_button_style(&theme_clone_1.clone()))
567+
.into(),
568+
Button::new("Delete")
569+
.on_press(Message::SetConfig(SetConfigFields::Modes(
570+
Editable::Delete((key.clone(), value.clone())),
571+
)))
572+
.style(move |_, _| delete_button_style(&theme_clone_2))
573+
.into(),
574+
])
575+
.spacing(10)
576+
.into()
577+
}))
578+
.spacing(10),
579+
)
580+
.height(Length::Fill)
581+
.width(Length::Fill)
582+
.into(),
583+
Button::new(
584+
Text::new("+")
585+
.align_x(Alignment::Center)
586+
.align_y(Alignment::Center),
587+
)
588+
.on_press(Message::SetConfig(SetConfigFields::Modes(
589+
Editable::Create((String::new(), String::new())),
590+
)))
591+
.style(move |_, _| settings_add_button_style(&theme_clone.clone()))
592+
.into(),
593+
])
594+
.spacing(10)
595+
.width(Length::Fill)
596+
.align_x(Alignment::Center)
597+
.into()
598+
}

src/app/tile/update.rs

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task<Message> {
6666
} else {
6767
info!("Switching to default mode");
6868
tile.current_mode = "default".to_string();
69-
window::latest().map(|x| Message::HideWindow(x.unwrap()))
69+
Task::none()
7070
}
7171
}
7272

@@ -549,14 +549,69 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task<Message> {
549549
}
550550
}
551551

552+
Message::OpenFileDialogue(mode_name) => rfd::FileDialog::new()
553+
.add_filter("shell", &["sh", "bash", "zsh"])
554+
.set_directory(
555+
std::env::var("HOME").unwrap_or("".to_string()) + "/.config/rustcast/config.toml",
556+
)
557+
.pick_file()
558+
.and_then(|x| {
559+
x.to_str().map(|x| {
560+
Task::batch([
561+
Task::done(Message::SetConfig(SetConfigFields::Modes(
562+
Editable::Create((mode_name, x.to_string())),
563+
))),
564+
Task::done(Message::WriteConfig(false)),
565+
])
566+
})
567+
})
568+
.unwrap_or(Task::none()),
569+
552570
Message::SetConfig(config) => {
553571
let mut final_config = tile.config.clone();
554572
match config {
555573
SetConfigFields::ToggleHotkey(hk) => final_config.toggle_hotkey = hk,
556574
SetConfigFields::ClipboardHotkey(hk) => final_config.toggle_hotkey = hk,
557-
// SetConfigFields::Modes(modes) => final_config.modes = modes,
558-
// SetConfigFields::Aliases(aliases) => final_config.aliases = aliases,
559-
// SetConfigFields::SearchDirs(dirs) => final_config.search_dirs = dirs,
575+
SetConfigFields::Modes(Editable::Create((key, value))) => {
576+
final_config.modes.entry(key).or_insert(value);
577+
}
578+
SetConfigFields::Modes(Editable::Delete((key, _))) => {
579+
final_config.modes.remove(&key);
580+
}
581+
SetConfigFields::Modes(Editable::Update { old, new }) => {
582+
final_config.modes.remove(&old.0);
583+
final_config.modes.insert(new.0, new.1);
584+
}
585+
SetConfigFields::Aliases(Editable::Create((key, value))) => {
586+
final_config.aliases.entry(key).or_insert(value);
587+
}
588+
SetConfigFields::Aliases(Editable::Delete((key, _))) => {
589+
final_config.aliases.remove(&key);
590+
}
591+
SetConfigFields::Aliases(Editable::Update { old, new }) => {
592+
final_config.aliases.remove(&old.0);
593+
final_config.aliases.insert(new.0, new.1);
594+
}
595+
SetConfigFields::SearchDirs(Editable::Create(dir)) => {
596+
final_config.search_dirs = dir
597+
}
598+
SetConfigFields::SearchDirs(Editable::Delete(dirs)) => {
599+
final_config.search_dirs = final_config
600+
.search_dirs
601+
.iter()
602+
.filter_map(|dir| {
603+
if !dirs.contains(dir) {
604+
Some(dir.to_owned())
605+
} else {
606+
None
607+
}
608+
})
609+
.collect();
610+
}
611+
SetConfigFields::SearchDirs(Editable::Update { old, new }) => {
612+
let _ = old;
613+
let _ = new;
614+
}
560615
SetConfigFields::SearchUrl(url) => final_config.search_url = url,
561616
SetConfigFields::PlaceHolder(placeholder) => final_config.placeholder = placeholder,
562617
SetConfigFields::DebounceDelay(delay) => final_config.debounce_delay = delay,
@@ -588,9 +643,7 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task<Message> {
588643
SetConfigFields::ToDefault => {
589644
final_config = Config::default();
590645
final_config.shells = tile.config.shells.clone();
591-
final_config.aliases = tile.config.aliases.clone();
592646
final_config.search_dirs = tile.config.search_dirs.clone();
593-
final_config.modes = tile.config.modes.clone();
594647
}
595648
};
596649

src/styles.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,19 @@ pub fn settings_save_button_style(theme: &ConfigTheme) -> button::Style {
198198
}
199199
}
200200

201+
pub fn settings_add_button_style(theme: &ConfigTheme) -> button::Style {
202+
button::Style {
203+
background: None,
204+
text_color: theme.text_color(1.),
205+
border: Border {
206+
color: theme.text_color(0.7),
207+
width: 0.7,
208+
radius: Radius::new(10),
209+
},
210+
..Default::default()
211+
}
212+
}
213+
201214
pub fn settings_checkbox_style(theme: &ConfigTheme) -> checkbox::Style {
202215
checkbox::Style {
203216
background: Background::Color(Color::TRANSPARENT),

0 commit comments

Comments
 (0)