mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:12:43 +00:00 
			
		
		
		
	LibGUI: Make TabWidget focusable and allow left/right arrow tab switch
You can now focus a TabWidget by tabbing (with the keyboard!) to it. Once focused, you can switch the active tab by pressing the left/right keyboard keys.
This commit is contained in:
		
							parent
							
								
									73ea191a05
								
							
						
					
					
						commit
						698490c565
					
				
					 1 changed files with 39 additions and 8 deletions
				
			
		|  | @ -40,6 +40,8 @@ namespace GUI { | |||
| 
 | ||||
| TabWidget::TabWidget() | ||||
| { | ||||
|     set_focus_policy(FocusPolicy::TabFocus); | ||||
| 
 | ||||
|     REGISTER_INT_PROPERTY("container_padding", container_padding, set_container_padding); | ||||
|     REGISTER_BOOL_PROPERTY("uniform_tabs", uniform_tabs, set_uniform_tabs); | ||||
| 
 | ||||
|  | @ -79,14 +81,14 @@ void TabWidget::set_active_widget(Widget* widget) | |||
|     if (widget == m_active_widget) | ||||
|         return; | ||||
| 
 | ||||
|     bool had_focus = is_focused() || (m_active_widget && m_active_widget->is_focused()); | ||||
|     bool active_widget_had_focus = m_active_widget && m_active_widget->is_focused(); | ||||
| 
 | ||||
|     if (m_active_widget) | ||||
|         m_active_widget->set_visible(false); | ||||
|     m_active_widget = widget; | ||||
|     if (m_active_widget) { | ||||
|         m_active_widget->set_relative_rect(child_rect_for_size(size())); | ||||
|         if (had_focus) | ||||
|         if (active_widget_had_focus) | ||||
|             m_active_widget->set_focus(true); | ||||
|         m_active_widget->set_visible(true); | ||||
|         deferred_invoke([this](auto&) { | ||||
|  | @ -200,9 +202,15 @@ void TabWidget::paint_event(PaintEvent& event) | |||
|         bool hovered = static_cast<int>(i) == m_hovered_tab_index; | ||||
|         auto button_rect = this->button_rect(i); | ||||
|         Gfx::StylePainter::paint_tab_button(painter, button_rect, palette(), false, hovered, m_tabs[i].widget->is_enabled(), m_tab_position == TabPosition::Top); | ||||
|         auto text_rect = button_rect.translated(0, m_tab_position == TabPosition::Top ? 1 : 0); | ||||
|         paint_tab_icon_if_needed(m_tabs[i].icon, button_rect, text_rect); | ||||
|         painter.draw_text(text_rect, m_tabs[i].title, m_text_alignment, palette().button_text(), Gfx::TextElision::Right); | ||||
|         auto tab_button_content_rect = button_rect.translated(0, m_tab_position == TabPosition::Top ? 1 : 0); | ||||
|         paint_tab_icon_if_needed(m_tabs[i].icon, button_rect, tab_button_content_rect); | ||||
| 
 | ||||
|         Gfx::IntRect text_rect { 0, 0, min(tab_button_content_rect.width(), font().width(m_tabs[i].title)), font().glyph_height() }; | ||||
|         text_rect.inflate(6, 4); | ||||
|         text_rect.align_within(tab_button_content_rect, m_text_alignment); | ||||
|         text_rect.intersect(tab_button_content_rect); | ||||
| 
 | ||||
|         painter.draw_text(text_rect, m_tabs[i].title, Gfx::TextAlignment::Center, palette().button_text(), Gfx::TextElision::Right); | ||||
|     } | ||||
| 
 | ||||
|     for (size_t i = 0; i < m_tabs.size(); ++i) { | ||||
|  | @ -211,9 +219,20 @@ void TabWidget::paint_event(PaintEvent& event) | |||
|         bool hovered = static_cast<int>(i) == m_hovered_tab_index; | ||||
|         auto button_rect = this->button_rect(i); | ||||
|         Gfx::StylePainter::paint_tab_button(painter, button_rect, palette(), true, hovered, m_tabs[i].widget->is_enabled(), m_tab_position == TabPosition::Top); | ||||
|         auto text_rect = button_rect.translated(0, m_tab_position == TabPosition::Top ? 1 : 0); | ||||
|         paint_tab_icon_if_needed(m_tabs[i].icon, button_rect, text_rect); | ||||
|         painter.draw_text(text_rect, m_tabs[i].title, m_text_alignment, palette().button_text(), Gfx::TextElision::Right); | ||||
|         auto tab_button_content_rect = button_rect.translated(0, m_tab_position == TabPosition::Top ? 1 : 0); | ||||
|         paint_tab_icon_if_needed(m_tabs[i].icon, button_rect, tab_button_content_rect); | ||||
| 
 | ||||
|         Gfx::IntRect text_rect { 0, 0, min(tab_button_content_rect.width(), font().width(m_tabs[i].title)), font().glyph_height() }; | ||||
|         text_rect.inflate(6, 4); | ||||
|         text_rect.align_within(tab_button_content_rect, m_text_alignment); | ||||
|         text_rect.intersect(tab_button_content_rect); | ||||
| 
 | ||||
|         painter.draw_text(text_rect, m_tabs[i].title, Gfx::TextAlignment::Center, palette().button_text(), Gfx::TextElision::Right); | ||||
| 
 | ||||
|         if (is_focused()) { | ||||
|             painter.draw_focus_rect(text_rect, palette().focus_outline()); | ||||
|         } | ||||
| 
 | ||||
|         if (m_tab_position == TabPosition::Top) { | ||||
|             painter.draw_line(button_rect.bottom_left().translated(1, 1), button_rect.bottom_right().translated(-1, 1), palette().button()); | ||||
|         } else if (m_tab_position == TabPosition::Bottom) { | ||||
|  | @ -395,6 +414,18 @@ void TabWidget::keydown_event(KeyEvent& event) | |||
|         event.accept(); | ||||
|         return; | ||||
|     } | ||||
|     if (is_focused()) { | ||||
|         if (!event.modifiers() && event.key() == Key_Left) { | ||||
|             activate_previous_tab(); | ||||
|             event.accept(); | ||||
|             return; | ||||
|         } | ||||
|         if (!event.modifiers() && event.key() == Key_Right) { | ||||
|             activate_next_tab(); | ||||
|             event.accept(); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     Widget::keydown_event(event); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling