]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/slider.cpp
Ensure there is valid context for DrawRectangle
[wxWidgets.git] / src / msw / slider.cpp
index 3eb922c534cab47b92adcc2cbffdab972a7c7eb6..1b87047ed21f2442f194f96e3cb6dc96cffbbac1 100644 (file)
@@ -175,7 +175,7 @@ bool wxSlider::Create(wxWindow *parent,
     // and initialize everything
     SetRange(minValue, maxValue);
     SetValue(value);
-    SetPageSize((maxValue - minValue)/10);
+    SetPageSize( wxMax(1, (maxValue - minValue)/10) );
 
     // we need to position the labels correctly if we have them and if
     // SetSize() hadn't been called before (when best size was determined by
@@ -369,15 +369,12 @@ int wxSlider::GetLabelsSize(int *widthMin, int *widthMax) const
 {
     if ( widthMin && widthMax )
     {
-        if ( HasFlag(wxSL_MIN_MAX_LABELS) )
-        {
-            *widthMin = GetTextExtent(Format(m_rangeMin)).x;
-            *widthMax = GetTextExtent(Format(m_rangeMax)).x;
-        }
-        else
+        *widthMin = GetTextExtent(Format(m_rangeMin)).x;
+        *widthMax = GetTextExtent(Format(m_rangeMax)).x;
+
+        if ( HasFlag(wxSL_INVERSE) )
         {
-            *widthMin =
-            *widthMax = 0;
+            wxSwap(*widthMin, *widthMax);
         }
     }
 
@@ -394,10 +391,16 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
         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;
     if ( HasFlag(wxSL_TICKS))
        tickOffset = TICK;
@@ -409,70 +412,49 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
     // would return a wrong result and wrong size would be cached internally
     if ( HasFlag(wxSL_VERTICAL) )
     {
-        int holdTopWidth;
+        int labelOffset =  0;
         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;
-                holdTopWidth = m_minLabelWidth;
-                holdBottomX = xLabel - ((m_maxLabelWidth - m_minLabelWidth) / 2);
-                holdBottomWidth = m_maxLabelWidth;
-                if ( HasFlag(wxSL_INVERSE) )
-                {
-                    wxSwap(holdTopWidth, holdBottomWidth);
-                    wxSwap(holdTopX, holdBottomX);
-                }
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
-                    holdTopX,
-                    y,
-                    holdTopWidth, labelHeight);
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
-                    holdBottomX,
-                    y + height - labelHeight,
-                    holdBottomWidth, labelHeight);
-            }
-            if ( HasFlag(wxSL_VALUE_LABEL) )
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
-                    x + THUMB + tickOffset + HGAP,
-                    y + (height - labelHeight)/2,
-                    maxLabelWidth, labelHeight);
+            holdTopX = xLabel;
+            holdBottomX = xLabel - (abs(maxLabelWidth - minLabelWidth) / 2);
         }
         else // wxSL_RIGHT
         {
-            if ( HasFlag(wxSL_MIN_MAX_LABELS) )
+            holdTopX = xLabel + longestLabelWidth + (abs(maxLabelWidth - minLabelWidth) / 2);
+            holdBottomX = xLabel + longestLabelWidth;
+
+            labelOffset = longestLabelWidth + HGAP;
+        }
+
+        if ( HasFlag(wxSL_MIN_MAX_LABELS) )
+        {
+            if ( HasFlag(wxSL_INVERSE) )
             {
-                holdTopX = xLabel + maxLabelWidth + ((m_maxLabelWidth - m_minLabelWidth) / 2);
-                holdTopWidth = m_minLabelWidth;
-                holdBottomX = xLabel + maxLabelWidth;
-                holdBottomWidth = m_maxLabelWidth;
-                if ( HasFlag(wxSL_INVERSE) )
-                {
-                    wxSwap(holdTopWidth, holdBottomWidth);
-                    wxSwap(holdTopX, holdBottomX);
-                }
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
-                    holdTopX,
-                    y,
-                    holdTopWidth, labelHeight);
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
-                    holdBottomX,
-                    y + height - labelHeight,
-                    holdBottomWidth, labelHeight);
+                wxSwap(holdTopX, holdBottomX);
             }
-            if ( HasFlag(wxSL_VALUE_LABEL) )
-                labelOffset = maxLabelWidth + HGAP;
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
-                x,
-                y + (height - labelHeight)/2,
+
+            DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
+                holdTopX,
+                y,
+                minLabelWidth, labelHeight);
+            DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
+                holdBottomX,
+                y + height - labelHeight,
                 maxLabelWidth, labelHeight);
         }
 
