Better handling of full-width widgets inside of Ui:s with inf max size
This commit is contained in:
parent
be6ada6923
commit
274acff47e
3 changed files with 46 additions and 4 deletions
|
@ -54,14 +54,14 @@ impl CollapsingHeader {
|
|||
default_open,
|
||||
} = self;
|
||||
|
||||
// TODO: horizontal layout, with icon and text as labels. Inser background behind using Frame.
|
||||
// TODO: horizontal layout, with icon and text as labels. Insert background behind using Frame.
|
||||
|
||||
let title = &label.text; // TODO: not this
|
||||
let id = ui.make_unique_id(title);
|
||||
let text_pos = ui.cursor() + vec2(ui.style().indent, 0.0);
|
||||
let (title, text_size) = label.layout(text_pos, ui);
|
||||
let text_max_x = text_pos.x + text_size.x;
|
||||
let desired_width = ui.available_width().max(text_max_x - ui.cursor().x);
|
||||
let desired_width = ui.available_space_min().x.max(text_max_x - ui.cursor().x);
|
||||
|
||||
let interact = ui.reserve_space(
|
||||
vec2(
|
||||
|
|
|
@ -28,6 +28,8 @@ pub struct Ui {
|
|||
/// The widgets will TRY to fit within the rect,
|
||||
/// but may overflow (which you will see in child_bounds).
|
||||
/// Some widgets (like separator lines) will try to fill the full desired width of the ui.
|
||||
/// If the desired size is zero, it is a signal that child widgets should be as small as possible.
|
||||
/// If the desired size is initie, it is a signal that child widgets should take up as much room as they want.
|
||||
desired_rect: Rect, // TODO: rename as max_rect ?
|
||||
|
||||
/// Bounding box of all children.
|
||||
|
@ -161,11 +163,24 @@ impl Ui {
|
|||
|
||||
/// 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 inifnity if the desired rect is initinite,
|
||||
/// which mappens when a parent widget says "be as big as you want to be".
|
||||
pub fn bottom_right(&self) -> Pos2 {
|
||||
// If a child doesn't fit in desired_rect, we have effectively expanded:
|
||||
self.desired_rect.max.max(self.child_bounds.max)
|
||||
}
|
||||
|
||||
pub fn finite_bottom_right(&self) -> Pos2 {
|
||||
let mut bottom_right = self.child_bounds.max;
|
||||
if self.desired_rect.max.x.is_finite() {
|
||||
bottom_right.x = bottom_right.x.max(self.desired_rect.max.x);
|
||||
}
|
||||
if self.desired_rect.max.y.is_finite() {
|
||||
bottom_right.y = bottom_right.y.max(self.desired_rect.max.y);
|
||||
}
|
||||
bottom_right
|
||||
}
|
||||
|
||||
/// Position and current size of the ui.
|
||||
/// The size is the maximum of the origional (minimum/desired) size and
|
||||
/// the size of the containted children.
|
||||
|
@ -216,20 +231,31 @@ impl Ui {
|
|||
// ------------------------------------------------------------------------
|
||||
// Layout related measures:
|
||||
|
||||
/// A zero should be intepreted as "as little as possible".
|
||||
/// An infinite value should be intereted as "as much as you want"
|
||||
pub fn available_width(&self) -> f32 {
|
||||
self.available_space().x
|
||||
}
|
||||
|
||||
/// A zero should be intepreted as "as little as possible".
|
||||
/// An infinite value should be intereted as "as much as you want"
|
||||
pub fn available_height(&self) -> f32 {
|
||||
self.available_space().y
|
||||
}
|
||||
|
||||
/// This how much more space we can take up without overflowing our parent.
|
||||
/// Shrinks as cursor increments.
|
||||
/// A zero size should be intepreted as "as little as possible".
|
||||
/// An infinite size should be intereted as "as much as you want"
|
||||
pub fn available_space(&self) -> Vec2 {
|
||||
self.bottom_right() - self.cursor
|
||||
}
|
||||
|
||||
/// Use this for components that want to grow witout bounds.
|
||||
pub fn available_space_min(&self) -> Vec2 {
|
||||
self.finite_bottom_right() - self.cursor
|
||||
}
|
||||
|
||||
pub fn direction(&self) -> Direction {
|
||||
self.dir
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ pub struct Label {
|
|||
// TODO: not pub
|
||||
pub(crate) text: String,
|
||||
pub(crate) multiline: bool,
|
||||
auto_shrink: bool,
|
||||
pub(crate) text_style: TextStyle, // TODO: Option<TextStyle>, where None means "use the default for the ui"
|
||||
pub(crate) text_color: Option<Color>,
|
||||
}
|
||||
|
@ -32,6 +33,7 @@ impl Label {
|
|||
Self {
|
||||
text: text.into(),
|
||||
multiline: true,
|
||||
auto_shrink: false,
|
||||
text_style: TextStyle::Body,
|
||||
text_color: None,
|
||||
}
|
||||
|
@ -46,6 +48,13 @@ impl Label {
|
|||
self
|
||||
}
|
||||
|
||||
/// If true, will word wrap to the width of the current child_bounds.
|
||||
/// If false (defailt), will word wrap to the available width
|
||||
pub fn auto_shrink(mut self) -> Self {
|
||||
self.auto_shrink = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn text_style(mut self, text_style: TextStyle) -> Self {
|
||||
self.text_style = text_style;
|
||||
self
|
||||
|
@ -58,7 +67,13 @@ impl Label {
|
|||
|
||||
pub fn layout(&self, pos: Pos2, ui: &Ui) -> (Vec<font::TextFragment>, Vec2) {
|
||||
let font = &ui.fonts()[self.text_style];
|
||||
let max_width = ui.rect().right() - pos.x;
|
||||
|
||||
let max_width = if self.auto_shrink {
|
||||
ui.child_bounds().right() - pos.x
|
||||
} else {
|
||||
ui.rect().right() - pos.x
|
||||
};
|
||||
|
||||
if self.multiline {
|
||||
font.layout_multiline(&self.text, max_width)
|
||||
} else {
|
||||
|
@ -389,7 +404,8 @@ impl Separator {
|
|||
|
||||
impl Widget for Separator {
|
||||
fn ui(self, ui: &mut Ui) -> GuiResponse {
|
||||
let available_space = ui.available_space();
|
||||
let available_space = ui.available_space_min();
|
||||
|
||||
let extra = self.extra;
|
||||
let (points, interact) = match ui.direction() {
|
||||
Direction::Horizontal => {
|
||||
|
|
Loading…
Reference in a new issue