]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/slider.cpp
Use the data scheme to load resources in the WebKitGTK+ implementation, rather than...
[wxWidgets.git] / src / msw / slider.cpp
index 4d08687349438ff6635d975f4ce31475440b750b..7c1c7103f24bc49a62c6874d03924acbe66b6906 100644 (file)
@@ -63,80 +63,6 @@ const int TICK = 8;
 
 } // anonymous namespace
 
 
 } // anonymous namespace
 
-// ----------------------------------------------------------------------------
-// XTI
-// ----------------------------------------------------------------------------
-
-#if wxUSE_EXTENDED_RTTI
-WX_DEFINE_FLAGS( wxSliderStyle )
-
-wxBEGIN_FLAGS( wxSliderStyle )
-    // new style border flags, we put them first to
-    // use them for streaming out
-    wxFLAGS_MEMBER(wxBORDER_SIMPLE)
-    wxFLAGS_MEMBER(wxBORDER_SUNKEN)
-    wxFLAGS_MEMBER(wxBORDER_DOUBLE)
-    wxFLAGS_MEMBER(wxBORDER_RAISED)
-    wxFLAGS_MEMBER(wxBORDER_STATIC)
-    wxFLAGS_MEMBER(wxBORDER_NONE)
-
-    // old style border flags
-    wxFLAGS_MEMBER(wxSIMPLE_BORDER)
-    wxFLAGS_MEMBER(wxSUNKEN_BORDER)
-    wxFLAGS_MEMBER(wxDOUBLE_BORDER)
-    wxFLAGS_MEMBER(wxRAISED_BORDER)
-    wxFLAGS_MEMBER(wxSTATIC_BORDER)
-    wxFLAGS_MEMBER(wxBORDER)
-
-    // standard window styles
-    wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
-    wxFLAGS_MEMBER(wxCLIP_CHILDREN)
-    wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
-    wxFLAGS_MEMBER(wxWANTS_CHARS)
-    wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
-    wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
-    wxFLAGS_MEMBER(wxVSCROLL)
-    wxFLAGS_MEMBER(wxHSCROLL)
-
-    wxFLAGS_MEMBER(wxSL_HORIZONTAL)
-    wxFLAGS_MEMBER(wxSL_VERTICAL)
-    wxFLAGS_MEMBER(wxSL_AUTOTICKS)
-    wxFLAGS_MEMBER(wxSL_LEFT)
-    wxFLAGS_MEMBER(wxSL_TOP)
-    wxFLAGS_MEMBER(wxSL_RIGHT)
-    wxFLAGS_MEMBER(wxSL_BOTTOM)
-    wxFLAGS_MEMBER(wxSL_BOTH)
-    wxFLAGS_MEMBER(wxSL_SELRANGE)
-    wxFLAGS_MEMBER(wxSL_INVERSE)
-    wxFLAGS_MEMBER(wxSL_MIN_MAX_LABELS)
-    wxFLAGS_MEMBER(wxSL_VALUE_LABEL)
-    wxFLAGS_MEMBER(wxSL_LABELS)
-
-wxEND_FLAGS( wxSliderStyle )
-
-IMPLEMENT_DYNAMIC_CLASS_XTI(wxSlider, wxControl,"wx/slider.h")
-
-wxBEGIN_PROPERTIES_TABLE(wxSlider)
-    wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_CHANGED , wxScrollEvent )
-    wxEVENT_PROPERTY( Updated , wxEVT_COMMAND_SLIDER_UPDATED , wxCommandEvent )
-
-    wxPROPERTY( Value , int , SetValue, GetValue , 0, 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY( Minimum , int , SetMin, GetMin, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY( Maximum , int , SetMax, GetMax, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY( PageSize , int , SetPageSize, GetLineSize, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY( LineSize , int , SetLineSize, GetLineSize, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY( ThumbLength , int , SetThumbLength, GetThumbLength, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY_FLAGS( WindowStyle , wxSliderStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
-wxEND_PROPERTIES_TABLE()
-
-wxBEGIN_HANDLERS_TABLE(wxSlider)
-wxEND_HANDLERS_TABLE()
-
-wxCONSTRUCTOR_8( wxSlider , wxWindow* , Parent , wxWindowID , Id , int , Value , int , Minimum , int , Maximum , wxPoint , Position , wxSize , Size , long , WindowStyle )
-#else
-IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
-#endif
-
 // ============================================================================
 // wxSlider implementation
 // ============================================================================
 // ============================================================================
 // wxSlider implementation
 // ============================================================================
@@ -443,16 +369,8 @@ int wxSlider::GetLabelsSize(int *widthMin, int *widthMax) const
 {
     if ( widthMin && widthMax )
     {
 {
     if ( widthMin && widthMax )
     {
-        if ( HasFlag(wxSL_MIN_MAX_LABELS) )
-        {
-            *widthMin = GetTextExtent(Format(m_rangeMin)).x;
-            *widthMax = GetTextExtent(Format(m_rangeMax)).x;
-        }
-        else
-        {
-            *widthMin =
-            *widthMax = 0;
-        }
+        *widthMin = GetTextExtent(Format(m_rangeMin)).x;
+        *widthMax = GetTextExtent(Format(m_rangeMax)).x;
     }
 
     return HasFlag(wxSL_LABELS) ? GetCharHeight() : 0;
     }
 
     return HasFlag(wxSL_LABELS) ? GetCharHeight() : 0;
@@ -468,8 +386,15 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
         return;
     }
 
         return;
     }
 
-    const int labelHeight = GetLabelsSize(&m_minLabelWidth, &m_maxLabelWidth);
-    const int maxLabelWidth = wxMax(m_minLabelWidth, m_maxLabelWidth);
+    int minLabelWidth,
+        maxLabelWidth;
+    const int labelHeight = GetLabelsSize(&minLabelWidth, &maxLabelWidth);
+    const int longestLabelWidth = wxMax(minLabelWidth, maxLabelWidth);
+    if ( !HasFlag(wxSL_MIN_MAX_LABELS) )
+    {
+        minLabelWidth =
+        maxLabelWidth = 0;
+    }
 
     int labelOffset =  0;
     int tickOffset = 0;
 
     int labelOffset =  0;
     int tickOffset = 0;
@@ -487,16 +412,16 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
         int holdTopX;
         int holdBottomWidth;
         int holdBottomX;
         int holdTopX;
         int holdBottomWidth;
         int holdBottomX;
-        int xLabel = (wxMax((THUMB + (BORDERPAD * 2)), maxLabelWidth) / 2) -
-            (maxLabelWidth / 2) + x;
+        int xLabel = (wxMax((THUMB + (BORDERPAD * 2)), longestLabelWidth) / 2) -
+            (longestLabelWidth / 2) + x;
         if ( HasFlag(wxSL_LEFT) )
         {
             if ( HasFlag(wxSL_MIN_MAX_LABELS) )
             {
                 holdTopX = xLabel;
         if ( HasFlag(wxSL_LEFT) )
         {
             if ( HasFlag(wxSL_MIN_MAX_LABELS) )
             {
                 holdTopX = xLabel;
-                holdTopWidth = m_minLabelWidth;
-                holdBottomX = xLabel - ((m_maxLabelWidth - m_minLabelWidth) / 2);
-                holdBottomWidth = m_maxLabelWidth;
+                holdTopWidth = minLabelWidth;
+                holdBottomX = xLabel - ((maxLabelWidth - minLabelWidth) / 2);
+                holdBottomWidth = maxLabelWidth;
                 if ( HasFlag(wxSL_INVERSE) )
                 {
                     wxSwap(holdTopWidth, holdBottomWidth);
                 if ( HasFlag(wxSL_INVERSE) )
                 {
                     wxSwap(holdTopWidth, holdBottomWidth);
@@ -515,16 +440,16 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
                 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
                     x + THUMB + tickOffset + HGAP,
                     y + (height - labelHeight)/2,
                 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
                     x + THUMB + tickOffset + HGAP,
                     y + (height - labelHeight)/2,
-                    maxLabelWidth, labelHeight);
+                    longestLabelWidth, labelHeight);
         }
         else // wxSL_RIGHT
         {
             if ( HasFlag(wxSL_MIN_MAX_LABELS) )
             {
         }
         else // wxSL_RIGHT
         {
             if ( HasFlag(wxSL_MIN_MAX_LABELS) )
             {
-                holdTopX = xLabel + maxLabelWidth + ((m_maxLabelWidth - m_minLabelWidth) / 2);
-                holdTopWidth = m_minLabelWidth;
-                holdBottomX = xLabel + maxLabelWidth;
-                holdBottomWidth = m_maxLabelWidth;
+                holdTopX = xLabel + longestLabelWidth + ((maxLabelWidth - minLabelWidth) / 2);
+                holdTopWidth = minLabelWidth;
+                holdBottomX = xLabel + longestLabelWidth;
+                holdBottomWidth = maxLabelWidth;
                 if ( HasFlag(wxSL_INVERSE) )
                 {
                     wxSwap(holdTopWidth, holdBottomWidth);
                 if ( HasFlag(wxSL_INVERSE) )
                 {
                     wxSwap(holdTopWidth, holdBottomWidth);
@@ -540,11 +465,11 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
                     holdBottomWidth, labelHeight);
             }
             if ( HasFlag(wxSL_VALUE_LABEL) )
                     holdBottomWidth, labelHeight);
             }
             if ( HasFlag(wxSL_VALUE_LABEL) )
-                labelOffset = maxLabelWidth + HGAP;
+                labelOffset = longestLabelWidth + HGAP;
                 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
                 x,
                 y + (height - labelHeight)/2,
                 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
                 x,
                 y + (height - labelHeight)/2,
-                maxLabelWidth, labelHeight);
+                longestLabelWidth, labelHeight);
         }
 
         // position the slider itself along the left/right edge
         }
 
         // position the slider itself along the left/right edge
@@ -563,18 +488,31 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
         int yLabelMinMax =
             (y + ((THUMB + tickOffset) / 2)) - (labelHeight / 2);
         int xLabelValue =
         int yLabelMinMax =
             (y + ((THUMB + tickOffset) / 2)) - (labelHeight / 2);
         int xLabelValue =
-            x + m_minLabelWidth +
-            ((width  - (m_minLabelWidth + m_maxLabelWidth)) / 2) -
-            (m_maxLabelWidth / 2);
+            x + minLabelWidth +
+            ((width  - (minLabelWidth + maxLabelWidth)) / 2) -
+            (longestLabelWidth / 2);
+
+        int ySlider = y;
 
         if ( HasFlag(wxSL_BOTTOM) )
         {
 
         if ( HasFlag(wxSL_BOTTOM) )
         {
+            if ( HasFlag(wxSL_VALUE_LABEL) )
+            {
+                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
+                    xLabelValue,
+                    y,
+                    longestLabelWidth, labelHeight);
+
+                ySlider += labelHeight;
+                yLabelMinMax += labelHeight;
+            }
+
             if ( HasFlag(wxSL_MIN_MAX_LABELS) )
             {
                 holdLeftX = x;
             if ( HasFlag(wxSL_MIN_MAX_LABELS) )
             {
                 holdLeftX = x;
-                holdLeftWidth = m_minLabelWidth;
-                holdRightX = x + width - m_maxLabelWidth;
-                holdRightWidth = m_maxLabelWidth;
+                holdLeftWidth = minLabelWidth;
+                holdRightX = x + width - maxLabelWidth;
+                holdRightWidth = maxLabelWidth;
                 if ( HasFlag(wxSL_INVERSE) )
                 {
                     wxSwap(holdLeftWidth, holdRightWidth);
                 if ( HasFlag(wxSL_INVERSE) )
                 {
                     wxSwap(holdLeftWidth, holdRightWidth);
@@ -589,22 +527,23 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
                     yLabelMinMax,
                     holdRightWidth, labelHeight);
             }
                     yLabelMinMax,
                     holdRightWidth, labelHeight);
             }
+        }
+        else // wxSL_TOP
+        {
             if ( HasFlag(wxSL_VALUE_LABEL) )
             {
                 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
                     xLabelValue,
             if ( HasFlag(wxSL_VALUE_LABEL) )
             {
                 DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
                     xLabelValue,
-                    y - labelHeight,
-                    maxLabelWidth, labelHeight);
+                    y + THUMB + tickOffset,
+                    longestLabelWidth, labelHeight);
             }
             }
-        }
-        else // wxSL_TOP
-        {
+
             if ( HasFlag(wxSL_MIN_MAX_LABELS) )
             {
                 holdLeftX = x;
             if ( HasFlag(wxSL_MIN_MAX_LABELS) )
             {
                 holdLeftX = x;
-                holdLeftWidth = m_minLabelWidth;
-                holdRightX = x + width - m_maxLabelWidth;
-                holdRightWidth = m_maxLabelWidth;
+                holdLeftWidth = minLabelWidth;
+                holdRightX = x + width - maxLabelWidth;
+                holdRightWidth = maxLabelWidth;
                 if ( HasFlag(wxSL_INVERSE) )
                 {
                     wxSwap(holdLeftWidth, holdRightWidth);
                 if ( HasFlag(wxSL_INVERSE) )
                 {
                     wxSwap(holdLeftWidth, holdRightWidth);
@@ -619,20 +558,15 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
                     yLabelMinMax,
                     holdRightWidth, labelHeight);
             }
                     yLabelMinMax,
                     holdRightWidth, labelHeight);
             }
-            if ( HasFlag(wxSL_VALUE_LABEL) )
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
-                    xLabelValue,
-                    y + THUMB + tickOffset,
-                    maxLabelWidth, labelHeight);
         }
 
         // position the slider itself along the top/bottom edge
         if ( HasFlag(wxSL_MIN_MAX_LABELS) || HasFlag(wxSL_VALUE_LABEL) )
             labelOffset = labelHeight;
         wxSliderBase::DoMoveWindow(
         }
 
         // position the slider itself along the top/bottom edge
         if ( HasFlag(wxSL_MIN_MAX_LABELS) || HasFlag(wxSL_VALUE_LABEL) )
             labelOffset = labelHeight;
         wxSliderBase::DoMoveWindow(
-            x + m_minLabelWidth + VGAP,
-            y,
-            width  - (m_minLabelWidth + m_maxLabelWidth  + (VGAP*2)),
+            x + minLabelWidth + VGAP,
+            ySlider,
+            width  - (minLabelWidth + maxLabelWidth  + (VGAP*2)),
             THUMB + tickOffset);
     }
 }
             THUMB + tickOffset);
     }
 }
