diff --git a/emigui/src/context.rs b/emigui/src/context.rs index 59e41732..c863ff1f 100644 --- a/emigui/src/context.rs +++ b/emigui/src/context.rs @@ -77,9 +77,6 @@ impl Context { self.used_ids.lock().clear(); self.input = gui_input; *self.cursor_icon.lock() = CursorIcon::Default; - if !gui_input.mouse_down || gui_input.mouse_pos.is_none() { - self.memory.lock().active_id = None; - } } pub fn drain_paint_lists(&self) -> Vec<(Rect, PaintCmd)> { @@ -130,35 +127,64 @@ impl Context { pub fn interact(&self, layer: Layer, rect: Rect, interaction_id: Option) -> InteractInfo { let mut memory = self.memory.lock(); + let input = &self.input; - let hovered = if let Some(mouse_pos) = self.input.mouse_pos { - if rect.contains(mouse_pos) { - let is_something_else_active = - memory.active_id.is_some() && memory.active_id != interaction_id; + let hovered = if let Some(mouse_pos) = input.mouse_pos { + rect.contains(mouse_pos) && layer == memory.layer_at(mouse_pos) + } else { + false + }; - !is_something_else_active && layer == memory.layer_at(mouse_pos) + let active = interaction_id.is_some() && memory.active_id == interaction_id; + + if input.mouse_pressed { + if hovered && interaction_id.is_some() { + if memory.active_id.is_some() { + // Already clicked something else this frame + InteractInfo { + rect, + hovered, + clicked: false, + active: false, + } + } else { + memory.active_id = interaction_id; + InteractInfo { + rect, + hovered, + clicked: false, + active: true, + } + } } else { - false + InteractInfo { + rect, + hovered, + clicked: false, + active: false, + } + } + } else if input.mouse_released { + InteractInfo { + rect, + hovered, + clicked: hovered && active, + active, + } + } else if input.mouse_down { + InteractInfo { + rect, + hovered: hovered && active, + clicked: false, + active, } } else { - false - }; - let active = if interaction_id.is_some() { - if hovered && self.input.mouse_clicked { - memory.active_id = interaction_id; + InteractInfo { + rect, + hovered, + clicked: false, + active, } - memory.active_id == interaction_id - } else { - false - }; - - let clicked = hovered && self.input.mouse_released; - - InteractInfo { - rect, - hovered, - clicked, - active, } } diff --git a/emigui/src/emigui.rs b/emigui/src/emigui.rs index 0fcc5d71..fad1b744 100644 --- a/emigui/src/emigui.rs +++ b/emigui/src/emigui.rs @@ -33,13 +33,17 @@ impl Emigui { } pub fn new_frame(&mut self, new_input: RawInput) { + if !self.last_input.mouse_down || self.last_input.mouse_pos.is_none() { + self.ctx.memory.lock().active_id = None; + } + let gui_input = GuiInput::from_last_and_new(&self.last_input, &new_input); self.last_input = new_input; // TODO: avoid this clone - let mut new_data = (*self.ctx).clone(); - new_data.new_frame(gui_input); - self.ctx = Arc::new(new_data); + let mut new_ctx = (*self.ctx).clone(); + new_ctx.new_frame(gui_input); + self.ctx = Arc::new(new_ctx); } /// A region for the entire screen, behind any windows. @@ -91,11 +95,11 @@ impl Emigui { font_definitions_ui(&mut new_font_definitions, region); self.ctx.fonts.texture().ui(region); if *old_font_definitions != new_font_definitions { - let mut new_data = (*self.ctx).clone(); + let mut new_ctx = (*self.ctx).clone(); let fonts = Fonts::from_definitions(new_font_definitions, self.ctx.input.pixels_per_point); - new_data.fonts = Arc::new(fonts); - self.ctx = Arc::new(new_data); + new_ctx.fonts = Arc::new(fonts); + self.ctx = Arc::new(new_ctx); } }); diff --git a/emigui/src/types.rs b/emigui/src/types.rs index 98c16c64..513926c1 100644 --- a/emigui/src/types.rs +++ b/emigui/src/types.rs @@ -30,10 +30,12 @@ pub struct RawInput { #[derive(Clone, Copy, Debug, Default)] pub struct GuiInput { /// Is the button currently down? + /// true the frame when it is pressed, + /// false the frame it is released. pub mouse_down: bool, /// The mouse went from !down to down - pub mouse_clicked: bool, + pub mouse_pressed: bool, /// The mouse went from down to !down pub mouse_released: bool, @@ -62,7 +64,7 @@ impl GuiInput { .unwrap_or_default(); GuiInput { mouse_down: new.mouse_down, - mouse_clicked: !last.mouse_down && new.mouse_down, + mouse_pressed: !last.mouse_down && new.mouse_down, mouse_released: last.mouse_down && !new.mouse_down, mouse_pos: new.mouse_pos, mouse_move, @@ -77,13 +79,13 @@ impl GuiInput { #[derive(Clone, Copy, Debug, Default, Serialize)] pub struct InteractInfo { - /// The mouse is hovering above this + /// The mouse is hovering above this thing pub hovered: bool, - /// The mouse went got pressed on this thing this frame + /// The mouse pressed this thing ealier, and now released on this thing too. pub clicked: bool, - /// The mouse is interacting with this thing (e.g. dragging it) + /// The mouse is interacting with this thing (e.g. dragging it or holding it) pub active: bool, /// The region of the screen we are talking about