]> 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,
     // draw the slider shaft
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
                                  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,
                                  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,
 
     // 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,
                                  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,
 
     // 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,
 
     // 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,
 
     // 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)
                                       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,
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  wxRect *rectShaft = NULL)
                                  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,
     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,
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int start,
                                  int end,
                                  int step = 1,
                                  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,
 
     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,
     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,
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const
                                       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
     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?
         { 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?
 
     // 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; }
 
     // 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)
 {
 
 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") );
 
     // 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;
 
     m_value = value;
 
-    // and the new one
-    RefreshThumb();
+    Refresh();
 
     // generate the event
     wxCommandEvent event(wxEVT_COMMAND_SLIDER_UPDATED, GetId());
 
     // generate the event
     wxCommandEvent event(wxEVT_COMMAND_SLIDER_UPDATED, GetId());
@@ -266,14 +261,14 @@ int wxSlider::GetMax() const
 
 void wxSlider::SetLineSize(int lineSize)
 {
 
 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)
 {
 
     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;
 }
 
     m_pageSize = pageSize;
 }
@@ -293,8 +288,8 @@ int wxSlider::GetPageSize() const
 {
     if ( !m_pageSize )
     {
 {
     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;
     }
 
     return m_pageSize;
@@ -302,7 +297,7 @@ int wxSlider::GetPageSize() const
 
 void wxSlider::SetThumbLength(int lenPixels)
 {
 
 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
 
     // 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
 {
 
 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))
 {
 
 void wxSlider::SetTickFreq(int n, int WXUNUSED(dummy))
 {
+    wxCHECK_RET (n > 0, _T("invalid slider tick frequency"));
+
     if ( n != m_tickFreq )
     {
         m_tickFreq = n;
     if ( n != m_tickFreq )
     {
         m_tickFreq = n;
@@ -364,7 +365,9 @@ wxSize wxSlider::CalcLabelSize() const
 wxSize wxSlider::DoGetBestClientSize() const
 {
     // this dimension is completely arbitrary
 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
 
     // 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 ( HasTicks() )
     {
         wxCoord lenTick = GetRenderer()->GetSliderTickLen();
+        if (style & wxSL_BOTH) 
+        {
+            lenTick = 2 * lenTick;
+        }
 
         if ( IsVert() )
             size.x += lenTick;
 
         if ( IsVert() )
             size.x += lenTick;
@@ -398,10 +405,14 @@ wxSize wxSlider::DoGetBestClientSize() const
     {
         wxSize sizeLabels = CalcLabelSize();
 
     {
         wxSize sizeLabels = CalcLabelSize();
 
-        if ( IsVert() )
+        if (style & (wxSL_LEFT|wxSL_RIGHT))
+        {
             size.x += sizeLabels.x + SLIDER_LABEL_MARGIN;
             size.x += sizeLabels.x + SLIDER_LABEL_MARGIN;
-        else
+        }
+        else if (style & (wxSL_TOP|wxSL_BOTTOM))
+        {
             size.y += sizeLabels.y + SLIDER_LABEL_MARGIN;
             size.y += sizeLabels.y + SLIDER_LABEL_MARGIN;
+        }
     }
 
     return size;
     }
 
     return size;
@@ -457,110 +468,102 @@ void wxSlider::CalcGeometry()
        | H *|
        ------
     */
        | H *|
        ------
     */
+    long style = GetWindowStyle();
 
 
+    // initialize to the full client rect
     wxRect rectTotal = GetClientRect();
     wxRect rectTotal = GetClientRect();
+    m_rectSlider = rectTotal;
+    wxSize sizeThumb = GetThumbSize();
+
+    // Labels reduce the size of the slider rect
     if ( HasLabels() )
     {
     if ( HasLabels() )
     {
-        wxSize sizeLabels = CalcLabelSize();
+       wxSize sizeLabels = CalcLabelSize();
 
 
-        m_rectSlider = rectTotal;
         m_rectLabel = wxRect(rectTotal.GetPosition(), sizeLabels);
 
         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 ( 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() )
         {
         // 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.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;
         }
             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
 {
     }
 }
 
 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 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
 {
 
 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,
 }
 
 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 )
     {
     // 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 )
     {
     }
 
     // calc the label rect
     if ( HasLabels() && rectLabelOut )
     {
+        long style = GetWindowStyle();
         wxRect rectLabel = m_rectLabel;
 
         // centre the label relatively to the thumb position
         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 )
         }
 
         *rectLabelOut = rectLabel;
     }
 
     if ( rectThumbOut )
+
         *rectThumbOut = rectThumb;
 }
 
         *rectThumbOut = rectThumb;
 }
 
@@ -662,47 +672,57 @@ void wxSlider::DoDraw(wxControlRenderer *renderer)
     wxDC& dc = renderer->GetDC();
     wxRect rectUpdate = GetUpdateClientRect();
 
     wxDC& dc = renderer->GetDC();
     wxRect rectUpdate = GetUpdateClientRect();
 
-    bool isVertical = IsVert();
     wxOrientation orient = GetOrientation();
     int flags = GetStateFlags();
     wxOrientation orient = GetOrientation();
     int flags = GetStateFlags();
+    long style = GetWindowStyle();
+
+    wxSize sz = GetThumbSize();
+    int len = IsVert() ? sz.x : sz.y;
 
     // first draw the shaft
 
     // first draw the shaft
-    wxRect rectShaft = rend->GetSliderShaftRect(m_rectSlider, orient);
+    wxRect rectShaft = rend->GetSliderShaftRect(m_rectSlider, len, orient, style);
     if ( rectUpdate.Intersects(rectShaft) )
     {
     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);
 
     }
 
     // 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
     }
 
     // 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());
         }
 
         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
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // wxSlider input processing
 // ----------------------------------------------------------------------------
@@ -734,7 +742,7 @@ bool wxSlider::PerformAction(const wxControlAction& action,
                              long numArg,
                              const wxString& strArg)
 {
                              long numArg,
                              const wxString& strArg)
 {
-    if ( action == wxACTION_SLIDER_START )
+     if ( action == wxACTION_SLIDER_START )
     {
         ChangeValueTo(m_min);
     }
     {
         ChangeValueTo(m_min);
     }
@@ -748,19 +756,19 @@ bool wxSlider::PerformAction(const wxControlAction& action,
     }
     else if ( action == wxACTION_SLIDER_LINE_UP )
     {
     }
     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 )
     {
     }
     else if ( action == wxACTION_SLIDER_PAGE_DOWN )
     {
-        return PerformAction(wxACTION_SLIDER_PAGE_CHANGE, 1);
+        ChangeValueBy(-GetPageSize());
     }
     else if ( action == wxACTION_SLIDER_THUMB_DRAG )
     {
     }
     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);
 
     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;
     }
 
     {
         return wxScrollThumb::Shaft_None;
     }
 
-
     // the position to test and the start and end of the thumb
     // 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;
     {
         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;
         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;
     }
 
     {
         // or to the left
         return wxScrollThumb::Shaft_Above;
     }
 
-    if ( x > x2 )
-    {
+    if ((x3 < x) & (x <= x4)) {
         // or to the right
         return wxScrollThumb::Shaft_Below;
     }
         // or to the right
         return wxScrollThumb::Shaft_Below;
     }
@@ -881,23 +890,44 @@ void wxSlider::SetShaftPartState(wxScrollThumb::Shaft shaftPart,
         else
             m_thumbFlags &= ~flag;
 
         else
             m_thumbFlags &= ~flag;
 
-        RefreshThumb();
+        Refresh();
     }
 }
 
 void wxSlider::OnThumbDragStart(int pos)
 {
     }
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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()
 }
 
 void wxSlider::OnPageScrollStart()