@@ -657,7 +591,8 @@ wxSize wxSlider::DoGetBestSize() const
             int hLabel = GetLabelsSize(&widthMin, &widthMax);
 
             // account for the labels
             int hLabel = GetLabelsSize(&widthMin, &widthMax);
 
             // account for the labels
-            size.x += HGAP + wxMax(widthMin, widthMax);
+            if ( HasFlag(wxSL_MIN_MAX_LABELS) )
+                size.x += HGAP + wxMax(widthMin, widthMax);
 
             // labels are indented relative to the slider itself
             size.y += hLabel;
 
             // labels are indented relative to the slider itself
             size.y += hLabel;
@@ -671,12 +606,17 @@ wxSize wxSlider::DoGetBestSize() const
 
         if ( m_labels )
         {
 
         if ( m_labels )
         {
-            // labels add extra height
             int labelSize = GetLabelsSize();
             int labelSize = GetLabelsSize();
-            if ( HasFlag(wxSL_MIN_MAX_LABELS) )
+
+            // Min/max labels are compensated by the ticks so we don't need
+            // extra space for them if we're also showing ticks.
+            if ( HasFlag(wxSL_MIN_MAX_LABELS) && !HasFlag(wxSL_TICKS) )
                 size.y += labelSize;
                 size.y += labelSize;
+
+            // The value label is always on top of the control and so does need
+            // extra space in any case.
             if ( HasFlag(wxSL_VALUE_LABEL) )
             if ( HasFlag(wxSL_VALUE_LABEL) )
-                size.y += labelSize*2.75;
+                size.y += labelSize;
         }
     }
 
         }
     }
 
