[window] remove frame delay when moving/resizing
This commit is contained in:
parent
bcc786fd95
commit
3de20d033e
4 changed files with 69 additions and 38 deletions
|
@ -24,6 +24,12 @@ pub(crate) struct State {
|
||||||
pub vel: Vec2,
|
pub vel: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
pub fn rect(&self) -> Rect {
|
||||||
|
Rect::from_min_size(self.pos, self.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Area {
|
pub struct Area {
|
||||||
id: Id,
|
id: Id,
|
||||||
|
@ -93,9 +99,8 @@ impl Area {
|
||||||
|
|
||||||
pub(crate) struct Prepared {
|
pub(crate) struct Prepared {
|
||||||
layer: Layer,
|
layer: Layer,
|
||||||
pub(crate) state: State,
|
state: State,
|
||||||
movable: bool,
|
movable: bool,
|
||||||
pub(crate) content_ui: Ui,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Area {
|
impl Area {
|
||||||
|
@ -122,35 +127,44 @@ impl Area {
|
||||||
state.pos = fixed_pos.unwrap_or(state.pos);
|
state.pos = fixed_pos.unwrap_or(state.pos);
|
||||||
state.pos = state.pos.round();
|
state.pos = state.pos.round();
|
||||||
|
|
||||||
let content_ui = Ui::new(
|
|
||||||
ctx.clone(),
|
|
||||||
layer,
|
|
||||||
id,
|
|
||||||
Rect::from_min_size(state.pos, Vec2::infinity()),
|
|
||||||
);
|
|
||||||
|
|
||||||
Prepared {
|
Prepared {
|
||||||
layer,
|
layer,
|
||||||
state,
|
state,
|
||||||
movable,
|
movable,
|
||||||
content_ui,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(self, ctx: &Arc<Context>, add_contents: impl FnOnce(&mut Ui)) -> InteractInfo {
|
pub fn show(self, ctx: &Arc<Context>, add_contents: impl FnOnce(&mut Ui)) -> InteractInfo {
|
||||||
let mut prepared = self.begin(ctx);
|
let prepared = self.begin(ctx);
|
||||||
add_contents(&mut prepared.content_ui);
|
let mut content_ui = prepared.content_ui(ctx);
|
||||||
prepared.end(ctx)
|
add_contents(&mut content_ui);
|
||||||
|
prepared.end(ctx, content_ui)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Prepared {
|
impl Prepared {
|
||||||
pub(crate) fn end(self, ctx: &Arc<Context>) -> InteractInfo {
|
pub(crate) fn state(&self) -> &State {
|
||||||
|
&self.state
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn state_mut(&mut self) -> &mut State {
|
||||||
|
&mut self.state
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn content_ui(&self, ctx: &Arc<Context>) -> Ui {
|
||||||
|
Ui::new(
|
||||||
|
ctx.clone(),
|
||||||
|
self.layer,
|
||||||
|
self.layer.id,
|
||||||
|
Rect::from_min_size(self.state.pos, Vec2::infinity()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn end(self, ctx: &Arc<Context>, content_ui: Ui) -> InteractInfo {
|
||||||
let Prepared {
|
let Prepared {
|
||||||
layer,
|
layer,
|
||||||
mut state,
|
mut state,
|
||||||
movable,
|
movable,
|
||||||
content_ui,
|
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
state.size = (content_ui.child_bounds().max - state.pos).ceil();
|
state.size = (content_ui.child_bounds().max - state.pos).ceil();
|
||||||
|
|
|
@ -167,9 +167,29 @@ impl<'open> Window<'open> {
|
||||||
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));
|
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));
|
||||||
|
|
||||||
let mut area = area.begin(ctx);
|
let mut area = area.begin(ctx);
|
||||||
|
|
||||||
|
// First interact (move etc) to avoid frame delay:
|
||||||
|
let last_frame_outer_rect = area.state().rect();
|
||||||
|
let interaction = if possible.movable || possible.resizable {
|
||||||
|
interact(
|
||||||
|
ctx,
|
||||||
|
possible,
|
||||||
|
area_layer,
|
||||||
|
area.state_mut(),
|
||||||
|
window_id,
|
||||||
|
resize_id,
|
||||||
|
last_frame_outer_rect,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let hover_interaction = resize_hover(ctx, possible, area_layer, last_frame_outer_rect);
|
||||||
|
|
||||||
|
let mut area_content_ui = area.content_ui(ctx);
|
||||||
|
|
||||||
{
|
{
|
||||||
// BEGIN FRAME --------------------------------
|
// BEGIN FRAME --------------------------------
|
||||||
let mut frame = frame.begin(&mut area.content_ui);
|
let mut frame = frame.begin(&mut area_content_ui);
|
||||||
|
|
||||||
let default_expanded = true;
|
let default_expanded = true;
|
||||||
let mut collapsing = collapsing_header::State::from_memory_with_default_open(
|
let mut collapsing = collapsing_header::State::from_memory_with_default_open(
|
||||||
|
@ -201,40 +221,25 @@ impl<'open> Window<'open> {
|
||||||
})
|
})
|
||||||
.map(|ri| ri.1);
|
.map(|ri| ri.1);
|
||||||
|
|
||||||
let outer_rect = frame.end(&mut area.content_ui);
|
let outer_rect = frame.end(&mut area_content_ui);
|
||||||
// END FRAME --------------------------------
|
// END FRAME --------------------------------
|
||||||
|
|
||||||
let interaction = if possible.movable || possible.resizable {
|
|
||||||
interact(
|
|
||||||
ctx,
|
|
||||||
possible,
|
|
||||||
area_layer,
|
|
||||||
&mut area.state,
|
|
||||||
window_id,
|
|
||||||
resize_id,
|
|
||||||
outer_rect,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let hover_interaction = resize_hover(ctx, possible, area_layer, outer_rect);
|
|
||||||
|
|
||||||
title_bar.ui(
|
title_bar.ui(
|
||||||
&mut area.content_ui,
|
&mut area_content_ui,
|
||||||
outer_rect,
|
outer_rect,
|
||||||
content_rect,
|
content_rect,
|
||||||
open,
|
open,
|
||||||
&mut collapsing,
|
&mut collapsing,
|
||||||
);
|
);
|
||||||
|
|
||||||
area.content_ui
|
area_content_ui
|
||||||
.memory()
|
.memory()
|
||||||
.collapsing_headers
|
.collapsing_headers
|
||||||
.insert(collapsing_id, collapsing);
|
.insert(collapsing_id, collapsing);
|
||||||
|
|
||||||
if let Some(interaction) = interaction {
|
if let Some(interaction) = interaction {
|
||||||
paint_frame_interaction(
|
paint_frame_interaction(
|
||||||
&mut area.content_ui,
|
&mut area_content_ui,
|
||||||
outer_rect,
|
outer_rect,
|
||||||
interaction,
|
interaction,
|
||||||
ctx.style().interact.active,
|
ctx.style().interact.active,
|
||||||
|
@ -242,7 +247,7 @@ impl<'open> Window<'open> {
|
||||||
} else {
|
} else {
|
||||||
if let Some(hover_interaction) = hover_interaction {
|
if let Some(hover_interaction) = hover_interaction {
|
||||||
paint_frame_interaction(
|
paint_frame_interaction(
|
||||||
&mut area.content_ui,
|
&mut area_content_ui,
|
||||||
outer_rect,
|
outer_rect,
|
||||||
hover_interaction,
|
hover_interaction,
|
||||||
ctx.style().interact.hovered,
|
ctx.style().interact.hovered,
|
||||||
|
@ -250,7 +255,7 @@ impl<'open> Window<'open> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let full_interact = area.end(ctx);
|
let full_interact = area.end(ctx, area_content_ui);
|
||||||
|
|
||||||
Some(full_interact)
|
Some(full_interact)
|
||||||
}
|
}
|
||||||
|
@ -377,6 +382,7 @@ fn window_interaction(
|
||||||
hover_window_interaction.set_cursor(ctx);
|
hover_window_interaction.set_cursor(ctx);
|
||||||
if ctx.input().mouse.pressed {
|
if ctx.input().mouse.pressed {
|
||||||
ctx.memory().interaction.drag_id = Some(id);
|
ctx.memory().interaction.drag_id = Some(id);
|
||||||
|
ctx.memory().interaction.drag_is_window = true;
|
||||||
window_interaction = Some(hover_window_interaction);
|
window_interaction = Some(hover_window_interaction);
|
||||||
ctx.memory().window_interaction = window_interaction;
|
ctx.memory().window_interaction = window_interaction;
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,9 +309,13 @@ impl Context {
|
||||||
info.active = true;
|
info.active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if sense.drag && !memory.interaction.drag_id.is_some() {
|
if sense.drag
|
||||||
|
&& (!memory.interaction.drag_id.is_some() || memory.interaction.drag_is_window)
|
||||||
|
{
|
||||||
// start of a drag
|
// start of a drag
|
||||||
memory.interaction.drag_id = Some(interaction_id);
|
memory.interaction.drag_id = Some(interaction_id);
|
||||||
|
memory.interaction.drag_is_window = false;
|
||||||
|
memory.window_interaction = None; // HACK: stop moving windows (if any)
|
||||||
info.active = true;
|
info.active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,13 @@ pub struct Interaction {
|
||||||
/// A widget interested in drags that has a mouse press on it.
|
/// A widget interested in drags that has a mouse press on it.
|
||||||
pub drag_id: Option<Id>,
|
pub drag_id: Option<Id>,
|
||||||
|
|
||||||
|
/// HACK: windows have low priority on dragging.
|
||||||
|
/// This is so that if you drag a slider in a window,
|
||||||
|
/// the slider will steal the drag away from the window.
|
||||||
|
/// This is needed because we do window interaction first (to prevent frame delay),
|
||||||
|
/// and then do content layout.
|
||||||
|
pub drag_is_window: bool,
|
||||||
|
|
||||||
/// Any interest in catching clicks this frame?
|
/// Any interest in catching clicks this frame?
|
||||||
/// Cleared to false at start of each frame.
|
/// Cleared to false at start of each frame.
|
||||||
pub click_interest: bool,
|
pub click_interest: bool,
|
||||||
|
|
Loading…
Reference in a new issue