feat(k-ui): text_input (label above, app owns text via on_change, caret, erase, submit, secret, placeholder); keys Left/Right/Space/Char/Erase; settings app filter; apps 8-page stack (k-ui overflowed 16K), args page -> 0x1000
This commit is contained in:
@@ -14,7 +14,7 @@ extern crate libkos;
|
||||
use alloc::format;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::vec::Vec;
|
||||
use k_ui::{App, ButtonVariant, Element, Spacing, TextColour, TextStyle, button, column, list_item, text, toggle};
|
||||
use k_ui::{App, ButtonVariant, Element, Spacing, TextColour, TextStyle, button, column, list_item, text, text_input, toggle};
|
||||
use libkos::apps::Apps;
|
||||
use libkos::session::Role;
|
||||
use manifest::{Capabilities, Capability};
|
||||
@@ -34,11 +34,13 @@ enum Screen {
|
||||
About,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone)]
|
||||
enum Event {
|
||||
Show(Screen),
|
||||
/// Allow or revoke this capability of the app on screen.
|
||||
Flip(Capability),
|
||||
/// What the app list is narrowed to.
|
||||
Filter(String),
|
||||
/// Use the display's `n`th theme.
|
||||
Theme(usize),
|
||||
SignOut,
|
||||
@@ -56,6 +58,8 @@ struct Settings {
|
||||
screen: Screen,
|
||||
apps: Option<Apps>,
|
||||
rows: Vec<AppRow>,
|
||||
/// Only apps whose name or id has this in it are listed.
|
||||
filter: String,
|
||||
/// Who is signed in, and how.
|
||||
who: Option<(String, Role)>,
|
||||
/// The display's themes, and which is in use.
|
||||
@@ -81,7 +85,8 @@ impl Settings {
|
||||
fn reload(&mut self) {
|
||||
self.rows.clear();
|
||||
let Some(apps) = &self.apps else { return };
|
||||
let mut buf = [0u8; LISTING];
|
||||
// On the heap: an app's stack is a few pages.
|
||||
let mut buf = alloc::vec![0u8; LISTING];
|
||||
let Ok(n) = apps.apps(&mut buf) else {
|
||||
self.trouble = Some("The permission manager did not answer.".to_string());
|
||||
return;
|
||||
@@ -141,12 +146,15 @@ impl Settings {
|
||||
}
|
||||
|
||||
fn app_list(&self) -> Element<Event> {
|
||||
let rows = self.rows.iter().enumerate().map(|(i, r)| {
|
||||
let wanted = self.filter.to_ascii_lowercase();
|
||||
let shown = |r: &&AppRow| r.name.to_ascii_lowercase().contains(&wanted) || r.id.contains(&wanted);
|
||||
let rows = self.rows.iter().enumerate().filter(|(_, r)| shown(r)).map(|(i, r)| {
|
||||
let allowed = r.granted.intersect(r.requested).iter().count();
|
||||
let asked = r.requested.iter().count();
|
||||
list_item(r.name.clone(), Event::Show(Screen::App(i))).subtitle(format!("{} · {} of {} allowed", r.id, allowed, asked))
|
||||
});
|
||||
let view = Self::hint(Self::heading("Apps"), "Esc goes back").children(rows);
|
||||
let find = text_input("Find an app", self.filter.clone(), Event::Filter).placeholder("Name or id");
|
||||
let view = Self::hint(Self::heading("Apps"), "Esc goes back, Down goes to the list").child(find).children(rows);
|
||||
self.with_trouble(view).into()
|
||||
}
|
||||
|
||||
@@ -209,7 +217,7 @@ impl App for Settings {
|
||||
.collect()
|
||||
});
|
||||
let theme = window.and_then(libkos::display::theme).map_or(0, |(i, _)| i);
|
||||
let mut s = Settings { screen: Screen::Home, apps, rows: Vec::new(), who, themes, theme, trouble: None };
|
||||
let mut s = Settings { screen: Screen::Home, apps, rows: Vec::new(), filter: String::new(), who, themes, theme, trouble: None };
|
||||
s.reload();
|
||||
s
|
||||
}
|
||||
@@ -219,6 +227,7 @@ impl App for Settings {
|
||||
Event::Show(screen) => {
|
||||
self.trouble = None;
|
||||
if screen == Screen::Apps {
|
||||
self.filter.clear();
|
||||
self.reload();
|
||||
}
|
||||
self.screen = screen;
|
||||
@@ -228,6 +237,7 @@ impl App for Settings {
|
||||
self.flip(i, cap);
|
||||
}
|
||||
}
|
||||
Event::Filter(f) => self.filter = f,
|
||||
Event::Theme(i) => self.choose_theme(i),
|
||||
Event::SignOut => {
|
||||
if let Some(s) = libkos::start::session() {
|
||||
|
||||
Reference in New Issue
Block a user