@@ -712,6 +652,11 @@ void wxSlider::SetValue(int value)
 
 void wxSlider::SetRange(int minValue, int maxValue)
 {
 
 void wxSlider::SetRange(int minValue, int maxValue)
 {
+    // Remember the old logical value if we need to update the physical control
+    // value after changing its range in wxSL_INVERSE case (and avoid an
+    // unnecessary call to GetValue() otherwise as it's just not needed).
+    const int valueOld = HasFlag(wxSL_INVERSE) ? GetValue() : 0;
+
     m_rangeMin = minValue;
     m_rangeMax = maxValue;
 
     m_rangeMin = minValue;
     m_rangeMax = maxValue;
 
@@ -725,12 +670,20 @@ void wxSlider::SetRange(int minValue, int maxValue)
         ::SetWindowText((*m_labels)[SliderLabel_Max],
                         Format(ValueInvertOrNot(m_rangeMax)).wx_str());
     }
         ::SetWindowText((*m_labels)[SliderLabel_Max],
                         Format(ValueInvertOrNot(m_rangeMax)).wx_str());
     }
+
+    // When emulating wxSL_INVERSE style in wxWidgets, we need to update the
+    // value after changing the range to ensure that the value seen by the user
+    // code, i.e. the one returned by GetValue(), does not change.
+    if ( HasFlag(wxSL_INVERSE) )
+    {
+        ::SendMessage(GetHwnd(), TBM_SETPOS, TRUE, ValueInvertOrNot(valueOld));
+    }
 }
 
 }
 
-void wxSlider::SetTickFreq(int n, int pos)
+void wxSlider::DoSetTickFreq(int n)
 {
     m_tickFreq = n;
 {
     m_tickFreq = n;
-    ::SendMessage( GetHwnd(), TBM_SETTICFREQ, (WPARAM) n, (LPARAM) pos );
+    ::SendMessage( GetHwnd(), TBM_SETTICFREQ, (WPARAM) n, (LPARAM) 0 );
 }
 
 void wxSlider::SetPageSize(int pageSize)
 }
 
 void wxSlider::SetPageSize(int pageSize)