mirror of https://github.com/wayvr-org/wayvr.git
keycaps theming
This commit is contained in:
parent
d311813899
commit
4e9b893304
|
|
@ -6,26 +6,29 @@ use crate::{
|
||||||
panel::{GuiPanel, NewGuiPanelParams, apply_custom_command},
|
panel::{GuiPanel, NewGuiPanelParams, apply_custom_command},
|
||||||
timer::GuiTimer,
|
timer::GuiTimer,
|
||||||
},
|
},
|
||||||
overlays::keyboard::alt_modifier_to_key,
|
overlays::keyboard::{ChildWidget, alt_modifier_to_key},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
subsystem::hid::XkbKeymap,
|
subsystem::hid::XkbKeymap,
|
||||||
windowing::backend::OverlayEventData,
|
windowing::backend::OverlayEventData,
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use glam::{FloatExt, Mat4, Vec2, vec2, vec3};
|
use glam::{FloatExt, Mat4, Vec2, vec2, vec3};
|
||||||
|
use smallvec::{SmallVec, smallvec};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
color::WguiColorName,
|
color::{WguiColor, WguiColorName},
|
||||||
drawing::{self},
|
|
||||||
event::{self, CallbackMetadata, EventListenerKind},
|
event::{self, CallbackMetadata, EventListenerKind},
|
||||||
layout::LayoutUpdateParams,
|
layout::{LayoutUpdateParams, WidgetID},
|
||||||
log::LogErr,
|
log::LogErr,
|
||||||
palette::WguiColorPalette,
|
palette::WguiColorPalette,
|
||||||
parser::{Fetchable, ParseDocumentParams, TemplateParams},
|
parser::{Fetchable, ParseDocumentParams, TemplateParams},
|
||||||
renderer_vk::util,
|
renderer_vk::util,
|
||||||
taffy::{self, prelude::length},
|
taffy::{self, prelude::length},
|
||||||
widget::{EventResult, div::WidgetDiv, rectangle::WidgetRectangle},
|
widget::{
|
||||||
|
EventResult, div::WidgetDiv, label::WidgetLabel, rectangle::WidgetRectangle,
|
||||||
|
sprite::WidgetSprite,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
|
@ -149,6 +152,8 @@ pub(super) fn create_keyboard_panel(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Ok(widget_id) = panel.parser_state.get_widget_id(&my_id) {
|
if let Ok(widget_id) = panel.parser_state.get_widget_id(&my_id) {
|
||||||
|
let (labels, sprites) = find_children(&panel, widget_id);
|
||||||
|
|
||||||
let key_state = {
|
let key_state = {
|
||||||
let rect = panel
|
let rect = panel
|
||||||
.layout
|
.layout
|
||||||
|
|
@ -165,6 +170,8 @@ pub(super) fn create_keyboard_panel(
|
||||||
cur_border_color: rect.params.border_color.into(),
|
cur_border_color: rect.params.border_color.into(),
|
||||||
border: rect.params.border,
|
border: rect.params.border,
|
||||||
drawn_state: false.into(),
|
drawn_state: false.into(),
|
||||||
|
labels,
|
||||||
|
sprites,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -322,6 +329,35 @@ pub(super) fn create_keyboard_panel(
|
||||||
Ok(panel)
|
Ok(panel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_children<S>(
|
||||||
|
panel: &GuiPanel<S>,
|
||||||
|
widget_id: WidgetID,
|
||||||
|
) -> (SmallVec<[ChildWidget; 3]>, SmallVec<[ChildWidget; 1]>) {
|
||||||
|
let mut labels = smallvec![];
|
||||||
|
let mut sprites = smallvec![];
|
||||||
|
|
||||||
|
let mut children = vec![];
|
||||||
|
panel
|
||||||
|
.layout
|
||||||
|
.collect_children_ids_recursive(widget_id, &mut children);
|
||||||
|
|
||||||
|
for (child, _) in children {
|
||||||
|
if let Some(widget) = panel.layout.state.widgets.get_as::<WidgetSprite>(child) {
|
||||||
|
sprites.push(ChildWidget {
|
||||||
|
id: child,
|
||||||
|
base_color: widget.get_color(),
|
||||||
|
});
|
||||||
|
} else if let Some(widget) = panel.layout.state.widgets.get_as::<WidgetLabel>(child) {
|
||||||
|
labels.push(ChildWidget {
|
||||||
|
id: child,
|
||||||
|
base_color: widget.get_color(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(labels, sprites)
|
||||||
|
}
|
||||||
|
|
||||||
const BUTTON_HOVER_SCALE: f32 = 0.1;
|
const BUTTON_HOVER_SCALE: f32 = 0.1;
|
||||||
|
|
||||||
fn get_anim_transform(pos: f32, widget_size: Vec2, width_mult: f32) -> Mat4 {
|
fn get_anim_transform(pos: f32, widget_size: Vec2, width_mult: f32) -> Mat4 {
|
||||||
|
|
@ -334,30 +370,22 @@ fn get_anim_transform(pos: f32, widget_size: Vec2, width_mult: f32) -> Mat4 {
|
||||||
util::centered_matrix(widget_size, &Mat4::from_scale(scale))
|
util::centered_matrix(widget_size, &Mat4::from_scale(scale))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HOVER_COLOR: WguiColor = WguiColorName::Tertiary.to_wgui_color();
|
||||||
|
const HOVER_BORDER_COLOR: WguiColor = WguiColorName::Tertiary.to_wgui_color().mult_rgb(0.5);
|
||||||
|
const HOVER_TEXT_COLOR: WguiColor = WguiColorName::OnTertiary.to_wgui_color();
|
||||||
|
const PRESS_BORDER_COLOR: WguiColor = WguiColorName::Highlight.to_wgui_color();
|
||||||
|
|
||||||
fn set_anim_color(
|
fn set_anim_color(
|
||||||
palette: &WguiColorPalette,
|
palette: &WguiColorPalette,
|
||||||
key_state: &KeyState,
|
key_state: &KeyState,
|
||||||
rect: &mut WidgetRectangle,
|
rect: &mut WidgetRectangle,
|
||||||
pos: f32,
|
pos: f32,
|
||||||
) {
|
) {
|
||||||
// fade to accent color
|
rect.params.color = key_state.color.lerp(palette, &HOVER_COLOR, pos);
|
||||||
rect.params.color = key_state
|
rect.params.color2 = key_state.color2.lerp(palette, &HOVER_COLOR, pos);
|
||||||
.color
|
|
||||||
.lerp(palette, &WguiColorName::Primary.into(), pos);
|
|
||||||
|
|
||||||
// fade to accent color
|
|
||||||
rect.params.color2 = key_state
|
|
||||||
.color2
|
|
||||||
.lerp(palette, &WguiColorName::Primary.into(), pos);
|
|
||||||
|
|
||||||
// fade to white
|
|
||||||
let cur_border_color = key_state.cur_border_color.get();
|
let cur_border_color = key_state.cur_border_color.get();
|
||||||
rect.params.border_color = cur_border_color.lerp(
|
rect.params.border_color = cur_border_color.lerp(palette, &HOVER_BORDER_COLOR, pos);
|
||||||
palette,
|
|
||||||
&drawing::Color::new(1.0, 1.0, 1.0, 1.0).into(),
|
|
||||||
pos,
|
|
||||||
);
|
|
||||||
|
|
||||||
rect.params.border = key_state.border.lerp(key_state.border * 1.5, pos);
|
rect.params.border = key_state.border.lerp(key_state.border * 1.5, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,6 +403,33 @@ fn on_enter_anim(
|
||||||
Box::new(move |common, data| {
|
Box::new(move |common, data| {
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
set_anim_color(&common.globals().palette, &key_state, rect, data.pos);
|
set_anim_color(&common.globals().palette, &key_state, rect, data.pos);
|
||||||
|
|
||||||
|
for child in key_state.labels.iter() {
|
||||||
|
let mut widget = common
|
||||||
|
.state
|
||||||
|
.widgets
|
||||||
|
.get_as::<WidgetLabel>(child.id)
|
||||||
|
.unwrap();
|
||||||
|
let color =
|
||||||
|
child
|
||||||
|
.base_color
|
||||||
|
.lerp(&common.globals().palette, &HOVER_TEXT_COLOR, data.pos);
|
||||||
|
widget.set_color(common, color, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for child in key_state.sprites.iter() {
|
||||||
|
let mut widget = common
|
||||||
|
.state
|
||||||
|
.widgets
|
||||||
|
.get_as::<WidgetSprite>(child.id)
|
||||||
|
.unwrap();
|
||||||
|
let color =
|
||||||
|
child
|
||||||
|
.base_color
|
||||||
|
.lerp(&common.globals().palette, &HOVER_TEXT_COLOR, data.pos);
|
||||||
|
widget.set_color(common, color);
|
||||||
|
}
|
||||||
|
|
||||||
data.data.transform =
|
data.data.transform =
|
||||||
get_anim_transform(data.pos, data.widget_boundary.size, width_mult);
|
get_anim_transform(data.pos, data.widget_boundary.size, width_mult);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
|
|
@ -396,6 +451,35 @@ fn on_leave_anim(
|
||||||
Box::new(move |common, data| {
|
Box::new(move |common, data| {
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
set_anim_color(&common.globals().palette, &key_state, rect, 1.0 - data.pos);
|
set_anim_color(&common.globals().palette, &key_state, rect, 1.0 - data.pos);
|
||||||
|
|
||||||
|
for child in key_state.labels.iter() {
|
||||||
|
let color = child.base_color.lerp(
|
||||||
|
&common.globals().palette,
|
||||||
|
&HOVER_TEXT_COLOR,
|
||||||
|
1.0 - data.pos,
|
||||||
|
);
|
||||||
|
let mut widget = common
|
||||||
|
.state
|
||||||
|
.widgets
|
||||||
|
.get_as::<WidgetLabel>(child.id)
|
||||||
|
.unwrap();
|
||||||
|
widget.set_color(common, color, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for child in key_state.sprites.iter() {
|
||||||
|
let color = child.base_color.lerp(
|
||||||
|
&common.globals().palette,
|
||||||
|
&HOVER_TEXT_COLOR,
|
||||||
|
1.0 - data.pos,
|
||||||
|
);
|
||||||
|
let mut widget = common
|
||||||
|
.state
|
||||||
|
.widgets
|
||||||
|
.get_as::<WidgetSprite>(child.id)
|
||||||
|
.unwrap();
|
||||||
|
widget.set_color(common, color);
|
||||||
|
}
|
||||||
|
|
||||||
data.data.transform =
|
data.data.transform =
|
||||||
get_anim_transform(1.0 - data.pos, data.widget_boundary.size, width_mult);
|
get_anim_transform(1.0 - data.pos, data.widget_boundary.size, width_mult);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
|
|
@ -412,9 +496,7 @@ fn on_press_anim(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
key_state
|
key_state.cur_border_color.set(PRESS_BORDER_COLOR);
|
||||||
.cur_border_color
|
|
||||||
.set(drawing::Color::new(1.0, 1.0, 1.0, 1.0).into());
|
|
||||||
rect.params.border_color = key_state.cur_border_color.get();
|
rect.params.border_color = key_state.cur_border_color.get();
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
key_state.drawn_state.set(true);
|
key_state.drawn_state.set(true);
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,11 @@ use anyhow::Context;
|
||||||
use glam::{Affine3A, Quat, Vec3, vec3};
|
use glam::{Affine3A, Quat, Vec3, vec3};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use slotmap::{SlotMap, new_key_type};
|
use slotmap::{SlotMap, new_key_type};
|
||||||
|
use smallvec::SmallVec;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
color::WguiColor,
|
color::WguiColor,
|
||||||
event::{InternalStateChangeEvent, MouseButtonEvent, MouseButtonIndex},
|
event::{InternalStateChangeEvent, MouseButtonEvent, MouseButtonIndex},
|
||||||
|
layout::WidgetID,
|
||||||
};
|
};
|
||||||
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
||||||
use wlx_common::{
|
use wlx_common::{
|
||||||
|
|
@ -355,6 +357,11 @@ fn play_key_click(app: &mut AppState) {
|
||||||
.play_sample(&mut app.audio_system, "key_click");
|
.play_sample(&mut app.audio_system, "key_click");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ChildWidget {
|
||||||
|
id: WidgetID,
|
||||||
|
base_color: WguiColor,
|
||||||
|
}
|
||||||
|
|
||||||
struct KeyState {
|
struct KeyState {
|
||||||
button_state: KeyButtonData,
|
button_state: KeyButtonData,
|
||||||
color: WguiColor,
|
color: WguiColor,
|
||||||
|
|
@ -363,6 +370,8 @@ struct KeyState {
|
||||||
cur_border_color: Cell<WguiColor>,
|
cur_border_color: Cell<WguiColor>,
|
||||||
border: f32,
|
border: f32,
|
||||||
drawn_state: Cell<bool>,
|
drawn_state: Cell<bool>,
|
||||||
|
labels: SmallVec<[ChildWidget; 3]>,
|
||||||
|
sprites: SmallVec<[ChildWidget; 1]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ impl Layout {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_children_ids_recursive(&self, widget_id: WidgetID, out: &mut Vec<(WidgetID, taffy::NodeId)>) {
|
pub fn collect_children_ids_recursive(&self, widget_id: WidgetID, out: &mut Vec<(WidgetID, taffy::NodeId)>) {
|
||||||
let Some(node_id) = self.state.nodes.get(widget_id) else {
|
let Some(node_id) = self.state.nodes.get(widget_id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ pub struct WidgetLabelParams {
|
||||||
pub parent_color: ParentColor,
|
pub parent_color: ParentColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_COLOR: WguiColor = WguiColorName::OnBackground.to_wgui_color();
|
||||||
|
|
||||||
pub struct WidgetLabel {
|
pub struct WidgetLabel {
|
||||||
id: WidgetID,
|
id: WidgetID,
|
||||||
|
|
||||||
|
|
@ -39,7 +41,7 @@ impl WidgetLabel {
|
||||||
|
|
||||||
pub fn create_ex(globals: &mut Globals, mut params: WidgetLabelParams) -> WidgetState {
|
pub fn create_ex(globals: &mut Globals, mut params: WidgetLabelParams) -> WidgetState {
|
||||||
if params.style.color.is_none() {
|
if params.style.color.is_none() {
|
||||||
params.style.color = Some(WguiColorName::OnPrimary.into());
|
params.style.color = Some(DEFAULT_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
let metrics = Metrics::from(¶ms.style);
|
let metrics = Metrics::from(¶ms.style);
|
||||||
|
|
@ -127,6 +129,10 @@ impl WidgetLabel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_color(&self) -> WguiColor {
|
||||||
|
self.params.style.color.unwrap() // create_ex populates this
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parent_color(&self) -> ParentColor {
|
pub fn parent_color(&self) -> ParentColor {
|
||||||
self.params.parent_color
|
self.params.parent_color
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ pub struct WidgetSpriteParams {
|
||||||
pub parent_color: ParentColor,
|
pub parent_color: ParentColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_COLOR: WguiColor = WguiColor::Raw(drawing::Color::from_hex("#ffffff").unwrap());
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct WidgetSprite {
|
pub struct WidgetSprite {
|
||||||
params: WidgetSpriteParams,
|
params: WidgetSpriteParams,
|
||||||
|
|
@ -47,8 +49,8 @@ impl WidgetSprite {
|
||||||
common.mark_widget_dirty(self.id);
|
common.mark_widget_dirty(self.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn get_color(&self) -> Option<WguiColor> {
|
pub fn get_color(&self) -> WguiColor {
|
||||||
self.params.color
|
self.params.color.unwrap_or(DEFAULT_COLOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_content(&mut self, alterables: &mut EventAlterables, content: Option<CustomGlyphData>) {
|
pub fn set_content(&mut self, alterables: &mut EventAlterables, content: Option<CustomGlyphData>) {
|
||||||
|
|
@ -80,9 +82,14 @@ impl WidgetObj for WidgetSprite {
|
||||||
top: 0.0,
|
top: 0.0,
|
||||||
width: boundary.size.x,
|
width: boundary.size.x,
|
||||||
height: boundary.size.y,
|
height: boundary.size.y,
|
||||||
color: Some(self.params.color.map_or(cosmic_text::Color::rgb(255, 255, 255), |c| {
|
color: Some(
|
||||||
c.resolve(&state.globals.palette).into()
|
self
|
||||||
})),
|
.params
|
||||||
|
.color
|
||||||
|
.unwrap_or(DEFAULT_COLOR)
|
||||||
|
.resolve(&state.globals.palette)
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
snap_to_physical_pixel: true,
|
snap_to_physical_pixel: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue