Skip to content

Commit

Permalink
Revert "Allow overlapping interactive widgets (emilk#2244)"
Browse files Browse the repository at this point in the history
This reverts commit d5eb877.
  • Loading branch information
NiceneNerd committed Dec 29, 2022
1 parent ae76973 commit 3803a32
Show file tree
Hide file tree
Showing 10 changed files with 699 additions and 771 deletions.
1,162 changes: 605 additions & 557 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -28,7 +28,7 @@ opt-level = 2 # fast and small wasm, basically same as `opt-level = 's'`

[profile.dev]
split-debuginfo = "unpacked" # faster debug builds on mac
# opt-level = 1 # Make debug builds run faster
opt-level = 1 # Make debug builds run faster

# Optimize all dependencies even in debug builds (does not affect workspace packages):
[profile.dev.package."*"]
Expand Down
88 changes: 40 additions & 48 deletions crates/egui/src/containers/area.rs
Expand Up @@ -189,7 +189,7 @@ impl Area {
pub(crate) struct Prepared {
layer_id: LayerId,
state: State,
move_response: Response,
pub(crate) movable: bool,
enabled: bool,
drag_bounds: Option<Rect>,

Expand Down Expand Up @@ -254,49 +254,6 @@ impl Area {
state.pos = anchor.align_size_within_rect(state.size, screen).min + offset;
}

// interact right away to prevent frame-delay
let move_response = {
let interact_id = layer_id.id.with("move");
let sense = if movable {
Sense::click_and_drag()
} else if interactable {
Sense::click() // allow clicks to bring to front
} else {
Sense::hover()
};

let move_response = ctx.interact(
Rect::EVERYTHING,
ctx.style().spacing.item_spacing,
layer_id,
interact_id,
state.rect(),
sense,
enabled,
);

// Important check - don't try to move e.g. a combobox popup!
if movable {
if move_response.dragged() {
state.pos += ctx.input().pointer.delta();
}

state.pos = ctx
.constrain_window_rect_to_area(state.rect(), drag_bounds)
.min;
}

if (move_response.dragged() || move_response.clicked())
|| pointer_pressed_on_area(ctx, layer_id)
|| !ctx.memory().areas.visible_last_frame(&layer_id)
{
ctx.memory().areas.move_to_top(layer_id);
ctx.request_repaint();
}

move_response
};

state.pos = ctx.round_pos_to_pixels(state.pos);

if constrain {
Expand All @@ -308,7 +265,7 @@ impl Area {
Prepared {
layer_id,
state,
move_response,
movable,
enabled,
drag_bounds,
temporarily_invisible: is_new,
Expand Down Expand Up @@ -402,14 +359,49 @@ impl Prepared {
let Prepared {
layer_id,
mut state,
move_response,
enabled: _,
drag_bounds: _,
movable,
enabled,
drag_bounds,
temporarily_invisible: _,
} = self;

state.size = content_ui.min_rect().size();

let interact_id = layer_id.id.with("move");
let sense = if movable {
Sense::click_and_drag()
} else {
Sense::click() // allow clicks to bring to front
};

let move_response = ctx.interact(
Rect::EVERYTHING,
ctx.style().spacing.item_spacing,
layer_id,
interact_id,
state.rect(),
sense,
enabled,
);

if move_response.dragged() && movable {
state.pos += ctx.input().pointer.delta();
}

// Important check - don't try to move e.g. a combobox popup!
if movable {
state.pos = ctx
.constrain_window_rect_to_area(state.rect(), drag_bounds)
.min;
}

if (move_response.dragged() || move_response.clicked())
|| pointer_pressed_on_area(ctx, layer_id)
|| !ctx.memory().areas.visible_last_frame(&layer_id)
{
ctx.memory().areas.move_to_top(layer_id);
ctx.request_repaint();
}
ctx.memory().areas.set_state(layer_id, state);

move_response
Expand Down
17 changes: 0 additions & 17 deletions crates/egui/src/containers/frame.rs
Expand Up @@ -115,45 +115,38 @@ impl Frame {
}

impl Frame {
#[inline]
pub fn fill(mut self, fill: Color32) -> Self {
self.fill = fill;
self
}

#[inline]
pub fn stroke(mut self, stroke: Stroke) -> Self {
self.stroke = stroke;
self
}

#[inline]
pub fn rounding(mut self, rounding: impl Into<Rounding>) -> Self {
self.rounding = rounding.into();
self
}

/// Margin within the painted frame.
#[inline]
pub fn inner_margin(mut self, inner_margin: impl Into<Margin>) -> Self {
self.inner_margin = inner_margin.into();
self
}

/// Margin outside the painted frame.
#[inline]
pub fn outer_margin(mut self, outer_margin: impl Into<Margin>) -> Self {
self.outer_margin = outer_margin.into();
self
}

#[deprecated = "Renamed inner_margin in egui 0.18"]
#[inline]
pub fn margin(self, margin: impl Into<Margin>) -> Self {
self.inner_margin(margin)
}

#[inline]
pub fn shadow(mut self, shadow: Shadow) -> Self {
self.shadow = shadow;
self
Expand All @@ -167,16 +160,6 @@ impl Frame {
}
}

impl Frame {
/// inner margin plus outer margin.
#[inline]
pub fn total_margin(&self) -> Margin {
self.inner_margin + self.outer_margin
}
}

// ----------------------------------------------------------------------------

pub struct Prepared {
pub frame: Frame,
where_to_put_background: ShapeIdx,
Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/containers/popup.rs
Expand Up @@ -355,7 +355,7 @@ pub fn popup_above_or_below_widget<R>(
// Note: we use a separate clip-rect for this area, so the popup can be outside the parent.
// See https://github.com/emilk/egui/issues/825
let frame = Frame::popup(ui.style());
let frame_margin = frame.total_margin();
let frame_margin = frame.inner_margin + frame.outer_margin;
frame
.show(ui, |ui| {
ui.with_layout(Layout::top_down_justified(Align::LEFT), |ui| {
Expand Down
77 changes: 37 additions & 40 deletions crates/egui/src/containers/scroll_area.rs
Expand Up @@ -14,12 +14,8 @@ pub struct State {
/// Positive offset means scrolling down/right
pub offset: Vec2,

/// Were the scroll bars visible last frame?
show_scroll: [bool; 2],

/// The content were to large to fit large frame.
content_is_too_large: [bool; 2],

/// Momentum, used for kinetic scrolling
#[cfg_attr(feature = "serde", serde(skip))]
vel: Vec2,
Expand All @@ -38,7 +34,6 @@ impl Default for State {
Self {
offset: Vec2::ZERO,
show_scroll: [false; 2],
content_is_too_large: [false; 2],
vel: Vec2::ZERO,
scroll_start_offset_from_top_left: [None; 2],
scroll_stuck_to_end: [true; 2],
Expand Down Expand Up @@ -422,40 +417,6 @@ impl ScrollArea {

let viewport = Rect::from_min_size(Pos2::ZERO + state.offset, inner_size);

if scrolling_enabled && (state.content_is_too_large[0] || state.content_is_too_large[1]) {
// Drag contents to scroll (for touch screens mostly).
// We must do this BEFORE adding content to the `ScrollArea`,
// or we will steal input from the widgets we contain.
let content_response = ui.interact(inner_rect, id.with("area"), Sense::drag());

if content_response.dragged() {
for d in 0..2 {
if has_bar[d] {
state.offset[d] -= ui.input().pointer.delta()[d];
state.vel[d] = ui.input().pointer.velocity()[d];
state.scroll_stuck_to_end[d] = false;
} else {
state.vel[d] = 0.0;
}
}
} else {
let stop_speed = 20.0; // Pixels per second.
let friction_coeff = 1000.0; // Pixels per second squared.
let dt = ui.input().unstable_dt;

let friction = friction_coeff * dt;
if friction > state.vel.length() || state.vel.length() < stop_speed {
state.vel = Vec2::ZERO;
} else {
state.vel -= friction * state.vel.normalized();
// Offset has an inverted coordinate system compared to
// the velocity, so we subtract it instead of adding it
state.offset -= state.vel * dt;
ui.ctx().request_repaint();
}
}
}

Prepared {
id,
state,
Expand Down Expand Up @@ -646,6 +607,43 @@ impl Prepared {
content_size.y > inner_rect.height(),
];

if content_is_too_large[0] || content_is_too_large[1] {
// Drag contents to scroll (for touch screens mostly):
let sense = if self.scrolling_enabled {
Sense::drag()
} else {
Sense::hover()
};
let content_response = ui.interact(inner_rect, id.with("area"), sense);

if content_response.dragged() {
for d in 0..2 {
if has_bar[d] {
state.offset[d] -= ui.input().pointer.delta()[d];
state.vel[d] = ui.input().pointer.velocity()[d];
state.scroll_stuck_to_end[d] = false;
} else {
state.vel[d] = 0.0;
}
}
} else {
let stop_speed = 20.0; // Pixels per second.
let friction_coeff = 1000.0; // Pixels per second squared.
let dt = ui.input().unstable_dt;

let friction = friction_coeff * dt;
if friction > state.vel.length() || state.vel.length() < stop_speed {
state.vel = Vec2::ZERO;
} else {
state.vel -= friction * state.vel.normalized();
// Offset has an inverted coordinate system compared to
// the velocity, so we subtract it instead of adding it
state.offset -= state.vel * dt;
ui.ctx().request_repaint();
}
}
}

let max_offset = content_size - inner_rect.size();
if scrolling_enabled && ui.rect_contains_pointer(outer_rect) {
for d in 0..2 {
Expand Down Expand Up @@ -856,7 +854,6 @@ impl Prepared {
];

state.show_scroll = show_scroll_this_frame;
state.content_is_too_large = content_is_too_large;

state.store(ui.ctx(), id);

Expand Down
5 changes: 1 addition & 4 deletions crates/egui/src/containers/window.rs
Expand Up @@ -899,11 +899,8 @@ impl TitleBar {
ui.painter().hline(outer_rect.x_range(), y, stroke);
}

// Don't cover the close- and collapse buttons:
let double_click_rect = self.rect.shrink2(vec2(32.0, 0.0));

if ui
.interact(double_click_rect, self.id, Sense::click())
.interact(self.rect, self.id, Sense::click())
.double_clicked()
&& collapsible
{
Expand Down

0 comments on commit 3803a32

Please sign in to comment.