[input] fix: hover highlight either scroll or window resize; not both
This commit is contained in:
parent
e43ff934a0
commit
ef7f3c4637
4 changed files with 53 additions and 27 deletions
|
@ -181,10 +181,10 @@ impl Prepared {
|
|||
|
||||
// intentionally use same id for inside and outside of handle
|
||||
let interact_id = id.with("vertical");
|
||||
let handle_interact = ui.interact(handle_rect, interact_id, Sense::click_and_drag());
|
||||
let mut interact = ui.interact(handle_rect, interact_id, Sense::click_and_drag());
|
||||
|
||||
if let Some(mouse_pos) = ui.input().mouse.pos {
|
||||
if handle_interact.active {
|
||||
if interact.active {
|
||||
if inner_rect.top() <= mouse_pos.y && mouse_pos.y <= inner_rect.bottom() {
|
||||
state.offset.y +=
|
||||
ui.input().mouse.delta.y * content_size.y / inner_rect.height();
|
||||
|
@ -199,6 +199,8 @@ impl Prepared {
|
|||
let mpos_top = mouse_pos.y - handle_rect.height() / 2.0;
|
||||
state.offset.y = remap(mpos_top, top..=bottom, 0.0..=content_size.y);
|
||||
}
|
||||
|
||||
interact = interact.union(scroll_bg_interact);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,8 +214,8 @@ impl Prepared {
|
|||
);
|
||||
|
||||
let style = ui.style();
|
||||
let handle_fill_color = style.interact(&handle_interact).fill_color;
|
||||
let handle_outline = style.interact(&handle_interact).rect_outline;
|
||||
let handle_fill_color = style.interact(&interact).fill_color;
|
||||
let handle_outline = style.interact(&interact).rect_outline;
|
||||
|
||||
ui.add_paint_cmd(paint::PaintCmd::Rect {
|
||||
rect: outer_scroll_rect,
|
||||
|
|
|
@ -168,7 +168,6 @@ impl<'open> Window<'open> {
|
|||
|
||||
let mut area = area.begin(ctx);
|
||||
{
|
||||
// TODO: pick style for frame and title based on interaction
|
||||
let mut frame = frame.begin(&mut area.content_ui);
|
||||
{
|
||||
let ui = &mut frame.content_ui;
|
||||
|
@ -211,6 +210,7 @@ impl<'open> Window<'open> {
|
|||
*open = false;
|
||||
}
|
||||
}
|
||||
// TODO: pick style for title based on move interaction
|
||||
title_bar.title_ui(ui);
|
||||
}
|
||||
|
||||
|
@ -402,6 +402,11 @@ fn resize_hover(
|
|||
}
|
||||
}
|
||||
|
||||
if ctx.memory().interaction.drag_interest {
|
||||
// Another widget will become active if we drag here
|
||||
return None;
|
||||
}
|
||||
|
||||
let side_interact_radius = 5.0; // TODO: from style
|
||||
let corner_interact_radius = 10.0; // TODO
|
||||
if rect.expand(side_interact_radius).contains(mouse_pos) {
|
||||
|
|
|
@ -147,28 +147,7 @@ impl Context {
|
|||
}
|
||||
|
||||
fn begin_frame_mut(&mut self, new_raw_input: RawInput) {
|
||||
if !self.input().mouse.could_be_click {
|
||||
self.memory().interaction.click_id = None;
|
||||
}
|
||||
|
||||
if !self.input.mouse.down || self.input.mouse.pos.is_none() {
|
||||
// mouse was not down last frame
|
||||
self.memory().interaction.click_id = None;
|
||||
self.memory().interaction.drag_id = None;
|
||||
|
||||
let window_interaction = self.memory().window_interaction.take();
|
||||
if let Some(window_interaction) = window_interaction {
|
||||
if !window_interaction.is_resize() {
|
||||
// Throw windows because it is fun:
|
||||
let area_layer = window_interaction.area_layer;
|
||||
let area_state = self.memory().areas.get(area_layer.id).clone();
|
||||
if let Some(mut area_state) = area_state {
|
||||
area_state.vel = self.input().mouse.velocity;
|
||||
self.memory().areas.set_state(area_layer, area_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.memory().begin_frame(&self.input);
|
||||
|
||||
self.used_ids.lock().clear();
|
||||
|
||||
|
@ -307,6 +286,10 @@ impl Context {
|
|||
let interaction_id = interaction_id.unwrap();
|
||||
|
||||
let mut memory = self.memory();
|
||||
|
||||
memory.interaction.click_interest |= hovered && sense.click;
|
||||
memory.interaction.drag_interest |= hovered && sense.drag;
|
||||
|
||||
let active = memory.interaction.click_id == Some(interaction_id)
|
||||
|| memory.interaction.drag_id == Some(interaction_id);
|
||||
|
||||
|
|
|
@ -43,6 +43,14 @@ pub struct Interaction {
|
|||
|
||||
/// A widget interested in drags that has a mouse press on it.
|
||||
pub drag_id: Option<Id>,
|
||||
|
||||
/// Any interest in catching clicks this frame?
|
||||
/// Cleared to false at start of each frame.
|
||||
pub click_interest: bool,
|
||||
|
||||
/// Any interest in catching clicks this frame?
|
||||
/// Cleared to false at start of each frame.
|
||||
pub drag_interest: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, serde_derive::Deserialize, serde_derive::Serialize)]
|
||||
|
@ -63,6 +71,34 @@ pub struct Areas {
|
|||
}
|
||||
|
||||
impl Memory {
|
||||
pub(crate) fn begin_frame(&mut self, prev_input: &crate::input::InputState) {
|
||||
self.interaction.click_interest = false;
|
||||
self.interaction.drag_interest = false;
|
||||
|
||||
if !prev_input.mouse.could_be_click {
|
||||
self.interaction.click_id = None;
|
||||
}
|
||||
|
||||
if !prev_input.mouse.down || prev_input.mouse.pos.is_none() {
|
||||
// mouse was not down last frame
|
||||
self.interaction.click_id = None;
|
||||
self.interaction.drag_id = None;
|
||||
|
||||
let window_interaction = self.window_interaction.take();
|
||||
if let Some(window_interaction) = window_interaction {
|
||||
if !window_interaction.is_resize() {
|
||||
// Throw windows because it is fun:
|
||||
let area_layer = window_interaction.area_layer;
|
||||
let area_state = self.areas.get(area_layer.id).clone();
|
||||
if let Some(mut area_state) = area_state {
|
||||
area_state.vel = prev_input.mouse.velocity;
|
||||
self.areas.set_state(area_layer, area_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn end_frame(&mut self) {
|
||||
self.areas.end_frame()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue