]> git.saurik.com Git - wxWidgets.git/commitdiff
Applied patch [ 621451 ] Fixed version of wxSlider class
authorJulian Smart <julian@anthemion.co.uk>
Fri, 24 Jan 2003 11:23:52 +0000 (11:23 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Fri, 24 Jan 2003 11:23:52 +0000 (11:23 +0000)
Otto Wyss

This patch corrects several bugs in the wxSlider class
for the wxUniversal/MSW port. It affects the files
"slider.h", "slider.cpp", "win32.cpp" and "gtk.cpp"
(and others). The slider should now work as expected. A simple test
program can be downloaded from

"http://dpartialmirror.sourceforge.net/Test/".

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

include/wx/univ/renderer.h
include/wx/univ/slider.h
src/univ/slider.cpp
src/univ/themes/gtk.cpp
src/univ/themes/win32.cpp

index f6fe94b5155060b1f47b175211b47adb5d3cefab..e11bf8c88379493a3f369a6c10550e3099b1a202 100644 (file)
@@ -228,25 +228,29 @@ public:
     // draw the slider shaft
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  wxRect *rectShaft = NULL) = 0;
 
     // draw the slider thumb
     virtual void DrawSliderThumb(wxDC& dc,
                                  const wxRect& rect,
                                  wxOrientation orient,
-                                 int flags = 0) = 0;
+                                 int flags = 0,
+                                 long style = 0) = 0;
 
     // draw the slider ticks
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int start,
                                  int end,
                                  int step = 1,
-                                 int flags = 0) = 0;
+                                 int flags = 0,
+                                 long style = 0) = 0;
 
     // draw a menu bar item
     virtual void DrawMenuBarItem(wxDC& dc,
@@ -405,10 +409,13 @@ public:
 
     // get the slider shaft rect from the total slider rect
     virtual wxRect GetSliderShaftRect(const wxRect& rect,
-                                      wxOrientation orient) const = 0;
+                                      int lenThumb,
+                                      wxOrientation orient,
+                                      long style = 0) const = 0;
 
     // get the size of the slider thumb for the given total slider rect
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const = 0;
 
     // get the size of one progress bar step (in horz and vertical directions)
@@ -637,25 +644,29 @@ public:
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  wxRect *rectShaft = NULL)
-        { m_renderer->DrawSliderShaft(dc, rect, orient, flags, rectShaft); }
+        { m_renderer->DrawSliderShaft(dc, rect, lenThumb, orient, flags, style, rectShaft); }
     virtual void DrawSliderThumb(wxDC& dc,
                                  const wxRect& rect,
                                  wxOrientation orient,
-                                 int flags = 0)
-        { m_renderer->DrawSliderThumb(dc, rect, orient, flags); }
+                                 int flags = 0,
+                                 long style = 0)
+        { m_renderer->DrawSliderThumb(dc, rect, orient, flags, style); }
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int start,
                                  int end,
                                  int step = 1,
-                                 int flags = 0)
-        { m_renderer->DrawSliderTicks(dc, rect, sizeThumb, orient,
-                                      start, end, step, flags); }
+                                 int flags = 0,
+                                 long style = 0)
+        { m_renderer->DrawSliderTicks(dc, rect, lenThumb, orient,
+                                      start, end, start, flags, style); }
 
     virtual void DrawMenuBarItem(wxDC& dc,
                                  const wxRect& rect,
@@ -778,11 +789,14 @@ public:
     virtual wxCoord GetSliderTickLen() const
         { return m_renderer->GetSliderTickLen(); }
     virtual wxRect GetSliderShaftRect(const wxRect& rect,
-                                      wxOrientation orient) const
-        { return m_renderer->GetSliderShaftRect(rect, orient); }
+                                      int lenThumb,
+                                      wxOrientation orient,
+                                      long style = 0) const
+        { return m_renderer->GetSliderShaftRect(rect, lenThumb, orient, style); }
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const
-        { return m_renderer->GetSliderThumbSize(rect, orient); }
+        { return m_renderer->GetSliderThumbSize(rect, lenThumb, orient); }
     virtual wxSize GetProgressBarStep() const
         { return m_renderer->GetProgressBarStep(); }
     virtual wxSize GetMenuBarItemSize(const wxSize& sizeText) const
index a5e51055f0166484f3e2ce90c55d68bbf1313a6f..729f68b5621bdc8f62236061b76ee34e83048f98 100644 (file)
@@ -95,10 +95,14 @@ public:
         { return IsVert() ? wxVERTICAL : wxHORIZONTAL; }
 
     // do we have labels?
-    bool HasLabels() const { return (GetWindowStyle() & wxSL_LABELS) != 0; }
+    bool HasLabels() const 
+        { return ((GetWindowStyle() & wxSL_LABELS) != 0) &
+                 ((GetWindowStyle() & (wxSL_TOP|wxSL_BOTTOM|wxSL_LEFT|wxSL_RIGHT)) != 0); }
 
     // do we have ticks?
-    bool HasTicks() const { return (GetWindowStyle() & wxSL_TICKS) != 0; }
+    bool HasTicks() const 
+        { return ((GetWindowStyle() & wxSL_TICKS) != 0) &
+                 ((GetWindowStyle() & (wxSL_TOP|wxSL_BOTTOM|wxSL_LEFT|wxSL_RIGHT|wxSL_BOTH)) != 0); }
 
     // implement wxControlWithThumb interface
     virtual wxWindow *GetWindow() { return this; }
