[window] fix a bunch of resize-releated bugs
This commit is contained in:
parent
cde1e05853
commit
347fdb97d6
7 changed files with 85 additions and 151 deletions
|
@ -16,7 +16,7 @@ This is the core library crate Egui. It is fully platform independent without an
|
||||||
* [ ] Windows should open from `UI`s and be boxed by parent ui.
|
* [ ] Windows should open from `UI`s and be boxed by parent ui.
|
||||||
* Then we could open the example app inside a window in the example app, recursively.
|
* Then we could open the example app inside a window in the example app, recursively.
|
||||||
* [x] Resize any side and corner on windows
|
* [x] Resize any side and corner on windows
|
||||||
* [ ] Fix autoshrink
|
* [x] Fix autoshrink
|
||||||
* [ ] Scroll areas
|
* [ ] Scroll areas
|
||||||
* [x] Vertical scrolling
|
* [x] Vertical scrolling
|
||||||
* [ ] Horizontal scrolling
|
* [ ] Horizontal scrolling
|
||||||
|
|
|
@ -80,7 +80,7 @@ fn menu_impl<'c>(
|
||||||
.fixed_pos(button_interact.rect.left_bottom());
|
.fixed_pos(button_interact.rect.left_bottom());
|
||||||
let frame = Frame::menu(ui.style());
|
let frame = Frame::menu(ui.style());
|
||||||
|
|
||||||
let resize = Resize::default().auto_sized();
|
let resize = Resize::default().auto_sized().outline(false);
|
||||||
|
|
||||||
let menu_interact = area.show(ui.ctx(), |ui| {
|
let menu_interact = area.show(ui.ctx(), |ui| {
|
||||||
frame.show(ui, |ui| {
|
frame.show(ui, |ui| {
|
||||||
|
|
|
@ -5,13 +5,19 @@ use crate::*;
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
pub(crate) size: Vec2,
|
/// This is the size that the user has picked by dragging the resize handles.
|
||||||
|
/// This may be smaller and/or larger than the actual size.
|
||||||
|
/// For instance, the user may have tried to shrink too much (not fitting the contents).
|
||||||
|
/// Or the user requested a large area, but the content don't need that much space.
|
||||||
|
pub(crate) desired_size: Vec2,
|
||||||
|
|
||||||
|
/// Actual size of content last frame
|
||||||
|
last_content_size: Vec2,
|
||||||
|
|
||||||
/// Externally requested size (e.g. by Window) for the next frame
|
/// Externally requested size (e.g. by Window) for the next frame
|
||||||
pub(crate) requested_size: Option<Vec2>,
|
pub(crate) requested_size: Option<Vec2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: auto-shink/grow should be part of another container!
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Resize {
|
pub struct Resize {
|
||||||
id: Option<Id>,
|
id: Option<Id>,
|
||||||
|
@ -25,14 +31,6 @@ pub struct Resize {
|
||||||
|
|
||||||
default_size: Vec2,
|
default_size: Vec2,
|
||||||
|
|
||||||
// If true, won't allow you to make window so big that it creates spacing
|
|
||||||
auto_shrink_width: bool,
|
|
||||||
auto_shrink_height: bool,
|
|
||||||
|
|
||||||
// If true, won't allow you to resize smaller than that everything fits.
|
|
||||||
expand_width_to_fit_content: bool,
|
|
||||||
expand_height_to_fit_content: bool,
|
|
||||||
|
|
||||||
outline: bool,
|
outline: bool,
|
||||||
handle_offset: Vec2,
|
handle_offset: Vec2,
|
||||||
}
|
}
|
||||||
|
@ -44,11 +42,7 @@ impl Default for Resize {
|
||||||
resizable: true,
|
resizable: true,
|
||||||
min_size: Vec2::splat(16.0),
|
min_size: Vec2::splat(16.0),
|
||||||
max_size: Vec2::infinity(),
|
max_size: Vec2::infinity(),
|
||||||
default_size: vec2(f32::INFINITY, 200.0), // TODO
|
default_size: vec2(200.0, 400.0), // TODO: default height for a resizable area (e.g. a window)
|
||||||
auto_shrink_width: false,
|
|
||||||
auto_shrink_height: false,
|
|
||||||
expand_width_to_fit_content: true,
|
|
||||||
expand_height_to_fit_content: true,
|
|
||||||
outline: true,
|
outline: true,
|
||||||
handle_offset: Default::default(),
|
handle_offset: Default::default(),
|
||||||
}
|
}
|
||||||
|
@ -98,22 +92,14 @@ impl Resize {
|
||||||
self.resizable
|
self.resizable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Not resizable, just takes the size of its contents.
|
/// Not manually resizable, just takes the size of its contents.
|
||||||
pub fn auto_sized(self) -> Self {
|
pub fn auto_sized(self) -> Self {
|
||||||
self.default_size(Vec2::splat(f32::INFINITY))
|
self.default_size(Vec2::splat(f32::INFINITY))
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
.auto_shrink_width(true)
|
|
||||||
.auto_expand_width(true)
|
|
||||||
.auto_shrink_height(true)
|
|
||||||
.auto_expand_height(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fixed_size(mut self, size: impl Into<Vec2>) -> Self {
|
pub fn fixed_size(mut self, size: impl Into<Vec2>) -> Self {
|
||||||
let size = size.into();
|
let size = size.into();
|
||||||
self.auto_shrink_width = false;
|
|
||||||
self.auto_shrink_height = false;
|
|
||||||
self.expand_width_to_fit_content = false;
|
|
||||||
self.expand_height_to_fit_content = false;
|
|
||||||
self.default_size = size;
|
self.default_size = size;
|
||||||
self.min_size = size;
|
self.min_size = size;
|
||||||
self.max_size = size;
|
self.max_size = size;
|
||||||
|
@ -126,38 +112,6 @@ impl Resize {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// true: prevent from resizing to smaller than contents.
|
|
||||||
/// false: allow shrinking to smaller than contents.
|
|
||||||
pub fn auto_expand(mut self, auto_expand: bool) -> Self {
|
|
||||||
self.expand_width_to_fit_content = auto_expand;
|
|
||||||
self.expand_height_to_fit_content = auto_expand;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// true: prevent from resizing to smaller than contents.
|
|
||||||
/// false: allow shrinking to smaller than contents.
|
|
||||||
pub fn auto_expand_width(mut self, auto_expand: bool) -> Self {
|
|
||||||
self.expand_width_to_fit_content = auto_expand;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// true: prevent from resizing to smaller than contents.
|
|
||||||
/// false: allow shrinking to smaller than contents.
|
|
||||||
pub fn auto_expand_height(mut self, auto_expand: bool) -> Self {
|
|
||||||
self.expand_height_to_fit_content = auto_expand;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn auto_shrink_width(mut self, auto_shrink_width: bool) -> Self {
|
|
||||||
self.auto_shrink_width = auto_shrink_width;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn auto_shrink_height(mut self, auto_shrink_height: bool) -> Self {
|
|
||||||
self.auto_shrink_height = auto_shrink_height;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Offset the position of the resize handle by this much
|
/// Offset the position of the resize handle by this much
|
||||||
pub fn handle_offset(mut self, handle_offset: impl Into<Vec2>) -> Self {
|
pub fn handle_offset(mut self, handle_offset: impl Into<Vec2>) -> Self {
|
||||||
self.handle_offset = handle_offset.into();
|
self.handle_offset = handle_offset.into();
|
||||||
|
@ -173,7 +127,6 @@ impl Resize {
|
||||||
struct Prepared {
|
struct Prepared {
|
||||||
id: Id,
|
id: Id,
|
||||||
state: State,
|
state: State,
|
||||||
is_new: bool,
|
|
||||||
corner_interact: Option<InteractInfo>,
|
corner_interact: Option<InteractInfo>,
|
||||||
content_ui: Ui,
|
content_ui: Ui,
|
||||||
}
|
}
|
||||||
|
@ -185,22 +138,17 @@ impl Resize {
|
||||||
self.max_size = self.max_size.min(ui.available().size());
|
self.max_size = self.max_size.min(ui.available().size());
|
||||||
self.max_size = self.max_size.max(self.min_size);
|
self.max_size = self.max_size.max(self.min_size);
|
||||||
|
|
||||||
let (is_new, mut state) = match ui.memory().resize.get(&id) {
|
let mut state = ui.memory().resize.get(&id).cloned().unwrap_or_else(|| {
|
||||||
Some(state) => (false, *state),
|
let default_size = self.default_size.clamp(self.min_size..=self.max_size);
|
||||||
None => {
|
|
||||||
let default_size = self.default_size.clamp(self.min_size..=self.max_size);
|
|
||||||
(
|
|
||||||
true,
|
|
||||||
State {
|
|
||||||
size: default_size,
|
|
||||||
requested_size: None,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
state.size = state.size.clamp(self.min_size..=self.max_size);
|
State {
|
||||||
let last_frame_size = state.size;
|
desired_size: default_size,
|
||||||
|
last_content_size: vec2(0.0, 0.0),
|
||||||
|
requested_size: None,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
state.desired_size = state.desired_size.clamp(self.min_size..=self.max_size);
|
||||||
|
|
||||||
let position = ui.available().min;
|
let position = ui.available().min;
|
||||||
|
|
||||||
|
@ -208,7 +156,7 @@ impl Resize {
|
||||||
// Resize-corner:
|
// Resize-corner:
|
||||||
let corner_size = Vec2::splat(16.0); // TODO: style
|
let corner_size = Vec2::splat(16.0); // TODO: style
|
||||||
let corner_rect = Rect::from_min_size(
|
let corner_rect = Rect::from_min_size(
|
||||||
position + state.size + self.handle_offset - corner_size,
|
position + state.desired_size + self.handle_offset - corner_size,
|
||||||
corner_size,
|
corner_size,
|
||||||
);
|
);
|
||||||
let corner_interact = ui.interact(corner_rect, id.with("corner"), Sense::drag());
|
let corner_interact = ui.interact(corner_rect, id.with("corner"), Sense::drag());
|
||||||
|
@ -217,12 +165,12 @@ impl Resize {
|
||||||
if let Some(mouse_pos) = ui.input().mouse.pos {
|
if let Some(mouse_pos) = ui.input().mouse.pos {
|
||||||
// This is the desired size. We may not be able to achieve it.
|
// This is the desired size. We may not be able to achieve it.
|
||||||
|
|
||||||
state.size = mouse_pos - position + 0.5 * corner_interact.rect.size()
|
state.desired_size = mouse_pos - position + 0.5 * corner_interact.rect.size()
|
||||||
- self.handle_offset;
|
- self.handle_offset;
|
||||||
// We don't clamp to max size, because we want to be able to push against outer bounds.
|
// We don't clamp to max size, because we want to be able to push against outer bounds.
|
||||||
// For instance, if we are inside a bigger Resize region, we want to expand that.
|
// For instance, if we are inside a bigger Resize region, we want to expand that.
|
||||||
// state.size = state.size.clamp(self.min_size..=self.max_size);
|
// state.desired_size = state.desired_size.clamp(self.min_size..=self.max_size);
|
||||||
state.size = state.size.max(self.min_size);
|
state.desired_size = state.desired_size.max(self.min_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(corner_interact)
|
Some(corner_interact)
|
||||||
|
@ -231,30 +179,29 @@ impl Resize {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(requested_size) = state.requested_size.take() {
|
if let Some(requested_size) = state.requested_size.take() {
|
||||||
state.size = requested_size;
|
state.desired_size = requested_size;
|
||||||
// We don't clamp to max size, because we want to be able to push against outer bounds.
|
// We don't clamp to max size, because we want to be able to push against outer bounds.
|
||||||
// For instance, if we are inside a bigger Resize region, we want to expand that.
|
// For instance, if we are inside a bigger Resize region, we want to expand that.
|
||||||
// state.size = state.size.clamp(self.min_size..=self.max_size);
|
// state.desired_size = state.desired_size.clamp(self.min_size..=self.max_size);
|
||||||
state.size = state.size.max(self.min_size);
|
state.desired_size = state.desired_size.max(self.min_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
let inner_rect = Rect::from_min_size(position, state.size);
|
let inner_rect = Rect::from_min_size(position, state.desired_size);
|
||||||
|
|
||||||
let mut content_clip_rect = ui
|
let mut content_clip_rect = inner_rect.expand(ui.style().clip_rect_margin);
|
||||||
.clip_rect()
|
|
||||||
.intersect(inner_rect.expand(ui.style().clip_rect_margin));
|
|
||||||
|
|
||||||
// If we pull the resize handle to shrink, we want to TRY to shink it.
|
// If we pull the resize handle to shrink, we want to TRY to shink it.
|
||||||
// After laying out the contents, we might be much bigger.
|
// After laying out the contents, we might be much bigger.
|
||||||
// In those cases we don't want the clip_rect to be smaller, because
|
// In those cases we don't want the clip_rect to be smaller, because
|
||||||
// then we will clip the contents of the region even thought the result gets larger. This is simply ugly!
|
// then we will clip the contents of the region even thought the result gets larger. This is simply ugly!
|
||||||
// So we use the memory of last_frame_size to make the clip rect large enough.
|
// So we use the memory of last_content_size to make the clip rect large enough.
|
||||||
content_clip_rect.max = content_clip_rect
|
content_clip_rect.max = content_clip_rect.max.max(
|
||||||
.max
|
inner_rect.min + state.last_content_size + Vec2::splat(ui.style().clip_rect_margin),
|
||||||
.max(content_clip_rect.min + last_frame_size)
|
);
|
||||||
.min(ui.clip_rect().max); // Respect parent region
|
|
||||||
|
content_clip_rect = content_clip_rect.intersect(ui.clip_rect()); // Respect parent region
|
||||||
|
|
||||||
let mut content_ui = ui.child_ui(inner_rect);
|
let mut content_ui = ui.child_ui(inner_rect);
|
||||||
content_ui.set_clip_rect(content_clip_rect);
|
content_ui.set_clip_rect(content_clip_rect);
|
||||||
|
@ -262,7 +209,6 @@ impl Resize {
|
||||||
Prepared {
|
Prepared {
|
||||||
id,
|
id,
|
||||||
state,
|
state,
|
||||||
is_new,
|
|
||||||
corner_interact,
|
corner_interact,
|
||||||
content_ui,
|
content_ui,
|
||||||
}
|
}
|
||||||
|
@ -279,39 +225,33 @@ impl Resize {
|
||||||
let Prepared {
|
let Prepared {
|
||||||
id,
|
id,
|
||||||
mut state,
|
mut state,
|
||||||
is_new,
|
|
||||||
corner_interact,
|
corner_interact,
|
||||||
content_ui,
|
content_ui,
|
||||||
} = prepared;
|
} = prepared;
|
||||||
|
|
||||||
let desired_size = content_ui.bounding_size();
|
state.last_content_size = content_ui.bounding_size();
|
||||||
let desired_size = desired_size.ceil(); // Avoid rounding errors in math
|
state.last_content_size = state.last_content_size.ceil(); // Avoid rounding errors in math
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
if self.auto_shrink_width {
|
if self.outline || self.resizable {
|
||||||
state.size.x = state.size.x.min(desired_size.x);
|
// We show how large we are,
|
||||||
}
|
// so we must follow the contents:
|
||||||
if self.auto_shrink_height {
|
|
||||||
state.size.y = state.size.y.min(desired_size.y);
|
|
||||||
}
|
|
||||||
if self.expand_width_to_fit_content || is_new {
|
|
||||||
state.size.x = state.size.x.max(desired_size.x);
|
|
||||||
}
|
|
||||||
if self.expand_height_to_fit_content || is_new {
|
|
||||||
state.size.y = state.size.y.max(desired_size.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.size = state.size.max(self.min_size);
|
state.desired_size = state.desired_size.max(state.last_content_size);
|
||||||
// state.size = state.size.clamp(self.min_size..=self.max_size);
|
state.desired_size = ui.round_vec_to_pixels(state.desired_size);
|
||||||
state.size = state.size.round(); // TODO: round to pixels
|
|
||||||
|
|
||||||
ui.allocate_space(state.size);
|
// We are as large as we look
|
||||||
|
ui.allocate_space(state.desired_size);
|
||||||
|
} else {
|
||||||
|
// Probably a window.
|
||||||
|
ui.allocate_space(state.last_content_size);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
if self.outline && corner_interact.is_some() {
|
if self.outline && corner_interact.is_some() {
|
||||||
let rect = Rect::from_min_size(content_ui.top_left(), state.size);
|
let rect = Rect::from_min_size(content_ui.top_left(), state.desired_size);
|
||||||
let rect = rect.expand(2.0); // breathing room for content
|
let rect = rect.expand(2.0); // breathing room for content
|
||||||
ui.add_paint_cmd(paint::PaintCmd::Rect {
|
ui.add_paint_cmd(paint::PaintCmd::Rect {
|
||||||
rect,
|
rect,
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl ScrollArea {
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
// content: size of contents (generally large)
|
// content: size of contents (generally large; that's why we want scroll bars)
|
||||||
// outer: size of scroll area including scroll bar(s)
|
// outer: size of scroll area including scroll bar(s)
|
||||||
// inner: excluding scroll bar(s). The area we clip the contents to.
|
// inner: excluding scroll bar(s). The area we clip the contents to.
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ impl Prepared {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check that nothing else is being inteacted with
|
// TODO: check that nothing else is being interacted with
|
||||||
if ui.contains_mouse(outer_rect) {
|
if ui.contains_mouse(outer_rect) {
|
||||||
state.offset.y -= ui.input().scroll_delta.y;
|
state.offset.y -= ui.input().scroll_delta.y;
|
||||||
}
|
}
|
||||||
|
@ -209,10 +209,17 @@ impl Prepared {
|
||||||
state.offset.y = state.offset.y.min(content_size.y - inner_rect.height());
|
state.offset.y = state.offset.y.min(content_size.y - inner_rect.height());
|
||||||
|
|
||||||
// Avoid frame-delay by calculating a new handle rect:
|
// Avoid frame-delay by calculating a new handle rect:
|
||||||
let handle_rect = Rect::from_min_max(
|
let mut handle_rect = Rect::from_min_max(
|
||||||
pos2(left, from_content(state.offset.y)),
|
pos2(left, from_content(state.offset.y)),
|
||||||
pos2(right, from_content(state.offset.y + inner_rect.height())),
|
pos2(right, from_content(state.offset.y + inner_rect.height())),
|
||||||
);
|
);
|
||||||
|
let min_handle_height = (2.0 * corner_radius).max(8.0);
|
||||||
|
if handle_rect.size().y < min_handle_height {
|
||||||
|
handle_rect = Rect::from_center_size(
|
||||||
|
handle_rect.center(),
|
||||||
|
vec2(handle_rect.size().x, min_handle_height),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let style = ui.style();
|
let style = ui.style();
|
||||||
let handle_fill = style.interact(&interact).fill;
|
let handle_fill = style.interact(&interact).fill;
|
||||||
|
@ -233,12 +240,10 @@ impl Prepared {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// let size = content_size.min(inner_rect.size());
|
let size = vec2(
|
||||||
// let size = vec2(
|
outer_rect.size().x,
|
||||||
// content_size.x, // ignore inner_rect, i.e. try to expand horizontally if necessary
|
outer_rect.size().y.min(content_size.y), // shrink if content is so small that we don't need scroll bars
|
||||||
// content_size.y.min(inner_rect.size().y), // respect vertical height.
|
);
|
||||||
// );
|
|
||||||
let size = outer_rect.size();
|
|
||||||
ui.allocate_space(size);
|
ui.allocate_space(size);
|
||||||
|
|
||||||
state.offset.y = state.offset.y.min(content_size.y - inner_rect.height());
|
state.offset.y = state.offset.y.min(content_size.y - inner_rect.height());
|
||||||
|
|
|
@ -27,13 +27,7 @@ impl<'open> Window<'open> {
|
||||||
open: None,
|
open: None,
|
||||||
area,
|
area,
|
||||||
frame: None,
|
frame: None,
|
||||||
resize: Resize::default()
|
resize: Resize::default().outline(false),
|
||||||
.auto_expand_height(false)
|
|
||||||
.auto_expand_width(true)
|
|
||||||
.auto_shrink_height(false)
|
|
||||||
.auto_shrink_width(true)
|
|
||||||
.handle_offset(Vec2::splat(4.0))
|
|
||||||
.outline(false),
|
|
||||||
scroll: Some(
|
scroll: Some(
|
||||||
ScrollArea::default()
|
ScrollArea::default()
|
||||||
.always_show_scroll(false)
|
.always_show_scroll(false)
|
||||||
|
@ -326,7 +320,8 @@ fn interact(
|
||||||
let mut resize_state = ctx.memory().resize.get(&resize_id).cloned().unwrap();
|
let mut resize_state = ctx.memory().resize.get(&resize_id).cloned().unwrap();
|
||||||
// resize_state.size += new_rect.size() - pre_resize.size();
|
// resize_state.size += new_rect.size() - pre_resize.size();
|
||||||
// resize_state.size = new_rect.size() - some margin;
|
// resize_state.size = new_rect.size() - some margin;
|
||||||
resize_state.requested_size = Some(resize_state.size + new_rect.size() - pre_resize.size());
|
resize_state.requested_size =
|
||||||
|
Some(resize_state.desired_size + new_rect.size() - pre_resize.size());
|
||||||
ctx.memory().resize.insert(resize_id, resize_state);
|
ctx.memory().resize.insert(resize_id, resize_state);
|
||||||
|
|
||||||
ctx.memory().areas.move_to_top(area_layer);
|
ctx.memory().areas.move_to_top(area_layer);
|
||||||
|
|
|
@ -50,32 +50,25 @@ impl ExampleApp {
|
||||||
|
|
||||||
Window::new("Examples")
|
Window::new("Examples")
|
||||||
.open(&mut open_windows.examples)
|
.open(&mut open_windows.examples)
|
||||||
.default_pos([32.0, 100.0])
|
|
||||||
.default_size([430.0, 600.0])
|
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
example_window.ui(ui);
|
example_window.ui(ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
Window::new("Settings")
|
Window::new("Settings")
|
||||||
.open(&mut open_windows.settings)
|
.open(&mut open_windows.settings)
|
||||||
.default_pos([500.0, 100.0])
|
|
||||||
.default_size([350.0, 400.0])
|
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
ctx.settings_ui(ui);
|
ctx.settings_ui(ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
Window::new("Inspection")
|
Window::new("Inspection")
|
||||||
.open(&mut open_windows.inspection)
|
.open(&mut open_windows.inspection)
|
||||||
.default_pos([500.0, 400.0])
|
|
||||||
.default_size([400.0, 300.0])
|
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
ctx.inspection_ui(ui);
|
ctx.inspection_ui(ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
Window::new("Memory")
|
Window::new("Memory")
|
||||||
.open(&mut open_windows.memory)
|
.open(&mut open_windows.memory)
|
||||||
.default_pos([700.0, 350.0])
|
.resizable(false)
|
||||||
.auto_sized()
|
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
ctx.memory_ui(ui);
|
ctx.memory_ui(ui);
|
||||||
});
|
});
|
||||||
|
@ -244,14 +237,10 @@ impl ExampleWindow {
|
||||||
CollapsingHeader::new("Resize")
|
CollapsingHeader::new("Resize")
|
||||||
.default_open(false)
|
.default_open(false)
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
Resize::default()
|
Resize::default().default_height(200.0).show(ui, |ui| {
|
||||||
.default_height(200.0)
|
ui.add(label!("This ui can be resized!"));
|
||||||
// .as_wide_as_possible()
|
ui.add(label!("Just pull the handle on the bottom right"));
|
||||||
.auto_shrink_height(false)
|
});
|
||||||
.show(ui, |ui| {
|
|
||||||
ui.add(label!("This ui can be resized!"));
|
|
||||||
ui.add(label!("Just pull the handle on the bottom right"));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.collapsing("Name clash example", |ui| {
|
ui.collapsing("Name clash example", |ui| {
|
||||||
|
|
|
@ -412,7 +412,7 @@ impl Widget for RadioButton {
|
||||||
|
|
||||||
pub struct Separator {
|
pub struct Separator {
|
||||||
line_width: Option<f32>,
|
line_width: Option<f32>,
|
||||||
min_spacing: f32,
|
spacing: f32,
|
||||||
extra: f32,
|
extra: f32,
|
||||||
color: Color,
|
color: Color,
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ impl Separator {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
line_width: None,
|
line_width: None,
|
||||||
min_spacing: 6.0,
|
spacing: 6.0,
|
||||||
extra: 0.0,
|
extra: 0.0,
|
||||||
color: color::WHITE,
|
color: color::WHITE,
|
||||||
}
|
}
|
||||||
|
@ -432,8 +432,9 @@ impl Separator {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn min_spacing(mut self, min_spacing: f32) -> Self {
|
/// How much space we take up. The line is painted in the middle of this.
|
||||||
self.min_spacing = min_spacing;
|
pub fn spacing(mut self, spacing: f32) -> Self {
|
||||||
|
self.spacing = spacing;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,7 +454,7 @@ impl Widget for Separator {
|
||||||
fn ui(self, ui: &mut Ui) -> InteractInfo {
|
fn ui(self, ui: &mut Ui) -> InteractInfo {
|
||||||
let Separator {
|
let Separator {
|
||||||
line_width,
|
line_width,
|
||||||
min_spacing,
|
spacing,
|
||||||
extra,
|
extra,
|
||||||
color,
|
color,
|
||||||
} = self;
|
} = self;
|
||||||
|
@ -462,9 +463,13 @@ impl Widget for Separator {
|
||||||
|
|
||||||
let available_space = ui.available_finite().size();
|
let available_space = ui.available_finite().size();
|
||||||
|
|
||||||
|
// TODO: only allocate `spacing`, but not our full width/height
|
||||||
|
// as that would make the false impression that we *need* all that space,
|
||||||
|
// wich would prevent regions from autoshrinking
|
||||||
|
|
||||||
let (points, rect) = match ui.layout().dir() {
|
let (points, rect) = match ui.layout().dir() {
|
||||||
Direction::Horizontal => {
|
Direction::Horizontal => {
|
||||||
let rect = ui.allocate_space(vec2(min_spacing, available_space.y));
|
let rect = ui.allocate_space(vec2(spacing, available_space.y));
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
pos2(rect.center().x, rect.top() - extra),
|
pos2(rect.center().x, rect.top() - extra),
|
||||||
|
@ -474,7 +479,7 @@ impl Widget for Separator {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Direction::Vertical => {
|
Direction::Vertical => {
|
||||||
let rect = ui.allocate_space(vec2(available_space.x, min_spacing));
|
let rect = ui.allocate_space(vec2(available_space.x, spacing));
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
pos2(rect.left() - extra, rect.center().y),
|
pos2(rect.left() - extra, rect.center().y),
|
||||||
|
|
Loading…
Reference in a new issue