+        if ( HasFlag(wxSL_VALUE_LABEL) )
+        {
+            DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
+                x + ( HasFlag(wxSL_LEFT) ? THUMB + tickOffset + HGAP : 0 ),
+                y + (height - labelHeight)/2,
+                longestLabelWidth, labelHeight);
+        }
+
         // position the slider itself along the left/right edge
         wxSliderBase::DoMoveWindow(
             x + labelOffset,
@@ -482,83 +464,46 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height)
     }
     else // horizontal
     {
-        int holdLeftWidth;
-        int holdLeftX;
-        int holdRightWidth;
-        int holdRightX;
         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_VALUE_LABEL) )
         {
-            if ( HasFlag(wxSL_MIN_MAX_LABELS) )
-            {
-                holdLeftX = x;
-                holdLeftWidth = m_minLabelWidth;
-                holdRightX = x + width - m_maxLabelWidth;
-                holdRightWidth = m_maxLabelWidth;
-                if ( HasFlag(wxSL_INVERSE) )
-                {
-                    wxSwap(holdLeftWidth, holdRightWidth);
-                    wxSwap(holdLeftX, holdRightX);
-                }
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
-                    holdLeftX,
-                    yLabelMinMax,
-                    holdLeftWidth, labelHeight);
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
-                    holdRightX,
-                    yLabelMinMax,
-                    holdRightWidth, labelHeight);
-            }
-            if ( HasFlag(wxSL_VALUE_LABEL) )
+            DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
+                xLabelValue,
+                y + (HasFlag(wxSL_BOTTOM) ? 0 : THUMB + tickOffset),
+                longestLabelWidth, labelHeight);
+
+            if ( HasFlag(wxSL_BOTTOM) )
             {
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
-                    xLabelValue,
-                    y - labelHeight,
-                    maxLabelWidth, labelHeight);
+                ySlider += labelHeight;
+                yLabelMinMax += labelHeight;
             }
         }
-        else // wxSL_TOP
+
+        if ( HasFlag(wxSL_MIN_MAX_LABELS) )
         {
-            if ( HasFlag(wxSL_MIN_MAX_LABELS) )
-            {
-                holdLeftX = x;
-                holdLeftWidth = m_minLabelWidth;
-                holdRightX = x + width - m_maxLabelWidth;
-                holdRightWidth = m_maxLabelWidth;
-                if ( HasFlag(wxSL_INVERSE) )
-                {
-                    wxSwap(holdLeftWidth, holdRightWidth);
-                    wxSwap(holdLeftX, holdRightX);
-                }
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
-                    holdLeftX,
-                    yLabelMinMax,
-                    holdLeftWidth, labelHeight);
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
-                    holdRightX,
-                    yLabelMinMax,
-                    holdRightWidth, labelHeight);
-            }
-            if ( HasFlag(wxSL_VALUE_LABEL) )
-                DoMoveSibling((HWND)(*m_labels)[SliderLabel_Value],
-                    xLabelValue,
-                    y + THUMB + tickOffset,
-                    maxLabelWidth, labelHeight);
+            DoMoveSibling((HWND)(*m_labels)[SliderLabel_Min],
+                x,
+                yLabelMinMax,
+                minLabelWidth, labelHeight);
+            DoMoveSibling((HWND)(*m_labels)[SliderLabel_Max],
+                x + width - maxLabelWidth,
+                yLabelMinMax,
+                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(
-            x + m_minLabelWidth + VGAP,
-            y,
-            width  - (m_minLabelWidth + m_maxLabelWidth  + (VGAP*2)),
+            x + minLabelWidth + VGAP,
+            ySlider,
+            width  - (minLabelWidth + maxLabelWidth  + (VGAP*2)),
             THUMB + tickOffset);
     }
 }
@@ -583,7 +528,8 @@ wxSize wxSlider::DoGetBestSize() const
             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;
@@ -597,12 +543,17 @@ wxSize wxSlider::DoGetBestSize() const
 
         if ( m_labels )
         {
-            // labels add extra height
             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;
+
+            // The value label is always on top of the control and so does need
+            // extra space in any case.
             if ( HasFlag(wxSL_VALUE_LABEL) )
-                size.y += labelSize*2.75;
+                size.y += labelSize;
         }
     }
 
@@ -632,7 +583,7 @@ void wxSlider::SetValue(int value)
 
     if ( m_labels )
     {
-        ::SetWindowText((*m_labels)[SliderLabel_Value], Format(value).wx_str());
+        ::SetWindowText((*m_labels)[SliderLabel_Value], Format(value).t_str());
     }
 }
 
@@ -652,9 +603,9 @@ void wxSlider::SetRange(int minValue, int maxValue)
     if ( m_labels )
     {
         ::SetWindowText((*m_labels)[SliderLabel_Min],
-                        Format(ValueInvertOrNot(m_rangeMin)).wx_str());
+                        Format(ValueInvertOrNot(m_rangeMin)).t_str());
         ::SetWindowText((*m_labels)[SliderLabel_Max],
-                        Format(ValueInvertOrNot(m_rangeMax)).wx_str());
+                        Format(ValueInvertOrNot(m_rangeMax)).t_str());
     }
 
     // When emulating wxSL_INVERSE style in wxWidgets, we need to update the
@@ -666,10 +617,10 @@ void wxSlider::SetRange(int minValue, int maxValue)
     }
 }
 
-void wxSlider::SetTickFreq(int n, int pos)
+void wxSlider::DoSetTickFreq(int 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)