]> git.saurik.com Git - wxWidgets.git/commitdiff
Improve horizontal scrolling in wxRibbonControl.
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 31 May 2013 23:21:11 +0000 (23:21 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 31 May 2013 23:21:11 +0000 (23:21 +0000)
Scroll by entire "sections", i.e. panes of the ribbon, instead of scrolling by
a fixed number of pixels as it's much more useful and user-friendly to uncover
the next section entirely instead of asking the user to press on the arrow
several times before being able to use it.

Closes #15232.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74068 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/ribbon/page.h
interface/wx/ribbon/page.h
src/ribbon/page.cpp

index b31383bd799165582405ca7c4f85fae474cd0d69..8cdf8755353fe84b375ff3544c8817db1fdd47a2 100644 (file)
@@ -645,6 +645,7 @@ All (GUI):
 - Add wxEVT_DIRCTRL_FILEACTIVATED event (troelsk).
 - Add wxControl::GetSizeFromTextSize() (Manuel Martin).
 - Optionally allow showing tooltips for disabled ribbon buttons (wxBen).
+- Improve horizontal scrolling in wxRibbonControl (wxBen).
 - Add wxTL_NO_HEADER style to wxTreeListCtrl (robboto).
 - Add possibility to delay showing wxRichToolTip (John Roberts).
 - Add "rect" paramerer to wxRichToolTip::ShowFor() (John Roberts).
index 5d3fed58c32bff0a9d2e69d0412b5235dad58ca9..44b836974190587dbbfe4beb00f41af7d83d039d 100644 (file)
@@ -56,6 +56,7 @@ public:
     virtual bool Layout();
     virtual bool ScrollLines(int lines);
     bool ScrollPixels(int pixels);
+    bool ScrollSections(int sections);
 
     wxOrientation GetMajorAxis() const;
 
index 72348ee23a623e55f36cf6df53ddff12ac59b351..a3ee66b334ddfef69aeeed3e78a9ceb0c10aa1a4 100644 (file)
@@ -148,6 +148,7 @@ public:
     
         @see GetMajorAxis()
         @see ScrollPixels()
+        @see ScrollSections()
     */
     virtual bool ScrollLines(int lines);
   
@@ -165,9 +166,27 @@ public:
     
         @see GetMajorAxis()
         @see ScrollLines()
+        @see ScrollSections()
     */
     bool ScrollPixels(int pixels);
 
+    /**
+        Scroll the page by an entire child section.
+
+        The @a sections parameter value should be 1 or -1. This will scroll
+        enough to uncover a partially visible child section or totally uncover
+        the next child section that may not be visible at all.
+
+        @return @true if the page scrolled at least one pixel in the given
+            direction, @false if it did not scroll.
+
+        @see ScrollPixels()
+        @see ScrollSections()
+
+        @since 2.9.5
+    */
+    bool ScrollSections(int sections);
+
     /**
         Get the direction in which ribbon panels are stacked within the page.
     
index 0fecb1c0a21360d8bce112e59d8a00d096f046ca..9440dddd9fff3f1477568246c3bf67878dc9f9e5 100644 (file)
@@ -135,11 +135,11 @@ void wxRibbonPageScrollButton::OnMouseUp(wxMouseEvent& WXUNUSED(evt))
         {
         case wxRIBBON_SCROLL_BTN_DOWN:
         case wxRIBBON_SCROLL_BTN_RIGHT:
-            m_sibling->ScrollLines(1);
+            m_sibling->ScrollSections(1);
             break;
         case wxRIBBON_SCROLL_BTN_UP:
         case wxRIBBON_SCROLL_BTN_LEFT:
-            m_sibling->ScrollLines(-1);
+            m_sibling->ScrollSections(-1);
             break;
         default:
             break;
@@ -336,6 +336,124 @@ bool wxRibbonPage::ScrollPixels(int pixels)
     return true;
 }
 
+bool wxRibbonPage::ScrollSections(int sections)
+{
+    // Currently the only valid values are -1 and 1 for scrolling left and
+    // right, respectively.
+    const bool scrollForward = sections >= 1;
+
+    // Determine by how many pixels to scroll. If something on the page
+    // is partially visible, scroll to make it fully visible. Otherwise
+    // find the next item that will become visible and scroll to make it
+    // fully visible. The ScrollPixel call will correct if we scroll too
+    // much if the available width is smaller than the items.
+
+    // Scroll at minimum the same amount as ScrollLines(1):
+    int minscroll = sections * 8;
+    // How many pixels to scroll:
+    int pixels = 0;
+
+    // Determine the scroll position, that is, the page border where items
+    // are appearing.
+    int scrollpos = 0;
+
+    wxOrientation major_axis = GetMajorAxis();
+    int gap = 0;
+
+    int width = 0;
+    int height = 0;
+    int x = 0;
+    int y = 0;
+    GetSize(&width, &height);
+    GetPosition(&x, &y);
+    if(major_axis == wxHORIZONTAL)
+    {
+        gap = m_art->GetMetric(wxRIBBON_ART_PANEL_X_SEPARATION_SIZE);
+        if (scrollForward)
+        {
+            scrollpos = width - m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_RIGHT_SIZE);
+        }
+        else
+        {
+            scrollpos = m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_LEFT_SIZE);
+        }
+    }
+    else
+    {
+        gap = m_art->GetMetric(wxRIBBON_ART_PANEL_Y_SEPARATION_SIZE);
+        if (scrollForward)
+        {
+            scrollpos = width - m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE);
+        }
+        else
+        {
+            scrollpos = m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_TOP_SIZE);
+        }
+    }
+
+    // Find the child that is partially shown or just beyond the scroll position
+    for(wxWindowList::compatibility_iterator
+            node = scrollForward ? GetChildren().GetFirst()
+                                 : GetChildren().GetLast();
+        node;
+        node = scrollForward ? node->GetNext()
+                             : node->GetPrevious())
+    {
+        wxWindow* child = node->GetData();
+        child->GetSize(&width, &height);
+        child->GetPosition(&x, &y);
+        int pos0 = 0;
+        int pos1 = 0;
+        if (major_axis == wxHORIZONTAL)
+        {
+            pos0 = x;
+            pos1 = x + width + gap;
+        }
+        else
+        {
+            pos0 = y;
+            pos1 = y + height + gap;
+        }
+        if (scrollpos >= pos0 && scrollpos <= pos1)
+        {
+            // This section is partially visible, scroll to make it fully visible.
+            if (scrollForward)
+            {
+                pixels += pos1 - scrollpos;
+            }
+            else
+            {
+                pixels += pos0 - scrollpos;
+            }
+            if (abs(pixels) >= abs(minscroll))
+                break;
+        }
+        if (scrollpos <= pos0 && scrollForward)
+        {
+            // This section is next, scroll the entire section width
+            pixels += (pos1 - pos0);
+            break;
+        }
+        if (scrollpos >= pos1 && !scrollForward)
+        {
+            // This section is next, scroll the entire section width
+            pixels += (pos0 - pos1);
+            break;
+        }
+    }
+    // Do a final safety sanity check, should not be necessary, but will not hurt either.
+    if (pixels == 0)
+    {
+        pixels = minscroll;
+    }
+    if (pixels * minscroll < 0)
+    {
+        pixels = -pixels;
+    }
+
+    return ScrollPixels(pixels);
+}
+
 void wxRibbonPage::SetSizeWithScrollButtonAdjustment(int x, int y, int width, int height)
 {
     if(m_scroll_buttons_visible)