mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 21:22:46 +00:00 
			
		
		
		
	LibGUI: Add Banner concept to AbstractScrollableWidget
Banners are abstract widgets which can house additional controls and information on a temporary basis, popping in from the top of their parent when needed.
This commit is contained in:
		
							parent
							
								
									c2cc01c920
								
							
						
					
					
						commit
						3c4a563415
					
				
					 2 changed files with 42 additions and 6 deletions
				
			
		|  | @ -40,6 +40,19 @@ AbstractScrollableWidget::AbstractScrollableWidget() | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void AbstractScrollableWidget::set_banner_widget(Widget* widget) | ||||||
|  | { | ||||||
|  |     if (m_banner_widget == widget) | ||||||
|  |         return; | ||||||
|  |     if (m_banner_widget) | ||||||
|  |         remove_child(*m_banner_widget); | ||||||
|  |     if (!widget) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     m_banner_widget = widget; | ||||||
|  |     add_child(*m_banner_widget); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void AbstractScrollableWidget::handle_wheel_event(MouseEvent& event, Widget& event_source) | void AbstractScrollableWidget::handle_wheel_event(MouseEvent& event, Widget& event_source) | ||||||
| { | { | ||||||
|     if (!m_scrollbars_enabled) { |     if (!m_scrollbars_enabled) { | ||||||
|  | @ -77,16 +90,25 @@ void AbstractScrollableWidget::mousewheel_event(MouseEvent& event) | ||||||
| void AbstractScrollableWidget::custom_layout() | void AbstractScrollableWidget::custom_layout() | ||||||
| { | { | ||||||
|     auto inner_rect = frame_inner_rect_for_size(size()); |     auto inner_rect = frame_inner_rect_for_size(size()); | ||||||
|  |     int height_wanted_by_banner_widget = m_banner_widget && m_banner_widget->is_visible() ? m_banner_widget->effective_min_size().height().as_int() : 0; | ||||||
|     int height_wanted_by_horizontal_scrollbar = m_horizontal_scrollbar->is_visible() ? m_horizontal_scrollbar->effective_min_size().height().as_int() : 0; |     int height_wanted_by_horizontal_scrollbar = m_horizontal_scrollbar->is_visible() ? m_horizontal_scrollbar->effective_min_size().height().as_int() : 0; | ||||||
|     int width_wanted_by_vertical_scrollbar = m_vertical_scrollbar->is_visible() ? m_vertical_scrollbar->effective_min_size().width().as_int() : 0; |     int width_wanted_by_vertical_scrollbar = m_vertical_scrollbar->is_visible() ? m_vertical_scrollbar->effective_min_size().width().as_int() : 0; | ||||||
| 
 | 
 | ||||||
|  |     if (m_banner_widget && m_banner_widget->is_visible()) { | ||||||
|  |         m_banner_widget->set_relative_rect( | ||||||
|  |             inner_rect.left(), | ||||||
|  |             inner_rect.top(), | ||||||
|  |             inner_rect.width(), | ||||||
|  |             height_wanted_by_banner_widget); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     { |     { | ||||||
|         int vertical_scrollbar_width = m_vertical_scrollbar->effective_min_size().width().as_int(); |         int vertical_scrollbar_width = m_vertical_scrollbar->effective_min_size().width().as_int(); | ||||||
|         m_vertical_scrollbar->set_relative_rect( |         m_vertical_scrollbar->set_relative_rect( | ||||||
|             inner_rect.right() + 1 - vertical_scrollbar_width, |             inner_rect.right() + 1 - vertical_scrollbar_width, | ||||||
|             inner_rect.top(), |             inner_rect.top() + height_wanted_by_banner_widget, | ||||||
|             vertical_scrollbar_width, |             vertical_scrollbar_width, | ||||||
|             inner_rect.height() - height_wanted_by_horizontal_scrollbar); |             inner_rect.height() - height_wanted_by_horizontal_scrollbar - height_wanted_by_banner_widget); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     { |     { | ||||||
|  | @ -160,7 +182,7 @@ void AbstractScrollableWidget::update_scrollbar_visibility() | ||||||
|         if (m_min_content_size == Gfx::IntSize {}) |         if (m_min_content_size == Gfx::IntSize {}) | ||||||
|             effective_min_content_size = m_content_size; |             effective_min_content_size = m_content_size; | ||||||
|         int horizontal_buffer = rect().width() - 2 * frame_thickness() - effective_min_content_size.width(); |         int horizontal_buffer = rect().width() - 2 * frame_thickness() - effective_min_content_size.width(); | ||||||
|         int vertical_buffer = rect().height() - 2 * frame_thickness() - effective_min_content_size.height(); |         int vertical_buffer = rect().height() - 2 * frame_thickness() - effective_min_content_size.height() - height_occupied_by_banner_widget(); | ||||||
|         bool horizontal_scrollbar_should_be_visible = false, vertical_scrollbar_should_be_visible = false; |         bool horizontal_scrollbar_should_be_visible = false, vertical_scrollbar_should_be_visible = false; | ||||||
|         vertical_scrollbar_should_be_visible = vertical_buffer < 0; |         vertical_scrollbar_should_be_visible = vertical_buffer < 0; | ||||||
|         if (vertical_scrollbar_should_be_visible) |         if (vertical_scrollbar_should_be_visible) | ||||||
|  | @ -198,6 +220,11 @@ void AbstractScrollableWidget::set_size_occupied_by_fixed_elements(Gfx::IntSize | ||||||
|     update_scrollbar_ranges(); |     update_scrollbar_ranges(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int AbstractScrollableWidget::height_occupied_by_banner_widget() const | ||||||
|  | { | ||||||
|  |     return m_banner_widget && m_banner_widget->is_visible() ? m_banner_widget->height() : 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int AbstractScrollableWidget::height_occupied_by_horizontal_scrollbar() const | int AbstractScrollableWidget::height_occupied_by_horizontal_scrollbar() const | ||||||
| { | { | ||||||
|     return m_horizontal_scrollbar->is_visible() ? m_horizontal_scrollbar->height() : 0; |     return m_horizontal_scrollbar->is_visible() ? m_horizontal_scrollbar->height() : 0; | ||||||
|  | @ -210,7 +237,7 @@ int AbstractScrollableWidget::width_occupied_by_vertical_scrollbar() const | ||||||
| 
 | 
 | ||||||
| Margins AbstractScrollableWidget::content_margins() const | Margins AbstractScrollableWidget::content_margins() const | ||||||
| { | { | ||||||
|     return Frame::content_margins() + Margins { 0, width_occupied_by_vertical_scrollbar(), height_occupied_by_horizontal_scrollbar(), 0 }; |     return Frame::content_margins() + Margins { height_occupied_by_banner_widget(), width_occupied_by_vertical_scrollbar(), height_occupied_by_horizontal_scrollbar(), 0 }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Gfx::IntRect AbstractScrollableWidget::visible_content_rect() const | Gfx::IntRect AbstractScrollableWidget::visible_content_rect() const | ||||||
|  | @ -312,7 +339,8 @@ Gfx::IntRect AbstractScrollableWidget::widget_inner_rect() const | ||||||
| { | { | ||||||
|     auto rect = frame_inner_rect(); |     auto rect = frame_inner_rect(); | ||||||
|     rect.set_width(rect.width() - width_occupied_by_vertical_scrollbar()); |     rect.set_width(rect.width() - width_occupied_by_vertical_scrollbar()); | ||||||
|     rect.set_height(rect.height() - height_occupied_by_horizontal_scrollbar()); |     rect.set_height(rect.height() - height_occupied_by_horizontal_scrollbar() - height_occupied_by_banner_widget()); | ||||||
|  |     rect.set_top(rect.top() + height_occupied_by_banner_widget()); | ||||||
|     return rect; |     return rect; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -336,7 +364,9 @@ Optional<UISize> AbstractScrollableWidget::calculated_min_size() const | ||||||
| { | { | ||||||
|     auto vertical_scrollbar = m_vertical_scrollbar->effective_min_size().height().as_int(); |     auto vertical_scrollbar = m_vertical_scrollbar->effective_min_size().height().as_int(); | ||||||
|     auto horizontal_scrollbar = m_horizontal_scrollbar->effective_min_size().width().as_int(); |     auto horizontal_scrollbar = m_horizontal_scrollbar->effective_min_size().width().as_int(); | ||||||
|     return { { horizontal_scrollbar + corner_widget().width() + frame_thickness() * 2, vertical_scrollbar + corner_widget().height() + frame_thickness() * 2 } }; |     auto banner = m_banner_widget && m_banner_widget->is_visible() ? m_banner_widget->effective_min_size().width().as_int() : 0; | ||||||
|  |     auto max_width = max(banner, horizontal_scrollbar + corner_widget().width() + frame_thickness() * 2); | ||||||
|  |     return { { max_width, vertical_scrollbar + corner_widget().height() + frame_thickness() * 2 + height_occupied_by_banner_widget() } }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -50,6 +50,10 @@ public: | ||||||
|     Widget& corner_widget() { return *m_corner_widget; } |     Widget& corner_widget() { return *m_corner_widget; } | ||||||
|     Widget const& corner_widget() const { return *m_corner_widget; } |     Widget const& corner_widget() const { return *m_corner_widget; } | ||||||
| 
 | 
 | ||||||
|  |     void set_banner_widget(Widget*); | ||||||
|  |     Widget* banner_widget() { return m_banner_widget; } | ||||||
|  |     Widget const* banner_widget() const { return m_banner_widget; } | ||||||
|  | 
 | ||||||
|     void scroll_to_top(); |     void scroll_to_top(); | ||||||
|     void scroll_to_bottom(); |     void scroll_to_bottom(); | ||||||
| 
 | 
 | ||||||
|  | @ -58,6 +62,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     int width_occupied_by_vertical_scrollbar() const; |     int width_occupied_by_vertical_scrollbar() const; | ||||||
|     int height_occupied_by_horizontal_scrollbar() const; |     int height_occupied_by_horizontal_scrollbar() const; | ||||||
|  |     int height_occupied_by_banner_widget() const; | ||||||
| 
 | 
 | ||||||
|     virtual Margins content_margins() const override; |     virtual Margins content_margins() const override; | ||||||
| 
 | 
 | ||||||
|  | @ -111,6 +116,7 @@ private: | ||||||
|     RefPtr<AbstractScrollableWidgetScrollbar> m_vertical_scrollbar; |     RefPtr<AbstractScrollableWidgetScrollbar> m_vertical_scrollbar; | ||||||
|     RefPtr<AbstractScrollableWidgetScrollbar> m_horizontal_scrollbar; |     RefPtr<AbstractScrollableWidgetScrollbar> m_horizontal_scrollbar; | ||||||
|     RefPtr<Widget> m_corner_widget; |     RefPtr<Widget> m_corner_widget; | ||||||
|  |     WeakPtr<Widget> m_banner_widget; | ||||||
|     Gfx::IntSize m_content_size; |     Gfx::IntSize m_content_size; | ||||||
|     Gfx::IntSize m_min_content_size; |     Gfx::IntSize m_min_content_size; | ||||||
|     Gfx::IntSize m_size_occupied_by_fixed_elements; |     Gfx::IntSize m_size_occupied_by_fixed_elements; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 thankyouverycool
						thankyouverycool