Fix bug: accidental interaction on mouse-up

This commit is contained in:
Emil Ernerfeldt 2020-04-21 20:43:47 +02:00
parent e9bdadb1da
commit 8b4e506493
3 changed files with 69 additions and 37 deletions

View file

@ -77,9 +77,6 @@ impl Context {
self.used_ids.lock().clear(); self.used_ids.lock().clear();
self.input = gui_input; self.input = gui_input;
*self.cursor_icon.lock() = CursorIcon::Default; *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)> { pub fn drain_paint_lists(&self) -> Vec<(Rect, PaintCmd)> {
@ -130,36 +127,65 @@ impl Context {
pub fn interact(&self, layer: Layer, rect: Rect, interaction_id: Option<Id>) -> InteractInfo { pub fn interact(&self, layer: Layer, rect: Rect, interaction_id: Option<Id>) -> InteractInfo {
let mut memory = self.memory.lock(); let mut memory = self.memory.lock();
let input = &self.input;
let hovered = if let Some(mouse_pos) = self.input.mouse_pos { let hovered = if let Some(mouse_pos) = input.mouse_pos {
if rect.contains(mouse_pos) { rect.contains(mouse_pos) && layer == memory.layer_at(mouse_pos)
let is_something_else_active =
memory.active_id.is_some() && memory.active_id != interaction_id;
!is_something_else_active && layer == memory.layer_at(mouse_pos)
} else {
false
}
} else {
false
};
let active = if interaction_id.is_some() {
if hovered && self.input.mouse_clicked {
memory.active_id = interaction_id;
}
memory.active_id == interaction_id
} else { } else {
false false
}; };
let clicked = hovered && self.input.mouse_released; 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 { InteractInfo {
rect, rect,
hovered, hovered,
clicked, clicked: false,
active: false,
}
} else {
memory.active_id = interaction_id;
InteractInfo {
rect,
hovered,
clicked: false,
active: true,
}
}
} else {
InteractInfo {
rect,
hovered,
clicked: false,
active: false,
}
}
} else if input.mouse_released {
InteractInfo {
rect,
hovered,
clicked: hovered && active,
active, active,
} }
} else if input.mouse_down {
InteractInfo {
rect,
hovered: hovered && active,
clicked: false,
active,
}
} else {
InteractInfo {
rect,
hovered,
clicked: false,
active,
}
}
} }
pub fn show_error(&self, pos: Pos2, text: &str) { pub fn show_error(&self, pos: Pos2, text: &str) {

View file

@ -33,13 +33,17 @@ impl Emigui {
} }
pub fn new_frame(&mut self, new_input: RawInput) { 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); let gui_input = GuiInput::from_last_and_new(&self.last_input, &new_input);
self.last_input = new_input; self.last_input = new_input;
// TODO: avoid this clone // TODO: avoid this clone
let mut new_data = (*self.ctx).clone(); let mut new_ctx = (*self.ctx).clone();
new_data.new_frame(gui_input); new_ctx.new_frame(gui_input);
self.ctx = Arc::new(new_data); self.ctx = Arc::new(new_ctx);
} }
/// A region for the entire screen, behind any windows. /// A region for the entire screen, behind any windows.
@ -91,11 +95,11 @@ impl Emigui {
font_definitions_ui(&mut new_font_definitions, region); font_definitions_ui(&mut new_font_definitions, region);
self.ctx.fonts.texture().ui(region); self.ctx.fonts.texture().ui(region);
if *old_font_definitions != new_font_definitions { if *old_font_definitions != new_font_definitions {
let mut new_data = (*self.ctx).clone(); let mut new_ctx = (*self.ctx).clone();
let fonts = let fonts =
Fonts::from_definitions(new_font_definitions, self.ctx.input.pixels_per_point); Fonts::from_definitions(new_font_definitions, self.ctx.input.pixels_per_point);
new_data.fonts = Arc::new(fonts); new_ctx.fonts = Arc::new(fonts);
self.ctx = Arc::new(new_data); self.ctx = Arc::new(new_ctx);
} }
}); });

View file

@ -30,10 +30,12 @@ pub struct RawInput {
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default)]
pub struct GuiInput { pub struct GuiInput {
/// Is the button currently down? /// Is the button currently down?
/// true the frame when it is pressed,
/// false the frame it is released.
pub mouse_down: bool, pub mouse_down: bool,
/// The mouse went from !down to down /// The mouse went from !down to down
pub mouse_clicked: bool, pub mouse_pressed: bool,
/// The mouse went from down to !down /// The mouse went from down to !down
pub mouse_released: bool, pub mouse_released: bool,
@ -62,7 +64,7 @@ impl GuiInput {
.unwrap_or_default(); .unwrap_or_default();
GuiInput { GuiInput {
mouse_down: new.mouse_down, 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_released: last.mouse_down && !new.mouse_down,
mouse_pos: new.mouse_pos, mouse_pos: new.mouse_pos,
mouse_move, mouse_move,
@ -77,13 +79,13 @@ impl GuiInput {
#[derive(Clone, Copy, Debug, Default, Serialize)] #[derive(Clone, Copy, Debug, Default, Serialize)]
pub struct InteractInfo { pub struct InteractInfo {
/// The mouse is hovering above this /// The mouse is hovering above this thing
pub hovered: bool, 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, 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, pub active: bool,
/// The region of the screen we are talking about /// The region of the screen we are talking about