Config window: keys typed with no field selected, as right after opening it, go into the search
This commit is contained in:
@@ -128,7 +128,7 @@ Left out on purpose: phone stats (iOS shares nothing Linux can read without extr
|
||||
|
||||
Every setting lives in `~/.config/amane/config.toml`: sizes, timings, text sizes, colours, poll intervals, equalizer presets and bands, the hotspot profile, the extra Sound output. The shell writes the file with every setting and its explanation the first time it starts (moving `cover_colors`, `transition_ms`, `hotspot` and `extra_output` over from an old `shell.conf`, which it no longer reads). Saving the file applies it at once; a line left out takes its default, and a line the shell can't use is listed at the top of the config window. The font and the cava bar count take effect on restart.
|
||||
|
||||
The config window edits the same file: Settings at the foot of the control centre, or `amane ipc call config toggle`. It is a normal window with a page per part of the shell, a page per Hyprland category, and a search over everything. Numbers with a range get a slider and a field, switches toggle, colours show a swatch; a typed value applies on Enter. Reset brings back the default.
|
||||
The config window edits the same file: Settings at the foot of the control centre, or `amane ipc call config toggle`. It is a normal window with a page per part of the shell, a page per Hyprland category, and a search over everything; typing with no field selected (as right after opening it) goes into the search. Numbers with a range get a slider and a field, switches toggle, colours show a swatch; a typed value applies on Enter. Reset brings back the default.
|
||||
|
||||
### Glass
|
||||
|
||||
|
||||
+51
-12
@@ -37,17 +37,21 @@ pub struct Ui {
|
||||
query: String,
|
||||
message: Option<(String, bool)>,
|
||||
hover: Option<String>,
|
||||
// just opened, or a key went to the search: it takes the keys on the next frame
|
||||
focus_search: bool,
|
||||
}
|
||||
|
||||
impl Service for Ui {
|
||||
fn new() -> Self {
|
||||
Self { page: String::from("appearance"), query: String::new(), message: None, hover: None }
|
||||
Self { page: String::from("appearance"), query: String::new(), message: None, hover: None, focus_search: false }
|
||||
}
|
||||
|
||||
fn listen() {}
|
||||
}
|
||||
|
||||
pub fn open() {
|
||||
Ui::write().focus_search = true;
|
||||
|
||||
open_window(NAME, view);
|
||||
|
||||
hypr::load();
|
||||
@@ -158,6 +162,16 @@ fn say(result: Result<(), String>, done: String) {
|
||||
pub fn view() -> Window {
|
||||
theme::begin();
|
||||
|
||||
/*
|
||||
* only on this frame: a TextInput that's .focused() takes the keys every frame it's
|
||||
* drawn, so always focused, the search would take them back from a value being typed
|
||||
*/
|
||||
let focus_search = Ui::read().focus_search;
|
||||
|
||||
if focus_search {
|
||||
Ui::write().focus_search = false;
|
||||
}
|
||||
|
||||
let colors = theme::now();
|
||||
let ui = Ui::read();
|
||||
let hypr = Hypr::read();
|
||||
@@ -283,22 +297,43 @@ pub fn view() -> Window {
|
||||
.title(TITLE)
|
||||
.size(1100.0, 760.0)
|
||||
.resizable(true)
|
||||
// Escape closes it, also from a field (a typed value only applies on Enter)
|
||||
.on_key(|key| {
|
||||
if key == Key::Escape {
|
||||
close_window(NAME);
|
||||
}
|
||||
/*
|
||||
* Escape closes it, also from a field (a typed value only applies on Enter). keys no
|
||||
* field takes, like right after opening, are typed into the search, which then takes
|
||||
* the keys itself: amane drops a field's focus whenever one of the shell's windows
|
||||
* loses the keyboard, as one does when this window opens
|
||||
*/
|
||||
.on_key(|key| match key {
|
||||
Key::Escape => close_window(NAME),
|
||||
Key::Character(letter) => search_key(Some(letter)),
|
||||
Key::Space => search_key(Some(' ')),
|
||||
Key::Backspace => search_key(None),
|
||||
_ => {}
|
||||
})
|
||||
.child(
|
||||
Rectangle::new()
|
||||
.width(width)
|
||||
.height(height)
|
||||
.fill(colors.surface_low)
|
||||
.child(Row::new(children![sidebar(&ui, &hypr, height, &colors), main])),
|
||||
.child(Row::new(children![sidebar(&ui, &hypr, height, &colors, focus_search), main])),
|
||||
)
|
||||
}
|
||||
|
||||
fn sidebar(ui: &Ui, hypr: &Hypr, height: f32, colors: &Colors) -> Rectangle {
|
||||
// a key typed with no field focused: into the search (none: Backspace), which takes the next keys
|
||||
fn search_key(letter: Option<char>) {
|
||||
let mut ui = Ui::write();
|
||||
|
||||
match letter {
|
||||
Some(letter) => ui.query.push(letter),
|
||||
None => {
|
||||
ui.query.pop();
|
||||
}
|
||||
}
|
||||
|
||||
ui.focus_search = true;
|
||||
}
|
||||
|
||||
fn sidebar(ui: &Ui, hypr: &Hypr, height: f32, colors: &Colors, focus_search: bool) -> Rectangle {
|
||||
let mut entries: Vec<Box<dyn Widget>> = vec![Box::new(caption("SHELL", colors))];
|
||||
|
||||
for module in config::modules() {
|
||||
@@ -333,11 +368,15 @@ fn sidebar(ui: &Ui, hypr: &Hypr, height: f32, colors: &Colors) -> Rectangle {
|
||||
.padding(Padding { top: 0.0, right: 10.0, bottom: 0.0, left: 10.0 })
|
||||
.align_child(Start, Center)
|
||||
.cursor(Cursor::Text)
|
||||
.child(TextInput::new(SEARCH).placeholder("Search all settings").size(config::appearance::text::body()).color(colors.text).on_change(|text| {
|
||||
SYNCED.with_borrow_mut(|synced| synced.insert(SEARCH, text.clone()));
|
||||
.child({
|
||||
let input = TextInput::new(SEARCH).placeholder("Search all settings").size(config::appearance::text::body()).color(colors.text).on_change(|text| {
|
||||
SYNCED.with_borrow_mut(|synced| synced.insert(SEARCH, text.clone()));
|
||||
|
||||
Ui::write().query = text;
|
||||
}));
|
||||
Ui::write().query = text;
|
||||
});
|
||||
|
||||
if focus_search { input.focused() } else { input }
|
||||
});
|
||||
|
||||
Rectangle::new()
|
||||
.width(SIDEBAR_W)
|
||||
|
||||
Reference in New Issue
Block a user