]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/slider.cpp
Fixes for building wxOS2 shared with OpenWatcom.
[wxWidgets.git] / src / univ / slider.cpp
index 8361ab7d543a3b6221fc64805c1a46b66ed995d0..50147c8c2e466c6d856fbda4f465ee61bce01aae 100644 (file)
@@ -22,9 +22,9 @@
    or right.
 
    What we really need is probably a more fine grain control on labels, i.e. we
    or right.
 
    What we really need is probably a more fine grain control on labels, i.e. we
-   should be able to select if we show nothign at all, the current value only
+   should be able to select if we show nothing at all, the current value only
    or the value and the limits - the current approach is just that of the
    or the value and the limits - the current approach is just that of the
-   greatest common denominator.
+   lowest common denominator.
 
    TODO:
 
 
    TODO:
 
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "univslider.h"
-#endif
-
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
@@ -143,7 +139,7 @@ bool wxSlider::Create(wxWindow *parent,
 {
     if ( !wxSliderBase::Create(parent, id, pos, size, style,
                                validator, name) )
 {
     if ( !wxSliderBase::Create(parent, id, pos, size, style,
                                validator, name) )
-        return FALSE;
+        return false;
 
     SetRange(minValue, maxValue);
     SetValue(value);
 
     SetRange(minValue, maxValue);
     SetValue(value);
@@ -154,7 +150,7 @@ bool wxSlider::Create(wxWindow *parent,
 
     CreateInputHandler(wxINP_HANDLER_SLIDER);
 
 
     CreateInputHandler(wxINP_HANDLER_SLIDER);
 
-    return TRUE;
+    return true;
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -183,21 +179,16 @@ bool wxSlider::ChangeValueBy(int inc)
 
 bool wxSlider::ChangeValueTo(int value)
 {
 
 bool wxSlider::ChangeValueTo(int 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
     // check if the value is going to change at all
-    if ( value == m_value )
-        return FALSE;
+    if (value == m_value) return false;
 
 
-    // refresh the old thumb position
-    RefreshThumb();
+    // this method is protected and we should only call it with normalized
+    // value!
+    wxCHECK_MSG( IsInRange(value), false, _T("invalid slider value") );
 
     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());
@@ -206,7 +197,7 @@ bool wxSlider::ChangeValueTo(int value)
 
     (void)GetEventHandler()->ProcessEvent(event);
 
 
     (void)GetEventHandler()->ProcessEvent(event);
 
-    return TRUE;
+    return true;
 }
 
 void wxSlider::SetValue(int value)
 }
 
 void wxSlider::SetValue(int value)
@@ -266,14 +257,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 +284,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 +293,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 +307,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 +326,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 +361,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 +385,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 +401,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 +464,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 +568,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,
@@ -596,8 +595,9 @@ void wxSlider::CalcThumbRect(const wxRect *rectShaftIn,
     }
 
     wxCoord lenShaft,
     }
 
     wxCoord lenShaft,
-            lenThumb,
-           *p;
+            lenThumb;
+    wxCoord *p;
+
     wxRect rectThumb(rectShaft.GetPosition(), GetThumbSize());
     if ( isVertical )
     {
     wxRect rectThumb(rectShaft.GetPosition(), GetThumbSize());
     if ( isVertical )
     {
@@ -620,30 +620,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 +669,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_HORIZONTAL|wxALIGN_TOP;
+        }
+        else if (style & wxSL_BOTTOM)
         {
         {
-            align = wxALIGN_CENTRE_VERTICAL |
-                    (GetWindowStyle() & wxSL_RIGHT ? wxALIGN_LEFT
-                                                   : wxALIGN_RIGHT);
+            align = wxALIGN_CENTRE_HORIZONTAL|wxALIGN_BOTTOM;
         }
         }
-        else // horz
+        else if (style & wxSL_LEFT)
         {
         {
-            align = wxALIGN_CENTRE;
+            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 +731,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
 // ----------------------------------------------------------------------------
@@ -748,24 +753,24 @@ 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 )
     {
         // no special processing for it
     }
     else if ( action == wxACTION_SLIDER_THUMB_DRAG )
     {
         // no special processing for it
-        return TRUE;
+        return true;
     }
     else if ( action == wxACTION_SLIDER_THUMB_MOVE ||
               action == wxACTION_SLIDER_THUMB_RELEASE )
     }
     else if ( action == wxACTION_SLIDER_THUMB_MOVE ||
               action == wxACTION_SLIDER_THUMB_RELEASE )
@@ -777,7 +782,7 @@ bool wxSlider::PerformAction(const wxControlAction& action,
         return wxControl::PerformAction(action, numArg, strArg);
     }
 
         return wxControl::PerformAction(action, numArg, strArg);
     }
 
-    return TRUE;
+    return true;
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -787,38 +792,40 @@ bool wxSlider::PerformAction(const wxControlAction& action,
 wxScrollThumb::Shaft wxSlider::HitTest(const wxPoint& pt) const
 {
     wxRect rectShaft = GetShaftRect();
 wxScrollThumb::Shaft wxSlider::HitTest(const wxPoint& pt) const
 {
     wxRect rectShaft = GetShaftRect();
-    if ( !rectShaft.Inside(pt) )
+    wxRect rectThumb;
+    CalcThumbRect(&rectShaft, &rectThumb, NULL);
+
+    // check for possible shaft or thumb hit
+    if (!rectShaft.Inside(pt) && !rectThumb.Inside(pt))
     {
         return wxScrollThumb::Shaft_None;
     }
 
     {
         return wxScrollThumb::Shaft_None;
     }
 
-    // inside the shaft, where is it relatively to the thumb?
-    wxRect rectThumb;
-    CalcThumbRect(&rectShaft, &rectThumb, NULL);
-
     // 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;
     }
@@ -880,23 +887,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()
@@ -928,19 +956,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;
@@ -956,11 +984,11 @@ bool wxStdSliderButtonInputHandler::HandleKey(wxInputConsumer *consumer,
                 break;
         }
 
                 break;
         }
 
-        if ( !!action )
+        if ( !action.IsEmpty() )
         {
             consumer->PerformAction(action);
 
         {
             consumer->PerformAction(action);
 
-            return TRUE;
+            return true;
         }
     }
 
         }
     }
 
@@ -975,7 +1003,7 @@ bool wxStdSliderButtonInputHandler::HandleMouse(wxInputConsumer *consumer,
     if ( slider->GetThumb().HandleMouse(event) )
     {
         // processed by the thumb
     if ( slider->GetThumb().HandleMouse(event) )
     {
         // processed by the thumb
-        return FALSE;
+        return false;
     }
 
     return wxStdInputHandler::HandleMouse(consumer, event);
     }
 
     return wxStdInputHandler::HandleMouse(consumer, event);
@@ -989,17 +1017,18 @@ bool wxStdSliderButtonInputHandler::HandleMouseMove(wxInputConsumer *consumer,
     if ( slider->GetThumb().HandleMouseMove(event) )
     {
         // processed by the thumb
     if ( slider->GetThumb().HandleMouseMove(event) )
     {
         // processed by the thumb
-        return FALSE;
+        return false;
     }
 
     return wxStdInputHandler::HandleMouseMove(consumer, event);
 }
 
     }
 
     return wxStdInputHandler::HandleMouseMove(consumer, event);
 }
 
-bool wxStdSliderButtonInputHandler::HandleFocus(wxInputConsumer *consumer,
-                                                const wxFocusEvent& event)
+bool
+wxStdSliderButtonInputHandler::HandleFocus(wxInputConsumer * WXUNUSED(consumer),
+                                           const wxFocusEvent& WXUNUSED(event))
 {
     // slider's appearance changes when it gets/loses focus
 {
     // slider's appearance changes when it gets/loses focus
-    return TRUE;
+    return true;
 }
 
 #endif // wxUSE_SLIDER
 }
 
 #endif // wxUSE_SLIDER