mirror of https://github.com/wayvr-org/wayvr.git
dash-frontend: Bindings view UX improvements
This commit is contained in:
parent
0962f4c015
commit
4edc6053ce
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE --><path fill="#F55" d="m8.4 17l3.6-3.6l3.6 3.6l1.4-1.4l-3.6-3.6L17 8.4L15.6 7L12 10.6L8.4 7L7 8.4l3.6 3.6L7 15.6zm3.6 5q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8"/></svg>
|
||||||
|
After Width: | Height: | Size: 573 B |
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
viewBox="0 0 384.00001 383.99998"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="hand_left.svg"
|
||||||
|
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:clip-to-page="false"
|
||||||
|
inkscape:zoom="8"
|
||||||
|
inkscape:cx="24"
|
||||||
|
inkscape:cy="15.9375"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1016"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m 223.99926,120.14002 v 90.93 c 0,46.2 -36.85,84.55 -83,85.06 a 83.7,83.7 0 0 1 -60.400003,-24.59 c -21.81,-23.07 -46.45,-79.4 -46.45,-79.4 a 16,16 0 0 1 6.53,-22.23 c 7.66,-4 17.1,-0.84 21.4,6.62 l 21,36.44 a 6.09,6.09 0 0 0 6,3.09 h 0.12 a 8.19,8.19 0 0 0 6.800001,-8.18 v -103.74 A 16,16 0 0 1 112.76926,88.140018 c 8.61,0.4 15.23,7.82 15.23,16.430002 v 63.57 a 8,8 0 0 0 8.53,8 8.17,8.17 0 0 0 7.47,-8.25 V 88.140018 a 16,16 0 0 1 16.77,-15.999999 c 8.61,0.4 15.23,7.82 15.23,16.429999 v 87.570002 a 8,8 0 0 0 8.53,8 8.17,8.17 0 0 0 7.47,-8.25 v -55.3 c 0,-8.61 6.62,-16 15.23,-16.43 a 16,16 0 0 1 16.77,15.98"
|
||||||
|
id="path1" />
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M 263.19112,258.73409 V 112.03922 h 18.49095 v 130.25847 h 64.10196 v 16.4364 z"
|
||||||
|
id="text1"
|
||||||
|
aria-label="L" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
viewBox="0 0 384 383.99998"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="hand_right.svg"
|
||||||
|
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="8"
|
||||||
|
inkscape:cx="24"
|
||||||
|
inkscape:cy="15.9375"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1016"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M 30.079989,119.60999 V 210.54 c 0,46.2 36.85,84.55 83.000011,85.06 a 83.7,83.7 0 0 0 60.4,-24.59 c 21.81,-23.07 46.45,-79.4 46.45,-79.4 a 16,16 0 0 0 -6.53,-22.23 c -7.66,-4.00001 -17.1,-0.84 -21.4,6.62 l -21,36.44 a 6.09,6.09 0 0 1 -6,3.09 h -0.12 a 8.19,8.19 0 0 1 -6.8,-8.18 V 103.60999 a 16,16 0 0 0 -16.77,-16 c -8.61,0.4 -15.23,7.82 -15.23,16.43 V 167.61 a 8,8 0 0 1 -8.53,8 8.17,8.17 0 0 1 -7.47,-8.25 V 87.60999 A 16,16 0 0 0 93.309986,71.609992 c -8.609997,0.4 -15.229997,7.819999 -15.229997,16.429998 V 175.61 a 8,8 0 0 1 -8.53,8 8.17,8.17 0 0 1 -7.47,-8.25 v -55.30001 c 0,-8.61 -6.62,-16 -15.23,-16.43 a 16,16 0 0 0 -16.77,15.98"
|
||||||
|
id="path1" />
|
||||||
|
<path
|
||||||
|
d="m 301.74274,111.50919 q 27.32551,0 40.26918,10.4782 13.14912,10.27275 13.14912,31.22916 0,11.71094 -4.31456,19.51824 -4.31455,7.80729 -11.09457,12.53275 -6.57456,4.52001 -13.97094,7.19093 l 40.26918,65.7456 h -21.57277 l -35.54372,-60.60923 h -29.17461 v 60.60923 H 261.2681 V 111.50919 Z m -1.02728,16.02549 h -20.95641 v 54.44558 h 21.98369 q 17.87458,0 26.09278,-6.98547 8.2182,-7.19092 8.2182,-20.95642 0,-14.38185 -8.62911,-20.34004 -8.62911,-6.16365 -26.70915,-6.16365 z"
|
||||||
|
id="text1"
|
||||||
|
fill="currentColor"
|
||||||
|
aria-label="R" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
|
|
@ -8,16 +8,16 @@
|
||||||
border_color="#FFFFFF66"
|
border_color="#FFFFFF66"
|
||||||
justify_content="space_between" />
|
justify_content="space_between" />
|
||||||
|
|
||||||
<!-- id, text, translation, tooltip -->
|
<!-- id, text, translation, tooltip, min_width -->
|
||||||
<template name="DropdownButton">
|
<template name="DropdownButton">
|
||||||
<label text="${text}" translation="${translation}" />
|
<label text="${text}" translation="${translation}" />
|
||||||
<Button id="${id}" height="32" tooltip="${tooltip}" >
|
<Button id="${id}" height="32" tooltip="${tooltip}" >
|
||||||
<div padding_left="8" padding_right="8" min_width="200">
|
<div padding_left="8" padding_right="8" min_width="${min_width}">
|
||||||
<label id="${id}_value" weight="bold" />
|
<label id="${id}_value" weight="bold" />
|
||||||
</div>
|
</div>
|
||||||
<div gap="2">
|
<div gap="2">
|
||||||
<div padding_top="4" padding_bottom="4">
|
<div padding_top="4" padding_bottom="4">
|
||||||
<rectangle width="2" height="100%" color="#FFFFFF66" />
|
<rectangle width="2" height="100%" color="#FFFFFF1A" />
|
||||||
</div>
|
</div>
|
||||||
<sprite margin_left="-4" width="30" height="30" color="~color_text" src_builtin="dashboard/down.svg" />
|
<sprite margin_left="-4" width="30" height="30" color="~color_text" src_builtin="dashboard/down.svg" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,30 @@
|
||||||
<layout>
|
<layout>
|
||||||
|
<include src="../t_group_box.xml" />
|
||||||
|
|
||||||
|
<!-- used at runtime [!!!] -->
|
||||||
<include src="../t_dropdown_button.xml" />
|
<include src="../t_dropdown_button.xml" />
|
||||||
|
|
||||||
<!-- id, translation -->
|
<!-- id, translation -->
|
||||||
<template name="ActionRow">
|
<template name="ActionRow">
|
||||||
<div id="${id}" flex_direction="column" gap="4" width="100%" padding="6" round="6" color="#00000044" border="1" border_color="#FFFFFF33">
|
<rectangle macro="group_box" id="${id}">
|
||||||
<label translation="${translation}" weight="bold" size="14" />
|
<!-- top row -->
|
||||||
</div>
|
<div flex_direction="row" gap="8" align_items="center">
|
||||||
|
<sprite src_builtin="dashboard/controller.svg" width="24" height="24"/>
|
||||||
|
<label translation="${translation}" color="~color_accent" weight="bold" size="14" />
|
||||||
|
</div>
|
||||||
|
<!-- filled-in at runtime -->
|
||||||
|
</rectangle>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<div flex_direction="column" gap="8" width="100%" align_items="center">
|
<div flex_direction="column" gap="8" width="100%">
|
||||||
<label id="controller_type" text="OpenXR Bindings" weight="bold" size="18" />
|
<div flex_direction="column" gap="8" align_items="center" overflow_y="scroll" width="100%" padding="16">
|
||||||
<div id="list_parent" flex_direction="column" gap="6" width="100%"></div>
|
<div id="list_parent" flex_direction="column" gap="6" width="100%"></div>
|
||||||
<div flex_direction="row" gap="4" align_self="end">
|
|
||||||
<Button id="btn_save" height="32" translation="APP_SETTINGS.SAVE" />
|
|
||||||
<Button id="btn_cancel" height="32" translation="APP_SETTINGS.CANCEL" />
|
|
||||||
</div>
|
</div>
|
||||||
|
<rectangle color="#000000cc" flex_direction="row" gap="8" justify_content="end" padding="8">
|
||||||
|
<Button id="btn_cancel" sprite_src_builtin="dashboard/cancel.svg" min_width="100" height="32" translation="APP_SETTINGS.CANCEL" />
|
||||||
|
<Button id="btn_save" sprite_src_builtin="dashboard/check.svg" min_width="100" height="32" translation="APP_SETTINGS.SAVE" />
|
||||||
|
</rectangle>
|
||||||
</div>
|
</div>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@
|
||||||
gradient="vertical"
|
gradient="vertical"
|
||||||
position="relative"
|
position="relative"
|
||||||
>
|
>
|
||||||
<div id="content" padding="16" width="100%" height="100%" position="absolute" overflow_y="scroll">
|
<div id="content" width="100%" height="100%" position="absolute" overflow_y="scroll">
|
||||||
|
<!-- Padding set at runtime -->
|
||||||
<!-- Content, filled-in at runtime -->
|
<!-- Content, filled-in at runtime -->
|
||||||
</div>
|
</div>
|
||||||
</rectangle>
|
</rectangle>
|
||||||
|
|
|
||||||
|
|
@ -80,12 +80,18 @@ fn create_input_profiles_button(
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn mount(par: SettingsMountParams) -> anyhow::Result<State> {
|
pub fn mount(par: SettingsMountParams) -> anyhow::Result<State> {
|
||||||
|
let tasks = Tasks::<Task>::new();
|
||||||
|
let popup = PopupHolder::<input_profiles::View>::default();
|
||||||
|
|
||||||
let c = options_category(
|
let c = options_category(
|
||||||
par.mp,
|
par.mp,
|
||||||
par.id_parent,
|
par.id_parent,
|
||||||
"APP_SETTINGS.CONTROLS",
|
"APP_SETTINGS.CONTROLS",
|
||||||
"dashboard/controller.svg",
|
"dashboard/controller.svg",
|
||||||
)?;
|
)?;
|
||||||
|
if par.feats.openxr {
|
||||||
|
create_input_profiles_button(par.mp, c, tasks.clone(), &popup)?;
|
||||||
|
}
|
||||||
options_dropdown::<wlx_common::config::AltModifier>(par.mp, c, &SettingType::KeyboardMiddleClick)?;
|
options_dropdown::<wlx_common::config::AltModifier>(par.mp, c, &SettingType::KeyboardMiddleClick)?;
|
||||||
options_dropdown::<wlx_common::config::HandsfreePointer>(par.mp, c, &SettingType::HandsfreePointer)?;
|
options_dropdown::<wlx_common::config::HandsfreePointer>(par.mp, c, &SettingType::HandsfreePointer)?;
|
||||||
options_checkbox(par.mp, c, SettingType::FocusFollowsMouseMode)?;
|
options_checkbox(par.mp, c, SettingType::FocusFollowsMouseMode)?;
|
||||||
|
|
@ -111,13 +117,6 @@ impl State {
|
||||||
|
|
||||||
options_slider_i32(par.mp, c, SettingType::ClickFreezeTimeMs, 0, 500, 50)?;
|
options_slider_i32(par.mp, c, SettingType::ClickFreezeTimeMs, 0, 500, 50)?;
|
||||||
|
|
||||||
let tasks = Tasks::<Task>::new();
|
|
||||||
let popup = PopupHolder::<input_profiles::View>::default();
|
|
||||||
|
|
||||||
if par.feats.openxr {
|
|
||||||
create_input_profiles_button(par.mp, c, tasks.clone(), &popup)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(State {
|
Ok(State {
|
||||||
popup_input_profiles: popup,
|
popup_input_profiles: popup,
|
||||||
frontend_tasks: par.frontend_tasks.clone(),
|
frontend_tasks: par.frontend_tasks.clone(),
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,12 @@ use std::{
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::button::ComponentButton,
|
components::button::ComponentButton,
|
||||||
event::EventAlterables,
|
event::{EventAlterables, StyleSetRequest},
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{Layout, LayoutTask, LayoutTasks, WidgetID},
|
layout::{Layout, LayoutTask, LayoutTasks, WidgetID},
|
||||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
|
taffy::Rect,
|
||||||
widget::label::WidgetLabel,
|
widget::label::WidgetLabel,
|
||||||
};
|
};
|
||||||
use wlx_common::config::GeneralConfig;
|
use wlx_common::config::GeneralConfig;
|
||||||
|
|
@ -187,19 +188,33 @@ pub struct PopupContentFuncData<'a> {
|
||||||
type PopupClosedCallback = Box<dyn FnOnce()>;
|
type PopupClosedCallback = Box<dyn FnOnce()>;
|
||||||
type OnContentCallback = Box<dyn FnOnce(PopupContentFuncData) -> anyhow::Result<PopupClosedCallback>>;
|
type OnContentCallback = Box<dyn FnOnce(PopupContentFuncData) -> anyhow::Result<PopupClosedCallback>>;
|
||||||
|
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
pub enum PopupPadding {
|
||||||
|
#[default]
|
||||||
|
Normal,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub struct MountPopupOnceParamsExtra {
|
||||||
|
pub padding: PopupPadding,
|
||||||
|
}
|
||||||
|
|
||||||
// we need to implement Clone here, but the underlying function can be called only once.
|
// we need to implement Clone here, but the underlying function can be called only once.
|
||||||
// on_content will be cleared after the first call
|
// on_content will be cleared after the first call
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MountPopupOnceParams {
|
pub struct MountPopupOnceParams {
|
||||||
title: Translation,
|
title: Translation,
|
||||||
on_content: Rc<RefCell<Option<OnContentCallback>>>,
|
on_content: Rc<RefCell<Option<OnContentCallback>>>,
|
||||||
|
extra: MountPopupOnceParamsExtra,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MountPopupOnceParams {
|
impl MountPopupOnceParams {
|
||||||
pub fn new(title: Translation, on_content: OnContentCallback) -> Self {
|
pub fn new(title: Translation, on_content: OnContentCallback, extra: MountPopupOnceParamsExtra) -> Self {
|
||||||
Self {
|
Self {
|
||||||
title,
|
title,
|
||||||
on_content: Rc::new(RefCell::new(Some(on_content))),
|
on_content: Rc::new(RefCell::new(Some(on_content))),
|
||||||
|
extra,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -257,6 +272,7 @@ impl PopupManager {
|
||||||
layout: &mut Layout,
|
layout: &mut Layout,
|
||||||
frontend_tasks: &FrontendTasks,
|
frontend_tasks: &FrontendTasks,
|
||||||
popup_title: &Translation,
|
popup_title: &Translation,
|
||||||
|
popup_padding: PopupPadding,
|
||||||
) -> anyhow::Result<(PopupHandle, WidgetID /* content widget ID */)> {
|
) -> anyhow::Result<(PopupHandle, WidgetID /* content widget ID */)> {
|
||||||
let doc_params = &ParseDocumentParams {
|
let doc_params = &ParseDocumentParams {
|
||||||
globals: globals.clone(),
|
globals: globals.clone(),
|
||||||
|
|
@ -268,6 +284,16 @@ impl PopupManager {
|
||||||
let id_root = state.get_widget_id("root")?;
|
let id_root = state.get_widget_id("root")?;
|
||||||
let id_content = state.get_widget_id("content")?;
|
let id_content = state.get_widget_id("content")?;
|
||||||
|
|
||||||
|
let padding = match popup_padding {
|
||||||
|
PopupPadding::Normal => 16.0,
|
||||||
|
PopupPadding::None => 0.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
layout.tasks.push(LayoutTask::SetWidgetStyle(
|
||||||
|
id_content,
|
||||||
|
StyleSetRequest::Padding(Rect::length(padding)),
|
||||||
|
));
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut label_title = state.fetch_widget_as::<WidgetLabel>(&layout.state, "popup_title")?;
|
let mut label_title = state.fetch_widget_as::<WidgetLabel>(&layout.state, "popup_title")?;
|
||||||
label_title.set_text_simple(&mut globals.get(), popup_title.clone());
|
label_title.set_text_simple(&mut globals.get(), popup_title.clone());
|
||||||
|
|
@ -330,7 +356,8 @@ impl PopupManager {
|
||||||
anyhow::bail!("mount_popup_once called more than once");
|
anyhow::bail!("mount_popup_once called more than once");
|
||||||
};
|
};
|
||||||
|
|
||||||
let (popup_handle, id_content) = self.mount_popup_prepare(globals, layout, frontend_tasks, ¶ms.title)?;
|
let (popup_handle, id_content) =
|
||||||
|
self.mount_popup_prepare(globals, layout, frontend_tasks, ¶ms.title, params.extra.padding)?;
|
||||||
|
|
||||||
// mount user-set popup content
|
// mount user-set popup content
|
||||||
let closed_callback = on_content_func(PopupContentFuncData {
|
let closed_callback = on_content_func(PopupContentFuncData {
|
||||||
|
|
|
||||||
|
|
@ -453,5 +453,6 @@ pub fn mount_popup(frontend_tasks: FrontendTasks, globals: WguiGlobals, entry: D
|
||||||
popup.set_view(data.handle, view, None);
|
popup.set_view(data.handle, view, None);
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
Default::default(), /* extra */
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{borrow::Cow, collections::HashMap, rc::Rc};
|
use std::{borrow::Cow, collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
|
use glam::Vec2;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::button::{ButtonClickEvent, ComponentButton},
|
components::button::{ButtonClickEvent, ComponentButton},
|
||||||
|
|
@ -22,7 +23,8 @@ use crate::{
|
||||||
tab::settings::horiz_cell,
|
tab::settings::horiz_cell,
|
||||||
util::{
|
util::{
|
||||||
openxr_bindings_schema::{ClickType, Component, IdentifierType, ParsedOpenXrInputPath, Profile, Side},
|
openxr_bindings_schema::{ClickType, Component, IdentifierType, ParsedOpenXrInputPath, Profile, Side},
|
||||||
popup_manager::{MountPopupOnceParams, PopupHolder},
|
popup_manager::{MountPopupOnceParams, MountPopupOnceParamsExtra, PopupHolder, PopupPadding},
|
||||||
|
wgui_simple,
|
||||||
},
|
},
|
||||||
views::{ViewTrait, ViewUpdateParams},
|
views::{ViewTrait, ViewUpdateParams},
|
||||||
};
|
};
|
||||||
|
|
@ -85,7 +87,7 @@ impl ViewTrait for View {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dropdown handling
|
// Dropdown handling
|
||||||
if let TickResult::Action(name) = self.context_menu.tick(&mut par.layout, &mut self.parser_state)?
|
if let TickResult::Action(name) = self.context_menu.tick(par.layout, &mut self.parser_state)?
|
||||||
&& let (Some(action), Some(_), Some(action_name), Some(side), Some(value)) = {
|
&& let (Some(action), Some(_), Some(action_name), Some(side), Some(value)) = {
|
||||||
let mut s = name.splitn(5, ';');
|
let mut s = name.splitn(5, ';');
|
||||||
(s.next(), s.next(), s.next(), s.next(), s.next())
|
(s.next(), s.next(), s.next(), s.next(), s.next())
|
||||||
|
|
@ -95,8 +97,8 @@ impl ViewTrait for View {
|
||||||
|
|
||||||
log::warn!("{action_name}");
|
log::warn!("{action_name}");
|
||||||
|
|
||||||
let mut cur_profile = &mut self.profiles[self.cur_profile_idx];
|
let cur_profile = &mut self.profiles[self.cur_profile_idx];
|
||||||
let action_mut = get_action_mut(&mut cur_profile, action_name);
|
let action_mut = get_action_mut(cur_profile, action_name);
|
||||||
let side_mut = if side == "right" {
|
let side_mut = if side == "right" {
|
||||||
&mut action_mut.right
|
&mut action_mut.right
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -163,14 +165,6 @@ impl View {
|
||||||
let list_parent = parser_state.fetch_widget(¶ms.layout.state, "list_parent")?.id;
|
let list_parent = parser_state.fetch_widget(¶ms.layout.state, "list_parent")?.id;
|
||||||
let tasks = Tasks::new();
|
let tasks = Tasks::new();
|
||||||
|
|
||||||
{
|
|
||||||
let mut title_label = parser_state.fetch_widget_as::<WidgetLabel>(¶ms.layout.state, "controller_type")?;
|
|
||||||
title_label.set_text_simple(
|
|
||||||
&mut params.globals.get(),
|
|
||||||
Translation::from_raw_text_rc(params.profile.title.clone()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.handle_button(
|
tasks.handle_button(
|
||||||
&parser_state.fetch_component_as::<ComponentButton>("btn_save")?,
|
&parser_state.fetch_component_as::<ComponentButton>("btn_save")?,
|
||||||
Task::Save,
|
Task::Save,
|
||||||
|
|
@ -267,7 +261,7 @@ pub fn mount_popup(
|
||||||
frontend_tasks
|
frontend_tasks
|
||||||
.clone()
|
.clone()
|
||||||
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
||||||
Translation::from_translation_key("APP_SETTINGS.INPUT_PROFILES"),
|
Translation::from_raw_text_rc(profile.title.clone()),
|
||||||
Box::new(move |data| {
|
Box::new(move |data| {
|
||||||
let close_callback = popup.get_close_callback(data.layout);
|
let close_callback = popup.get_close_callback(data.layout);
|
||||||
let view = View::new(Params {
|
let view = View::new(Params {
|
||||||
|
|
@ -282,6 +276,9 @@ pub fn mount_popup(
|
||||||
popup.set_view(data.handle, view, None);
|
popup.set_view(data.handle, view, None);
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
MountPopupOnceParamsExtra {
|
||||||
|
padding: PopupPadding::None,
|
||||||
|
},
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,16 +364,13 @@ fn input_controls_for_hand(
|
||||||
return Ok(()); // skip
|
return Ok(()); // skip
|
||||||
}
|
}
|
||||||
|
|
||||||
let current = current
|
let current = current.and_then(|cur| ParsedOpenXrInputPath::try_from(cur).log_warn(cur).ok());
|
||||||
.map(|cur| ParsedOpenXrInputPath::try_from(cur).log_warn(cur).ok())
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
let parent = horiz_cell(mp.layout, parent)?;
|
let parent = horiz_cell(mp.layout, parent)?;
|
||||||
|
|
||||||
let available_components = current
|
let available_components = current
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|par| profile.subpaths.get(&par.to_subpath()))
|
.and_then(|par| profile.subpaths.get(&par.to_subpath()))
|
||||||
.flatten()
|
|
||||||
.map(|subp| subp.get_effective_components())
|
.map(|subp| subp.get_effective_components())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
|
@ -387,8 +381,7 @@ fn input_controls_for_hand(
|
||||||
.filter_map(|(key, _)| {
|
.filter_map(|(key, _)| {
|
||||||
key
|
key
|
||||||
.strip_prefix("/input/")
|
.strip_prefix("/input/")
|
||||||
.map(|ident| IdentifierType::try_from(ident).ok())
|
.and_then(|ident| IdentifierType::try_from(ident).ok())
|
||||||
.flatten()
|
|
||||||
})
|
})
|
||||||
.collect::<Rc<[IdentifierType]>>();
|
.collect::<Rc<[IdentifierType]>>();
|
||||||
|
|
||||||
|
|
@ -430,11 +423,16 @@ fn subpath_dropdown(
|
||||||
|
|
||||||
let mut params: HashMap<Rc<str>, Rc<str>> = HashMap::new();
|
let mut params: HashMap<Rc<str>, Rc<str>> = HashMap::new();
|
||||||
params.insert(Rc::from("id"), Rc::from(id.as_ref()));
|
params.insert(Rc::from("id"), Rc::from(id.as_ref()));
|
||||||
params.insert(
|
|
||||||
Rc::from("translation"),
|
|
||||||
Rc::from(format!("APP_SETTINGS.BINDINGS.{}", side.as_ref().to_uppercase())),
|
|
||||||
);
|
|
||||||
params.insert(Rc::from("tooltip"), Rc::from("APP_SETTINGS.BINDINGS.SUBPATH"));
|
params.insert(Rc::from("tooltip"), Rc::from("APP_SETTINGS.BINDINGS.SUBPATH"));
|
||||||
|
params.insert(Rc::from("min_width"), Rc::from("100"));
|
||||||
|
|
||||||
|
// left/right hand icon
|
||||||
|
wgui_simple::create_icon(
|
||||||
|
mp.layout,
|
||||||
|
parent,
|
||||||
|
Vec2::new(32.0, 32.0),
|
||||||
|
AssetPath::BuiltIn(&format!("dashboard/hand_{}.svg", side.as_ref().to_lowercase())),
|
||||||
|
)?;
|
||||||
|
|
||||||
mp.parser_state
|
mp.parser_state
|
||||||
.instantiate_template(mp.doc_params, "DropdownButton", mp.layout, parent, params)?;
|
.instantiate_template(mp.doc_params, "DropdownButton", mp.layout, parent, params)?;
|
||||||
|
|
@ -508,6 +506,7 @@ fn component_dropdown(
|
||||||
params.insert(Rc::from("id"), Rc::from(id.as_ref()));
|
params.insert(Rc::from("id"), Rc::from(id.as_ref()));
|
||||||
params.insert(Rc::from("text"), Rc::from("・"));
|
params.insert(Rc::from("text"), Rc::from("・"));
|
||||||
params.insert(Rc::from("tooltip"), Rc::from("APP_SETTINGS.BINDINGS.COMPONENT"));
|
params.insert(Rc::from("tooltip"), Rc::from("APP_SETTINGS.BINDINGS.COMPONENT"));
|
||||||
|
params.insert(Rc::from("min_width"), Rc::from("100"));
|
||||||
|
|
||||||
mp.parser_state
|
mp.parser_state
|
||||||
.instantiate_template(mp.doc_params, "DropdownButton", mp.layout, parent, params)?;
|
.instantiate_template(mp.doc_params, "DropdownButton", mp.layout, parent, params)?;
|
||||||
|
|
@ -561,6 +560,7 @@ fn clicks_dropdown(mp: &mut MacroParams, parent: WidgetID, action: Rc<str>, curr
|
||||||
params.insert(Rc::from("id"), Rc::from(id.as_ref()));
|
params.insert(Rc::from("id"), Rc::from(id.as_ref()));
|
||||||
params.insert(Rc::from("text"), Rc::from("・"));
|
params.insert(Rc::from("text"), Rc::from("・"));
|
||||||
params.insert(Rc::from("tooltip"), Rc::from("APP_SETTINGS.BINDINGS.CLICK.TYPE"));
|
params.insert(Rc::from("tooltip"), Rc::from("APP_SETTINGS.BINDINGS.CLICK.TYPE"));
|
||||||
|
params.insert(Rc::from("min_width"), Rc::from("100"));
|
||||||
|
|
||||||
mp.parser_state
|
mp.parser_state
|
||||||
.instantiate_template(mp.doc_params, "DropdownButton", mp.layout, parent, params)?;
|
.instantiate_template(mp.doc_params, "DropdownButton", mp.layout, parent, params)?;
|
||||||
|
|
|
||||||
|
|
@ -123,5 +123,6 @@ pub fn mount_popup(popup: PopupHolder<View>, frontend_tasks: FrontendTasks, para
|
||||||
popup.set_view(data.handle, view, None);
|
popup.set_view(data.handle, view, None);
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
Default::default(), /* extra */
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -261,5 +261,6 @@ pub fn mount_popup(
|
||||||
popup.set_view(data.handle, view, Some(on_view_close));
|
popup.set_view(data.handle, view, Some(on_view_close));
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
Default::default(), /* extra */
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -224,5 +224,6 @@ pub fn mount_popup(
|
||||||
popup.set_view(data.handle, view, None);
|
popup.set_view(data.handle, view, None);
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
Default::default(), /* extra */
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,5 +136,6 @@ pub fn mount_popup(frontend_tasks: FrontendTasks, globals: WguiGlobals, popup: P
|
||||||
popup.set_view(data.handle, view, None);
|
popup.set_view(data.handle, view, None);
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
Default::default(), /* extra */
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -393,5 +393,6 @@ pub fn mount_popup(
|
||||||
popup.set_view(data.handle, view, None);
|
popup.set_view(data.handle, view, None);
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
Default::default(), /* extra */
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -297,5 +297,6 @@ pub fn mount_popup(
|
||||||
popup.set_view(data.handle, view, None);
|
popup.set_view(data.handle, view, None);
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
Default::default(), /* extra */
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -265,5 +265,6 @@ pub fn mount_popup(frontend_tasks: FrontendTasks, globals: WguiGlobals, popup: P
|
||||||
popup.set_view(data.handle, view, None);
|
popup.set_view(data.handle, view, None);
|
||||||
Ok(popup.get_close_callback(data.layout))
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
|
Default::default(), /* extra */
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,7 @@ impl Event {
|
||||||
pub enum StyleSetRequest {
|
pub enum StyleSetRequest {
|
||||||
Display(taffy::Display),
|
Display(taffy::Display),
|
||||||
Margin(taffy::Rect<taffy::LengthPercentageAuto>),
|
Margin(taffy::Rect<taffy::LengthPercentageAuto>),
|
||||||
|
Padding(taffy::Rect<taffy::LengthPercentage>),
|
||||||
Width(taffy::Dimension),
|
Width(taffy::Dimension),
|
||||||
Height(taffy::Dimension),
|
Height(taffy::Dimension),
|
||||||
Size(taffy::Size<taffy::Dimension>),
|
Size(taffy::Size<taffy::Dimension>),
|
||||||
|
|
|
||||||
|
|
@ -817,6 +817,9 @@ impl Layout {
|
||||||
event::StyleSetRequest::Margin(margin) => {
|
event::StyleSetRequest::Margin(margin) => {
|
||||||
cur_style.margin = *margin;
|
cur_style.margin = *margin;
|
||||||
}
|
}
|
||||||
|
event::StyleSetRequest::Padding(padding) => {
|
||||||
|
cur_style.padding = *padding;
|
||||||
|
}
|
||||||
event::StyleSetRequest::Width(val) => {
|
event::StyleSetRequest::Width(val) => {
|
||||||
cur_style.size.width = *val;
|
cur_style.size.width = *val;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue