dash-frontend: application list grouping
This commit is contained in:
@@ -99,6 +99,7 @@
|
||||
</rectangle>
|
||||
<!-- BOTTOM PANEL -->
|
||||
<rectangle
|
||||
consume_mouse_events="1"
|
||||
width="100%"
|
||||
height="48"
|
||||
min_height="48"
|
||||
|
||||
@@ -1,22 +1,33 @@
|
||||
<layout>
|
||||
<include src="t_tab_title.xml" />
|
||||
<include src="../theme.xml" />
|
||||
|
||||
<template name="AppEntry">
|
||||
<Button
|
||||
id="button" width="116" max_width="140" min_height="100" flex_grow="1"
|
||||
flex_direction="column" overflow="visible" align_items="center" justify_content="center" gap="4">
|
||||
flex_direction="column" overflow="visible" align_items="center" justify_content="center" gap="4"
|
||||
color="#3385FF10"
|
||||
>
|
||||
<div>
|
||||
<sprite src="${src}" src_ext="${src_ext}" width="64" height="64" />
|
||||
</div>
|
||||
<div align_items="center" justify_content="center">
|
||||
<label width="116" weight="bold" text="${name}" size="12" wrap="1" align="center" padding_left="16" padding_right="16"/>
|
||||
<label width="116" weight="bold" text="${name}" size="12" wrap="1" align="center" padding_left="16" padding_right="16" />
|
||||
</div>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
<template name="CategoryText">
|
||||
<rectangle width="100%" flex_direction="column" round="8" border="2" gradient="vertical" color2="#4477FF09" color="#5588FF10" border_color="#FFFFFF00">
|
||||
<label margin="8" text="${text}" weight="bold" size="22" />
|
||||
<rectangle height="2" color="~color_accent" margin_left="4" margin_right="4" />
|
||||
</rectangle>
|
||||
</template>
|
||||
|
||||
<elements>
|
||||
<TabTitle translation="APPLICATIONS" icon="dashboard/apps.svg" />
|
||||
<!-- placeholders for now -->
|
||||
<!--
|
||||
<div gap="4" align_items="center">
|
||||
<Button width="48" height="38">
|
||||
<sprite src_builtin="dashboard/alphabetical.svg" width="24" height="24" />
|
||||
@@ -25,18 +36,17 @@
|
||||
<sprite src_builtin="dashboard/category_search.svg" width="24" height="24" />
|
||||
</Button>
|
||||
<sprite src_builtin="dashboard/search.svg" width="24" height="24" />
|
||||
<!-- placeholder editbox -->
|
||||
<rectangle flex_grow="1" height="100%" color="#1d2e51" border_color="#294774" border="2" round="4" align_items="center" padding_left="12">
|
||||
<label text="Search" color="#FFFFFF88" weight="bold" />
|
||||
</rectangle>
|
||||
</div>
|
||||
-->
|
||||
<div
|
||||
id="app_list_parent"
|
||||
flex_direction="row"
|
||||
flex_wrap="wrap"
|
||||
justify_content="center"
|
||||
gap="4"
|
||||
overflow_y="scroll"
|
||||
/>
|
||||
</elements>
|
||||
</layout>
|
||||
</layout>
|
||||
@@ -7,7 +7,7 @@
|
||||
</template>
|
||||
|
||||
<template name="ApplicationIcon">
|
||||
<sprite src_ext="${path}" width="128" height="128" />
|
||||
<sprite src_ext="${path}" width="96" height="96" />
|
||||
</template>
|
||||
|
||||
<include src="../t_separator.xml" />
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<elements>
|
||||
<div flex_direction="row" gap="16">
|
||||
<rectangle macro="group_box" id="icon_parent" padding="8" color="#0033aa66" color2="#00000022" gradient="vertical" justify_content="center">
|
||||
<rectangle macro="group_box" id="icon_parent" padding="16" color="#0033aa66" color2="#00000022" gradient="vertical" justify_content="center">
|
||||
|
||||
</rectangle>
|
||||
<div flex_direction="column" gap="8">
|
||||
@@ -25,7 +25,7 @@
|
||||
<Separator />
|
||||
<RadioGroup id="radio_compositor" flex_direction="row" gap="16">
|
||||
<RadioBox text="Native mode" value="Native" checked="1" />
|
||||
<RadioBox text="Compatibility mode" value="Cage"/> <!-- TODO: tooltips -->
|
||||
<RadioBox text="Compatibility mode" value="Cage" /> <!-- TODO: tooltips -->
|
||||
</RadioGroup>
|
||||
<Separator />
|
||||
<label text="Resolution" />
|
||||
@@ -51,4 +51,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</elements>
|
||||
</layout>
|
||||
</layout>
|
||||
@@ -70,6 +70,7 @@ struct AppList {
|
||||
//data: Vec<ParserData>,
|
||||
entries_to_mount: VecDeque<DesktopEntry>,
|
||||
list_parent: WidgetPair,
|
||||
prev_first_letter: char,
|
||||
}
|
||||
|
||||
// called after the user clicks any desktop entry
|
||||
@@ -130,12 +131,21 @@ impl<T> TabApps<T> {
|
||||
let tasks = Tasks::new();
|
||||
let state = Rc::new(RefCell::new(State { view_launcher: None }));
|
||||
|
||||
let mut entries = frontend.interface.desktop_finder(data).find_entries();
|
||||
let parser_state = wgui::parser::parse_from_assets(&doc_params(globals.clone()), &mut frontend.layout, parent_id)?;
|
||||
let app_list_parent = parser_state.fetch_widget(&frontend.layout.state, "app_list_parent")?;
|
||||
|
||||
let mut entries_sorted: Vec<_> = frontend
|
||||
.interface
|
||||
.desktop_finder(data)
|
||||
.find_entries()
|
||||
.into_values()
|
||||
.collect();
|
||||
entries_sorted.sort_by(|a, b| a.app_name.cmp(&b.app_name));
|
||||
|
||||
let app_list = AppList {
|
||||
entries_to_mount: entries.into_values().collect(),
|
||||
entries_to_mount: entries_sorted.drain(..).collect(),
|
||||
list_parent: app_list_parent,
|
||||
prev_first_letter: ' ',
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
@@ -156,37 +166,55 @@ impl AppList {
|
||||
doc_params: &ParseDocumentParams,
|
||||
entry: &DesktopEntry,
|
||||
) -> anyhow::Result<Rc<ComponentButton>> {
|
||||
let mut template_params = HashMap::new();
|
||||
if let Some(ch) = entry.app_name.chars().next()
|
||||
&& self.prev_first_letter != ch
|
||||
{
|
||||
self.prev_first_letter = ch;
|
||||
let mut params = HashMap::<Rc<str>, Rc<str>>::new();
|
||||
params.insert("text".into(), format!("{}", ch).into());
|
||||
|
||||
// entry icon
|
||||
template_params.insert(
|
||||
Rc::from("src_ext"),
|
||||
entry
|
||||
.icon_path
|
||||
.as_ref()
|
||||
.map_or_else(|| Rc::from(""), |icon_path| icon_path.clone()),
|
||||
);
|
||||
parser_state.parse_template(
|
||||
doc_params,
|
||||
"CategoryText",
|
||||
&mut frontend.layout,
|
||||
self.list_parent.id,
|
||||
params,
|
||||
)?;
|
||||
}
|
||||
|
||||
// entry fallback (question mark) icon
|
||||
template_params.insert(
|
||||
Rc::from("src"),
|
||||
if entry.icon_path.is_none() {
|
||||
Rc::from("dashboard/terminal.svg")
|
||||
} else {
|
||||
Rc::from("")
|
||||
},
|
||||
);
|
||||
{
|
||||
let mut params = HashMap::new();
|
||||
|
||||
template_params.insert(Rc::from("name"), entry.app_name.clone());
|
||||
// entry icon
|
||||
params.insert(
|
||||
"src_ext".into(),
|
||||
entry
|
||||
.icon_path
|
||||
.as_ref()
|
||||
.map_or_else(|| "".into(), |icon_path| icon_path.clone()),
|
||||
);
|
||||
|
||||
let data = parser_state.parse_template(
|
||||
doc_params,
|
||||
"AppEntry",
|
||||
&mut frontend.layout,
|
||||
self.list_parent.id,
|
||||
template_params,
|
||||
)?;
|
||||
data.fetch_component_as::<ComponentButton>("button")
|
||||
// entry fallback (question mark) icon
|
||||
params.insert(
|
||||
"src".into(),
|
||||
if entry.icon_path.is_none() {
|
||||
"dashboard/terminal.svg".into()
|
||||
} else {
|
||||
"".into()
|
||||
},
|
||||
);
|
||||
params.insert("name".into(), entry.app_name.clone());
|
||||
|
||||
let data = parser_state.parse_template(
|
||||
doc_params,
|
||||
"AppEntry",
|
||||
&mut frontend.layout,
|
||||
self.list_parent.id,
|
||||
params,
|
||||
)?;
|
||||
|
||||
data.fetch_component_as::<ComponentButton>("button")
|
||||
}
|
||||
}
|
||||
|
||||
fn tick<T>(
|
||||
|
||||
@@ -79,7 +79,7 @@ fn handle_button_click(button: Rc<ComponentButton>, label: Widget, text: &'stati
|
||||
}
|
||||
|
||||
impl TestbedGeneric {
|
||||
fn doc_params(globals: &WguiGlobals, extra: ParseDocumentExtra) -> ParseDocumentParams {
|
||||
fn doc_params(globals: &'_ WguiGlobals, extra: ParseDocumentExtra) -> ParseDocumentParams<'_> {
|
||||
ParseDocumentParams {
|
||||
globals: globals.clone(),
|
||||
path: AssetPath::BuiltIn("gui/various_widgets.xml"),
|
||||
|
||||
Reference in New Issue
Block a user