mirror of https://github.com/wayvr-org/wayvr.git
Merge branch 'wgui_tooltip_fixes'
This commit is contained in:
commit
6aba32ae05
|
|
@ -75,11 +75,15 @@ impl Default for Params {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct State {}
|
struct State {
|
||||||
|
position_shift: Vec2, // in case if the tooltip goes out of bounds
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::struct_field_names)]
|
#[allow(clippy::struct_field_names)]
|
||||||
struct Data {
|
struct Data {
|
||||||
id_root: WidgetID, // Rectangle
|
id_root: WidgetID, // div
|
||||||
|
id_rect: WidgetID, // rectangle
|
||||||
|
side: TooltipSide,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ComponentTooltip {
|
pub struct ComponentTooltip {
|
||||||
|
|
@ -99,8 +103,47 @@ impl ComponentTrait for ComponentTooltip {
|
||||||
&self.base
|
&self.base
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refresh(&self, _data: &mut RefreshData) {
|
fn refresh(&self, data: &mut RefreshData) {
|
||||||
// nothing to do
|
let layout_size = data.layout.content_size;
|
||||||
|
let pin_pos = data.layout.state.get_widget_boundary(self.data.id_root).pos;
|
||||||
|
let rect_size = data.layout.state.get_widget_boundary(self.data.id_rect).size;
|
||||||
|
|
||||||
|
let rect_pos_topleft: Vec2 = match self.data.side {
|
||||||
|
TooltipSide::Left => pin_pos + Vec2::new(-rect_size.x, -rect_size.y / 2.0),
|
||||||
|
TooltipSide::Right => pin_pos + Vec2::new(0.0, -rect_size.y / 2.0),
|
||||||
|
TooltipSide::Top => pin_pos + Vec2::new(-rect_size.x / 2.0, -rect_size.y),
|
||||||
|
TooltipSide::Bottom => pin_pos + Vec2::new(-rect_size.x / 2.0, 0.0),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut state = self.state.borrow_mut();
|
||||||
|
|
||||||
|
let padding = 8.0;
|
||||||
|
let rect_right = rect_pos_topleft.x + rect_size.x + padding;
|
||||||
|
let rect_bottom = rect_pos_topleft.y + rect_size.y + padding;
|
||||||
|
|
||||||
|
let diff_right = rect_right - layout_size.x;
|
||||||
|
let diff_bottom = rect_bottom - layout_size.y;
|
||||||
|
|
||||||
|
// limit x < 0 or rect_right > layout_size.x
|
||||||
|
if rect_pos_topleft.x < 0.0 {
|
||||||
|
state.position_shift.x = -rect_pos_topleft.x;
|
||||||
|
} else if diff_right > 0.0 {
|
||||||
|
state.position_shift.x = -diff_right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit y < 0 or rect_bottom > layout_size.y
|
||||||
|
if rect_pos_topleft.y < 0.0 {
|
||||||
|
state.position_shift.y = -rect_pos_topleft.y;
|
||||||
|
} else if diff_bottom > 0.0 {
|
||||||
|
state.position_shift.y = -diff_bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*log::info!(
|
||||||
|
"layout size {:?}, pin pos {:?}, rect size {:?}",
|
||||||
|
layout_size,
|
||||||
|
pin_pos,
|
||||||
|
rect_size
|
||||||
|
);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,7 +170,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
||||||
|
|
||||||
let spacing = 8.0;
|
let spacing = 8.0;
|
||||||
|
|
||||||
let transform = Mat4::from_translation(Vec3::new(-0.5, 0.0, 0.0));
|
let transform = Mat4::from_translation(Vec3::new(0.0, 0.0, 0.0));
|
||||||
|
|
||||||
// this value needs to be bigger than rectangle padding sizes due to the
|
// this value needs to be bigger than rectangle padding sizes due to the
|
||||||
// transform stack & scissoring design. Needs investigation, zero-size objects
|
// transform stack & scissoring design. Needs investigation, zero-size objects
|
||||||
|
|
@ -219,18 +262,25 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let (label, _) = ess.layout.add_child(rect.id, label, Default::default())?;
|
let (label, _) = ess.layout.add_child(rect.id, label, Default::default())?;
|
||||||
|
|
||||||
let data = Rc::new(Data { id_root: div.id });
|
let data = Rc::new(Data {
|
||||||
|
id_root: div.id,
|
||||||
|
id_rect: rect.id,
|
||||||
|
side: params.info.side.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
let state = Rc::new(RefCell::new(State {}));
|
let state = Rc::new(RefCell::new(State {
|
||||||
|
position_shift: Vec2::default(),
|
||||||
|
}));
|
||||||
|
|
||||||
let base = ComponentBase::default();
|
let base = ComponentBase::default();
|
||||||
|
|
||||||
let tooltip = Rc::new(ComponentTooltip {
|
let tooltip = Rc::new(ComponentTooltip {
|
||||||
base,
|
base,
|
||||||
data,
|
data,
|
||||||
state,
|
state: state.clone(),
|
||||||
tasks: ess.layout.tasks.clone(),
|
tasks: ess.layout.tasks.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -246,21 +296,29 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
||||||
rect.id,
|
rect.id,
|
||||||
(10.0 * anim_mult) as u32,
|
(10.0 * anim_mult) as u32,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |common, data| {
|
{
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap(); /* safe */
|
Box::new(move |common, data| {
|
||||||
let alpha = data.pos;
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap(); /* safe */
|
||||||
rect.params.color.a = alpha;
|
let alpha = data.pos;
|
||||||
rect.params.border_color.a = alpha;
|
rect.params.color.a = alpha;
|
||||||
|
rect.params.border_color.a = alpha;
|
||||||
|
|
||||||
let dir_mult = (1.0 - data.pos) * 5.0;
|
let position_shift = state.borrow().position_shift;
|
||||||
data.data.transform = Mat4::from_translation(Vec3::new(direction.x * dir_mult, direction.y * dir_mult, 0.0));
|
|
||||||
|
|
||||||
if let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(label.id) {
|
let dir_mult = (1.0 - data.pos) * 5.0;
|
||||||
label.set_color(common, Color::new(1.0, 1.0, 1.0, alpha), true);
|
data.data.transform = Mat4::from_translation(Vec3::new(
|
||||||
}
|
direction.x * dir_mult + position_shift.x,
|
||||||
|
direction.y * dir_mult + position_shift.y,
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
|
|
||||||
common.alterables.mark_redraw();
|
if let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(label.id) {
|
||||||
}),
|
label.set_color(common, Color::new(1.0, 1.0, 1.0, alpha), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
common.alterables.mark_redraw();
|
||||||
|
})
|
||||||
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
ess.layout.defer_component_refresh(Component(tooltip.clone()));
|
ess.layout.defer_component_refresh(Component(tooltip.clone()));
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ pub struct Layout {
|
||||||
pub content_root_node: taffy::NodeId,
|
pub content_root_node: taffy::NodeId,
|
||||||
|
|
||||||
pub prev_size: Vec2,
|
pub prev_size: Vec2,
|
||||||
pub content_size: Vec2,
|
pub content_size: Vec2, // cached value
|
||||||
|
|
||||||
pub needs_redraw: bool,
|
pub needs_redraw: bool,
|
||||||
pub haptics_triggered: bool,
|
pub haptics_triggered: bool,
|
||||||
|
|
@ -720,9 +720,10 @@ impl Layout {
|
||||||
pub fn tick(&mut self) -> anyhow::Result<()> {
|
pub fn tick(&mut self) -> anyhow::Result<()> {
|
||||||
let mut alterables = EventAlterables::default();
|
let mut alterables = EventAlterables::default();
|
||||||
self.animations.tick(&self.state, &mut alterables);
|
self.animations.tick(&self.state, &mut alterables);
|
||||||
self.process_pending_components();
|
|
||||||
self.process_pending_widget_ticks(&mut alterables);
|
self.process_pending_widget_ticks(&mut alterables);
|
||||||
self.process_alterables(alterables)?;
|
self.process_alterables(alterables)?;
|
||||||
|
self.try_recompute_layout(self.content_size /* cached value */)?;
|
||||||
|
self.process_pending_components();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use slotmap::Key;
|
||||||
use taffy::AvailableSpace;
|
use taffy::AvailableSpace;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{self, Boundary, PrimitiveExtent},
|
drawing::{self, PrimitiveExtent},
|
||||||
event::CallbackDataCommon,
|
event::CallbackDataCommon,
|
||||||
globals::Globals,
|
globals::Globals,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
|
|
@ -28,7 +28,6 @@ pub struct WidgetLabel {
|
||||||
|
|
||||||
params: WidgetLabelParams,
|
params: WidgetLabelParams,
|
||||||
buffer: Rc<RefCell<Buffer>>,
|
buffer: Rc<RefCell<Buffer>>,
|
||||||
last_boundary: Boundary,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetLabel {
|
impl WidgetLabel {
|
||||||
|
|
@ -64,7 +63,6 @@ impl WidgetLabel {
|
||||||
Box::new(Self {
|
Box::new(Self {
|
||||||
params,
|
params,
|
||||||
buffer: Rc::new(RefCell::new(buffer)),
|
buffer: Rc::new(RefCell::new(buffer)),
|
||||||
last_boundary: Boundary::default(),
|
|
||||||
id: WidgetID::null(),
|
id: WidgetID::null(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
@ -122,12 +120,9 @@ impl WidgetObj for WidgetLabel {
|
||||||
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
||||||
let boundary = drawing::Boundary::construct_relative(state.transform_stack);
|
let boundary = drawing::Boundary::construct_relative(state.transform_stack);
|
||||||
|
|
||||||
if self.last_boundary != boundary {
|
let mut font_system = state.globals.font_system.system.lock();
|
||||||
self.last_boundary = boundary;
|
let mut buffer = self.buffer.borrow_mut();
|
||||||
let mut font_system = state.globals.font_system.system.lock();
|
buffer.set_size(&mut font_system, Some(boundary.size.x), Some(boundary.size.y));
|
||||||
let mut buffer = self.buffer.borrow_mut();
|
|
||||||
buffer.set_size(&mut font_system, Some(boundary.size.x), Some(boundary.size.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
state.primitives.push(drawing::RenderPrimitive::Text(
|
state.primitives.push(drawing::RenderPrimitive::Text(
|
||||||
PrimitiveExtent {
|
PrimitiveExtent {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue