Browse Source

LibGUI: Make scrollbar thumb size relative to content size

In order to calculate a thumb size that is a representation
of the visible portion (page) of the content, that information
needs to be taken into account.
Tom 5 years ago
parent
commit
fc568ea13a

+ 13 - 3
Libraries/LibGUI/ScrollBar.cpp

@@ -115,14 +115,17 @@ ScrollBar::~ScrollBar()
 {
 }
 
-void ScrollBar::set_range(int min, int max)
+void ScrollBar::set_range(int min, int max, int page)
 {
     ASSERT(min <= max);
-    if (m_min == min && m_max == max)
+    if (page < 0)
+        page = 0;
+    if (m_min == min && m_max == max && m_page == page)
         return;
 
     m_min = min;
     m_max = max;
+    m_page = page;
 
     int old_value = m_value;
     m_value = clamp(m_value, m_min, m_max);
@@ -190,7 +193,14 @@ int ScrollBar::scrubber_size() const
 {
     int pixel_range = length(orientation()) - button_size() * 2;
     int value_range = m_max - m_min;
-    return ::max(pixel_range - value_range, button_size());
+    
+    int scrubber_size = 0;
+    if (value_range > 0) {
+        // Scrubber size should be proportional to the visible portion
+        // (page) in relation to the content (value range + page)
+        scrubber_size = (m_page * pixel_range) / (value_range + m_page);
+    }
+    return ::max(scrubber_size, button_size());
 }
 
 Gfx::IntRect ScrollBar::scrubber_rect() const

+ 7 - 3
Libraries/LibGUI/ScrollBar.h

@@ -43,12 +43,15 @@ public:
     int value() const { return m_value; }
     int min() const { return m_min; }
     int max() const { return m_max; }
+    int page() const { return m_page; }
     int step() const { return m_step; }
     int big_step() const { return m_big_step; }
 
-    void set_min(int min) { set_range(min, max()); }
-    void set_max(int max) { set_range(min(), max); }
-    void set_range(int min, int max);
+    void set_min(int min) { set_range(min, max(), page()); }
+    void set_max(int max) { set_range(min(), max, page()); }
+    void set_page(int page) { set_range(min(), max(), page); }
+    void set_range(int min, int max) { set_range(min, max, page()); }
+    void set_range(int min, int max, int page);
     void set_value(int value);
     void set_step(int step) { m_step = step; }
     void set_big_step(int big_step) { m_big_step = big_step; }
@@ -91,6 +94,7 @@ private:
 
     int m_min { 0 };
     int m_max { 0 };
+    int m_page { 0 };
     int m_value { 0 };
     int m_step { 1 };
     int m_big_step { 5 };

+ 2 - 2
Libraries/LibGUI/ScrollableWidget.cpp

@@ -107,13 +107,13 @@ void ScrollableWidget::update_scrollbar_ranges()
     auto available_size = this->available_size();
 
     int excess_height = max(0, m_content_size.height() - available_size.height());
-    m_vertical_scrollbar->set_range(0, excess_height);
+    m_vertical_scrollbar->set_range(0, excess_height, available_size.height());
 
     if (should_hide_unnecessary_scrollbars())
         m_vertical_scrollbar->set_visible(excess_height > 0);
 
     int excess_width = max(0, m_content_size.width() - available_size.width());
-    m_horizontal_scrollbar->set_range(0, excess_width);
+    m_horizontal_scrollbar->set_range(0, excess_width, available_size.width());
 
     if (should_hide_unnecessary_scrollbars())
         m_horizontal_scrollbar->set_visible(excess_width > 0);