index 8381f531a6a514e35545211aeba6f4d8dabe6d2a..adfa70db53dce77cec466cb10e09ecb19eda80cc 100644 (file)
@@ -183,21 +183,16 @@ bool wxSlider::ChangeValueBy(int inc)
 
 bool wxSlider::ChangeValueTo(int value)
 {
+    // check if the value is going to change at all
+    if (value == m_value) return FALSE;
+
     // this method is protected and we should only call it with normalized
     // value!
     wxCHECK_MSG( IsInRange(value), FALSE, _T("invalid slider value") );
 
-    // check if the value is going to change at all
-    if ( value == m_value )
-        return FALSE;
-
-    // refresh the old thumb position
-    RefreshThumb();
-
     m_value = value;
 
-    // and the new one
-    RefreshThumb();
+    Refresh();
 
     // generate the event
     wxCommandEvent event(wxEVT_COMMAND_SLIDER_UPDATED, GetId());
@@ -266,14 +261,14 @@ int wxSlider::GetMax() const
 
 void wxSlider::SetLineSize(int lineSize)
 {
-    wxCHECK_RET( lineSize > 0, _T("invalid slider line size") );
+    wxCHECK_RET( lineSize >= 0, _T("invalid slider line size") );
 
     m_lineSize = lineSize;
 }
 
 void wxSlider::SetPageSize(int pageSize)
 {
-    wxCHECK_RET( pageSize > 0, _T("invalid slider page size") );
+    wxCHECK_RET( pageSize >= 0, _T("invalid slider page size") );
 
     m_pageSize = pageSize;
 }
@@ -293,8 +288,8 @@ int wxSlider::GetPageSize() const
 {
     if ( !m_pageSize )
     {
-        // the default page increment is 1/10 of the range
-        wxConstCast(this, wxSlider)->m_pageSize = (m_max - m_min) / 10;
+        // the default page increment is m_tickFreq
+        wxConstCast(this, wxSlider)->m_pageSize = m_tickFreq;
     }
 
     return m_pageSize;
@@ -302,7 +297,7 @@ int wxSlider::GetPageSize() const
 
 void wxSlider::SetThumbLength(int lenPixels)
 {
-    wxCHECK_RET( lenPixels > 0, _T("invalid slider thumb size") );
+    wxCHECK_RET( lenPixels >= 0, _T("invalid slider thumb size") );
 
     // use m_thumbSize here directly and not GetThumbLength() to avoid setting
     // it to the default value as we don't need it
@@ -316,13 +311,17 @@ void wxSlider::SetThumbLength(int lenPixels)
 
 int wxSlider::GetThumbLength() const
 {
-    if ( !m_thumbSize )
+    wxSize sz = GetDefaultThumbSize();
+    int len = (IsVert() ? sz.x : sz.y);
+    if (m_thumbSize > len) 
+    {
+        return m_thumbSize;
+    }
+    else
     {
-        wxSize sz = GetDefaultThumbSize();
-        return IsVert() ? sz.y : sz.x;
+        return len;
     }
 
-    return m_thumbSize;
 }
 
 // ----------------------------------------------------------------------------
@@ -331,6 +330,8 @@ int wxSlider::GetThumbLength() const
 
 void wxSlider::SetTickFreq(int n, int WXUNUSED(dummy))
 {
+    wxCHECK_RET (n > 0, _T("invalid slider tick frequency"));
+
     if ( n != m_tickFreq )
     {
         m_tickFreq = n;
@@ -364,7 +365,9 @@ wxSize wxSlider::CalcLabelSize() const
 wxSize wxSlider::DoGetBestClientSize() const
 {
     // this dimension is completely arbitrary
-    static const wxCoord SLIDER_WIDTH = 100;
+    static const wxCoord SLIDER_WIDTH = 40;
+
+    long style = GetWindowStyle();
 
     // first calculate the size of the slider itself: i.e. the shaft and the
     // thumb
@@ -386,6 +389,10 @@ wxSize wxSlider::DoGetBestClientSize() const
     if ( HasTicks() )
     {
         wxCoord lenTick = GetRenderer()->GetSliderTickLen();
+        if (style & wxSL_BOTH) 
+        {
+            lenTick = 2 * lenTick;
+        }
 
         if ( IsVert() )
             size.x += lenTick;
@@ -398,10 +405,14 @@ wxSize wxSlider::DoGetBestClientSize() const
     {
         wxSize sizeLabels = CalcLabelSize();
 
-        if ( IsVert() )
+        if (style & (wxSL_LEFT|wxSL_RIGHT))
+        {
             size.x += sizeLabels.x + SLIDER_LABEL_MARGIN;
-        else
+        }
+        else if (style & (wxSL_TOP|wxSL_BOTTOM))
+        {
             size.y += sizeLabels.y + SLIDER_LABEL_MARGIN;
+        }
     }
 
     return size;
@@ -457,110 +468,102 @@ void wxSlider::CalcGeometry()
        | H *|
        ------
     */
+    long style = GetWindowStyle();
 
+    // initialize to the full client rect
     wxRect rectTotal = GetClientRect();
+    m_rectSlider = rectTotal;
+    wxSize sizeThumb = GetThumbSize();
+
+    // Labels reduce the size of the slider rect
     if ( HasLabels() )
     {
-        wxSize sizeLabels = CalcLabelSize();
+       wxSize sizeLabels = CalcLabelSize();
 
-        m_rectSlider = rectTotal;
         m_rectLabel = wxRect(rectTotal.GetPosition(), sizeLabels);
 
-        // split the rect
-        if ( IsVert() )
+        if (style & wxSL_TOP) 
         {
-            sizeLabels.x += SLIDER_LABEL_MARGIN;
-
-            if ( GetWindowStyle() & wxSL_LEFT )
-            {
-                // shrink and offset the slider to the right
-                m_rectSlider.x += sizeLabels.x;
-                m_rectSlider.width -= sizeLabels.x;
-            }
-            else // wxSL_RIGHT
-            {
-                // just shrink the slider and move the label to the right
-                m_rectSlider.width -= sizeLabels.x;
-
-                m_rectLabel.x += m_rectSlider.width + SLIDER_LABEL_MARGIN;
-            }
+            // shrink and offset the slider to the bottom
+            m_rectSlider.y += sizeLabels.y + SLIDER_LABEL_MARGIN;
+            m_rectSlider.height -= sizeLabels.y + SLIDER_LABEL_MARGIN;
         }
-        else // horizontal
+        else if (style & wxSL_BOTTOM) 
         {
-            // same logic as above but x/y are trasnposed
-            sizeLabels.y += SLIDER_LABEL_MARGIN;
-
-            if ( GetWindowStyle() & wxSL_TOP )
-            {
-                m_rectSlider.y += sizeLabels.y;
-                m_rectSlider.height -= sizeLabels.y;
-            }
-            else // wxSL_BOTTOM
-            {
-                m_rectSlider.height -= sizeLabels.y;
-
-                m_rectLabel.y += m_rectSlider.height + SLIDER_LABEL_MARGIN;
-            }
+            // shrink the slider and move the label to the bottom
+            m_rectSlider.height -= sizeLabels.y + SLIDER_LABEL_MARGIN;
+            m_rectLabel.y += m_rectSlider.height + SLIDER_LABEL_MARGIN;
+        }
+        else if (style & wxSL_LEFT) 
+        {
+            // shrink and offset the slider to the right
+            m_rectSlider.x += sizeLabels.x + SLIDER_LABEL_MARGIN;
+            m_rectSlider.width -= sizeLabels.x + SLIDER_LABEL_MARGIN;
+        }
+        else if (style & wxSL_RIGHT) 
+        {
+            // shrink the slider and move the label to the right
+            m_rectSlider.width -= sizeLabels.x + SLIDER_LABEL_MARGIN;
+            m_rectLabel.x += m_rectSlider.width + SLIDER_LABEL_MARGIN;
         }
-    }
-    else // no labels
-    {
-        // the slider takes the whole client rect
-        m_rectSlider = rectTotal;
     }
 
-    // now adjust for ticks too
+    // calculate ticks too
     if ( HasTicks() )
     {
         wxCoord lenTick = GetRenderer()->GetSliderTickLen();
 
-        if ( IsVert() )
-        {
-            m_rectSlider.width -= lenTick;
-        }
-        else // horizontal
-        {
-            m_rectSlider.height -= lenTick;
-        }
-
-        // note that we must compute m_rectSlider first as GetShaftRect() uses
         // it
         m_rectTicks = GetShaftRect();
 
         if ( IsVert() )
         {
-            m_rectTicks.x = m_rectSlider.x + m_rectSlider.width;
+            if (style & (wxSL_LEFT|wxSL_BOTH)) 
+            {
+                m_rectTicks.x = m_rectSlider.x;
+            }
+            else
+            { // wxSL_RIGHT
+                m_rectTicks.x = m_rectSlider.x + m_rectSlider.width - lenTick;
+            }
             m_rectTicks.width = lenTick;
         }
         else // horizontal
         {
-            m_rectTicks.y = m_rectSlider.y + m_rectSlider.height;
+            if (style & (wxSL_TOP|wxSL_BOTH)) 
+            {
+                m_rectTicks.y = m_rectSlider.y;
+            }
+            else
+            { // wxSL_BOTTOM
+                m_rectTicks.y = m_rectSlider.y + m_rectSlider.height - lenTick;
+            }
             m_rectTicks.height = lenTick;
         }
+    }
 
+    // slider is never smaller than thumb size unless rectTotal
+    if ( IsVert() )
+    {
+        wxCoord width = wxMin ( rectTotal.width, sizeThumb.x );
+        m_rectSlider.width = wxMax ( m_rectSlider.width, width );
+    }
+    else
+    {
+        wxCoord height = wxMin ( rectTotal.height, sizeThumb.y );
+        m_rectSlider.height = wxMax ( m_rectSlider.height, height );
     }
 }
 
 wxSize wxSlider::GetDefaultThumbSize() const
 {
-    return GetRenderer()->GetSliderThumbSize(GetSliderRect(), GetOrientation());
+    // Default size has no styles (arrows)
+    return GetRenderer()->GetSliderThumbSize(GetSliderRect(), 0, GetOrientation());
 }
 
 wxSize wxSlider::GetThumbSize() const
 {
-    wxSize sizeThumb = GetDefaultThumbSize();
-
-    // if we have our own thumb length (set by the user), use it instead of the
-    // default value
-    if ( m_thumbSize )
-    {
-        if ( IsVert() )
-            sizeThumb.y = m_thumbSize;
-        else
-            sizeThumb.x = m_thumbSize;
-    }
-
-    return sizeThumb;
+    return GetRenderer()->GetSliderThumbSize(GetSliderRect(), m_thumbSize, GetOrientation());
 }
 
 // ----------------------------------------------------------------------------
@@ -569,7 +572,7 @@ wxSize wxSlider::GetThumbSize() const
 
 wxRect wxSlider::GetShaftRect() const
 {
-    return GetRenderer()->GetSliderShaftRect(m_rectSlider, GetOrientation());
+    return GetRenderer()->GetSliderShaftRect(m_rectSlider, m_thumbSize, GetOrientation(), GetWindowStyle());
 }
 
 void wxSlider::CalcThumbRect(const wxRect *rectShaftIn,
@@ -620,30 +623,37 @@ void wxSlider::CalcThumbRect(const wxRect *rectShaftIn,
     // position is not at lenShaft but at lenShaft - thumbSize
     if ( m_max != m_min )
     {
-        *p += ((lenShaft - lenThumb)*(value - m_min))/(m_max - m_min);
+        if ( isVertical )
+        {
+            *p += ((lenShaft - lenThumb)*(m_max - value))/(m_max - m_min);
+        }
+        else
+        { // horz
+            *p += ((lenShaft - lenThumb)*(value - m_min))/(m_max - m_min);
+        }
     }
 
     // calc the label rect
     if ( HasLabels() && rectLabelOut )
     {
+        long style = GetWindowStyle();
         wxRect rectLabel = m_rectLabel;
 
         // centre the label relatively to the thumb position
-        if ( isVertical )
+        if (style & (wxSL_TOP|wxSL_BOTTOM))
         {
-            rectLabel.y =
-                rectThumb.y + (rectThumb.height - m_rectLabel.height)/2;
+            rectLabel.x = rectThumb.x + (rectThumb.width - m_rectLabel.width)/2;
         }
-        else // horz
+        else if (style & (wxSL_LEFT|wxSL_RIGHT))
         {
-            rectLabel.x =
-                rectThumb.x + (rectThumb.width - m_rectLabel.width)/2;
+            rectLabel.y = rectThumb.y + (rectThumb.height - m_rectLabel.height)/2;
         }
 
         *rectLabelOut = rectLabel;
     }
 
     if ( rectThumbOut )
+
         *rectThumbOut = rectThumb;
 }
 
@@ -662,47 +672,57 @@ void wxSlider::DoDraw(wxControlRenderer *renderer)
     wxDC& dc = renderer->GetDC();
     wxRect rectUpdate = GetUpdateClientRect();
 
-    bool isVertical = IsVert();
     wxOrientation orient = GetOrientation();
     int flags = GetStateFlags();
+    long style = GetWindowStyle();
+
+    wxSize sz = GetThumbSize();
+    int len = IsVert() ? sz.x : sz.y;
 
     // first draw the shaft
-    wxRect rectShaft = rend->GetSliderShaftRect(m_rectSlider, orient);
+    wxRect rectShaft = rend->GetSliderShaftRect(m_rectSlider, len, orient, style);
     if ( rectUpdate.Intersects(rectShaft) )
     {
-        rend->DrawSliderShaft(dc, m_rectSlider, orient, flags);
+        rend->DrawSliderShaft(dc, m_rectSlider, len, orient, flags, style);
     }
 
     // calculate the thumb position in pixels and draw it
     wxRect rectThumb, rectLabel;
     CalcThumbRect(&rectShaft, &rectThumb, &rectLabel);
 
-    if ( rectUpdate.Intersects(rectThumb) )
+    // then draw the ticks
+    if ( HasTicks() && rectUpdate.Intersects(m_rectTicks) )
     {
-        rend->DrawSliderThumb(dc, rectThumb, orient, flags | m_thumbFlags);
+        rend->DrawSliderTicks(dc, m_rectSlider, len, orient,
+                              m_min, m_max, m_tickFreq, flags, style);
     }
 
-    // then draw the ticks
-    if ( HasTicks() && rectUpdate.Intersects(m_rectTicks) )
+    // then draw the thumb
+    if ( rectUpdate.Intersects(rectThumb) )
     {
-        rend->DrawSliderTicks(dc, m_rectTicks, rectThumb.GetSize(), orient,
-                              m_min, m_max, m_tickFreq);
+        rend->DrawSliderThumb(dc, rectThumb, orient, flags | m_thumbFlags, style);
     }
 
     // finally, draw the label near the thumb
     if ( HasLabels() && rectUpdate.Intersects(rectLabel) )
     {
         // align it to be close to the shaft
-        int align;
-        if ( isVertical )
+        int align = 0;
+        if (style & wxSL_TOP) 
         {
-            align = wxALIGN_CENTRE_VERTICAL |
-                    (GetWindowStyle() & wxSL_RIGHT ? wxALIGN_LEFT
-                                                   : wxALIGN_RIGHT);
+            align = wxALIGN_CENTRE_HORIZONTAL|wxALIGN_TOP;
         }
-        else // horz
+        else if (style & wxSL_BOTTOM) 
         {
-            align = wxALIGN_CENTRE;
+            align = wxALIGN_CENTRE_HORIZONTAL|wxALIGN_BOTTOM;
+        }
+        else if (style & wxSL_LEFT) 
+        {
+            align = wxALIGN_CENTRE_VERTICAL|wxALIGN_LEFT;
+        }
+        else if (style & wxSL_RIGHT) 
+        {
+            align = wxALIGN_CENTRE_VERTICAL|wxALIGN_RIGHT;
         }
 
         dc.SetFont(GetFont());
@@ -714,18 +734,6 @@ void wxSlider::DoDraw(wxControlRenderer *renderer)
     }
 }
 
-void wxSlider::RefreshThumb()
-{
-    wxRect rectThumb, rectLabel;
-    CalcThumbRect(NULL, &rectThumb, &rectLabel);
-
-    Refresh(TRUE /* erase background */, &rectThumb);
-    if ( HasLabels() )
-    {
-        Refresh(TRUE, &rectLabel);
-    }
-}
-
 // ----------------------------------------------------------------------------
 // wxSlider input processing
 // ----------------------------------------------------------------------------
@@ -734,7 +742,7 @@ bool wxSlider::PerformAction(const wxControlAction& action,
                              long numArg,
                              const wxString& strArg)
 {
-    if ( action == wxACTION_SLIDER_START )
+     if ( action == wxACTION_SLIDER_START )
     {
         ChangeValueTo(m_min);
     }
@@ -748,19 +756,19 @@ bool wxSlider::PerformAction(const wxControlAction& action,
     }
     else if ( action == wxACTION_SLIDER_LINE_UP )
     {
-        ChangeValueBy(-GetLineSize());
+        ChangeValueBy(+GetLineSize());
     }
-    else if ( action == wxACTION_SLIDER_PAGE_UP )
+    else if ( action == wxACTION_SLIDER_LINE_DOWN )
     {
-        return PerformAction(wxACTION_SLIDER_PAGE_CHANGE, -1);
+        ChangeValueBy(-GetLineSize());
     }
-    else if ( action == wxACTION_SLIDER_LINE_DOWN )
+    else if ( action == wxACTION_SLIDER_PAGE_UP )
     {
-        ChangeValueBy(GetLineSize());
+        ChangeValueBy(+GetPageSize());
     }
     else if ( action == wxACTION_SLIDER_PAGE_DOWN )
     {
-        return PerformAction(wxACTION_SLIDER_PAGE_CHANGE, 1);
+        ChangeValueBy(-GetPageSize());
     }
     else if ( action == wxACTION_SLIDER_THUMB_DRAG )
     {
@@ -790,36 +798,37 @@ wxScrollThumb::Shaft wxSlider::HitTest(const wxPoint& pt) const
     wxRect rectThumb;
     CalcThumbRect(&rectShaft, &rectThumb, NULL);
 
-       // check for possible shaft or thumb hit
-    if (!rectShaft.Inside(pt) && !rectThumb.Inside(pt))
+    // check for possible shaft or thumb hit
+    if (!rectShaft.Inside(pt) && !rectThumb.Inside(pt)) 
     {
         return wxScrollThumb::Shaft_None;
     }
 
-
     // the position to test and the start and end of the thumb
-    wxCoord x, x1, x2;
-    if ( IsVert() )
+    wxCoord x, x1, x2, x3, x4;
+    if (IsVert()) 
     {
         x = pt.y;
-        x1 = rectThumb.GetTop();
-        x2 = rectThumb.GetBottom();
+        x1 = rectThumb.GetBottom();
+        x2 = rectShaft.GetBottom();
+        x3 = rectShaft.GetTop();
+        x4 = rectThumb.GetTop();
     }
-    else // horz
-    {
+    else
+    { // horz
         x = pt.x;
-        x1 = rectThumb.GetLeft();
-        x2 = rectThumb.GetRight();
+        x1 = rectShaft.GetLeft();
+        x2 = rectThumb.GetLeft();
+        x3 = rectThumb.GetRight();
+        x4 = rectShaft.GetRight();
     }
-
-    if ( x < x1 )
+    if ((x1 <= x) & (x < x2)) 
     {
         // or to the left
         return wxScrollThumb::Shaft_Above;
     }
 
-    if ( x > x2 )
-    {
+    if ((x3 < x) & (x <= x4)) {
         // or to the right
         return wxScrollThumb::Shaft_Below;
     }
@@ -881,23 +890,44 @@ void wxSlider::SetShaftPartState(wxScrollThumb::Shaft shaftPart,
         else
             m_thumbFlags &= ~flag;
 
-        RefreshThumb();
+        Refresh();
     }
 }
 
 void wxSlider::OnThumbDragStart(int pos)
 {
-    PerformAction(wxACTION_SLIDER_THUMB_DRAG, pos);
+    if (IsVert()) 
+    {
+        PerformAction(wxACTION_SLIDER_THUMB_DRAG, m_max - pos);
+    }
+    else
+    {
+        PerformAction(wxACTION_SLIDER_THUMB_DRAG, pos);
+    }
 }
 
 void wxSlider::OnThumbDrag(int pos)
 {
-    PerformAction(wxACTION_SLIDER_THUMB_MOVE, pos);
+    if (IsVert()) 
+    {
+        PerformAction(wxACTION_SLIDER_THUMB_MOVE, m_max - pos);
+    }
+    else
+    {
+        PerformAction(wxACTION_SLIDER_THUMB_MOVE, pos);
+    }
 }
 
 void wxSlider::OnThumbDragEnd(int pos)
 {
-    PerformAction(wxACTION_SLIDER_THUMB_RELEASE, pos);
+    if (IsVert()) 
+    {
+        PerformAction(wxACTION_SLIDER_THUMB_RELEASE, m_max - pos);
+    }
+    else
+    {
+        PerformAction(wxACTION_SLIDER_THUMB_RELEASE, pos);
+    }
 }
 
 void wxSlider::OnPageScrollStart()
@@ -921,7 +951,7 @@ bool wxStdSliderButtonInputHandler::HandleKey(wxInputConsumer *consumer,
                                               const wxKeyEvent& event,
                                               bool pressed)
 {
-    if ( pressed )
+   if ( pressed )
     {
         int keycode = event.GetKeyCode();
 
@@ -929,19 +959,19 @@ bool wxStdSliderButtonInputHandler::HandleKey(wxInputConsumer *consumer,
         switch ( keycode )
         {
             case WXK_HOME:
-                action = wxACTION_SLIDER_START;
+                action = wxACTION_SLIDER_END;
                 break;
 
             case WXK_END:
-                action = wxACTION_SLIDER_END;
+                action = wxACTION_SLIDER_START;
                 break;
 
-            case WXK_LEFT:
+            case WXK_RIGHT:
             case WXK_UP:
                 action = wxACTION_SLIDER_LINE_UP;
                 break;
 
-            case WXK_RIGHT:
+            case WXK_LEFT:
             case WXK_DOWN:
                 action = wxACTION_SLIDER_LINE_DOWN;
                 break;
index b3a5c59d4a01454e7260885b9ca6457eb7083ece..9ad98cbcd597a4a517fb381890d9a22e5ab7684d 100644 (file)
@@ -184,21 +184,25 @@ public:
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  wxRect *rectShaft = NULL);
     virtual void DrawSliderThumb(wxDC& dc,
                                  const wxRect& rect,
                                  wxOrientation orient,
-                                 int flags = 0);
+                                 int flags = 0,
+                                 long style = 0);
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int start,
                                  int end,
-                                 int step,
-                                 int flags)
+                                 int step = 1,
+                                 int flags = 0,
+                                 long style = 0)
     {
         // we don't have the ticks in GTK version
     }
@@ -305,8 +309,11 @@ public:
     virtual wxCoord GetSliderDim() const { return 15; }
     virtual wxCoord GetSliderTickLen() const { return 0; }
     virtual wxRect GetSliderShaftRect(const wxRect& rect,
-                                      wxOrientation orient) const;
+                                      int lenThumb,
+                                      wxOrientation orient,
+                                      long style = 0) const;
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const;
     virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
 
@@ -1865,13 +1872,14 @@ void wxGTKRenderer::DrawTab(wxDC& dc,
 // ----------------------------------------------------------------------------
 
 wxSize wxGTKRenderer::GetSliderThumbSize(const wxRect& rect,
+                                         int lenThumb,
                                          wxOrientation orient) const
 {
     static const wxCoord SLIDER_THUMB_LENGTH = 30;
 
     wxSize size;
 
-    wxRect rectShaft = GetSliderShaftRect(rect, orient);
+    wxRect rectShaft = GetSliderShaftRect(rect, lenThumb, orient);
     if ( orient == wxHORIZONTAL )
     {
         size.x = wxMin(SLIDER_THUMB_LENGTH, rectShaft.width);
@@ -1887,15 +1895,19 @@ wxSize wxGTKRenderer::GetSliderThumbSize(const wxRect& rect,
 }
 
 wxRect wxGTKRenderer::GetSliderShaftRect(const wxRect& rect,
-                                         wxOrientation WXUNUSED(orient)) const
+                                         int lenThumb,
+                                         wxOrientation WXUNUSED(orient),
+                                         long style) const
 {
     return rect.Deflate(2*BORDER_THICKNESS, 2*BORDER_THICKNESS);
 }
 
 void wxGTKRenderer::DrawSliderShaft(wxDC& dc,
                                     const wxRect& rectOrig,
+                                    int lenThumb,
                                     wxOrientation orient,
                                     int flags,
+                                    long style,
                                     wxRect *rectShaft)
 {
     wxRect rect = rectOrig;
@@ -1922,7 +1934,8 @@ void wxGTKRenderer::DrawSliderShaft(wxDC& dc,
 void wxGTKRenderer::DrawSliderThumb(wxDC& dc,
                                     const wxRect& rectOrig,
                                     wxOrientation orient,
-                                    int flags)
+                                    int flags,
+                                    long style)
 {
     // draw the thumb border
     wxRect rect = rectOrig;
index 085a67263804d81fc11401f7b39ddff1caa63af1..9dfdf2fc88099271299e89a8ce26123afefe918f 100644 (file)
@@ -80,6 +80,10 @@ static const size_t WIDTH_STATUSBAR_GRIP_BAND = 4;
 static const size_t STATUSBAR_GRIP_SIZE =
     WIDTH_STATUSBAR_GRIP_BAND*NUM_STATUSBAR_GRIP_BANDS;
 
+static const wxCoord SLIDER_MARGIN = 6; // margin around slider
+static const wxCoord SLIDER_THUMB_LENGTH = 18;
+static const wxCoord SLIDER_TICK_LENGTH = 6;
+
 enum IndicatorType
 {
     IndicatorType_Check,
@@ -253,21 +257,25 @@ public:
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  wxRect *rectShaft = NULL);
     virtual void DrawSliderThumb(wxDC& dc,
                                  const wxRect& rect,
                                  wxOrientation orient,
-                                 int flags = 0);
+                                 int flags = 0,
+                                 long style = 0);
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int start,
                                  int end,
                                  int step = 1,
-                                 int flags = 0);
+                                 int flags = 0,
+                                 long style = 0);
 
     virtual void DrawMenuBarItem(wxDC& dc,
                                  const wxRect& rect,
@@ -366,11 +374,14 @@ public:
     virtual wxSize GetTabIndent() const { return wxSize(2, 2); }
     virtual wxSize GetTabPadding() const { return wxSize(6, 5); }
 
-    virtual wxCoord GetSliderDim() const { return 20; }
-    virtual wxCoord GetSliderTickLen() const { return 4; }
+    virtual wxCoord GetSliderDim() const { return SLIDER_THUMB_LENGTH + 2*BORDER_THICKNESS; }
+    virtual wxCoord GetSliderTickLen() const { return SLIDER_TICK_LENGTH; }
     virtual wxRect GetSliderShaftRect(const wxRect& rect,
-                                      wxOrientation orient) const;
+                                      int lenThumb,
+                                      wxOrientation orient,
+                                      long style = 0) const;
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const;
     virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
 
@@ -2571,52 +2582,80 @@ void wxWin32Renderer::DrawTab(wxDC& dc,
 // ----------------------------------------------------------------------------
 
 wxSize wxWin32Renderer::GetSliderThumbSize(const wxRect& rect,
+                                           int lenThumb,
                                            wxOrientation orient) const
 {
     wxSize size;
+    wxCoord width  = wxMax (lenThumb, SLIDER_THUMB_LENGTH) / 2;
+    wxCoord height = wxMax (lenThumb, SLIDER_THUMB_LENGTH);
 
-    wxRect rectShaft = GetSliderShaftRect(rect, orient);
-    if ( orient == wxHORIZONTAL )
+    if (orient == wxHORIZONTAL) 
     {
-        size.y = rect.height - 6;
-        size.x = wxMin(size.y / 2, rectShaft.width);
+        size.x = width;
+        size.y = height;
     }
-    else // vertical
-    {
-        size.x = rect.width - 6;
-        size.y = wxMin(size.x / 2, rectShaft.height);
+    else
+    { // == wxVERTICAL
+        size.x = height;
+        size.y = width;
     }
 
     return size;
 }
 
 wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
-                                           wxOrientation orient) const
+                                           int lenThumb,
+                                           wxOrientation orient,
+                                           long style) const
 {
-    static const wxCoord SLIDER_MARGIN = 6;
+    bool transpose = (orient == wxVERTICAL);
+    bool left  = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_TOP) != 0) & !transpose |
+                  ((style & wxSL_LEFT) != 0) & transpose |
+                  ((style & wxSL_BOTH) != 0));
+    bool right = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_BOTTOM) != 0) & !transpose |
+                  ((style & wxSL_RIGHT) != 0) & transpose |
+                  ((style & wxSL_BOTH) != 0));
 
     wxRect rect = rectOrig;
 
-    if ( orient == wxHORIZONTAL )
-    {
-        // make the rect of minimal width and centre it
-        rect.height = 2*BORDER_THICKNESS;
-        rect.y = rectOrig.y + (rectOrig.height - rect.height) / 2;
-        if ( rect.y < 0 )
-            rect.y = 0;
+    wxSize sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
 
-        // leave margins on the sides
-        rect.Deflate(SLIDER_MARGIN, 0);
+    if (orient == wxHORIZONTAL) {
+        rect.x += SLIDER_MARGIN;
+        if (left & right) 
+        {
+            rect.y += wxMax ((rect.height - 2*BORDER_THICKNESS) / 2, sizeThumb.y/2);
+        }
+        else if (left) 
+        {
+            rect.y += wxMax ((rect.height - 2*BORDER_THICKNESS - sizeThumb.y/2), sizeThumb.y/2);
+        }
+        else
+        {
+            rect.y += sizeThumb.y/2;
+        }
+        rect.width -= 2*SLIDER_MARGIN;
+        rect.height = 2*BORDER_THICKNESS;
     }
-    else // vertical
-    {
-        // same as above but in other direction
+    else
+    { // == wxVERTICAL
+        rect.y += SLIDER_MARGIN;
+        if (left & right) 
+        {
+            rect.x += wxMax ((rect.width - 2*BORDER_THICKNESS) / 2, sizeThumb.x/2);
+        }
+        else if (left) 
+        {
+            rect.x += wxMax ((rect.width - 2*BORDER_THICKNESS - sizeThumb.x/2), sizeThumb.x/2);
+        }
+        else
+        {
+            rect.x += sizeThumb.x/2;
+        }
         rect.width = 2*BORDER_THICKNESS;
-        rect.x = rectOrig.x + (rectOrig.width - rect.width) / 2;
-        if ( rect.x < 0 )
-            rect.x = 0;
-
-        rect.Deflate(0, SLIDER_MARGIN);
+        rect.height -= 2*SLIDER_MARGIN;
     }
 
     return rect;
@@ -2624,19 +2663,37 @@ wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
 
 void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
                                       const wxRect& rectOrig,
+                                      int lenThumb,
                                       wxOrientation orient,
                                       int flags,
+                                      long style,
                                       wxRect *rectShaft)
 {
-    if ( flags & wxCONTROL_FOCUSED )
-    {
+    /*    show shaft geometry
+
+             shaft
+        +-------------+
+        |             |
+        |     XXX     |  <-- x1
+        |     XXX     |
+        |     XXX     |
+        |     XXX     |
+        |     XXX     |  <-- x2
+        |             |
+        +-------------+
+
+              ^ ^
+              | |
+             y1 y2
+    */
+
+    if (flags & wxCONTROL_FOCUSED) {
         DrawFocusRect(dc, rectOrig);
     }
 
-    wxRect rect = GetSliderShaftRect(rectOrig, orient);
+    wxRect rect = GetSliderShaftRect(rectOrig, lenThumb, orient, style);
 
-    if ( rectShaft )
-        *rectShaft = rect;
+    if (rectShaft) *rectShaft = rect;
 
     DrawSunkenBorder(dc, &rect);
 }
@@ -2644,26 +2701,31 @@ void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
 void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
                                       const wxRect& rect,
                                       wxOrientation orient,
-                                      int flags)
+                                      int flags,
+                                      long style)
 {
-    /*
-       we are drawing a shape of this form
-
-       HHHHHHB <--- y
-       H    DB
-       H    DB
-       H    DB   where H is hightlight colour
-       H    DB         D    dark grey
-       H    DB         B    black
-       H    DB
-       H    DB <--- y3
-        H  DB
-         HDB
-          B    <--- y2
-
-       ^  ^  ^
-       |  |  |
-       x x3  x2
+    /*    show thumb geometry
+
+             H       <--- y1
+           H H B
+         H     H B
+       H         H B <--- y3
+       H         D B
+       H         D B
+       H         D B
+       H         D B   where H is hightlight colour
+       H         D B         D    dark grey
+       H         D B         B    black
+       H         D B
+       H         D B
+       H         D B <--- y4
+         H     D B
+           H D B
+             B       <--- y2
+
+       ^     ^     ^
+       |     |     |
+       x1    x3    x2
 
        The interior of this shape is filled with the hatched brush if the thumb
        is pressed.
@@ -2671,51 +2733,81 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
 
     DrawBackground(dc, wxNullColour, rect, flags);
 
-    bool transpose = orient == wxVERTICAL;
+    bool transpose = (orient == wxVERTICAL);
+    bool left  = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_TOP) != 0) & !transpose |
+                  ((style & wxSL_LEFT) != 0) & transpose) &
+                 ((style & wxSL_BOTH) == 0);
+    bool right = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_BOTTOM) != 0) & !transpose |
+                  ((style & wxSL_RIGHT) != 0) & transpose) &
+                 ((style & wxSL_BOTH) == 0);
+
+    wxCoord sizeArrow = (transpose ? rect.height : rect.width) / 2;
+    wxCoord c = ((transpose ? rect.height : rect.width) - 2*sizeArrow);
+
+    wxCoord x1, x2, x3, y1, y2, y3, y4;
+    x1 = (transpose ? rect.y : rect.x);
+    x2 = (transpose ? rect.GetBottom() : rect.GetRight());
+    x3 = (x1-1+c) + sizeArrow;
+    y1 = (transpose ? rect.x : rect.y);
+    y2 = (transpose ? rect.GetRight() : rect.GetBottom());
+    y3 = (left  ? (y1-1+c) + sizeArrow : y1);
+    y4 = (right ? (y2+1-c) - sizeArrow : y2);
 
-    wxCoord x, y, x2, y2;
-    if ( transpose )
+    dc.SetPen(m_penBlack);
+    if (left) {
+        DrawLine(dc, x3+1-c, y1, x2, y3, transpose);
+    }
+    DrawLine(dc, x2, y3, x2, y4, transpose);
+    if (right) 
     {
-        x = rect.y;
-        y = rect.x;
-        x2 = rect.GetBottom();
-        y2 = rect.GetRight();
+        DrawLine(dc, x3+1-c, y2, x2, y4, transpose);
     }
     else
     {
-        x = rect.x;
-        y = rect.y;
-        x2 = rect.GetRight();
-        y2 = rect.GetBottom();
+        DrawLine(dc, x1, y2, x2, y2, transpose);
     }
 
-    // the size of the pointed part of the thumb
-    wxCoord sizeArrow = (transpose ? rect.height : rect.width) / 2;
-
-    wxCoord x3 = x + sizeArrow,
-            y3 = y2 - sizeArrow;
-
-    dc.SetPen(m_penHighlight);
-    DrawLine(dc, x, y, x2, y, transpose);
-    DrawLine(dc, x, y + 1, x, y2 - sizeArrow, transpose);
-    DrawLine(dc, x, y3, x3, y2, transpose);
-
-    dc.SetPen(m_penBlack);
-    DrawLine(dc, x3, y2, x2, y3, transpose);
-    DrawLine(dc, x2, y3, x2, y - 1, transpose);
-
     dc.SetPen(m_penDarkGrey);
-    DrawLine(dc, x3, y2 - 1, x2 - 1, y3, transpose);
-    DrawLine(dc, x2 - 1, y3, x2 - 1, y, transpose);
+    DrawLine(dc, x2-1, y3+1, x2-1, y4-1, transpose);
+    if (right) {
+        DrawLine(dc, x3+1-c, y2-1, x2-1, y4, transpose);
+    }
+    else
+    {
+        DrawLine(dc, x1+1, y2-1, x2-1, y2-1, transpose);
+    }
 
-    if ( flags & wxCONTROL_PRESSED )
+    dc.SetPen(m_penHighlight);
+    if (left) 
+    {
+        DrawLine(dc, x1, y3, x3, y1, transpose);
+        DrawLine(dc, x3+1-c, y1+1, x2-1, y3, transpose);
+    }
+    else
+    {
+        DrawLine(dc, x1, y1, x2, y1, transpose);
+    }
+    DrawLine(dc, x1, y3, x1, y4, transpose);
+    if (right) 
     {
+        DrawLine(dc, x1, y4, x3+c, y2+c, transpose);
+    }
+
+    if (flags & wxCONTROL_PRESSED) {
         // TODO: MSW fills the entire area inside, not just the rect
         wxRect rectInt = rect;
-        if ( transpose )
-            rectInt.SetRight(y3);
+        if ( transpose ) 
+        {
+            rectInt.SetLeft(y3);
+            rectInt.SetRight(y4);
+        }
         else
-            rectInt.SetBottom(y3);
+        {
+            rectInt.SetTop(y3);
+            rectInt.SetBottom(y4);
+        }
         rectInt.Deflate(2);
 
 #if !defined(__WXMGL__)
@@ -2757,73 +2849,80 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
 
 void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
                                       const wxRect& rect,
-                                      const wxSize& sizeThumb,
+                                      int lenThumb,
                                       wxOrientation orient,
                                       int start,
                                       int end,
                                       int step,
-                                      int flags)
+                                      int flags,
+                                      long style)
 {
-    if ( end == start )
-    {
-        // empty slider?
-        return;
-    }
-
-    // this would lead to an infinite loop below
-    wxCHECK_RET( step > 1, _T("invalid step in wxRenderer::DrawSliderTicks") );
-
-    // the variable names correspond to horizontal case, but they can be used
-    // for both orientations
-    wxCoord x1, x2, y1, y2, len, widthThumb;
-    if ( orient == wxHORIZONTAL )
-    {
-        x1 = rect.GetLeft();
-        x2 = rect.GetRight();
-
-        // draw from bottom to top to leave one pixel space between the ticks
-        // and the slider as Windows do
-        y1 = rect.GetBottom();
-        y2 = rect.GetTop();
-
-        len = rect.width;
-
-        widthThumb = sizeThumb.x;
-    }
-    else // vertical
-    {
-        x1 = rect.GetTop();
-        x2 = rect.GetBottom();
-
-        y1 = rect.GetRight();
-        y2 = rect.GetLeft();
-
-        len = rect.height;
-
-        widthThumb = sizeThumb.y;
-    }
-
-    // the first tick should be positioned in such way that a thumb drawn in
-    // the first position points down directly to it
-    x1 += widthThumb / 2;
-    x2 -= widthThumb / 2;
+    /*    show ticks geometry
+
+        left        right
+        ticks shaft ticks
+        ----   XX   ----  <-- x1
+        ----   XX   ----
+        ----   XX   ----
+        ----   XX   ----  <-- x2
+
+        ^  ^        ^  ^
+        |  |        |  |
+        y3 y1       y2 y4
+    */
 
-    // this also means that we have slightly less space for the ticks in
-    // between the first and the last
-    len -= widthThumb;
+    // empty slider?
+    if (end == start) return;
+
+    bool transpose = (orient == wxVERTICAL);
+    bool left  = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_TOP) != 0) & !transpose |
+                  ((style & wxSL_LEFT) != 0) & transpose |
+                  ((style & wxSL_BOTH) != 0));
+    bool right = ((style & wxSL_AUTOTICKS) != 0) &
+                 (((style & wxSL_BOTTOM) != 0) & !transpose |
+                  ((style & wxSL_RIGHT) != 0) & transpose |
+                  ((style & wxSL_BOTH) != 0));
+
+    // default thumb size
+    wxSize sizeThumb = GetSliderThumbSize (rect, 0, orient);
+    wxCoord defaultLen = (transpose ? sizeThumb.x : sizeThumb.y);
+
+    // normal thumb size
+    sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
+    wxCoord widthThumb  = (transpose ? sizeThumb.y : sizeThumb.x);
+
+    wxRect rectShaft = GetSliderShaftRect (rect, lenThumb, orient, style);
+
+    wxCoord x1, x2, y1, y2, y3, y4 , len;
+    x1 = (transpose ? rectShaft.y : rectShaft.x) + widthThumb/2;
+    x2 = (transpose ? rectShaft.GetBottom() : rectShaft.GetRight()) - widthThumb/2;
+    y1 = (transpose ? rectShaft.x : rectShaft.y) - defaultLen/2;
+    y2 = (transpose ? rectShaft.GetRight() : rectShaft.GetBottom()) + defaultLen/2;
+    y3 = (transpose ? rect.x : rect.y);
+    y4 = (transpose ? rect.GetRight() : rect.GetBottom());
+    len = x2 - x1;
 
     dc.SetPen(m_penBlack);
 
     int range = end - start;
-    for ( int n = 0; n < range; n += step )
-    {
+    for ( int n = 0; n < range; n += step ) {
         wxCoord x = x1 + (len*n) / range;
 
-        DrawLine(dc, x, y1, x, y2, orient == wxVERTICAL);
+        if (left & (y1 > y3)) {
+            DrawLine(dc, x, y1, x, y3, orient == wxVERTICAL);
+        }
+        if (right & (y4 > y2)) {
+            DrawLine(dc, x, y2, x, y4, orient == wxVERTICAL);
+        }
     }
-
     // always draw the line at the end position
-    DrawLine(dc, x2, y1, x2, y2, orient == wxVERTICAL);
+    if (left & (y1 > y3)) {
+        DrawLine(dc, x2, y1, x2, y3, orient == wxVERTICAL);
+    }
+    if (right & (y4 > y2)) {
+        DrawLine(dc, x2, y2, x2, y4, orient == wxVERTICAL);
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -3987,6 +4086,18 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
                 size->y += 9;
         }
 
+        // for compatibility with other ports, the buttons default size is never
+        // less than the standard one, but not when display not PDAs.
+        if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA)
+        {
+        if ( !(window->GetWindowStyle() & wxBU_EXACTFIT) )
+            {
+                       wxSize szDef = wxButton::GetDefaultSize();
+                if ( size->x < szDef.x )
+                    size->x = szDef.x;
+            }
+        }
+
         // no border width adjustments for buttons
         return;
     }