From 5ac39d9643be6a69a93b2c9202df9d9bf4d51b7b Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 1 May 2020 10:02:53 +0200 Subject: [PATCH] Better handling of forcibly trying to shink something that can't be --- emigui/src/containers/resize.rs | 10 ++++++- emigui/src/containers/scroll_area.rs | 41 ++++++++++++++++++++-------- emigui/src/region.rs | 18 ++++++------ emigui/src/style.rs | 4 +++ 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/emigui/src/containers/resize.rs b/emigui/src/containers/resize.rs index 6e6bb4a3..5c83f91e 100644 --- a/emigui/src/containers/resize.rs +++ b/emigui/src/containers/resize.rs @@ -179,10 +179,18 @@ impl Resize { let inner_rect = Rect::from_min_size(region.cursor(), state.size); let desired_size = { let mut contents_region = region.child_region(inner_rect); + contents_region.clip_rect = region + .clip_rect() + .intersect(&inner_rect.expand(region.style().clip_rect_margin)); + + // region.debug_text_at( + // inner_rect.min + last_frame_size, + // &format!("last_frame_size: {:?}", last_frame_size), + // ); // 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. - // In those cases we don't want the clip_rect too 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! contents_region.clip_rect.max = contents_region .clip_rect diff --git a/emigui/src/containers/scroll_area.rs b/emigui/src/containers/scroll_area.rs index 1057ff0c..ae6edfb8 100644 --- a/emigui/src/containers/scroll_area.rs +++ b/emigui/src/containers/scroll_area.rs @@ -8,6 +8,7 @@ pub struct State { pub show_scroll: bool, // TODO: default value? } +// TODO: rename VScroll #[derive(Clone, Debug)] pub struct ScrollArea { max_height: f32, @@ -59,29 +60,44 @@ impl ScrollArea { // outer: size of scroll area including scroll bar(s) // inner: excluding scroll bar(s). The area we clip the contents to. - let scroll_bar_width = 16.0; + let max_scroll_bar_width = 16.0; + + let current_scroll_bar_width = if state.show_scroll || !self.auto_hide_scroll { + max_scroll_bar_width // TODO: animate? + } else { + 0.0 + }; let outer_size = vec2( outer_region.available_width(), outer_region.available_height().min(self.max_height), ); - let outer_rect = Rect::from_min_size(outer_region.cursor, outer_size); - let inner_size = if state.show_scroll || !self.auto_hide_scroll { - outer_size - vec2(scroll_bar_width, 0.0) // TODO: animate? - } else { - outer_size - }; + let inner_size = outer_size - vec2(current_scroll_bar_width, 0.0); let inner_rect = Rect::from_min_size(outer_region.cursor, inner_size); let mut content_region = outer_region.child_region(Rect::from_min_size( outer_region.cursor() - state.offset, vec2(inner_size.x, f32::INFINITY), )); - content_region.clip_rect = outer_region.clip_rect().intersect(&inner_rect); + // content_region.clip_rect = outer_region.clip_rect().intersect(&inner_rect); + content_region.clip_rect = outer_region.clip_rect(); // Nice handling of forced resizing beyon the possible add_contents(&mut content_region); let content_size = content_region.bounding_size(); + let inner_rect = Rect::from_min_size( + inner_rect.min, + vec2( + inner_rect.width().max(content_size.x), // Expand width to fit content + inner_rect.height(), + ), + ); + + let outer_rect = Rect::from_min_size( + inner_rect.min, + inner_rect.size() + vec2(current_scroll_bar_width, 0.0), + ); + let content_interact = outer_region.interact_rect(&inner_rect, scroll_area_id.with("area")); if content_interact.active { // Dragging scroll area to scroll: @@ -166,10 +182,11 @@ impl ScrollArea { } // let size = content_size.min(inner_rect.size()); - let size = vec2( - content_size.x, // ignore inner_rect, i.e. try to expand horizontally if necessary - content_size.y.min(inner_rect.size().y), // respect vertical height. - ); + // let size = vec2( + // content_size.x, // ignore inner_rect, i.e. try to expand horizontally if necessary + // content_size.y.min(inner_rect.size().y), // respect vertical height. + // ); + let size = outer_rect.size(); outer_region.reserve_space(size, None); state.offset.y = state.offset.y.min(content_size.y - inner_rect.height()); diff --git a/emigui/src/region.rs b/emigui/src/region.rs index 85db5294..f2aacbab 100644 --- a/emigui/src/region.rs +++ b/emigui/src/region.rs @@ -52,9 +52,6 @@ pub struct Region { pub(crate) cursor: Pos2, } -// Allow child widgets to be just on the border and still have an outline with some thickness -const CLIP_RECT_MARGIN: f32 = 3.0; - impl Region { // ------------------------------------------------------------------------ // Creation: @@ -65,7 +62,7 @@ impl Region { ctx, id, layer, - clip_rect: rect.expand(CLIP_RECT_MARGIN), + clip_rect: rect.expand(style.clip_rect_margin), desired_rect: rect, child_bounds: Rect::from_min_size(rect.min, Vec2::zero()), // TODO: Rect::nothing() ? style, @@ -76,9 +73,10 @@ impl Region { } pub fn child_region(&self, child_rect: Rect) -> Self { - let clip_rect = self - .clip_rect - .intersect(&child_rect.expand(CLIP_RECT_MARGIN)); + // let clip_rect = self + // .clip_rect + // .intersect(&child_rect.expand(self.style().clip_rect_margin)); + let clip_rect = self.clip_rect(); // Keep it unless the child explciitly desires differently Region { ctx: self.ctx.clone(), layer: self.layer, @@ -374,7 +372,11 @@ impl Region { /// Paint some debug text at current cursor pub fn debug_text(&self, text: &str) { - self.ctx.debug_text(self.cursor, text); + self.debug_text_at(self.cursor, text); + } + + pub fn debug_text_at(&self, pos: Pos2, text: &str) { + self.ctx.debug_text(pos, text); } /// Show some text anywhere in the region. diff --git a/emigui/src/style.rs b/emigui/src/style.rs index 484d0157..fd5d3d80 100644 --- a/emigui/src/style.rs +++ b/emigui/src/style.rs @@ -37,6 +37,9 @@ pub struct Style { pub window: Window, + /// Allow child widgets to be just on the border and still have an outline with some thickness + pub clip_rect_margin: f32, + // ----------------------------------------------- // Debug rendering: pub debug_regions: bool, @@ -61,6 +64,7 @@ impl Default for Style { text_cursor_width: 2.0, animation_time: 1.0 / 20.0, window: Window::default(), + clip_rect_margin: 3.0, debug_regions: false, } }