Browse Source

Ui: clean up min_rect/max_rect related functions

pull/28/head
Emil Ernerfeldt 4 years ago
parent
commit
3f345b5963
  1. 3
      egui/src/containers/collapsing_header.rs
  2. 6
      egui/src/containers/resize.rs
  3. 4
      egui/src/containers/window.rs
  4. 6
      egui/src/introspection.rs
  5. 140
      egui/src/ui.rs

3
egui/src/containers/collapsing_header.rs

@ -81,14 +81,13 @@ impl State {
clip_rect.max.y = clip_rect.max.y.min(child_ui.max_rect().top() + max_height);
child_ui.set_clip_rect(clip_rect);
let left_top = child_ui.left_top();
let r = add_contents(child_ui);
self.open_height = Some(child_ui.min_size().y);
// Pretend children took up less space:
let mut min_rect = child_ui.min_rect();
min_rect.max.y = min_rect.max.y.min(left_top.y + max_height);
min_rect.max.y = min_rect.max.y.min(min_rect.top() + max_height);
child_ui.force_set_min_rect(min_rect);
r
}))

6
egui/src/containers/resize.rs

@ -261,7 +261,7 @@ impl Resize {
// ------------------------------
if self.with_stroke && corner_response.is_some() {
let rect = Rect::from_min_size(content_ui.left_top(), state.desired_size);
let rect = Rect::from_min_size(content_ui.min_rect().left_top(), state.desired_size);
let rect = rect.expand(2.0); // breathing room for content
ui.painter().add(paint::PaintCmd::Rect {
rect,
@ -283,12 +283,12 @@ impl Resize {
if ui.ctx().style().visuals.debug_resize {
ui.ctx().debug_painter().debug_rect(
Rect::from_min_size(content_ui.left_top(), state.desired_size),
Rect::from_min_size(content_ui.min_rect().left_top(), state.desired_size),
color::GREEN,
"desired_size",
);
ui.ctx().debug_painter().debug_rect(
Rect::from_min_size(content_ui.left_top(), state.last_content_size),
Rect::from_min_size(content_ui.min_rect().left_top(), state.last_content_size),
color::LIGHT_BLUE,
"last_content_size",
);

4
egui/src/containers/window.rs

@ -643,7 +643,7 @@ fn show_title_bar(
),
Vec2::splat(button_size),
);
ui.expand_to_include_child(close_rect);
ui.expand_to_include_rect(close_rect);
}
TitleBar {
@ -724,7 +724,7 @@ impl TitleBar {
fn close_button(ui: &mut Ui, rect: Rect) -> Response {
let close_id = ui.make_child_id("window_close_button");
let response = ui.interact(rect, close_id, Sense::click());
ui.expand_to_include_child(response.rect);
ui.expand_to_include_rect(response.rect);
let stroke = ui.style().interact(&response).fg_stroke;
ui.painter()

6
egui/src/introspection.rs

@ -30,7 +30,11 @@ impl Texture {
if ui.hovered(rect) {
show_tooltip(ui.ctx(), |ui| {
let pos = ui.input().mouse.pos.unwrap_or_else(|| ui.left_top());
let pos = ui
.input()
.mouse
.pos
.unwrap_or_else(|| ui.min_rect().left_top());
let zoom_rect = ui.allocate_space(vec2(128.0, 128.0));
let u = remap_clamp(pos.x, rect.x_range(), 0.0..=tex_w);
let v = remap_clamp(pos.y, rect.y_range(), 0.0..=tex_h);

140
egui/src/ui.rs

@ -179,28 +179,24 @@ impl Ui {
/// ## Sizes etc
impl Ui {
/// Screen-space position of this Ui.
/// This may have moved from its original if a child overflowed to the left or up (rare).
pub fn left_top(&self) -> Pos2 {
// If a child doesn't fit in max_rect, we have effectively expanded:
self.max_rect.min
}
/// Screen-space position of the current bottom right corner of this Ui.
/// This may move when we add children that overflow our desired rectangle bounds.
/// This position may be at infinity if the desired rect is infinite,
/// which happens when a parent widget says "be as big as you want to be".
pub fn right_bottom(&self) -> Pos2 {
// If a child doesn't fit in max_rect, we have effectively expanded:
self.max_rect.max
}
/// Bounding box of all contained children
/// The current size of this Ui.
/// Bounding box of all contained child widgets.
/// No matter what, the final Ui will be at least this large.
/// This will grow as new widgets are added, but never shrink.
pub fn min_rect(&self) -> Rect {
self.min_rect
}
/// Size of content; same as `min_rect().size()`
pub fn min_size(&self) -> Vec2 {
self.min_rect.size()
}
/// This is the soft max size of the Ui.
/// New widgets will *try* to fit within this rectangle.
/// For instance, text will wrap to fit within it.
/// If a widget doesn't fit within the `max_rect` then it will expand.
/// `max_rect()` is always at least as large as `min_rect()`.
pub fn max_rect(&self) -> Rect {
self.max_rect
}
@ -214,91 +210,111 @@ impl Ui {
/// If the desired rect is infinite ("be as big as you want")
/// this will be bounded by `min_rect` instead.
pub fn max_rect_finite(&self) -> Rect {
let mut right_bottom = self.min_rect.max;
if self.max_rect.max.x.is_finite() {
right_bottom.x = right_bottom.x.max(self.max_rect.max.x);
let mut result = self.max_rect;
if !result.min.x.is_finite() {
result.min.x = self.min_rect.min.x;
}
if !result.min.y.is_finite() {
result.min.y = self.min_rect.min.y;
}
if self.max_rect.max.y.is_finite() {
right_bottom.y = right_bottom.y.max(self.max_rect.max.y);
if !result.max.x.is_finite() {
result.max.x = self.min_rect.max.x;
}
if !result.max.y.is_finite() {
result.max.y = self.min_rect.max.y;
}
result
}
Rect::from_min_max(self.left_top(), right_bottom)
// ------------------------------------------------------------------------
/// Set the maximum size of the ui.
/// You won't be able to shrink it below the current minimum size.
pub fn set_max_size(&mut self, size: Vec2) {
self.set_max_width(size.x);
self.set_max_height(size.y);
}
/// Set the width of the ui.
/// You won't be able to shrink it beyond its current child bounds.
/// Set the maximum width of the ui.
/// You won't be able to shrink it below the current minimum size.
pub fn set_max_width(&mut self, width: f32) {
let min_width = self.min_rect.max.x - self.left_top().x;
let width = width.at_least(min_width);
self.max_rect.max.x = self.left_top().x + width;
if self.layout.dir() == Direction::Horizontal && self.layout.is_reversed() {
debug_assert_eq!(self.min_rect.max.x, self.max_rect.max.x);
self.max_rect.min.x = self.max_rect.max.x - width.at_least(self.min_rect.width());
} else {
debug_assert_eq!(self.min_rect.min.x, self.max_rect.min.x);
self.max_rect.max.x = self.max_rect.min.x + width.at_least(self.min_rect.width());
}
}
/// Set the height of the ui.
/// You won't be able to shrink it beyond its current child bounds.
/// Set the maximum height of the ui.
/// You won't be able to shrink it below the current minimum size.
pub fn set_max_height(&mut self, height: f32) {
let min_height = self.min_rect.max.y - self.left_top().y;
let height = height.at_least(min_height);
self.max_rect.max.y = self.left_top().y + height;
if self.layout.dir() == Direction::Vertical && self.layout.is_reversed() {
debug_assert_eq!(self.min_rect.max.y, self.max_rect.max.y);
self.max_rect.min.y = self.max_rect.max.y - height.at_least(self.min_rect.height());
} else {
debug_assert_eq!(self.min_rect.min.y, self.max_rect.min.y);
self.max_rect.max.y = self.max_rect.min.y + height.at_least(self.min_rect.height());
}
}
// ------------------------------------------------------------------------
/// Set the minimum size of the ui.
/// This can't shrink the ui, only make it larger.
pub fn set_min_size(&mut self, size: Vec2) {
self.set_min_width(size.x);
self.set_min_height(size.y);
}
/// Set the minimum width of the ui.
/// This can't shrink the ui, only make it larger.
pub fn set_min_width(&mut self, width: f32) {
if self.layout.dir() == Direction::Horizontal && self.layout.is_reversed() {
debug_assert_eq!(self.min_rect.max.x, self.max_rect.max.x);
self.min_rect.min.x = self.min_rect.min.x.min(self.min_rect.max.x - width);
self.max_rect.min.x = self.max_rect.min.x.min(self.max_rect.max.x - width);
} else {
debug_assert_eq!(self.min_rect.min.x, self.max_rect.min.x);
self.min_rect.max.x = self.min_rect.max.x.max(self.min_rect.min.x + width);
self.max_rect.max.x = self.max_rect.max.x.max(self.max_rect.min.x + width);
}
self.max_rect = self.max_rect.union(self.min_rect);
}
/// Set the minimum height of the ui.
/// This can't shrink the ui, only make it larger.
pub fn set_min_height(&mut self, height: f32) {
if self.layout.dir() == Direction::Vertical && self.layout.is_reversed() {
debug_assert_eq!(self.min_rect.max.y, self.max_rect.max.y);
self.min_rect.min.y = self.min_rect.min.y.min(self.min_rect.max.y - height);
self.max_rect.min.y = self.max_rect.min.y.min(self.max_rect.max.y - height);
} else {
debug_assert_eq!(self.min_rect.min.y, self.max_rect.min.y);
self.min_rect.max.y = self.min_rect.max.y.max(self.min_rect.min.y + height);
self.max_rect.max.y = self.max_rect.max.y.max(self.max_rect.min.y + height);
}
self.max_rect = self.max_rect.union(self.min_rect);
}
/// Helper: shrinks the max/desired width to the current width,
// ------------------------------------------------------------------------
/// Helper: shrinks the max width to the current width,
/// so further widgets will try not to be wider than previous widgets.
/// Useful for normal vertical layouts.
pub fn shrink_width_to_current(&mut self) {
self.set_max_width(self.min_rect().width())
}
/// Helper: shrinks the max/desired height to the current height,
/// Helper: shrinks the max height to the current height,
/// so further widgets will try not to be wider than previous widgets.
pub fn shrink_height_to_current(&mut self) {
self.set_min_height(self.min_rect().height())
}
/// Size of content
pub fn min_size(&self) -> Vec2 {
self.min_rect.size()
self.set_max_height(self.min_rect().height())
}
/// Expand the bounding rect of this ui to include a child at the given rect.
pub fn expand_to_include_child(&mut self, rect: Rect) {
/// Expand the `min_rect` and `max_rect` of this ui to include a child at the given rect.
pub fn expand_to_include_rect(&mut self, rect: Rect) {
self.min_rect = self.min_rect.union(rect);
self.max_rect = self.max_rect.union(rect);
}
pub fn expand_to_size(&mut self, size: Vec2) {
self.min_rect.extend_with(self.left_top() + size);
self.max_rect.extend_with(self.left_top() + size);
}
// ------------------------------------------------------------------------
// Layout related measures:
@ -318,13 +334,6 @@ impl Ui {
pub fn available_finite(&self) -> Rect {
self.layout.available(self.cursor, self.max_rect_finite())
}
// ------------------------------------------------------------------------
pub fn contains_mouse(&self, rect: Rect) -> bool {
self.ctx()
.contains_mouse(self.layer(), self.clip_rect(), rect)
}
}
/// # `Id` creation
@ -393,6 +402,11 @@ impl Ui {
self.interact_hover(rect).hovered
}
pub fn contains_mouse(&self, rect: Rect) -> bool {
self.ctx()
.contains_mouse(self.layer(), self.clip_rect(), rect)
}
// ------------------------------------------------------------------------
// Stuff that moves the cursor, i.e. allocates space in this ui!
@ -664,7 +678,7 @@ impl Ui {
"You can only indent vertical layouts"
);
let indent = vec2(self.style().spacing.indent, 0.0);
let child_rect = Rect::from_min_max(self.cursor + indent, self.right_bottom()); // TODO: wrong for reversed layouts
let child_rect = Rect::from_min_max(self.cursor + indent, self.max_rect.right_bottom()); // TODO: wrong for reversed layouts
let mut child_ui = Ui {
id: self.id.with(id_source),
..self.child_ui(child_rect, self.layout)
@ -788,8 +802,10 @@ impl Ui {
let mut columns: Vec<Self> = (0..num_columns)
.map(|col_idx| {
let pos = self.cursor + vec2((col_idx as f32) * (column_width + spacing), 0.0);
let child_rect =
Rect::from_min_max(pos, pos2(pos.x + column_width, self.right_bottom().y));
let child_rect = Rect::from_min_max(
pos,
pos2(pos.x + column_width, self.max_rect.right_bottom().y),
);
Self {
id: self.make_child_id(&("column", col_idx)),

Loading…
Cancel
Save