Sfoglia il codice sorgente

LibGUI: Hide unnecessary Scrollbars in ComboBox windows

And simplify rect calculations using content size.
thankyouverycool 2 anni fa
parent
commit
1bba8589fe
1 ha cambiato i file con 18 aggiunte e 33 eliminazioni
  1. 18 33
      Userland/Libraries/LibGUI/ComboBox.cpp

+ 18 - 33
Userland/Libraries/LibGUI/ComboBox.cpp

@@ -126,7 +126,7 @@ ComboBox::ComboBox()
     m_list_window->on_input_preemption = [this](auto) { close(); };
 
     m_list_view = m_list_window->set_main_widget<ListView>();
-    m_list_view->horizontal_scrollbar().set_visible(false);
+    m_list_view->set_should_hide_unnecessary_scrollbars(true);
     m_list_view->set_alternating_row_colors(false);
     m_list_view->set_hover_highlighting(true);
     m_list_view->set_frame_thickness(1);
@@ -247,44 +247,29 @@ void ComboBox::select_all()
 
 void ComboBox::open()
 {
-    if (!model())
-        return;
-
-    auto my_screen_rect = screen_relative_rect();
+    m_editor->set_focus(true);
 
-    int longest_item_width = 0;
-    for (int i = 0; i < model()->row_count(); ++i) {
-        auto index = model()->index(i);
-        auto item_text = index.data().to_string();
-        longest_item_width = max(longest_item_width, m_list_view->font().width(item_text));
-    }
-    Gfx::IntSize size {
-        max(width(), longest_item_width + m_list_view->width_occupied_by_vertical_scrollbar() + m_list_view->frame_thickness() * 2 + m_list_view->horizontal_padding()),
-        model()->row_count() * m_list_view->item_height() + m_list_view->frame_thickness() * 2
-    };
+    // Force content size update while invisible
+    m_list_view->resize({});
 
-    auto taskbar_height = GUI::Desktop::the().taskbar_height();
-    Gfx::IntRect list_window_rect { my_screen_rect.bottom_left(), size };
-    list_window_rect.intersect(Desktop::the().rect().shrunken(0, taskbar_height * 2));
+    auto frame = m_list_view->frame_thickness() * 2;
+    auto max_height = min(m_list_view->item_height() * m_max_visible_items, m_list_view->content_height());
+    Gfx::IntSize size { max(width(), m_list_view->content_width() + frame), max_height + frame };
+    Gfx::IntRect rect { screen_relative_rect().bottom_left(), size };
 
-    m_editor->set_focus(true);
-    if (m_selected_index.has_value()) {
-        // Don't set m_updating_model to true here because we only want to
-        // change the list view's selected item without triggering a change to it.
-        m_list_view->set_cursor(m_selected_index.value(), AbstractView::SelectionUpdate::Set);
-    }
-
-    // Change direction and go upwards to prevent the list from becoming
-    // infinitesimally small when pushed up against the screen edge.
-    auto minimum_height = min(3, model()->row_count()) * m_list_view->item_height() + m_list_view->frame_thickness() * 2;
-    bool go_upwards_instead = list_window_rect.height() < minimum_height;
+    auto desktop = Desktop::the().rect().shrunken(0, 0, Desktop::the().taskbar_height(), 0);
+    auto min_height = 5 * m_list_view->item_height() + frame;
+    auto go_upwards_instead = rect.bottom() >= desktop.height() && rect.intersected(desktop).height() < min_height;
     if (go_upwards_instead) {
-        auto origin_point = my_screen_rect.top_left();
-        list_window_rect = { Gfx::IntPoint { origin_point.x(), origin_point.y() - size.height() }, size };
-        list_window_rect.intersect(Desktop::the().rect());
+        auto origin = screen_relative_rect().top_left();
+        rect = { Gfx::IntPoint { origin.x(), origin.y() - size.height() }, size };
     }
+    rect.intersect(desktop);
+    m_list_window->set_rect(rect);
+
+    if (m_selected_index.has_value())
+        m_list_view->set_cursor(m_selected_index.value(), AbstractView::SelectionUpdate::Set);
 
-    m_list_window->set_rect(list_window_rect);
     m_list_window->show();
 }