dash-frontend: application list grouping
This commit is contained in:
@@ -99,6 +99,7 @@
|
|||||||
</rectangle>
|
</rectangle>
|
||||||
<!-- BOTTOM PANEL -->
|
<!-- BOTTOM PANEL -->
|
||||||
<rectangle
|
<rectangle
|
||||||
|
consume_mouse_events="1"
|
||||||
width="100%"
|
width="100%"
|
||||||
height="48"
|
height="48"
|
||||||
min_height="48"
|
min_height="48"
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
<layout>
|
<layout>
|
||||||
<include src="t_tab_title.xml" />
|
<include src="t_tab_title.xml" />
|
||||||
|
<include src="../theme.xml" />
|
||||||
|
|
||||||
<template name="AppEntry">
|
<template name="AppEntry">
|
||||||
<Button
|
<Button
|
||||||
id="button" width="116" max_width="140" min_height="100" flex_grow="1"
|
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>
|
<div>
|
||||||
<sprite src="${src}" src_ext="${src_ext}" width="64" height="64" />
|
<sprite src="${src}" src_ext="${src_ext}" width="64" height="64" />
|
||||||
</div>
|
</div>
|
||||||
<div align_items="center" justify_content="center">
|
<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>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</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>
|
<elements>
|
||||||
<TabTitle translation="APPLICATIONS" icon="dashboard/apps.svg" />
|
<TabTitle translation="APPLICATIONS" icon="dashboard/apps.svg" />
|
||||||
<!-- placeholders for now -->
|
<!-- placeholders for now -->
|
||||||
|
<!--
|
||||||
<div gap="4" align_items="center">
|
<div gap="4" align_items="center">
|
||||||
<Button width="48" height="38">
|
<Button width="48" height="38">
|
||||||
<sprite src_builtin="dashboard/alphabetical.svg" width="24" height="24" />
|
<sprite src_builtin="dashboard/alphabetical.svg" width="24" height="24" />
|
||||||
@@ -25,16 +36,15 @@
|
|||||||
<sprite src_builtin="dashboard/category_search.svg" width="24" height="24" />
|
<sprite src_builtin="dashboard/category_search.svg" width="24" height="24" />
|
||||||
</Button>
|
</Button>
|
||||||
<sprite src_builtin="dashboard/search.svg" width="24" height="24" />
|
<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">
|
<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" />
|
<label text="Search" color="#FFFFFF88" weight="bold" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
<div
|
<div
|
||||||
id="app_list_parent"
|
id="app_list_parent"
|
||||||
flex_direction="row"
|
flex_direction="row"
|
||||||
flex_wrap="wrap"
|
flex_wrap="wrap"
|
||||||
justify_content="center"
|
|
||||||
gap="4"
|
gap="4"
|
||||||
overflow_y="scroll"
|
overflow_y="scroll"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="ApplicationIcon">
|
<template name="ApplicationIcon">
|
||||||
<sprite src_ext="${path}" width="128" height="128" />
|
<sprite src_ext="${path}" width="96" height="96" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<include src="../t_separator.xml" />
|
<include src="../t_separator.xml" />
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<div flex_direction="row" gap="16">
|
<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>
|
</rectangle>
|
||||||
<div flex_direction="column" gap="8">
|
<div flex_direction="column" gap="8">
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<Separator />
|
<Separator />
|
||||||
<RadioGroup id="radio_compositor" flex_direction="row" gap="16">
|
<RadioGroup id="radio_compositor" flex_direction="row" gap="16">
|
||||||
<RadioBox text="Native mode" value="Native" checked="1" />
|
<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>
|
</RadioGroup>
|
||||||
<Separator />
|
<Separator />
|
||||||
<label text="Resolution" />
|
<label text="Resolution" />
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ struct AppList {
|
|||||||
//data: Vec<ParserData>,
|
//data: Vec<ParserData>,
|
||||||
entries_to_mount: VecDeque<DesktopEntry>,
|
entries_to_mount: VecDeque<DesktopEntry>,
|
||||||
list_parent: WidgetPair,
|
list_parent: WidgetPair,
|
||||||
|
prev_first_letter: char,
|
||||||
}
|
}
|
||||||
|
|
||||||
// called after the user clicks any desktop entry
|
// called after the user clicks any desktop entry
|
||||||
@@ -130,12 +131,21 @@ impl<T> TabApps<T> {
|
|||||||
let tasks = Tasks::new();
|
let tasks = Tasks::new();
|
||||||
let state = Rc::new(RefCell::new(State { view_launcher: None }));
|
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 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 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 {
|
let app_list = AppList {
|
||||||
entries_to_mount: entries.into_values().collect(),
|
entries_to_mount: entries_sorted.drain(..).collect(),
|
||||||
list_parent: app_list_parent,
|
list_parent: app_list_parent,
|
||||||
|
prev_first_letter: ' ',
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -156,37 +166,55 @@ impl AppList {
|
|||||||
doc_params: &ParseDocumentParams,
|
doc_params: &ParseDocumentParams,
|
||||||
entry: &DesktopEntry,
|
entry: &DesktopEntry,
|
||||||
) -> anyhow::Result<Rc<ComponentButton>> {
|
) -> 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
|
parser_state.parse_template(
|
||||||
template_params.insert(
|
doc_params,
|
||||||
Rc::from("src_ext"),
|
"CategoryText",
|
||||||
entry
|
&mut frontend.layout,
|
||||||
.icon_path
|
self.list_parent.id,
|
||||||
.as_ref()
|
params,
|
||||||
.map_or_else(|| Rc::from(""), |icon_path| icon_path.clone()),
|
)?;
|
||||||
);
|
}
|
||||||
|
|
||||||
// entry fallback (question mark) icon
|
{
|
||||||
template_params.insert(
|
let mut params = HashMap::new();
|
||||||
Rc::from("src"),
|
|
||||||
if entry.icon_path.is_none() {
|
|
||||||
Rc::from("dashboard/terminal.svg")
|
|
||||||
} else {
|
|
||||||
Rc::from("")
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
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(
|
// entry fallback (question mark) icon
|
||||||
doc_params,
|
params.insert(
|
||||||
"AppEntry",
|
"src".into(),
|
||||||
&mut frontend.layout,
|
if entry.icon_path.is_none() {
|
||||||
self.list_parent.id,
|
"dashboard/terminal.svg".into()
|
||||||
template_params,
|
} else {
|
||||||
)?;
|
"".into()
|
||||||
data.fetch_component_as::<ComponentButton>("button")
|
},
|
||||||
|
);
|
||||||
|
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>(
|
fn tick<T>(
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ fn handle_button_click(button: Rc<ComponentButton>, label: Widget, text: &'stati
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TestbedGeneric {
|
impl TestbedGeneric {
|
||||||
fn doc_params(globals: &WguiGlobals, extra: ParseDocumentExtra) -> ParseDocumentParams {
|
fn doc_params(globals: &'_ WguiGlobals, extra: ParseDocumentExtra) -> ParseDocumentParams<'_> {
|
||||||
ParseDocumentParams {
|
ParseDocumentParams {
|
||||||
globals: globals.clone(),
|
globals: globals.clone(),
|
||||||
path: AssetPath::BuiltIn("gui/various_widgets.xml"),
|
path: AssetPath::BuiltIn("gui/various_widgets.xml"),
|
||||||
|
|||||||
Reference in New Issue
Block a user