Ui: clean up min_rect/max_rect related functions
This commit is contained in:
parent
ba98ea715f
commit
3f345b5963
5 changed files with 90 additions and 71 deletions
|
@ -81,14 +81,13 @@ impl State {
|
||||||
clip_rect.max.y = clip_rect.max.y.min(child_ui.max_rect().top() + max_height);
|
clip_rect.max.y = clip_rect.max.y.min(child_ui.max_rect().top() + max_height);
|
||||||
child_ui.set_clip_rect(clip_rect);
|
child_ui.set_clip_rect(clip_rect);
|
||||||
|
|
||||||
let left_top = child_ui.left_top();
|
|
||||||
let r = add_contents(child_ui);
|
let r = add_contents(child_ui);
|
||||||
|
|
||||||
self.open_height = Some(child_ui.min_size().y);
|
self.open_height = Some(child_ui.min_size().y);
|
||||||
|
|
||||||
// Pretend children took up less space:
|
// Pretend children took up less space:
|
||||||
let mut min_rect = child_ui.min_rect();
|
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);
|
child_ui.force_set_min_rect(min_rect);
|
||||||
r
|
r
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -261,7 +261,7 @@ impl Resize {
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
if self.with_stroke && corner_response.is_some() {
|
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
|
let rect = rect.expand(2.0); // breathing room for content
|
||||||
ui.painter().add(paint::PaintCmd::Rect {
|
ui.painter().add(paint::PaintCmd::Rect {
|
||||||
rect,
|
rect,
|
||||||
|
@ -283,12 +283,12 @@ impl Resize {
|
||||||
|
|
||||||
if ui.ctx().style().visuals.debug_resize {
|
if ui.ctx().style().visuals.debug_resize {
|
||||||
ui.ctx().debug_painter().debug_rect(
|
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,
|
color::GREEN,
|
||||||
"desired_size",
|
"desired_size",
|
||||||
);
|
);
|
||||||
ui.ctx().debug_painter().debug_rect(
|
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,
|
color::LIGHT_BLUE,
|
||||||
"last_content_size",
|
"last_content_size",
|
||||||
);
|
);
|
||||||
|
|
|
@ -643,7 +643,7 @@ fn show_title_bar(
|
||||||
),
|
),
|
||||||
Vec2::splat(button_size),
|
Vec2::splat(button_size),
|
||||||
);
|
);
|
||||||
ui.expand_to_include_child(close_rect);
|
ui.expand_to_include_rect(close_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
TitleBar {
|
TitleBar {
|
||||||
|
@ -724,7 +724,7 @@ impl TitleBar {
|
||||||
fn close_button(ui: &mut Ui, rect: Rect) -> Response {
|
fn close_button(ui: &mut Ui, rect: Rect) -> Response {
|
||||||
let close_id = ui.make_child_id("window_close_button");
|
let close_id = ui.make_child_id("window_close_button");
|
||||||
let response = ui.interact(rect, close_id, Sense::click());
|
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;
|
let stroke = ui.style().interact(&response).fg_stroke;
|
||||||
ui.painter()
|
ui.painter()
|
||||||
|
|
|
@ -30,7 +30,11 @@ impl Texture {
|
||||||
|
|
||||||
if ui.hovered(rect) {
|
if ui.hovered(rect) {
|
||||||
show_tooltip(ui.ctx(), |ui| {
|
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 zoom_rect = ui.allocate_space(vec2(128.0, 128.0));
|
||||||
let u = remap_clamp(pos.x, rect.x_range(), 0.0..=tex_w);
|
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);
|
let v = remap_clamp(pos.y, rect.y_range(), 0.0..=tex_h);
|
||||||
|
|
140
egui/src/ui.rs
140
egui/src/ui.rs
|
@ -179,28 +179,24 @@ impl Ui {
|
||||||
|
|
||||||
/// ## Sizes etc
|
/// ## Sizes etc
|
||||||
impl Ui {
|
impl Ui {
|
||||||
/// Screen-space position of this Ui.
|
/// The current size of this Ui.
|
||||||
/// This may have moved from its original if a child overflowed to the left or up (rare).
|
/// Bounding box of all contained child widgets.
|
||||||
pub fn left_top(&self) -> Pos2 {
|
/// No matter what, the final Ui will be at least this large.
|
||||||
// If a child doesn't fit in max_rect, we have effectively expanded:
|
/// This will grow as new widgets are added, but never shrink.
|
||||||
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
|
|
||||||
pub fn min_rect(&self) -> Rect {
|
pub fn min_rect(&self) -> Rect {
|
||||||
self.min_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.
|
/// 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 {
|
pub fn max_rect(&self) -> Rect {
|
||||||
self.max_rect
|
self.max_rect
|
||||||
}
|
}
|
||||||
|
@ -214,91 +210,111 @@ impl Ui {
|
||||||
/// If the desired rect is infinite ("be as big as you want")
|
/// If the desired rect is infinite ("be as big as you want")
|
||||||
/// this will be bounded by `min_rect` instead.
|
/// this will be bounded by `min_rect` instead.
|
||||||
pub fn max_rect_finite(&self) -> Rect {
|
pub fn max_rect_finite(&self) -> Rect {
|
||||||
let mut right_bottom = self.min_rect.max;
|
let mut result = self.max_rect;
|
||||||
if self.max_rect.max.x.is_finite() {
|
if !result.min.x.is_finite() {
|
||||||
right_bottom.x = right_bottom.x.max(self.max_rect.max.x);
|
result.min.x = self.min_rect.min.x;
|
||||||
}
|
}
|
||||||
if self.max_rect.max.y.is_finite() {
|
if !result.min.y.is_finite() {
|
||||||
right_bottom.y = right_bottom.y.max(self.max_rect.max.y);
|
result.min.y = self.min_rect.min.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.
|
/// Set the maximum width of the ui.
|
||||||
/// You won't be able to shrink it beyond its current child bounds.
|
/// You won't be able to shrink it below the current minimum size.
|
||||||
pub fn set_max_width(&mut self, width: f32) {
|
pub fn set_max_width(&mut self, width: f32) {
|
||||||
let min_width = self.min_rect.max.x - self.left_top().x;
|
if self.layout.dir() == Direction::Horizontal && self.layout.is_reversed() {
|
||||||
let width = width.at_least(min_width);
|
debug_assert_eq!(self.min_rect.max.x, self.max_rect.max.x);
|
||||||
self.max_rect.max.x = self.left_top().x + width;
|
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.
|
/// Set the maximum height of the ui.
|
||||||
/// You won't be able to shrink it beyond its current child bounds.
|
/// You won't be able to shrink it below the current minimum size.
|
||||||
pub fn set_max_height(&mut self, height: f32) {
|
pub fn set_max_height(&mut self, height: f32) {
|
||||||
let min_height = self.min_rect.max.y - self.left_top().y;
|
if self.layout.dir() == Direction::Vertical && self.layout.is_reversed() {
|
||||||
let height = height.at_least(min_height);
|
debug_assert_eq!(self.min_rect.max.y, self.max_rect.max.y);
|
||||||
self.max_rect.max.y = self.left_top().y + height;
|
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) {
|
pub fn set_min_size(&mut self, size: Vec2) {
|
||||||
self.set_min_width(size.x);
|
self.set_min_width(size.x);
|
||||||
self.set_min_height(size.y);
|
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) {
|
pub fn set_min_width(&mut self, width: f32) {
|
||||||
if self.layout.dir() == Direction::Horizontal && self.layout.is_reversed() {
|
if self.layout.dir() == Direction::Horizontal && self.layout.is_reversed() {
|
||||||
debug_assert_eq!(self.min_rect.max.x, self.max_rect.max.x);
|
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.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 {
|
} else {
|
||||||
debug_assert_eq!(self.min_rect.min.x, self.max_rect.min.x);
|
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.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) {
|
pub fn set_min_height(&mut self, height: f32) {
|
||||||
if self.layout.dir() == Direction::Vertical && self.layout.is_reversed() {
|
if self.layout.dir() == Direction::Vertical && self.layout.is_reversed() {
|
||||||
debug_assert_eq!(self.min_rect.max.y, self.max_rect.max.y);
|
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.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 {
|
} else {
|
||||||
debug_assert_eq!(self.min_rect.min.y, self.max_rect.min.y);
|
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.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.
|
/// so further widgets will try not to be wider than previous widgets.
|
||||||
/// Useful for normal vertical layouts.
|
/// Useful for normal vertical layouts.
|
||||||
pub fn shrink_width_to_current(&mut self) {
|
pub fn shrink_width_to_current(&mut self) {
|
||||||
self.set_max_width(self.min_rect().width())
|
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.
|
/// so further widgets will try not to be wider than previous widgets.
|
||||||
pub fn shrink_height_to_current(&mut self) {
|
pub fn shrink_height_to_current(&mut self) {
|
||||||
self.set_min_height(self.min_rect().height())
|
self.set_max_height(self.min_rect().height())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Size of content
|
/// Expand the `min_rect` and `max_rect` of this ui to include a child at the given rect.
|
||||||
pub fn min_size(&self) -> Vec2 {
|
pub fn expand_to_include_rect(&mut self, rect: Rect) {
|
||||||
self.min_rect.size()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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) {
|
|
||||||
self.min_rect = self.min_rect.union(rect);
|
self.min_rect = self.min_rect.union(rect);
|
||||||
self.max_rect = self.max_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:
|
// Layout related measures:
|
||||||
|
|
||||||
|
@ -318,13 +334,6 @@ impl Ui {
|
||||||
pub fn available_finite(&self) -> Rect {
|
pub fn available_finite(&self) -> Rect {
|
||||||
self.layout.available(self.cursor, self.max_rect_finite())
|
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
|
/// # `Id` creation
|
||||||
|
@ -393,6 +402,11 @@ impl Ui {
|
||||||
self.interact_hover(rect).hovered
|
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!
|
// Stuff that moves the cursor, i.e. allocates space in this ui!
|
||||||
|
|
||||||
|
@ -664,7 +678,7 @@ impl Ui {
|
||||||
"You can only indent vertical layouts"
|
"You can only indent vertical layouts"
|
||||||
);
|
);
|
||||||
let indent = vec2(self.style().spacing.indent, 0.0);
|
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 {
|
let mut child_ui = Ui {
|
||||||
id: self.id.with(id_source),
|
id: self.id.with(id_source),
|
||||||
..self.child_ui(child_rect, self.layout)
|
..self.child_ui(child_rect, self.layout)
|
||||||
|
@ -788,8 +802,10 @@ impl Ui {
|
||||||
let mut columns: Vec<Self> = (0..num_columns)
|
let mut columns: Vec<Self> = (0..num_columns)
|
||||||
.map(|col_idx| {
|
.map(|col_idx| {
|
||||||
let pos = self.cursor + vec2((col_idx as f32) * (column_width + spacing), 0.0);
|
let pos = self.cursor + vec2((col_idx as f32) * (column_width + spacing), 0.0);
|
||||||
let child_rect =
|
let child_rect = Rect::from_min_max(
|
||||||
Rect::from_min_max(pos, pos2(pos.x + column_width, self.right_bottom().y));
|
pos,
|
||||||
|
pos2(pos.x + column_width, self.max_rect.right_bottom().y),
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
id: self.make_child_id(&("column", col_idx)),
|
id: self.make_child_id(&("column", col_idx)),
|
||||||
|
|
Loading…
Reference in a new issue