X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/33b35531ecaae0444d97ba9fe59d727f2a20d2f6..e795e8b56f213f97745636a017609091746894a0:/src/mac/carbon/slider.cpp diff --git a/src/mac/carbon/slider.cpp b/src/mac/carbon/slider.cpp index 79f83f1b52..bbf97a3d9f 100644 --- a/src/mac/carbon/slider.cpp +++ b/src/mac/carbon/slider.cpp @@ -9,23 +9,17 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "slider.h" -#endif - -#include "wx/defs.h" +#include "wx/wxprec.h" #if wxUSE_SLIDER #include "wx/slider.h" #include "wx/mac/uma.h" -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl) BEGIN_EVENT_TABLE(wxSlider, wxControl) END_EVENT_TABLE() -#endif // The dimensions of the different styles of sliders (From Aqua document) #define wxSLIDER_DIMENSIONACROSS 15 @@ -36,8 +30,8 @@ END_EVENT_TABLE() #define wxSLIDER_BORDERTEXT 5 /* NB! The default orientation for a slider is horizontal however if the user specifies - * some slider styles but dosen't specify the orientation we have to assume he wants a - * horizontal one. Therefore in this file when testing for the sliders orientation + * some slider styles but doesn't specify the orientation we have to assume he wants a + * horizontal one. Therefore in this file when testing for the slider's orientation * vertical is tested for if this is not set then we use the horizontal one * eg. if(GetWindowStyle() & wxSL_VERTICAL) {} else { horizontal case }> */ @@ -52,8 +46,6 @@ END_EVENT_TABLE() m_tickFreq = 0; } -extern ControlActionUPP wxMacLiveScrollbarActionUPP ; - bool wxSlider::Create(wxWindow *parent, wxWindowID id, int value, int minValue, int maxValue, const wxPoint& pos, @@ -63,6 +55,34 @@ bool wxSlider::Create(wxWindow *parent, wxWindowID id, { m_macIsUserPane = false ; + // 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") ); + if ( !wxControl::Create(parent, id, pos, size, style, validator, name) ) return false; @@ -70,7 +90,6 @@ bool wxSlider::Create(wxWindow *parent, wxWindowID id, m_macMaximumStatic = NULL ; m_macValueStatic = NULL ; - m_lineSize = 1; m_tickFreq = 0; @@ -90,13 +109,12 @@ bool wxSlider::Create(wxWindow *parent, wxWindowID id, tickMarks = (maxValue - minValue) + 1; //+1 for the 0 value while (tickMarks > 20) - tickMarks /= 5; //keep the number of tickmarks from becoming unwieldly + tickMarks /= 5; //keep the number of tickmarks from becoming unwieldly - m_peer = new wxMacControl() ; + m_peer = new wxMacControl(this) ; verify_noerr ( CreateSliderControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()) , &bounds , - value , minValue , maxValue , kControlSliderPointsDownOrRight , tickMarks , true /* liveTracking */ , - wxMacLiveScrollbarActionUPP , m_peer->GetControlRefAddr() ) ); - + value , minValue , maxValue , kControlSliderPointsDownOrRight , tickMarks , true /* liveTracking */ , + GetwxMacLiveScrollbarActionProc() , m_peer->GetControlRefAddr() ) ); if(style & wxSL_VERTICAL) { SetSizeHints(10, -1, 10, -1); // Forces SetSize to use the proper width @@ -124,7 +142,7 @@ bool wxSlider::Create(wxWindow *parent, wxWindowID id, wxSlider::~wxSlider() { - // this is a special case, as we had to add windows as siblings we are + // this is a special case, as we had to add windows as siblings we are // responsible for their disposal, but only if we are not part of a DestroyAllChildren if ( m_parent && m_parent->IsBeingDeleted() == false ) { @@ -136,7 +154,8 @@ wxSlider::~wxSlider() int wxSlider::GetValue() const { - return m_peer->GetValue() ; + // We may need to invert the value returned by the widget + return ValueInvertOrNot( m_peer->GetValue() ) ; } void wxSlider::SetValue(int value) @@ -145,7 +164,9 @@ void wxSlider::SetValue(int value) valuestring.Printf( wxT("%d") , value ) ; if ( m_macValueStatic ) m_macValueStatic->SetLabel( valuestring ) ; - m_peer->SetValue( value ) ; + + // We only invert for the setting of the actual native widget + m_peer->SetValue( ValueInvertOrNot ( value ) ) ; } void wxSlider::SetRange(int minValue, int maxValue) @@ -159,11 +180,11 @@ void wxSlider::SetRange(int minValue, int maxValue) m_peer->SetMaximum( m_rangeMax); if(m_macMinimumStatic) { - value.Printf(wxT("%d"), m_rangeMin); + value.Printf(wxT("%d"), ValueInvertOrNot( m_rangeMin ) ); m_macMinimumStatic->SetLabel(value); } if(m_macMaximumStatic) { - value.Printf(wxT("%d"), m_rangeMax); + value.Printf(wxT("%d"), ValueInvertOrNot( m_rangeMax ) ); m_macMaximumStatic->SetLabel(value); } SetValue(m_rangeMin); @@ -250,7 +271,9 @@ void wxSlider::Command (wxCommandEvent & event) void wxSlider::MacHandleControlClick( WXWidget control , wxInt16 controlpart, bool mouseStillDown ) { - SInt16 value = m_peer->GetValue() ; + // Whatever the native value is, we may need to invert it for calling + // SetValue and putting the possibly inverted value in the event + SInt16 value = ValueInvertOrNot ( m_peer->GetValue() ) ; SetValue( value ) ; @@ -272,7 +295,9 @@ void wxSlider::MacHandleControlClick( WXWidget control , wxInt16 controlpart, bo wxInt32 wxSlider::MacControlHit( WXEVENTHANDLERREF handler , WXEVENTREF mevent ) { - SInt16 value = m_peer->GetValue() ; + // Whatever the native value is, we may need to invert it for calling + // SetValue and putting the possibly inverted value in the event + SInt16 value = ValueInvertOrNot ( m_peer->GetValue() ) ; SetValue( value ) ; @@ -293,7 +318,6 @@ wxInt32 wxSlider::MacControlHit( WXEVENTHANDLERREF handler , WXEVENTREF mevent ) return noErr ; } - /* This is overloaded in wxSlider so that the proper width/height will always be used * for the slider different values would cause redrawing and mouse detection problems */ void wxSlider::DoSetSizeHints( int minW, int minH, @@ -313,23 +337,31 @@ void wxSlider::DoSetSizeHints( int minW, int minH, wxSize wxSlider::DoGetBestSize() const { wxSize size; - int textwidth, textheight; + int textwidth = 0; + int textheight = 0; + int mintwidth, mintheight; + int maxtwidth, maxtheight; if(GetWindowStyle() & wxSL_LABELS) { wxString text; - int ht, wd; // Get maximum text label width and height - text.Printf(wxT("%d"), m_rangeMin); - GetTextExtent(text, &textwidth, &textheight); - text.Printf(wxT("%d"), m_rangeMax); - GetTextExtent(text, &wd, &ht); - if(ht > textheight) { - textheight = ht; + text.Printf(wxT("%d"), ValueInvertOrNot( m_rangeMin ) ); + GetTextExtent(text, &mintwidth, &mintheight); + text.Printf(wxT("%d"), ValueInvertOrNot( m_rangeMax ) ); + GetTextExtent(text, &maxtwidth, &maxtheight); + if(maxtheight > mintheight) { + textheight = maxtheight; + } + else { + textheight = mintheight; } - if (wd > textwidth) { - textwidth = wd; + if (maxtwidth > mintwidth) { + textwidth = maxtwidth; + } + else { + textwidth = mintwidth; } } @@ -354,10 +386,13 @@ wxSize wxSlider::DoGetBestSize() const else { size.y = wxSLIDER_DIMENSIONACROSS_ARROW; } + + size.x = 150; + if(GetWindowStyle() & wxSL_LABELS) { size.y += textheight + wxSLIDER_BORDERTEXT; + size.x += (mintwidth/2) + (maxtwidth/2); } - size.x = 150; } return size; } @@ -365,34 +400,60 @@ wxSize wxSlider::DoGetBestSize() const void wxSlider::DoSetSize(int x, int y, int w, int h, int sizeFlags) { int xborder, yborder; - int minValWidth, maxValWidth, textwidth, textheight; + int minValWidth, maxValWidth, textheight; int sliderBreadth; + int width = w; xborder = yborder = 0; if (GetWindowStyle() & wxSL_LABELS) { - //Labels have this control's parent as their parent - //so if this control is not at 0,0 relative to the parent - //the labels need to know the position of this control - //relative to its parent in order to size properly, so - //move the control first so we can use GetPosition() - wxControl::DoSetSize( x, y , w , h ,sizeFlags ) ; wxString text; - int ht; + int ht, valValWidth; // Get maximum text label width and height - text.Printf(wxT("%d"), m_rangeMin); + text.Printf(wxT("%d"), ValueInvertOrNot( m_rangeMin ) ); GetTextExtent(text, &minValWidth, &textheight); - text.Printf(wxT("%d"), m_rangeMax); + text.Printf(wxT("%d"), ValueInvertOrNot( m_rangeMax ) ); GetTextExtent(text, &maxValWidth, &ht); + if(ht > textheight) { textheight = ht; } - textwidth = (minValWidth > maxValWidth ? minValWidth : maxValWidth); - xborder = textwidth + wxSLIDER_BORDERTEXT; + if(GetWindowStyle() & wxSL_HORIZONTAL) + { + if ( m_macMinimumStatic ) { + w-=minValWidth/2; + x+=minValWidth/2; + } + if ( m_macMaximumStatic ) { + w-=maxValWidth/2; + } + } + + + //Labels have this control's parent as their parent + //so if this control is not at 0,0 relative to the parent + //the labels need to know the position of this control + //relative to its parent in order to size properly, so + //move the control first so we can use GetPosition() + wxControl::DoSetSize( x, y , w , h ,sizeFlags ) ; + + // If vertical, use current value + if(GetWindowStyle() & wxSL_VERTICAL) + { + text.Printf(wxT("%d"), (int)m_peer->GetValue()); + } + // Use max so that the current value doesn't drift as centering would need to change + else + { + text.Printf(wxT("%d"), m_rangeMax); + } + + GetTextExtent(text, &valValWidth, &ht); + yborder = textheight + wxSLIDER_BORDERTEXT; // Get slider breadth @@ -408,29 +469,46 @@ void wxSlider::DoSetSize(int x, int y, int w, int h, int sizeFlags) h = h - yborder ; if ( m_macMinimumStatic ) - m_macMinimumStatic->Move(GetPosition().x + sliderBreadth + wxSLIDER_BORDERTEXT, - GetPosition().y + h - yborder); + m_macMinimumStatic->Move(GetPosition().x + sliderBreadth + wxSLIDER_BORDERTEXT, GetPosition().y + h - yborder); if ( m_macMaximumStatic ) m_macMaximumStatic->Move(GetPosition().x + sliderBreadth + wxSLIDER_BORDERTEXT, GetPosition().y + 0); if ( m_macValueStatic ) - m_macValueStatic->Move(GetPosition().x, GetPosition().y + h ); + m_macValueStatic->Move(GetPosition().x + sliderBreadth + wxSLIDER_BORDERTEXT, GetPosition().y + (h/2) - (ht/2)); } else { - w = w - xborder ; if ( m_macMinimumStatic ) - m_macMinimumStatic->Move(GetPosition().x + 0, GetPosition().y + sliderBreadth + wxSLIDER_BORDERTEXT); + m_macMinimumStatic->Move(GetPosition().x, GetPosition().y + sliderBreadth + wxSLIDER_BORDERTEXT); if ( m_macMaximumStatic ) - m_macMaximumStatic->Move(GetPosition().x + w - (maxValWidth/2), - GetPosition().y + sliderBreadth + wxSLIDER_BORDERTEXT); + m_macMaximumStatic->Move(GetPosition().x + w - maxValWidth, GetPosition().y + sliderBreadth + wxSLIDER_BORDERTEXT); if ( m_macValueStatic ) - m_macValueStatic->Move(GetPosition().x + w, GetPosition().y + 0); + m_macValueStatic->Move(GetPosition().x + (w/2) - (valValWidth/2), GetPosition().y + sliderBreadth + wxSLIDER_BORDERTEXT); } } + + // yet another hack since this is a composite control + // when wxSlider has it's size hardcoded, we're not allowed to + // change the size. But when the control has labels, we DO need + // to resize the internal Mac control to accommodate the text labels. + // We need to trick the wxWidgets resize mechanism so that we can + // resize the slider part of the control ONLY. + + // TODO: Can all of this code go in the conditional wxSL_LABELS block? + + int minWidth; + minWidth = m_minWidth; + + if (GetWindowStyle() & wxSL_LABELS) + { + // make sure we don't allow the entire control to be resized accidently + if (width == GetSize().x) + m_minWidth = -1; + } //If the control has labels, we still need to call this again because //the labels alter the control's w and h values. wxControl::DoSetSize( x, y , w , h ,sizeFlags ) ; + m_minWidth = minWidth; } void wxSlider::DoMoveWindow(int x, int y, int width, int height) @@ -438,4 +516,23 @@ void wxSlider::DoMoveWindow(int x, int y, int width, int height) wxControl::DoMoveWindow(x,y,width,height) ; } +// Common processing to invert slider values based on wxSL_INVERSE +int wxSlider::ValueInvertOrNot(int value) const +{ + if (m_windowStyle & wxSL_VERTICAL) + { + // The reason for the backwards logic is that Mac's vertical sliders are + // inverted compared to Windows and GTK, hence we want inversion to be the + // default, and if wxSL_INVERSE is set, then we do not invert (use native) + if (m_windowStyle & wxSL_INVERSE) + return value; + else + return (m_rangeMax + m_rangeMin) - value; + } + else // normal logic applies to HORIZONTAL sliders + { + return wxSliderBase::ValueInvertOrNot(value); + } +} + #endif // wxUSE_SLIDER