X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7d0d80bd1ce297cdefc2c8f8de3be84cbe9cced0..bae3be5d736c3a53cd3ce904d4cdd2e6c74bfd73:/src/msw/slider95.cpp diff --git a/src/msw/slider95.cpp b/src/msw/slider95.cpp index 260aee5565..479a180b82 100644 --- a/src/msw/slider95.cpp +++ b/src/msw/slider95.cpp @@ -42,6 +42,8 @@ #include #endif +#define USE_DEFERRED_SIZING 1 + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -110,7 +112,7 @@ wxEND_FLAGS( wxSliderStyle ) IMPLEMENT_DYNAMIC_CLASS_XTI(wxSlider, wxControl,"wx/scrolbar.h") wxBEGIN_PROPERTIES_TABLE(wxSlider) - wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_ENDSCROLL , wxScrollEvent ) + 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")) @@ -147,6 +149,8 @@ void wxSlider::Init() m_rangeMax = 0; m_rangeMin = 0; m_tickFreq = 0; + + m_isDragging = false; } bool @@ -161,6 +165,35 @@ wxSlider::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { + // our styles are redundant: wxSL_LEFT/RIGHT imply wxSL_VERTICAL and + // wxSL_TOP/BOTTOM imply wxSL_HORIZONTAL, but for backwards compatibility + // reasons we can't really change it, instead try to infer the orientation + // from the flags given to us here + switch ( style & (wxSL_LEFT | wxSL_RIGHT | wxSL_TOP | wxSL_BOTTOM) ) + { + case wxSL_LEFT: + case wxSL_RIGHT: + style |= wxSL_VERTICAL; + break; + + case wxSL_TOP: + case wxSL_BOTTOM: + style |= wxSL_HORIZONTAL; + break; + + case 0: + // no specific direction, do we have at least the orientation? + if ( !(style & (wxSL_HORIZONTAL | wxSL_VERTICAL)) ) + { + // no, choose default + style |= wxSL_BOTTOM | wxSL_HORIZONTAL; + } + }; + + wxASSERT_MSG( !(style & wxSL_VERTICAL) | !(style & wxSL_HORIZONTAL), + _T("incompatible slider direction and orientation") ); + + // initialize everything if ( !CreateControl(parent, id, pos, size, style, validator, name) ) return false; @@ -223,24 +256,29 @@ WXDWORD wxSlider::MSWGetStyle(long style, WXDWORD *exstyle) const { WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle); - // TBS_HORZ is 0 anyhow, but do mention it explicitly for clarity + // TBS_HORZ, TBS_RIGHT and TBS_BOTTOM are 0 but do include them for clarity msStyle |= style & wxSL_VERTICAL ? TBS_VERT : TBS_HORZ; - if ( style & wxSL_AUTOTICKS ) - msStyle |= TBS_AUTOTICKS ; - - // again, TBS_RIGHT is 0 but do include it for clarity - if ( style & wxSL_LEFT ) - msStyle |= TBS_LEFT; - else if ( style & wxSL_RIGHT ) - msStyle |= TBS_RIGHT; - else if ( style & wxSL_TOP ) - msStyle |= TBS_TOP; - else if ( style & wxSL_BOTTOM ) - msStyle |= TBS_BOTTOM; - else if ( style & wxSL_BOTH ) + if ( style & wxSL_BOTH ) + { + // this fully specifies the style combined with TBS_VERT/HORZ above msStyle |= TBS_BOTH; - else if ( !(style & wxSL_AUTOTICKS) ) + } + else // choose one direction + { + if ( style & wxSL_LEFT ) + msStyle |= TBS_LEFT; + else if ( style & wxSL_RIGHT ) + msStyle |= TBS_RIGHT; + else if ( style & wxSL_TOP ) + msStyle |= TBS_TOP; + else if ( style & wxSL_BOTTOM ) + msStyle |= TBS_BOTTOM; + } + + if ( style & wxSL_AUTOTICKS ) + msStyle |= TBS_AUTOTICKS; + else msStyle |= TBS_NOTICKS; if ( style & wxSL_SELRANGE ) @@ -292,14 +330,29 @@ bool wxSlider::MSWOnScroll(int WXUNUSED(orientation), case SB_THUMBTRACK: scrollEvent = wxEVT_SCROLL_THUMBTRACK; + m_isDragging = true; break; case SB_THUMBPOSITION: - scrollEvent = wxEVT_SCROLL_THUMBRELEASE; + if ( m_isDragging ) + { + scrollEvent = wxEVT_SCROLL_THUMBRELEASE; + m_isDragging = false; + } + else + { + // this seems to only happen when the mouse wheel is used: in + // this case, as it might be unexpected to get THUMBRELEASE + // without preceding THUMBTRACKs, we don't generate it at all + // but generate CHANGED event because the control itself does + // not send us SB_ENDSCROLL for whatever reason when mouse + // wheel is used + scrollEvent = wxEVT_SCROLL_CHANGED; + } break; case SB_ENDSCROLL: - scrollEvent = wxEVT_SCROLL_ENDSCROLL; + scrollEvent = wxEVT_SCROLL_CHANGED; break; default: @@ -407,6 +460,16 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height) return; } + // if our parent had prepared a defer window handle for us, use it (unless + // we are a top level window) + wxWindowMSW *parent = GetParent(); + +#if USE_DEFERRED_SIZING + HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL; +#else + HDWP hdwp = 0; +#endif + // be careful to position the slider itself after moving the labels as // otherwise our GetBoundingBox(), which is called from WM_SIZE handler, // would return a wrong result and wrong size would be cached internally @@ -419,22 +482,21 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height) // position all labels: min at the top, value in the middle and max at // the bottom - ::MoveWindow((*m_labels)[SliderLabel_Min], - xLabel, y, wLabel, hLabel, TRUE); + wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min], + xLabel, y, wLabel, hLabel); - ::MoveWindow((*m_labels)[SliderLabel_Value], - xLabel, y + (height - hLabel)/2, wLabel, hLabel, TRUE); + wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value], + xLabel, y + (height - hLabel)/2, wLabel, hLabel); - ::MoveWindow((*m_labels)[SliderLabel_Max], - xLabel, y + height - hLabel, wLabel, hLabel, TRUE); + wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max], + xLabel, y + height - hLabel, wLabel, hLabel); // position the slider itself along the left/right edge - ::MoveWindow(GetHwnd(), + wxMoveWindowDeferred(hdwp, this, GetHwnd(), HasFlag(wxSL_LEFT) ? x : x + wLabel + HGAP, y + hLabel/2, width - wLabel - HGAP, - height - hLabel, - TRUE); + height - hLabel); } else // horizontal { @@ -445,36 +507,46 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height) // position all labels: min on the left, value in the middle and max to // the right - ::MoveWindow((*m_labels)[SliderLabel_Min], - x, yLabel, wLabel, hLabel, TRUE); + wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min], + x, yLabel, wLabel, hLabel); - ::MoveWindow((*m_labels)[SliderLabel_Value], - x + (width - wLabel)/2, yLabel, wLabel, hLabel, TRUE); + wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value], + x + (width - wLabel)/2, yLabel, wLabel, hLabel); - ::MoveWindow((*m_labels)[SliderLabel_Max], - x + width - wLabel, yLabel, wLabel, hLabel, TRUE); + wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max], + x + width - wLabel, yLabel, wLabel, hLabel); // position the slider itself along the top/bottom edge - ::MoveWindow(GetHwnd(), + wxMoveWindowDeferred(hdwp, this, GetHwnd(), x, HasFlag(wxSL_TOP) ? y : y + hLabel, width, - height - hLabel, - TRUE); + height - hLabel); + } + +#if USE_DEFERRED_SIZING + if ( parent ) + { + // hdwp must be updated as it may have been changed + parent->m_hDWP = (WXHANDLE)hdwp; } +#endif } wxSize wxSlider::DoGetBestSize() const { // these values are arbitrary static const int length = 100; - static const int thickness = 26; + static const int thumb = 24; + static const int ticks = 8; + int *width; wxSize size; if ( HasFlag(wxSL_VERTICAL) ) { - size.x = thickness; + size.x = thumb; size.y = length; + width = &size.x; if ( m_labels ) { @@ -491,7 +563,8 @@ wxSize wxSlider::DoGetBestSize() const else // horizontal { size.x = length; - size.y = thickness; + size.y = thumb; + width = &size.y; if ( m_labels ) { @@ -500,6 +573,16 @@ wxSize wxSlider::DoGetBestSize() const } } + // need extra space to show ticks + if ( HasFlag(wxSL_TICKS) ) + { + *width += ticks; + + // and maybe twice as much if we show them on both sides + if ( HasFlag(wxSL_BOTH) ) + *width += ticks; + } + return size; } @@ -527,7 +610,8 @@ void wxSlider::SetRange(int minValue, int maxValue) m_rangeMin = minValue; m_rangeMax = maxValue; - ::SendMessage(GetHwnd(), TBM_SETRANGE, TRUE, MAKELONG(minValue, maxValue)); + ::SendMessage(GetHwnd(), TBM_SETRANGEMIN, TRUE, m_rangeMin); + ::SendMessage(GetHwnd(), TBM_SETRANGEMAX, TRUE, m_rangeMax); if ( m_labels ) { @@ -576,7 +660,7 @@ int wxSlider::GetLineSize() const int wxSlider::GetSelEnd() const { - return (int)::SendMessage(GetHwnd(), TBM_SETSELEND, 0, 0); + return (int)::SendMessage(GetHwnd(), TBM_GETSELEND, 0, 0); } int wxSlider::GetSelStart() const