Improve window throwing

This commit is contained in:
Emil Ernerfeldt 2020-05-17 17:44:18 +02:00
parent 84099b24c9
commit d123d7e9c6
3 changed files with 43 additions and 52 deletions

View file

@ -255,17 +255,17 @@ struct PossibleInteractions {
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct FrameInteraction { pub(crate) struct WindowInteraction {
area_layer: Layer, pub(crate) area_layer: Layer,
start_rect: Rect, pub(crate) start_rect: Rect,
start_mouse_pos: Pos2, pub(crate) start_mouse_pos: Pos2,
left: bool, pub(crate) left: bool,
right: bool, pub(crate) right: bool,
top: bool, pub(crate) top: bool,
bottom: bool, pub(crate) bottom: bool,
} }
impl FrameInteraction { impl WindowInteraction {
pub fn set_cursor(&self, ctx: &Context) { pub fn set_cursor(&self, ctx: &Context) {
if (self.left && self.top) || (self.right && self.bottom) { if (self.left && self.top) || (self.right && self.bottom) {
ctx.output().cursor_icon = CursorIcon::ResizeNwSe; ctx.output().cursor_icon = CursorIcon::ResizeNwSe;
@ -281,10 +281,6 @@ impl FrameInteraction {
pub fn is_resize(&self) -> bool { pub fn is_resize(&self) -> bool {
self.left || self.right || self.top || self.bottom self.left || self.right || self.top || self.bottom
} }
pub fn is_pure_move(&self) -> bool {
!self.is_resize()
}
} }
fn resize_window( fn resize_window(
@ -294,26 +290,26 @@ fn resize_window(
id: Id, id: Id,
mut rect: Rect, mut rect: Rect,
) -> Rect { ) -> Rect {
if let Some(frame_interaction) = frame_interaction(ctx, possible, area_layer, id, rect) { if let Some(window_interaction) = window_interaction(ctx, possible, area_layer, id, rect) {
frame_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 {
rect = frame_interaction.start_rect; // prevent drift rect = window_interaction.start_rect; // prevent drift
if frame_interaction.is_resize() { if window_interaction.is_resize() {
if frame_interaction.left { if window_interaction.left {
rect.min.x = ctx.round_to_pixel(mouse_pos.x); rect.min.x = ctx.round_to_pixel(mouse_pos.x);
} else if frame_interaction.right { } else if window_interaction.right {
rect.max.x = ctx.round_to_pixel(mouse_pos.x); rect.max.x = ctx.round_to_pixel(mouse_pos.x);
} }
if frame_interaction.top { if window_interaction.top {
rect.min.y = ctx.round_to_pixel(mouse_pos.y); rect.min.y = ctx.round_to_pixel(mouse_pos.y);
} else if frame_interaction.bottom { } else if window_interaction.bottom {
rect.max.y = ctx.round_to_pixel(mouse_pos.y); rect.max.y = ctx.round_to_pixel(mouse_pos.y);
} }
} else { } else {
// movevement // movevement
rect = rect.translate(mouse_pos - frame_interaction.start_mouse_pos); rect = rect.translate(mouse_pos - window_interaction.start_mouse_pos);
} }
} }
} }
@ -321,55 +317,39 @@ fn resize_window(
return rect; return rect;
} }
fn frame_interaction( fn window_interaction(
ctx: &Context, ctx: &Context,
possible: PossibleInteractions, possible: PossibleInteractions,
area_layer: Layer, area_layer: Layer,
id: Id, id: Id,
rect: Rect, rect: Rect,
) -> Option<FrameInteraction> { ) -> Option<WindowInteraction> {
{ {
let active_id = ctx.memory().active_id; let active_id = ctx.memory().active_id;
if active_id.is_none() {
let frame_interaction = ctx.memory().frame_interaction;
if let Some(frame_interaction) = frame_interaction {
if frame_interaction.area_layer == area_layer {
eprintln!("Letting go of window");
if frame_interaction.is_pure_move() {
// Throw window:
let mut area_state = ctx.memory().areas.get(area_layer.id).unwrap();
area_state.vel = ctx.input().mouse_velocity;
eprintln!("Throwing window with velocity {:?}", area_state.vel);
ctx.memory().areas.set_state(area_layer, area_state);
}
ctx.memory().frame_interaction = None;
}
}
}
if active_id.is_some() && active_id != Some(id) { if active_id.is_some() && active_id != Some(id) {
return None; return None;
} }
} }
let mut frame_interaction = { ctx.memory().frame_interaction.clone() }; let mut window_interaction = { ctx.memory().window_interaction.clone() };
if frame_interaction.is_none() { if window_interaction.is_none() {
if let Some(hover_frame_interaction) = resize_hover(ctx, possible, area_layer, rect) { if let Some(hover_window_interaction) = resize_hover(ctx, possible, area_layer, rect) {
hover_frame_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);
frame_interaction = Some(hover_frame_interaction); window_interaction = Some(hover_window_interaction);
ctx.memory().frame_interaction = frame_interaction; ctx.memory().window_interaction = window_interaction;
} }
} }
} }
if let Some(frame_interaction) = frame_interaction { if let Some(window_interaction) = window_interaction {
let is_active = ctx.memory().active_id == Some(id); let is_active = ctx.memory().active_id == Some(id);
if is_active && frame_interaction.area_layer == area_layer { if is_active && window_interaction.area_layer == area_layer {
return Some(frame_interaction); return Some(window_interaction);
} }
} }
@ -381,7 +361,7 @@ fn resize_hover(
possible: PossibleInteractions, possible: PossibleInteractions,
area_layer: Layer, area_layer: Layer,
rect: Rect, rect: Rect,
) -> Option<FrameInteraction> { ) -> 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 {
@ -427,7 +407,7 @@ fn resize_hover(
} }
if any_resize || possible.movable { if any_resize || possible.movable {
Some(FrameInteraction { Some(WindowInteraction {
area_layer, area_layer,
start_rect: rect, start_rect: rect,
start_mouse_pos: mouse_pos, start_mouse_pos: mouse_pos,

View file

@ -169,6 +169,17 @@ impl Context {
fn begin_frame_mut(&mut self, new_raw_input: RawInput) { fn begin_frame_mut(&mut self, new_raw_input: RawInput) {
if !self.raw_input.mouse_down || self.raw_input.mouse_pos.is_none() { if !self.raw_input.mouse_down || self.raw_input.mouse_pos.is_none() {
self.memory().active_id = None; self.memory().active_id = None;
let window_interaction = self.memory().window_interaction.take();
if let Some(window_interaction) = window_interaction {
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 {
// Throw windows because it is fun:
area_state.vel = self.input().mouse_velocity;
self.memory().areas.set_state(area_layer, area_state);
}
}
} }
self.used_ids.lock().clear(); self.used_ids.lock().clear();

View file

@ -25,7 +25,7 @@ pub struct Memory {
pub(crate) text_edit: HashMap<Id, text_edit::State>, pub(crate) text_edit: HashMap<Id, text_edit::State>,
#[serde(skip)] #[serde(skip)]
pub(crate) frame_interaction: Option<window::FrameInteraction>, pub(crate) window_interaction: Option<window::WindowInteraction>,
pub(crate) areas: Areas, pub(crate) areas: Areas,
} }