edit overlay design
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
use taffy::{
|
use taffy::{
|
||||||
AlignItems, JustifyContent,
|
|
||||||
prelude::{length, percent},
|
prelude::{length, percent},
|
||||||
|
AlignItems, JustifyContent,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -13,10 +13,10 @@ use crate::{
|
|||||||
layout::{self, WidgetID, WidgetPair},
|
layout::{self, WidgetID, WidgetPair},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
widget::{
|
widget::{
|
||||||
ConstructEssentials, EventResult,
|
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
|
ConstructEssentials, EventResult,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ use crate::{
|
|||||||
util,
|
util,
|
||||||
},
|
},
|
||||||
widget::{
|
widget::{
|
||||||
ConstructEssentials, EventResult,
|
|
||||||
div::WidgetDiv,
|
div::WidgetDiv,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
|
ConstructEssentials, EventResult,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,6 +50,7 @@ struct State {
|
|||||||
dragging: bool,
|
dragging: bool,
|
||||||
hovered: bool,
|
hovered: bool,
|
||||||
values: ValuesMinMax,
|
values: ValuesMinMax,
|
||||||
|
on_value_changed: Option<SliderValueChangedCallback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
@@ -61,6 +62,13 @@ struct Data {
|
|||||||
slider_body_node: taffy::NodeId,
|
slider_body_node: taffy::NodeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SliderValueChangedEvent {
|
||||||
|
pub value: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type SliderValueChangedCallback =
|
||||||
|
Box<dyn Fn(&mut CallbackDataCommon, SliderValueChangedEvent) -> anyhow::Result<()>>;
|
||||||
|
|
||||||
pub struct ComponentSlider {
|
pub struct ComponentSlider {
|
||||||
base: ComponentBase,
|
base: ComponentBase,
|
||||||
data: Rc<Data>,
|
data: Rc<Data>,
|
||||||
@@ -79,6 +87,20 @@ impl ComponentTrait for ComponentSlider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ComponentSlider {
|
||||||
|
pub fn get_value(&self) -> f32 {
|
||||||
|
self.state.borrow().values.value
|
||||||
|
}
|
||||||
|
pub fn set_value(&mut self, common: &mut CallbackDataCommon, value: f32) {
|
||||||
|
let mut state = self.state.borrow_mut();
|
||||||
|
state.set_value(common, &self.data, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_value_changed(&self, func: SliderValueChangedCallback) {
|
||||||
|
self.state.borrow_mut().on_value_changed = Some(func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTICE: this can be re-used in the future
|
// NOTICE: this can be re-used in the future
|
||||||
fn map_mouse_x_to_normalized(mouse_x_rel: f32, widget_width: f32) -> f32 {
|
fn map_mouse_x_to_normalized(mouse_x_rel: f32, widget_width: f32) -> f32 {
|
||||||
(mouse_x_rel / widget_width).clamp(0.0, 1.0)
|
(mouse_x_rel / widget_width).clamp(0.0, 1.0)
|
||||||
@@ -137,6 +159,9 @@ impl State {
|
|||||||
|
|
||||||
fn set_value(&mut self, common: &mut CallbackDataCommon, data: &Data, value: f32) {
|
fn set_value(&mut self, common: &mut CallbackDataCommon, data: &Data, value: f32) {
|
||||||
//common.call_on_widget(data.slider_handle_id, |_div: &mut Div| {});
|
//common.call_on_widget(data.slider_handle_id, |_div: &mut Div| {});
|
||||||
|
|
||||||
|
let changed = (self.values.value - value).abs() > f32::EPSILON;
|
||||||
|
|
||||||
self.values.value = value;
|
self.values.value = value;
|
||||||
let mut style = common.state.tree.style(data.slider_handle_node).unwrap().clone();
|
let mut style = common.state.tree.style(data.slider_handle_node).unwrap().clone();
|
||||||
conf_handle_style(&self.values, data.slider_body_node, &mut style, &common.state.tree);
|
conf_handle_style(&self.values, data.slider_body_node, &mut style, &common.state.tree);
|
||||||
@@ -147,6 +172,12 @@ impl State {
|
|||||||
if let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(data.slider_text_id) {
|
if let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(data.slider_text_id) {
|
||||||
Self::update_text(common, &mut label, value);
|
Self::update_text(common, &mut label, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if changed && let Some(on_value_changed) = &self.on_value_changed {
|
||||||
|
if let Err(e) = on_value_changed(common, SliderValueChangedEvent { value }) {
|
||||||
|
log::error!("{e:?}"); // FIXME: proper error handling
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,6 +393,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
dragging: false,
|
dragging: false,
|
||||||
hovered: false,
|
hovered: false,
|
||||||
values: params.values,
|
values: params.values,
|
||||||
|
on_value_changed: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let globals = ess.layout.state.globals.clone();
|
let globals = ess.layout.state.globals.clone();
|
||||||
|
|||||||
@@ -4,40 +4,54 @@
|
|||||||
<var key="tint_color" value="#0044CC99" />
|
<var key="tint_color" value="#0044CC99" />
|
||||||
</theme>
|
</theme>
|
||||||
|
|
||||||
<template name="TopButton">
|
|
||||||
<rectangle id="~id" color="~bg_color" padding="8" round="50%">
|
|
||||||
<sprite color="~device_color" width="48" height="48" src="${src}" />
|
|
||||||
</rectangle>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<macro name="button_style"
|
<macro name="button_style"
|
||||||
margin="2" overflow="hidden" box_sizing="border_box" align_items="center" justify_content="center"
|
margin="2" overflow="hidden" box_sizing="border_box" align_items="center" justify_content="center"
|
||||||
border_color="#0044CC" border="2" round="8" color="#000A1C" color2="#000002" gradient="vertical" />
|
border="2" round="50%" padding="8" gradient="vertical" tooltip_side="bottom" />
|
||||||
|
|
||||||
|
<template name="TopButton">
|
||||||
|
<Button id="${id}" macro="button_style" tooltip="${tooltip}" _press="${press}" border_color="#0044CC" color="#000A1C" color2="#000002" >
|
||||||
|
<sprite color="~device_color" width="48" height="48" src="${src}" />
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="TopButtonDanger">
|
||||||
|
<Button id="${id}" macro="button_style" tooltip="${tooltip}" _press="${press}" border_color="#CC0000" color="#110000" color2="#020000" >
|
||||||
|
<sprite color="~device_color" width="48" height="48" src="${src}" />
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="TopButtonFaded">
|
||||||
|
<Button id="${id}" macro="button_style" tooltip="${tooltip}" _press="${press}" border_color="#707070" color="#202020" color2="#010101" >
|
||||||
|
<sprite color="~device_color" width="48" height="48" src="${src}" />
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<div width="100%" height="100%">
|
<div width="100%" height="100%">
|
||||||
<rectangle width="100%" height="100%" padding="4" gap="4" align_items="center" justify_content="center" color="#000000DD" flex_direction="row">
|
<rectangle width="100%" height="100%" padding="4" gap="4" align_items="center" justify_content="center" color="#000000DD" flex_direction="row">
|
||||||
<div></div>
|
|
||||||
<div flex_direction="column">
|
<div flex_direction="column">
|
||||||
<div></div>
|
<rectangle padding="20" gap="8" round="100%" color="~bg_color" justify_content="center" >
|
||||||
<rectangle padding="10" gap="8" round="100%" color="~bg_color" justify_content="center" >
|
<div flex_direction="column" gap="8">
|
||||||
<TopButton id="lock" src="bar/lock_open.svg" />
|
<label align="center" translation="Point on a window to change its parameters.
Once done, leave edit mode using the button on the right." />
|
||||||
<TopButton id="anchor" src="bar/anchor.svg" />
|
<div flex_direction="row" gap="4">
|
||||||
<TopButton id="mouse" src="bar/mouse.svg" />
|
<TopButton id="lock" src="bar/lock_open.svg" tooltip="Lock interaction" kind="btn_primary" />
|
||||||
<TopButton id="fade" src="bar/fade.svg" />
|
<TopButton id="anchor" src="bar/anchor.svg" tooltip="Positioning" kind="btn_primary" />
|
||||||
<TopButton id="move" src="bar/move-all.svg" />
|
<TopButton id="fade" src="bar/fade.svg" tooltip="Opacity" kind="btn_primary" />
|
||||||
<TopButton id="resize" src="bar/resize.svg" />
|
<TopButton id="move" src="bar/move-all.svg" tooltip="Move (click & drag)" kind="btn_primary" />
|
||||||
<TopButton id="inout" src="bar/inout.svg" />
|
<TopButton id="resize" src="bar/resize.svg" tooltip="Resize (click & drag)" kind="btn_primary" />
|
||||||
<TopButton id="delete" src="bar/delete.svg" />
|
<TopButton id="inout" src="bar/inout.svg" tooltip="Adjust distance (click & drag)" kind="btn_primary" />
|
||||||
</rectangle>
|
<TopButtonDanger id="delete" src="bar/delete.svg" tooltip="Delete" kind="btn_danger" />
|
||||||
<rectangle padding="8" gap="8" round="100%" color="~bg_color_active" justify_content="center" align_items="center">
|
<div width="8" height="100%" />
|
||||||
<label text="range 10-20 value 15" />
|
<TopButtonFaded src="watch/edit.svg" tooltip="Leave edit mode" press="::EditToggle" kind="btn_faded" />
|
||||||
<Slider width="200" height="16" min_value="10" max_value="20" value="15" />
|
</div>
|
||||||
<CheckBox id="test0" text="AM/PM clock" />
|
<div padding="8" gap="8" justify_content="center" align_items="center">
|
||||||
</rectangle>
|
<label translation="Opacity" />
|
||||||
<div></div>
|
<Slider width="200" height="16" min_value="5" max_value="100" value="100" />
|
||||||
|
<CheckBox id="additive" translation="Additive" tooltip="Alpha blend mode" tooltip_side="bottom" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div></div>
|
</rectangle>
|
||||||
|
</div>
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</div>
|
</div>
|
||||||
</elements>
|
</elements>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::{collections::VecDeque, time::Instant};
|
|||||||
|
|
||||||
use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles};
|
use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles};
|
||||||
|
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
use crate::overlays::anchor::ANCHOR_NAME;
|
use crate::overlays::anchor::ANCHOR_NAME;
|
||||||
use crate::state::{AppSession, AppState};
|
use crate::state::{AppSession, AppState};
|
||||||
@@ -521,6 +521,7 @@ where
|
|||||||
let pointer = &mut app.input_state.pointers[pointer_idx];
|
let pointer = &mut app.input_state.pointers[pointer_idx];
|
||||||
let ray_origin = pointer.pose;
|
let ray_origin = pointer.pose;
|
||||||
let mode = pointer.interaction.mode;
|
let mode = pointer.interaction.mode;
|
||||||
|
let edit_mode = overlays.get_edit_mode();
|
||||||
|
|
||||||
let mut hits: SmallVec<[RayHit; 8]> = smallvec!();
|
let mut hits: SmallVec<[RayHit; 8]> = smallvec!();
|
||||||
|
|
||||||
@@ -528,7 +529,7 @@ where
|
|||||||
let Some(overlay_state) = overlay.config.active_state.as_ref() else {
|
let Some(overlay_state) = overlay.config.active_state.as_ref() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if !overlay_state.interactable {
|
if !overlay_state.interactable && !edit_mode {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ pub(super) fn setup_custom_button<S: 'static>(
|
|||||||
"::WatchHide" => todo!(),
|
"::WatchHide" => todo!(),
|
||||||
"::WatchSwapHand" => todo!(),
|
"::WatchSwapHand" => todo!(),
|
||||||
// TODO
|
// TODO
|
||||||
#[allow(clippy::match_same_arms)]
|
|
||||||
"::EditToggle" => Box::new(move |_common, _data, app, _| {
|
"::EditToggle" => Box::new(move |_common, _data, app, _| {
|
||||||
app.tasks.enqueue(TaskType::ToggleEditMode);
|
app.tasks.enqueue(TaskType::ToggleEditMode);
|
||||||
Ok(EventResult::Consumed)
|
Ok(EventResult::Consumed)
|
||||||
|
|||||||
Reference in New Issue
Block a user