X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b5c4505960515b5a9809286670ca9089f46e378c..bdebb379299aaf1ee588dbe15968829df49ccedc:/src/msw/slider95.cpp diff --git a/src/msw/slider95.cpp b/src/msw/slider95.cpp index 705ca4bd7f..f9106b7830 100644 --- a/src/msw/slider95.cpp +++ b/src/msw/slider95.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: msw/slider95.cpp -// Purpose: wxSlider95, using the Win95 trackbar control +// Name: msw/slider.cpp +// Purpose: wxSlider, using the Win95 (and later) trackbar control // Author: Julian Smart // Modified by: // Created: 04/01/98 @@ -42,11 +42,13 @@ #include #endif +#define USE_DEFERRED_SIZING 1 + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- -// indices of labels in wxSlider95::m_labels +// indices of labels in wxSlider::m_labels enum { SliderLabel_Min, @@ -103,12 +105,13 @@ wxBEGIN_FLAGS( wxSliderStyle ) wxFLAGS_MEMBER(wxSL_BOTTOM) wxFLAGS_MEMBER(wxSL_BOTH) wxFLAGS_MEMBER(wxSL_SELRANGE) + wxFLAGS_MEMBER(wxSL_INVERSE) wxEND_FLAGS( wxSliderStyle ) -IMPLEMENT_DYNAMIC_CLASS_XTI(wxSlider95, wxControl,"wx/scrolbar.h") +IMPLEMENT_DYNAMIC_CLASS_XTI(wxSlider, wxControl,"wx/scrolbar.h") -wxBEGIN_PROPERTIES_TABLE(wxSlider95) +wxBEGIN_PROPERTIES_TABLE(wxSlider) wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_ENDSCROLL , wxScrollEvent ) wxEVENT_PROPERTY( Updated , wxEVT_COMMAND_SLIDER_UPDATED , wxCommandEvent ) @@ -121,23 +124,23 @@ wxBEGIN_PROPERTIES_TABLE(wxSlider95) wxPROPERTY_FLAGS( WindowStyle , wxSliderStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style wxEND_PROPERTIES_TABLE() -wxBEGIN_HANDLERS_TABLE(wxSlider95) +wxBEGIN_HANDLERS_TABLE(wxSlider) wxEND_HANDLERS_TABLE() -wxCONSTRUCTOR_8( wxSlider95 , wxWindow* , Parent , wxWindowID , Id , int , Value , int , Minimum , int , Maximum , wxPoint , Position , wxSize , Size , long , WindowStyle ) +wxCONSTRUCTOR_8( wxSlider , wxWindow* , Parent , wxWindowID , Id , int , Value , int , Minimum , int , Maximum , wxPoint , Position , wxSize , Size , long , WindowStyle ) #else -IMPLEMENT_DYNAMIC_CLASS(wxSlider95, wxControl) +IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl) #endif // ============================================================================ -// wxSlider95 implementation +// wxSlider implementation // ============================================================================ // ---------------------------------------------------------------------------- // construction // ---------------------------------------------------------------------------- -void wxSlider95::Init() +void wxSlider::Init() { m_labels = NULL; @@ -149,17 +152,46 @@ void wxSlider95::Init() } bool -wxSlider95::Create(wxWindow *parent, - wxWindowID id, - int value, - int minValue, - int maxValue, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& validator, - const wxString& name) -{ +wxSlider::Create(wxWindow *parent, + wxWindowID id, + int value, + int minValue, + int maxValue, + const wxPoint& pos, + const wxSize& size, + long style, + 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; @@ -218,28 +250,33 @@ wxSlider95::Create(wxWindow *parent, return true; } -WXDWORD wxSlider95::MSWGetStyle(long style, WXDWORD *exstyle) const +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 ) @@ -248,7 +285,7 @@ WXDWORD wxSlider95::MSWGetStyle(long style, WXDWORD *exstyle) const return msStyle; } -wxSlider95::~wxSlider95() +wxSlider::~wxSlider() { delete m_labels; } @@ -257,10 +294,10 @@ wxSlider95::~wxSlider95() // event handling // ---------------------------------------------------------------------------- -bool wxSlider95::MSWOnScroll(int WXUNUSED(orientation), - WXWORD wParam, - WXWORD WXUNUSED(pos), - WXHWND control) +bool wxSlider::MSWOnScroll(int WXUNUSED(orientation), + WXWORD wParam, + WXWORD WXUNUSED(pos), + WXHWND control) { wxEventType scrollEvent; switch ( wParam ) @@ -306,7 +343,7 @@ bool wxSlider95::MSWOnScroll(int WXUNUSED(orientation), return false; } - int newPos = (int) ::SendMessage((HWND) control, TBM_GETPOS, 0, 0); + int newPos = ValueInvertOrNot((int) ::SendMessage((HWND) control, TBM_GETPOS, 0, 0)); if ( (newPos < GetMin()) || (newPos > GetMax()) ) { // out of range - but we did process it @@ -327,7 +364,7 @@ bool wxSlider95::MSWOnScroll(int WXUNUSED(orientation), return GetEventHandler()->ProcessEvent( cevent ); } -void wxSlider95::Command (wxCommandEvent & event) +void wxSlider::Command (wxCommandEvent & event) { SetValue (event.GetInt()); ProcessCommand (event); @@ -337,7 +374,7 @@ void wxSlider95::Command (wxCommandEvent & event) // geometry stuff // ---------------------------------------------------------------------------- -wxRect wxSlider95::GetBoundingBox() const +wxRect wxSlider::GetBoundingBox() const { // take care not to call our own functions which would call us recursively int x, y, w, h; @@ -355,7 +392,7 @@ wxRect wxSlider95::GetBoundingBox() const return rect; } -void wxSlider95::DoGetSize(int *width, int *height) const +void wxSlider::DoGetSize(int *width, int *height) const { wxRect rect = GetBoundingBox(); @@ -365,7 +402,7 @@ void wxSlider95::DoGetSize(int *width, int *height) const *height = rect.height; } -void wxSlider95::DoGetPosition(int *x, int *y) const +void wxSlider::DoGetPosition(int *x, int *y) const { wxRect rect = GetBoundingBox(); @@ -375,7 +412,7 @@ void wxSlider95::DoGetPosition(int *x, int *y) const *y = rect.y; } -int wxSlider95::GetLabelsSize(int *width) const +int wxSlider::GetLabelsSize(int *width) const { int cy; @@ -396,7 +433,7 @@ int wxSlider95::GetLabelsSize(int *width) const return EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); } -void wxSlider95::DoMoveWindow(int x, int y, int width, int height) +void wxSlider::DoMoveWindow(int x, int y, int width, int height) { // all complications below are because we need to position the labels, // without them everything is easy @@ -406,6 +443,16 @@ void wxSlider95::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 @@ -418,22 +465,21 @@ void wxSlider95::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 { @@ -444,36 +490,46 @@ void wxSlider95::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 wxSlider95::DoGetBestSize() const +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 ) { @@ -490,7 +546,8 @@ wxSize wxSlider95::DoGetBestSize() const else // horizontal { size.x = length; - size.y = thickness; + size.y = thumb; + width = &size.y; if ( m_labels ) { @@ -499,6 +556,16 @@ wxSize wxSlider95::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; } @@ -506,14 +573,14 @@ wxSize wxSlider95::DoGetBestSize() const // slider-specific methods // ---------------------------------------------------------------------------- -int wxSlider95::GetValue() const +int wxSlider::GetValue() const { - return ::SendMessage(GetHwnd(), TBM_GETPOS, 0, 0); + return ValueInvertOrNot(::SendMessage(GetHwnd(), TBM_GETPOS, 0, 0)); } -void wxSlider95::SetValue(int value) +void wxSlider::SetValue(int value) { - ::SendMessage(GetHwnd(), TBM_SETPOS, (WPARAM)TRUE, (LPARAM)value); + ::SendMessage(GetHwnd(), TBM_SETPOS, (WPARAM)TRUE, (LPARAM)ValueInvertOrNot(value)); if ( m_labels ) { @@ -521,109 +588,110 @@ void wxSlider95::SetValue(int value) } } -void wxSlider95::SetRange(int minValue, int maxValue) +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 ) { - ::SetWindowText((*m_labels)[SliderLabel_Min], Format(m_rangeMin)); - ::SetWindowText((*m_labels)[SliderLabel_Max], Format(m_rangeMax)); + ::SetWindowText((*m_labels)[SliderLabel_Min], Format(ValueInvertOrNot(m_rangeMin))); + ::SetWindowText((*m_labels)[SliderLabel_Max], Format(ValueInvertOrNot(m_rangeMax))); } } -void wxSlider95::SetTickFreq(int n, int pos) +void wxSlider::SetTickFreq(int n, int pos) { m_tickFreq = n; ::SendMessage( GetHwnd(), TBM_SETTICFREQ, (WPARAM) n, (LPARAM) pos ); } -void wxSlider95::SetPageSize(int pageSize) +void wxSlider::SetPageSize(int pageSize) { ::SendMessage( GetHwnd(), TBM_SETPAGESIZE, (WPARAM) 0, (LPARAM) pageSize ); m_pageSize = pageSize; } -int wxSlider95::GetPageSize() const +int wxSlider::GetPageSize() const { return m_pageSize; } -void wxSlider95::ClearSel() +void wxSlider::ClearSel() { ::SendMessage(GetHwnd(), TBM_CLEARSEL, (WPARAM) TRUE, (LPARAM) 0); } -void wxSlider95::ClearTicks() +void wxSlider::ClearTicks() { ::SendMessage(GetHwnd(), TBM_CLEARTICS, (WPARAM) TRUE, (LPARAM) 0); } -void wxSlider95::SetLineSize(int lineSize) +void wxSlider::SetLineSize(int lineSize) { m_lineSize = lineSize; ::SendMessage(GetHwnd(), TBM_SETLINESIZE, (WPARAM) 0, (LPARAM) lineSize); } -int wxSlider95::GetLineSize() const +int wxSlider::GetLineSize() const { return (int)::SendMessage(GetHwnd(), TBM_GETLINESIZE, 0, 0); } -int wxSlider95::GetSelEnd() const +int wxSlider::GetSelEnd() const { return (int)::SendMessage(GetHwnd(), TBM_SETSELEND, 0, 0); } -int wxSlider95::GetSelStart() const +int wxSlider::GetSelStart() const { return (int)::SendMessage(GetHwnd(), TBM_GETSELSTART, 0, 0); } -void wxSlider95::SetSelection(int minPos, int maxPos) +void wxSlider::SetSelection(int minPos, int maxPos) { ::SendMessage(GetHwnd(), TBM_SETSEL, (WPARAM) TRUE /* redraw */, (LPARAM) MAKELONG( minPos, maxPos) ); } -void wxSlider95::SetThumbLength(int len) +void wxSlider::SetThumbLength(int len) { ::SendMessage(GetHwnd(), TBM_SETTHUMBLENGTH, (WPARAM) len, (LPARAM) 0); } -int wxSlider95::GetThumbLength() const +int wxSlider::GetThumbLength() const { - return (int)::SendMessage( GetHwnd(), TBM_GETTHUMBLENGTH, 0, 0); + return (int)::SendMessage( GetHwnd(), TBM_GETTHUMBLENGTH, 0, 0); } -void wxSlider95::SetTick(int tickPos) +void wxSlider::SetTick(int tickPos) { - ::SendMessage( GetHwnd(), TBM_SETTIC, (WPARAM) 0, (LPARAM) tickPos ); + ::SendMessage( GetHwnd(), TBM_SETTIC, (WPARAM) 0, (LPARAM) tickPos ); } // ---------------------------------------------------------------------------- // composite control methods // ---------------------------------------------------------------------------- -WXHWND wxSlider95::GetStaticMin() const +WXHWND wxSlider::GetStaticMin() const { return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Min] : NULL; } -WXHWND wxSlider95::GetStaticMax() const +WXHWND wxSlider::GetStaticMax() const { return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Max] : NULL; } -WXHWND wxSlider95::GetEditValue() const +WXHWND wxSlider::GetEditValue() const { return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Value] : NULL; } -WX_FORWARD_STD_METHODS_TO_SUBWINDOWS(wxSlider95, wxSliderBase, m_labels) +WX_FORWARD_STD_METHODS_TO_SUBWINDOWS(wxSlider, wxSliderBase, m_labels) #endif // wxUSE_SLIDER