@@ -921,7 +951,7 @@ bool wxStdSliderButtonInputHandler::HandleKey(wxInputConsumer *consumer,
                                               const wxKeyEvent& event,
                                               bool pressed)
 {
                                               const wxKeyEvent& event,
                                               bool pressed)
 {
-    if ( pressed )
+   if ( pressed )
     {
         int keycode = event.GetKeyCode();
 
     {
         int keycode = event.GetKeyCode();
 
@@ -929,19 +959,19 @@ bool wxStdSliderButtonInputHandler::HandleKey(wxInputConsumer *consumer,
         switch ( keycode )
         {
             case WXK_HOME:
         switch ( keycode )
         {
             case WXK_HOME:
-                action = wxACTION_SLIDER_START;
+                action = wxACTION_SLIDER_END;
                 break;
 
             case WXK_END:
                 break;
 
             case WXK_END:
-                action = wxACTION_SLIDER_END;
+                action = wxACTION_SLIDER_START;
                 break;
 
                 break;
 
-            case WXK_LEFT:
+            case WXK_RIGHT:
             case WXK_UP:
                 action = wxACTION_SLIDER_LINE_UP;
                 break;
 
             case WXK_UP:
                 action = wxACTION_SLIDER_LINE_UP;
                 break;
 
-            case WXK_RIGHT:
+            case WXK_LEFT:
             case WXK_DOWN:
                 action = wxACTION_SLIDER_LINE_DOWN;
                 break;
             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,
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  wxRect *rectShaft = NULL);
     virtual void DrawSliderThumb(wxDC& dc,
                                  const wxRect& rect,
                                  wxOrientation orient,
                                  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,
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int start,
                                  int end,
                                  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
     }
     {
         // 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,
     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,
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const;
     virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
 
                                       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,
 // ----------------------------------------------------------------------------
 
 wxSize wxGTKRenderer::GetSliderThumbSize(const wxRect& rect,
+                                         int lenThumb,
                                          wxOrientation orient) const
 {
     static const wxCoord SLIDER_THUMB_LENGTH = 30;
 
     wxSize size;
 
                                          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);
     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,
 }
 
 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,
 {
     return rect.Deflate(2*BORDER_THICKNESS, 2*BORDER_THICKNESS);
 }
 
 void wxGTKRenderer::DrawSliderShaft(wxDC& dc,
                                     const wxRect& rectOrig,
+                                    int lenThumb,
                                     wxOrientation orient,
                                     int flags,
                                     wxOrientation orient,
                                     int flags,
+                                    long style,
                                     wxRect *rectShaft)
 {
     wxRect rect = rectOrig;
                                     wxRect *rectShaft)
 {
     wxRect rect = rectOrig;
@@ -1922,7 +1934,8 @@ void wxGTKRenderer::DrawSliderShaft(wxDC& dc,
 void wxGTKRenderer::DrawSliderThumb(wxDC& dc,
                                     const wxRect& rectOrig,
                                     wxOrientation orient,
 void wxGTKRenderer::DrawSliderThumb(wxDC& dc,
                                     const wxRect& rectOrig,
                                     wxOrientation orient,
-                                    int flags)
+                                    int flags,
+                                    long style)
 {
     // draw the thumb border
     wxRect rect = rectOrig;
 {
     // 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 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,
 enum IndicatorType
 {
     IndicatorType_Check,
@@ -253,21 +257,25 @@ public:
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
 
     virtual void DrawSliderShaft(wxDC& dc,
                                  const wxRect& rect,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int flags = 0,
                                  wxOrientation orient,
                                  int flags = 0,
+                                 long style = 0,
                                  wxRect *rectShaft = NULL);
     virtual void DrawSliderThumb(wxDC& dc,
                                  const wxRect& rect,
                                  wxOrientation orient,
                                  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,
     virtual void DrawSliderTicks(wxDC& dc,
                                  const wxRect& rect,
-                                 const wxSize& sizeThumb,
+                                 int lenThumb,
                                  wxOrientation orient,
                                  int start,
                                  int end,
                                  int step = 1,
                                  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,
 
     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 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,
     virtual wxRect GetSliderShaftRect(const wxRect& rect,
-                                      wxOrientation orient) const;
+                                      int lenThumb,
+                                      wxOrientation orient,
+                                      long style = 0) const;
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
     virtual wxSize GetSliderThumbSize(const wxRect& rect,
+                                      int lenThumb,
                                       wxOrientation orient) const;
     virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
 
                                       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,
 // ----------------------------------------------------------------------------
 
 wxSize wxWin32Renderer::GetSliderThumbSize(const wxRect& rect,
+                                           int lenThumb,
                                            wxOrientation orient) const
 {
     wxSize size;
                                            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,
     }
 
     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;
 
 
     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.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;
     }
 
     return rect;
@@ -2624,19 +2663,37 @@ wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
 
 void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
                                       const wxRect& rectOrig,
 
 void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
                                       const wxRect& rectOrig,
+                                      int lenThumb,
                                       wxOrientation orient,
                                       int flags,
                                       wxOrientation orient,
                                       int flags,
+                                      long style,
                                       wxRect *rectShaft)
 {
                                       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);
     }
 
         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);
 }
 
     DrawSunkenBorder(dc, &rect);
 }
@@ -2644,26 +2701,31 @@ void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
 void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
                                       const wxRect& rect,
                                       wxOrientation orient,
 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.
 
        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);
 
 
     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
     {
     }
     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);
     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;
         // 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
         else
-            rectInt.SetBottom(y3);
+        {
+            rectInt.SetTop(y3);
+            rectInt.SetBottom(y4);
+        }
         rectInt.Deflate(2);
 
 #if !defined(__WXMGL__)
         rectInt.Deflate(2);
 
 #if !defined(__WXMGL__)
@@ -2757,73 +2849,80 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
 
 void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
                                       const wxRect& rect,
 
 void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
                                       const wxRect& rect,
-                                      const wxSize& sizeThumb,
+                                      int lenThumb,
                                       wxOrientation orient,
                                       int start,
                                       int end,
                                       int step,
                                       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;
 
     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;
 
         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
     // 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;
         }
 
                 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;
     }
         // no border width adjustments for buttons
         return;
     }