diff --git a/rust_programs/libgui/src/bordered.rs b/rust_programs/libgui/src/bordered.rs index bb472025..406e8fe0 100644 --- a/rust_programs/libgui/src/bordered.rs +++ b/rust_programs/libgui/src/bordered.rs @@ -23,6 +23,13 @@ pub fn draw_outer_mouse_highlight( border_color, StrokeThickness::Width(highlight_border_width), ); + frame_after_outer_mouse_highlight(self_size) +} + +pub fn frame_after_outer_mouse_highlight(self_size: Size) -> Rect { + // PT: It is crucial that this exactly matches the logic in draw_outer_mouse_highlight() + let highlight_border_width = 1; + let outer_border = Rect::from_parts(Point::zero(), self_size); let frame_without_outer_highlight = outer_border.inset_by( highlight_border_width, highlight_border_width, @@ -100,6 +107,35 @@ fn draw_inner_margin( bottom_right_inset.draw(onto, inset_color, StrokeThickness::Width(inner_margin_size)); } +// Extracted so that we can re-use the drawing code within a specialized impl for the scroll view border +pub fn compute_inner_margin_and_content_frames( + outer_border_insets: RectInsets, + inner_border_insets: RectInsets, + self_size: Size, + highlight_enabled: bool, +) -> (Rect, Rect) { + // PT: It is crucial that this exactly matches the logic in draw_border_with_insets() + let frame_without_outer_highlight = if highlight_enabled { + frame_after_outer_mouse_highlight(self_size) + } else { + Rect::from_parts(Point::zero(), self_size) + }; + let frame_of_inner_margin = frame_without_outer_highlight.inset_by( + outer_border_insets.bottom, + outer_border_insets.left, + outer_border_insets.right, + outer_border_insets.top, + ); + + let inner_content = frame_of_inner_margin.inset_by( + inner_border_insets.bottom, + inner_border_insets.left, + inner_border_insets.right, + inner_border_insets.top, + ); + (frame_of_inner_margin, inner_content) +} + // Extracted so that we can re-use the drawing code within a specialized impl for the scroll view border pub fn draw_border_with_insets( onto: &mut Box, @@ -123,21 +159,14 @@ pub fn draw_border_with_insets( StrokeThickness::Width(outer_border_insets.bottom), ); - let frame_of_inner_margin = frame_without_outer_highlight.inset_by( - outer_border_insets.bottom, - outer_border_insets.left, - outer_border_insets.right, - outer_border_insets.top, + let (frame_of_inner_margin, frame_of_inner_content) = compute_inner_margin_and_content_frames( + outer_border_insets, + inner_border_insets, + self_size, + highlight_enabled, ); draw_inner_margin(onto, inner_border_insets, frame_of_inner_margin); - - let inner_content = frame_of_inner_margin.inset_by( - inner_border_insets.bottom, - inner_border_insets.left, - inner_border_insets.right, - inner_border_insets.top, - ); - (frame_of_inner_margin, inner_content) + (frame_of_inner_margin, frame_of_inner_content) } pub trait Bordered: Drawable + UIElement { diff --git a/rust_programs/libgui/src/scroll_view.rs b/rust_programs/libgui/src/scroll_view.rs index fdc22e92..35926738 100644 --- a/rust_programs/libgui/src/scroll_view.rs +++ b/rust_programs/libgui/src/scroll_view.rs @@ -1,6 +1,6 @@ use core::{cell::RefCell, fmt::Display}; -use crate::bordered::{draw_border_with_insets, draw_outer_mouse_highlight}; +use crate::bordered::{compute_inner_margin_and_content_frames, draw_border_with_insets, draw_outer_mouse_highlight}; use crate::window_events::KeyCode; use crate::{ bordered::Bordered, @@ -693,6 +693,26 @@ impl ScrollView { fn scroll_bar_width() -> isize { 42 } + fn scroll_bar_content_frame(&self) -> Rect { + let (frame_of_inner_margin, frame_of_content) = compute_inner_margin_and_content_frames( + self.outer_border_insets(), + self.inner_border_insets(), + self.frame().size, + true, + ); + + // Start from y=0 so that the top border lines up with the content's border + let scroll_bar_content_frame = Rect::from_parts( + Point::new(frame_of_inner_margin.max_x(), 0), + Size::new( + Self::scroll_bar_width(), + frame_of_inner_margin.height() + + self.outer_border_insets().top + + self.outer_border_insets().bottom, + ), + ); + scroll_bar_content_frame + } } impl Bordered for ScrollView { @@ -709,7 +729,7 @@ impl Bordered for ScrollView { } fn draw_border_with_insets(&self, onto: &mut Box) -> Rect { - let (frame_of_inner_margin, frame_of_content) = draw_border_with_insets( + let (_, frame_of_content) = draw_border_with_insets( onto, self.outer_border_insets(), self.inner_border_insets(), @@ -717,23 +737,7 @@ impl Bordered for ScrollView { true, self.currently_contains_mouse(), ); - - // Start from y=0 so that the top border lines up with the content's border - /* - let scroll_bar_content_frame = Rect::from_parts( - Point::new(frame_of_inner_margin.max_x(), frame_of_inner_margin.min_y()), - Size::new(Self::scroll_bar_width(), frame_of_inner_margin.height()), - ); - */ - let scroll_bar_content_frame = Rect::from_parts( - Point::new(frame_of_inner_margin.max_x(), 0), - Size::new( - Self::scroll_bar_width(), - frame_of_inner_margin.height() - + self.outer_border_insets().top - + self.outer_border_insets().bottom, - ), - ); + let scroll_bar_content_frame = self.scroll_bar_content_frame(); // Fill the scroll bar area with the same gray as the rest of the outer margin // (Currently, our rect filling only supports a constant thickness around all edges, so the border @@ -874,7 +878,6 @@ impl UIElement for ScrollView { content_frame.origin, scrollable_region_size(self.layer.frame().size, content_frame.size), ); - dbg!(delta_z, scroll_offset, scrollable_region); // Would this exceed the visible content frame? // If so, don't allow the user to scroll there.