left click to open info panel. refiddling how drag events are detected.

kind of messy code, but the behavior is FINALLY right.
This commit is contained in:
Dustin Carlino 2019-12-11 13:52:01 -08:00
parent 706f602e10
commit 14f4dc2e3c
6 changed files with 48 additions and 28 deletions

View File

@ -18,7 +18,10 @@ pub struct Canvas {
pub(crate) cursor_y: f64,
pub(crate) window_has_cursor: bool,
pub(crate) left_mouse_drag_from: Option<ScreenPt>,
// Only for drags starting on the map. Only used to pan the map.
pub(crate) drag_canvas_from: Option<ScreenPt>,
pub(crate) actually_dragging: bool,
pub(crate) drag_just_ended: bool,
pub window_width: f64,
pub window_height: f64,
@ -48,7 +51,10 @@ impl Canvas {
cursor_y: 0.0,
window_has_cursor: true,
left_mouse_drag_from: None,
drag_canvas_from: None,
actually_dragging: false,
drag_just_ended: false,
window_width: initial_width,
window_height: initial_height,
@ -63,20 +69,13 @@ impl Canvas {
}
}
pub(crate) fn is_dragging(&self) -> bool {
self.left_mouse_drag_from.is_some()
}
pub fn handle_event(&mut self, input: &mut UserInput) {
// Can't start dragging or zooming on top of covered area
let mouse_on_map = self.get_cursor_in_map_space().is_some();
if input.left_mouse_button_pressed() && mouse_on_map {
self.left_mouse_drag_from = Some(self.get_cursor_in_screen_space());
}
if input.left_mouse_button_released() {
self.left_mouse_drag_from = None;
}
if mouse_on_map {
if self.get_cursor_in_map_space().is_some() {
if input.left_mouse_button_pressed() {
self.drag_canvas_from = Some(self.get_cursor_in_screen_space());
}
if let Some(scroll) = input.get_mouse_scroll() {
let old_zoom = self.cam_zoom;
self.cam_zoom = 1.1_f64.powf(old_zoom.log(1.1) + scroll);
@ -88,6 +87,28 @@ impl Canvas {
((self.cam_zoom / old_zoom) * (self.cursor_y + self.cam_y)) - self.cursor_y;
}
}
// If we start the drag on the map and move the mouse off the map, keep dragging.
if let Some(click) = self.drag_canvas_from {
let pt = self.get_cursor_in_screen_space();
self.cam_x += click.x - pt.x;
self.cam_y += click.y - pt.y;
self.drag_canvas_from = Some(pt);
if !self.actually_dragging && click != pt {
self.actually_dragging = true;
}
if input.left_mouse_button_released() {
self.drag_canvas_from = None;
if self.actually_dragging {
self.drag_just_ended = true;
} else {
}
self.actually_dragging = false;
}
} else if self.drag_just_ended {
self.drag_just_ended = false;
}
}
pub(crate) fn start_drawing(&self) {

View File

@ -43,10 +43,18 @@ impl<'a> EventCtx<'a> {
pub fn redo_mouseover(&self) -> bool {
self.input.window_lost_cursor()
|| (!self.canvas.is_dragging() && self.input.get_moved_mouse().is_some())
|| (!self.is_dragging() && self.input.get_moved_mouse().is_some())
|| self.input.get_mouse_scroll().is_some()
}
pub fn normal_left_click(&mut self) -> bool {
!self.is_dragging() && self.input.left_mouse_button_released()
}
fn is_dragging(&self) -> bool {
self.canvas.drag_canvas_from.is_some() || self.canvas.drag_just_ended
}
pub fn set_textures(&mut self, textures: Vec<(&str, TextureType)>, timer: &mut Timer) {
self.canvas.texture_arrays.clear();
self.canvas.texture_lookups.clear();

View File

@ -56,15 +56,8 @@ impl UserInput {
if let Some(pt) = input.get_moved_mouse() {
canvas.cursor_x = pt.x;
canvas.cursor_y = pt.y;
// OK to update this here; the drag has to be initiated from canvas.handle_event, which
// the caller must invoke.
if let Some(click) = canvas.left_mouse_drag_from {
canvas.cam_x += click.x - pt.x;
canvas.cam_y += click.y - pt.y;
canvas.left_mouse_drag_from = Some(pt);
}
}
if input.event == Event::WindowGainedCursor {
canvas.window_has_cursor = true;
}

View File

@ -28,8 +28,7 @@ impl State for InfoPanel {
self.menu.event(ctx);
// Can click on the map to cancel
if self.menu.action("quit")
|| (ctx.input.left_mouse_button_released()
&& ctx.canvas.get_cursor_in_map_space().is_some())
|| (ctx.normal_left_click() && ctx.canvas.get_cursor_in_map_space().is_some())
{
Transition::Pop
} else {

View File

@ -73,7 +73,7 @@ impl CommonState {
}
if let Some(ref id) = ui.primary.current_selection {
if ctx.input.contextual_action(Key::I, "info") {
if ctx.input.contextual_action(Key::I, "info") || ctx.normal_left_click() {
return Some(Transition::Push(Box::new(info::InfoPanel::new(
id.clone(),
ui,

View File

@ -118,8 +118,7 @@ impl State for NeighborhoodEditor {
} else {
self.mouseover_pt = None;
}
// TODO mouse dragging might be more intuitive, but it's unclear how to
// override part of canvas.handle_event
// TODO maybe click-and-drag is more intuitive
if self.mouseover_pt.is_some()
&& ctx
.input