refactor: group mouse input into own struct
This commit is contained in:
parent
538db9005e
commit
620442a64b
11 changed files with 94 additions and 70 deletions
|
@ -165,8 +165,8 @@ impl Area {
|
||||||
|
|
||||||
let input = ctx.input();
|
let input = ctx.input();
|
||||||
if move_interact.active {
|
if move_interact.active {
|
||||||
state.pos += input.mouse_move;
|
state.pos += input.mouse.delta;
|
||||||
state.vel = input.mouse_velocity;
|
state.vel = input.mouse.velocity;
|
||||||
} else {
|
} else {
|
||||||
let stop_speed = 20.0; // Pixels per second.
|
let stop_speed = 20.0; // Pixels per second.
|
||||||
let friction_coeff = 1000.0; // Pixels per second squared.
|
let friction_coeff = 1000.0; // Pixels per second squared.
|
||||||
|
@ -208,8 +208,8 @@ impl Area {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_pressed_on_area(ctx: &Context, layer: Layer) -> bool {
|
fn mouse_pressed_on_area(ctx: &Context, layer: Layer) -> bool {
|
||||||
if let Some(mouse_pos) = ctx.input().mouse_pos {
|
if let Some(mouse_pos) = ctx.input().mouse.pos {
|
||||||
ctx.input().mouse_pressed && ctx.memory().layer_at(mouse_pos) == Some(layer)
|
ctx.input().mouse.pressed && ctx.memory().layer_at(mouse_pos) == Some(layer)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ fn menu_impl<'c>(
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if menu_interact.hovered && ui.input().mouse_released {
|
if menu_interact.hovered && ui.input().mouse.released {
|
||||||
bar_state.open_menu = None;
|
bar_state.open_menu = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ fn interact_with_menu_button(
|
||||||
menu_id: Id,
|
menu_id: Id,
|
||||||
button_interact: &GuiResponse,
|
button_interact: &GuiResponse,
|
||||||
) {
|
) {
|
||||||
if button_interact.hovered && input.mouse_pressed {
|
if button_interact.hovered && input.mouse.pressed {
|
||||||
if bar_state.open_menu.is_some() {
|
if bar_state.open_menu.is_some() {
|
||||||
bar_state.open_menu = None;
|
bar_state.open_menu = None;
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,7 +122,7 @@ fn interact_with_menu_button(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if button_interact.hovered && input.mouse_released && bar_state.open_menu.is_some() {
|
if button_interact.hovered && input.mouse.released && bar_state.open_menu.is_some() {
|
||||||
let time_since_open = input.time - bar_state.open_time;
|
let time_since_open = input.time - bar_state.open_time;
|
||||||
if time_since_open < 0.4 {
|
if time_since_open < 0.4 {
|
||||||
// A quick click
|
// A quick click
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub fn show_tooltip(ctx: &Arc<Context>, add_contents: impl FnOnce(&mut Ui)) {
|
pub fn show_tooltip(ctx: &Arc<Context>, add_contents: impl FnOnce(&mut Ui)) {
|
||||||
if let Some(mouse_pos) = ctx.input().mouse_pos {
|
if let Some(mouse_pos) = ctx.input().mouse.pos {
|
||||||
// TODO: default size
|
// TODO: default size
|
||||||
let id = Id::tooltip();
|
let id = Id::tooltip();
|
||||||
let window_pos = mouse_pos + vec2(16.0, 16.0);
|
let window_pos = mouse_pos + vec2(16.0, 16.0);
|
||||||
|
|
|
@ -212,7 +212,7 @@ impl Resize {
|
||||||
let corner_interact = ui.interact_rect(corner_rect, id.with("corner"));
|
let corner_interact = ui.interact_rect(corner_rect, id.with("corner"));
|
||||||
|
|
||||||
if corner_interact.active {
|
if corner_interact.active {
|
||||||
if let Some(mouse_pos) = ui.input().mouse_pos {
|
if let Some(mouse_pos) = ui.input().mouse.pos {
|
||||||
// This is the desired size. We may not be able to achieve it.
|
// This is the desired size. We may not be able to achieve it.
|
||||||
|
|
||||||
state.size = mouse_pos - position + 0.5 * corner_interact.rect.size()
|
state.size = mouse_pos - position + 0.5 * corner_interact.rect.size()
|
||||||
|
|
|
@ -147,7 +147,7 @@ impl ScrollArea {
|
||||||
// Dragg contents to scroll (for touch screens mostly):
|
// Dragg contents to scroll (for touch screens mostly):
|
||||||
let content_interact = ui.interact_rect(inner_rect, id.with("area"));
|
let content_interact = ui.interact_rect(inner_rect, id.with("area"));
|
||||||
if content_interact.active {
|
if content_interact.active {
|
||||||
state.offset.y -= ui.input().mouse_move.y;
|
state.offset.y -= ui.input().mouse.delta.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,11 +181,11 @@ impl ScrollArea {
|
||||||
let interact_id = id.with("vertical");
|
let interact_id = id.with("vertical");
|
||||||
let handle_interact = ui.interact_rect(handle_rect, interact_id);
|
let handle_interact = ui.interact_rect(handle_rect, interact_id);
|
||||||
|
|
||||||
if let Some(mouse_pos) = ui.input().mouse_pos {
|
if let Some(mouse_pos) = ui.input().mouse.pos {
|
||||||
if handle_interact.active {
|
if handle_interact.active {
|
||||||
if inner_rect.top() <= mouse_pos.y && mouse_pos.y <= inner_rect.bottom() {
|
if inner_rect.top() <= mouse_pos.y && mouse_pos.y <= inner_rect.bottom() {
|
||||||
state.offset.y +=
|
state.offset.y +=
|
||||||
ui.input().mouse_move.y * content_size.y / inner_rect.height();
|
ui.input().mouse.delta.y * content_size.y / inner_rect.height();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check for mouse down outside handle:
|
// Check for mouse down outside handle:
|
||||||
|
|
|
@ -303,7 +303,7 @@ fn resize_window(
|
||||||
) -> Option<Rect> {
|
) -> Option<Rect> {
|
||||||
if let Some(window_interaction) = window_interaction(ctx, possible, area_layer, id, rect) {
|
if let Some(window_interaction) = window_interaction(ctx, possible, area_layer, id, rect) {
|
||||||
window_interaction.set_cursor(ctx);
|
window_interaction.set_cursor(ctx);
|
||||||
if let Some(mouse_pos) = ctx.input().mouse_pos {
|
if let Some(mouse_pos) = ctx.input().mouse.pos {
|
||||||
let mut rect = window_interaction.start_rect; // prevent drift
|
let mut rect = window_interaction.start_rect; // prevent drift
|
||||||
|
|
||||||
if window_interaction.is_resize() {
|
if window_interaction.is_resize() {
|
||||||
|
@ -350,7 +350,7 @@ fn window_interaction(
|
||||||
if window_interaction.is_none() {
|
if window_interaction.is_none() {
|
||||||
if let Some(hover_window_interaction) = resize_hover(ctx, possible, area_layer, rect) {
|
if let Some(hover_window_interaction) = resize_hover(ctx, possible, area_layer, rect) {
|
||||||
hover_window_interaction.set_cursor(ctx);
|
hover_window_interaction.set_cursor(ctx);
|
||||||
if ctx.input().mouse_pressed {
|
if ctx.input().mouse.pressed {
|
||||||
ctx.memory().active_id = Some(id);
|
ctx.memory().active_id = Some(id);
|
||||||
window_interaction = Some(hover_window_interaction);
|
window_interaction = Some(hover_window_interaction);
|
||||||
ctx.memory().window_interaction = window_interaction;
|
ctx.memory().window_interaction = window_interaction;
|
||||||
|
@ -375,7 +375,7 @@ fn resize_hover(
|
||||||
area_layer: Layer,
|
area_layer: Layer,
|
||||||
rect: Rect,
|
rect: Rect,
|
||||||
) -> Option<WindowInteraction> {
|
) -> Option<WindowInteraction> {
|
||||||
if let Some(mouse_pos) = ctx.input().mouse_pos {
|
if let Some(mouse_pos) = ctx.input().mouse.pos {
|
||||||
if let Some(top_layer) = ctx.memory().layer_at(mouse_pos) {
|
if let Some(top_layer) = ctx.memory().layer_at(mouse_pos) {
|
||||||
if top_layer != area_layer && top_layer.order != Order::Background {
|
if top_layer != area_layer && top_layer.order != Order::Background {
|
||||||
return None; // Another window is on top here
|
return None; // Another window is on top here
|
||||||
|
|
|
@ -176,7 +176,7 @@ impl Context {
|
||||||
let area_state = self.memory().areas.get(area_layer.id).clone();
|
let area_state = self.memory().areas.get(area_layer.id).clone();
|
||||||
if let Some(mut area_state) = area_state {
|
if let Some(mut area_state) = area_state {
|
||||||
// Throw windows because it is fun:
|
// Throw windows because it is fun:
|
||||||
area_state.vel = self.input().mouse_velocity;
|
area_state.vel = self.input().mouse.velocity;
|
||||||
self.memory().areas.set_state(area_layer, area_state);
|
self.memory().areas.set_state(area_layer, area_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
let new_input = GuiInput::from_last_and_new(&self.raw_input, &new_raw_input);
|
let new_input = GuiInput::from_last_and_new(&self.raw_input, &new_raw_input);
|
||||||
self.previus_input = std::mem::replace(&mut self.input, new_input);
|
self.previus_input = std::mem::replace(&mut self.input, new_input);
|
||||||
self.input.mouse_velocity = self.mouse_vel();
|
self.input.mouse.velocity = self.mouse_vel();
|
||||||
self.raw_input = new_raw_input;
|
self.raw_input = new_raw_input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ impl Context {
|
||||||
|
|
||||||
pub fn contains_mouse(&self, layer: Layer, clip_rect: Rect, rect: Rect) -> bool {
|
pub fn contains_mouse(&self, layer: Layer, clip_rect: Rect, rect: Rect) -> bool {
|
||||||
let rect = rect.intersect(clip_rect);
|
let rect = rect.intersect(clip_rect);
|
||||||
if let Some(mouse_pos) = self.input.mouse_pos {
|
if let Some(mouse_pos) = self.input.mouse.pos {
|
||||||
rect.contains(mouse_pos) && self.memory().layer_at(mouse_pos) == Some(layer)
|
rect.contains(mouse_pos) && self.memory().layer_at(mouse_pos) == Some(layer)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -324,7 +324,7 @@ impl Context {
|
||||||
let mut memory = self.memory();
|
let mut memory = self.memory();
|
||||||
let active = interaction_id.is_some() && memory.active_id == interaction_id;
|
let active = interaction_id.is_some() && memory.active_id == interaction_id;
|
||||||
|
|
||||||
if self.input.mouse_pressed {
|
if self.input.mouse.pressed {
|
||||||
if hovered && interaction_id.is_some() {
|
if hovered && interaction_id.is_some() {
|
||||||
if memory.active_id.is_some() {
|
if memory.active_id.is_some() {
|
||||||
// Already clicked something else this frame
|
// Already clicked something else this frame
|
||||||
|
@ -351,14 +351,14 @@ impl Context {
|
||||||
active: false,
|
active: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if self.input.mouse_released {
|
} else if self.input.mouse.released {
|
||||||
InteractInfo {
|
InteractInfo {
|
||||||
rect,
|
rect,
|
||||||
hovered,
|
hovered,
|
||||||
clicked: hovered && active,
|
clicked: hovered && active,
|
||||||
active,
|
active,
|
||||||
}
|
}
|
||||||
} else if self.input.mouse_down {
|
} else if self.input.mouse.down {
|
||||||
InteractInfo {
|
InteractInfo {
|
||||||
rect,
|
rect,
|
||||||
hovered: hovered && active,
|
hovered: hovered && active,
|
||||||
|
|
|
@ -449,7 +449,7 @@ impl Painting {
|
||||||
let current_line = self.lines.last_mut().unwrap();
|
let current_line = self.lines.last_mut().unwrap();
|
||||||
|
|
||||||
if interact.active {
|
if interact.active {
|
||||||
if let Some(mouse_pos) = ui.input().mouse_pos {
|
if let Some(mouse_pos) = ui.input().mouse.pos {
|
||||||
let canvas_pos = mouse_pos - rect.min;
|
let canvas_pos = mouse_pos - rect.min;
|
||||||
if current_line.last() != Some(&canvas_pos) {
|
if current_line.last() != Some(&canvas_pos) {
|
||||||
current_line.push(canvas_pos);
|
current_line.push(canvas_pos);
|
||||||
|
|
|
@ -45,28 +45,7 @@ pub struct RawInput {
|
||||||
/// What emigui maintains
|
/// What emigui maintains
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct GuiInput {
|
pub struct GuiInput {
|
||||||
// TODO: mouse: Mouse as separate
|
pub mouse: MouseInput,
|
||||||
//
|
|
||||||
/// 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_pressed: bool,
|
|
||||||
|
|
||||||
/// The mouse went from down to !down
|
|
||||||
pub mouse_released: bool,
|
|
||||||
|
|
||||||
/// Current position of the mouse in points.
|
|
||||||
/// None for touch screens when finger is not down.
|
|
||||||
pub mouse_pos: Option<Pos2>,
|
|
||||||
|
|
||||||
/// How much the mouse moved compared to last frame, in points.
|
|
||||||
pub mouse_move: Vec2,
|
|
||||||
|
|
||||||
/// Current velocity of mouse cursor, if any.
|
|
||||||
pub mouse_velocity: Vec2,
|
|
||||||
|
|
||||||
/// How many pixels the user scrolled
|
/// How many pixels the user scrolled
|
||||||
pub scroll_delta: Vec2,
|
pub scroll_delta: Vec2,
|
||||||
|
@ -99,6 +78,31 @@ pub struct GuiInput {
|
||||||
pub web: Option<Web>,
|
pub web: Option<Web>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// What emigui maintains
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct MouseInput {
|
||||||
|
/// Is the button currently down?
|
||||||
|
/// true the frame when it is pressed,
|
||||||
|
/// false the frame it is released.
|
||||||
|
pub down: bool,
|
||||||
|
|
||||||
|
/// The mouse went from !down to down
|
||||||
|
pub pressed: bool,
|
||||||
|
|
||||||
|
/// The mouse went from down to !down
|
||||||
|
pub released: bool,
|
||||||
|
|
||||||
|
/// Current position of the mouse in points.
|
||||||
|
/// None for touch screens when finger is not down.
|
||||||
|
pub pos: Option<Pos2>,
|
||||||
|
|
||||||
|
/// How much the mouse moved compared to last frame, in points.
|
||||||
|
pub delta: Vec2,
|
||||||
|
|
||||||
|
/// Current velocity of mouse cursor.
|
||||||
|
pub velocity: Vec2,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize)]
|
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct Web {
|
pub struct Web {
|
||||||
|
@ -147,22 +151,9 @@ pub enum Key {
|
||||||
|
|
||||||
impl GuiInput {
|
impl GuiInput {
|
||||||
pub fn from_last_and_new(last: &RawInput, new: &RawInput) -> GuiInput {
|
pub fn from_last_and_new(last: &RawInput, new: &RawInput) -> GuiInput {
|
||||||
let mouse_move = new
|
|
||||||
.mouse_pos
|
|
||||||
.and_then(|new| last.mouse_pos.map(|last| new - last))
|
|
||||||
.unwrap_or_default();
|
|
||||||
let dt = (new.time - last.time) as f32;
|
let dt = (new.time - last.time) as f32;
|
||||||
let mut mouse_velocity = mouse_move / dt;
|
|
||||||
if !mouse_velocity.is_finite() {
|
|
||||||
mouse_velocity = Vec2::zero();
|
|
||||||
}
|
|
||||||
GuiInput {
|
GuiInput {
|
||||||
mouse_down: new.mouse_down && new.mouse_pos.is_some(),
|
mouse: MouseInput::from_last_and_new(last, new),
|
||||||
mouse_pressed: !last.mouse_down && new.mouse_down,
|
|
||||||
mouse_released: last.mouse_down && !new.mouse_down,
|
|
||||||
mouse_pos: new.mouse_pos,
|
|
||||||
mouse_move,
|
|
||||||
mouse_velocity,
|
|
||||||
scroll_delta: new.scroll_delta,
|
scroll_delta: new.scroll_delta,
|
||||||
screen_size: new.screen_size,
|
screen_size: new.screen_size,
|
||||||
pixels_per_point: new.pixels_per_point.unwrap_or(1.0),
|
pixels_per_point: new.pixels_per_point.unwrap_or(1.0),
|
||||||
|
@ -177,6 +168,28 @@ impl GuiInput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MouseInput {
|
||||||
|
pub fn from_last_and_new(last: &RawInput, new: &RawInput) -> MouseInput {
|
||||||
|
let delta = new
|
||||||
|
.mouse_pos
|
||||||
|
.and_then(|new| last.mouse_pos.map(|last| new - last))
|
||||||
|
.unwrap_or_default();
|
||||||
|
let dt = (new.time - last.time) as f32;
|
||||||
|
let mut velocity = delta / dt;
|
||||||
|
if !velocity.is_finite() {
|
||||||
|
velocity = Vec2::zero();
|
||||||
|
}
|
||||||
|
MouseInput {
|
||||||
|
down: new.mouse_down && new.mouse_pos.is_some(),
|
||||||
|
pressed: !last.mouse_down && new.mouse_down,
|
||||||
|
released: last.mouse_down && !new.mouse_down,
|
||||||
|
pos: new.mouse_pos,
|
||||||
|
delta,
|
||||||
|
velocity,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RawInput {
|
impl RawInput {
|
||||||
pub fn ui(&self, ui: &mut crate::Ui) {
|
pub fn ui(&self, ui: &mut crate::Ui) {
|
||||||
use crate::label;
|
use crate::label;
|
||||||
|
@ -200,16 +213,11 @@ impl RawInput {
|
||||||
impl GuiInput {
|
impl GuiInput {
|
||||||
pub fn ui(&self, ui: &mut crate::Ui) {
|
pub fn ui(&self, ui: &mut crate::Ui) {
|
||||||
use crate::label;
|
use crate::label;
|
||||||
ui.add(label!("mouse_down: {}", self.mouse_down));
|
crate::containers::CollapsingHeader::new("mouse")
|
||||||
ui.add(label!("mouse_pressed: {}", self.mouse_pressed));
|
.default_open(true)
|
||||||
ui.add(label!("mouse_released: {}", self.mouse_released));
|
.show(ui, |ui| {
|
||||||
ui.add(label!("mouse_pos: {:?}", self.mouse_pos));
|
self.mouse.ui(ui);
|
||||||
ui.add(label!("mouse_move: {:?}", self.mouse_move));
|
});
|
||||||
ui.add(label!(
|
|
||||||
"mouse_velocity: [{:3.0} {:3.0}] points/sec",
|
|
||||||
self.mouse_velocity.x,
|
|
||||||
self.mouse_velocity.y
|
|
||||||
));
|
|
||||||
ui.add(label!("scroll_delta: {:?}", self.scroll_delta));
|
ui.add(label!("scroll_delta: {:?}", self.scroll_delta));
|
||||||
ui.add(label!("screen_size: {:?}", self.screen_size));
|
ui.add(label!("screen_size: {:?}", self.screen_size));
|
||||||
ui.add(label!("pixels_per_point: {}", self.pixels_per_point));
|
ui.add(label!("pixels_per_point: {}", self.pixels_per_point));
|
||||||
|
@ -223,6 +231,22 @@ impl GuiInput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MouseInput {
|
||||||
|
pub fn ui(&self, ui: &mut crate::Ui) {
|
||||||
|
use crate::label;
|
||||||
|
ui.add(label!("down: {}", self.down));
|
||||||
|
ui.add(label!("pressed: {}", self.pressed));
|
||||||
|
ui.add(label!("released: {}", self.released));
|
||||||
|
ui.add(label!("pos: {:?}", self.pos));
|
||||||
|
ui.add(label!("delta: {:?}", self.delta));
|
||||||
|
ui.add(label!(
|
||||||
|
"velocity: [{:3.0} {:3.0}] points/sec",
|
||||||
|
self.velocity.x,
|
||||||
|
self.velocity.y
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Web {
|
impl Web {
|
||||||
pub fn ui(&self, ui: &mut crate::Ui) {
|
pub fn ui(&self, ui: &mut crate::Ui) {
|
||||||
use crate::label;
|
use crate::label;
|
||||||
|
|
|
@ -154,7 +154,7 @@ impl<'a> Widget for Slider<'a> {
|
||||||
let range = self.range.clone();
|
let range = self.range.clone();
|
||||||
debug_assert!(range.start() <= range.end());
|
debug_assert!(range.start() <= range.end());
|
||||||
|
|
||||||
if let Some(mouse_pos) = ui.input().mouse_pos {
|
if let Some(mouse_pos) = ui.input().mouse.pos {
|
||||||
if interact.active {
|
if interact.active {
|
||||||
self.set_value_f32(remap_clamp(mouse_pos.x, left..=right, range.clone()));
|
self.set_value_f32(remap_clamp(mouse_pos.x, left..=right, range.clone()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ impl<'t> Widget for TextEdit<'t> {
|
||||||
|
|
||||||
if interact.clicked {
|
if interact.clicked {
|
||||||
ui.request_kb_focus(id);
|
ui.request_kb_focus(id);
|
||||||
if let Some(mouse_pos) = ui.input().mouse_pos {
|
if let Some(mouse_pos) = ui.input().mouse.pos {
|
||||||
state.cursor = Some(galley.char_at(mouse_pos - interact.rect.min).char_idx);
|
state.cursor = Some(galley.char_at(mouse_pos - interact.rect.min).char_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue