EmptyChaos 822326eea9 Update wxWidgets to 3.1.0
From wxWidgets master 81570ae070b35c9d52de47b1f14897f3ff1a66c7.

include/wx/defs.h -- __w64 warning disable patch by comex brought forward.

include/wx/msw/window.h -- added GetContentScaleFactor() which was not implemented on Windows but is necessary for wxBitmap scaling on Mac OS X so it needs to work to avoid #ifdef-ing the code.

src/gtk/window.cpp -- Modified DoSetClientSize() to direct call wxWindowGTK::DoSetSize() instead of using public wxWindowBase::SetSize() which now prevents derived classes (like wxAuiToolbar) intercepting the call and breaking it. This matches Windows which does NOT need to call DoSetSize internally. End result is this fixes Dolphin's debug tools toolbars on Linux.

src/osx/window_osx.cpp -- Same fix as for GTK since it has the same issue.

src/msw/radiobox.cpp -- Hacked to fix display in HiDPI (was clipping off end of text).

Updated CMakeLists for Linux and Mac OS X. Small code changes to Dolphin to fix debug error boxes, deprecation warnings, and retain previous UI behavior on Windows.
2016-06-26 15:25:29 +10:00

532 lines
15 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/osx/slider_osx.cpp
// Purpose: wxSlider
// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#if wxUSE_SLIDER
#include "wx/slider.h"
#include "wx/osx/private.h"
wxBEGIN_EVENT_TABLE(wxSlider, wxControl)
wxEND_EVENT_TABLE()
// The dimensions of the different styles of sliders (from Aqua document)
#if wxOSX_USE_COCOA
#define wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS 28
#define wxSLIDER_DIMENSIONACROSS_ARROW 21
#else
#define wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS 24
#define wxSLIDER_DIMENSIONACROSS_ARROW 18
#endif
// Distance between slider and text
#define wxSLIDER_BORDERTEXT 5
// NB: The default orientation for a slider is horizontal; however, if the user specifies
// 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
// e.g., if (GetWindowStyle() & wxSL_VERTICAL) {} else { horizontal case }.
wxSlider::wxSlider()
{
m_pageSize = 1;
m_lineSize = 1;
m_rangeMax = 0;
m_rangeMin = 0;
m_tickFreq = 0;
m_macMinimumStatic = NULL;
m_macMaximumStatic = NULL;
m_macValueStatic = NULL;
}
bool 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)
{
DontCreatePeer();
m_macMinimumStatic = NULL;
m_macMaximumStatic = NULL;
m_macValueStatic = NULL;
m_lineSize = 1;
m_tickFreq = 0;
m_rangeMax = maxValue;
m_rangeMin = minValue;
m_pageSize = (int)((maxValue - minValue) / 10);
// 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:
default:
// no specific direction, do we have at least the orientation?
if ( !(style & (wxSL_HORIZONTAL | wxSL_VERTICAL)) )
// no: choose default
style |= wxSL_BOTTOM | wxSL_HORIZONTAL;
break;
}
wxASSERT_MSG( !(style & wxSL_VERTICAL) || !(style & wxSL_HORIZONTAL),
wxT("incompatible slider direction and orientation") );
if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
return false;
SetPeer(wxWidgetImpl::CreateSlider( this, parent, id, value, minValue, maxValue, pos, size, style, GetExtraStyle() ));
#if 0
if (style & wxSL_VERTICAL)
// Forces SetSize to use the proper width
SetSizeHints(10, -1, 10, -1);
else
// Forces SetSize to use the proper height
SetSizeHints(-1, 10, -1, 10);
// NB: SetSizeHints is overloaded by wxSlider and will substitute 10 with the
// proper dimensions, it also means other people cannot bugger the slider with
// other values
#endif
if (style & wxSL_LABELS)
{
m_macMinimumStatic = new wxStaticText( parent, wxID_ANY, wxEmptyString );
m_macMaximumStatic = new wxStaticText( parent, wxID_ANY, wxEmptyString );
m_macValueStatic = new wxStaticText( parent, wxID_ANY, wxEmptyString );
}
SetRange(minValue, maxValue);
SetValue(value);
MacPostControlCreate(pos, size);
return true;
}
wxSlider::~wxSlider()
{
// 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() )
{
delete m_macMinimumStatic;
delete m_macMaximumStatic;
delete m_macValueStatic;
}
}
int wxSlider::GetValue() const
{
// We may need to invert the value returned by the widget
return ValueInvertOrNot( GetPeer()->GetValue() ) ;
}
void wxSlider::SetValue(int value)
{
if ( m_macValueStatic )
{
wxString valuestring;
valuestring.Printf( wxT("%d"), value );
m_macValueStatic->SetLabel( valuestring );
}
// We only invert for the setting of the actual native widget
GetPeer()->SetValue( ValueInvertOrNot( value ) );
}
void wxSlider::SetRange(int minValue, int maxValue)
{
// Changing the range preserves the value of the native control but may
// change our logical value if we're inverting the native value to get it
// as ValueInvertOrNot() depends on the range so preserve it before
// changing the range.
const int valueOld = GetValue();
wxString value;
m_rangeMin = minValue;
m_rangeMax = maxValue;
GetPeer()->SetMinimum( m_rangeMin );
GetPeer()->SetMaximum( m_rangeMax );
if (m_macMinimumStatic)
{
value.Printf( wxT("%d"), ValueInvertOrNot( m_rangeMin ) );
m_macMinimumStatic->SetLabel( value );
}
if (m_macMaximumStatic)
{
value.Printf( wxT("%d"), ValueInvertOrNot( m_rangeMax ) );
m_macMaximumStatic->SetLabel( value );
}
// If the range is out of bounds, set it to a
// value that is within bounds
// RN: Testing reveals OSX does its own
// bounding, perhaps this isn't needed?
int currentValue = GetValue();
if(currentValue < m_rangeMin)
SetValue(m_rangeMin);
else if(currentValue > m_rangeMax)
SetValue(m_rangeMax);
// Ensure that our value didn't change.
SetValue(valueOld);
}
// For trackbars only
void wxSlider::DoSetTickFreq(int n)
{
// TODO
m_tickFreq = n;
}
void wxSlider::SetPageSize(int pageSize)
{
// TODO
m_pageSize = pageSize;
}
int wxSlider::GetPageSize() const
{
return m_pageSize;
}
void wxSlider::ClearSel()
{
// TODO
}
void wxSlider::ClearTicks()
{
// TODO
}
void wxSlider::SetLineSize(int lineSize)
{
m_lineSize = lineSize;
// TODO
}
int wxSlider::GetLineSize() const
{
// TODO
return m_lineSize;
}
int wxSlider::GetSelEnd() const
{
// TODO
return 0;
}
int wxSlider::GetSelStart() const
{
// TODO
return 0;
}
void wxSlider::SetSelection(int WXUNUSED(minPos), int WXUNUSED(maxPos))
{
// TODO
}
void wxSlider::SetThumbLength(int WXUNUSED(len))
{
// TODO
}
int wxSlider::GetThumbLength() const
{
// TODO
return 0;
}
void wxSlider::SetTick(int WXUNUSED(tickPos))
{
// TODO
}
void wxSlider::Command(wxCommandEvent &event)
{
SetValue(event.GetInt());
ProcessCommand(event);
}
void wxSlider::TriggerScrollEvent( wxEventType scrollEvent)
{
// Whatever the native value is, we may need to invert it for calling
// SetValue and putting the possibly inverted value in the event
int value = ValueInvertOrNot( GetPeer()->GetValue() );
SetValue( value );
wxScrollEvent event( scrollEvent, m_windowId );
event.SetPosition( value );
event.SetEventObject( this );
HandleWindowEvent( event );
wxCommandEvent cevent( wxEVT_SLIDER, m_windowId );
cevent.SetInt( value );
cevent.SetEventObject( this );
HandleWindowEvent( cevent );
}
bool wxSlider::OSXHandleClicked( double WXUNUSED(timestampsec) )
{
TriggerScrollEvent(wxEVT_SCROLL_THUMBRELEASE);
return true;
}
// 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,
int maxW, int maxH,
int WXUNUSED(incW), int WXUNUSED(incH) )
{
wxSize size = GetBestSize();
if (GetWindowStyle() & wxSL_VERTICAL)
{
SetMinSize( wxSize(size.x,minH) );
SetMaxSize( wxSize(size.x,maxH) );
}
else
{
SetMinSize( wxSize(minW,size.y) );
SetMaxSize( wxSize(maxW,size.y) );
}
}
wxSize wxSlider::DoGetBestSize() const
{
wxSize size;
int textwidth, textheight;
int mintwidth, mintheight;
int maxtwidth, maxtheight;
textwidth = textheight = 0;
mintwidth = mintheight = 0;
maxtwidth = maxtheight = 0;
if (GetWindowStyle() & wxSL_LABELS)
{
wxString text;
// Get maximum text label width and height
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 (maxtwidth > mintwidth)
textwidth = maxtwidth;
else
textwidth = mintwidth;
}
if (GetWindowStyle() & wxSL_VERTICAL)
{
size.y = 150;
if (GetWindowStyle() & wxSL_AUTOTICKS)
size.x = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
else
size.x = wxSLIDER_DIMENSIONACROSS_ARROW;
if (GetWindowStyle() & wxSL_LABELS)
size.x += textwidth + wxSLIDER_BORDERTEXT;
}
else
{
size.x = 150;
if (GetWindowStyle() & wxSL_AUTOTICKS)
size.y = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
else
size.y = wxSLIDER_DIMENSIONACROSS_ARROW;
if (GetWindowStyle() & wxSL_LABELS)
{
size.y += textheight + wxSLIDER_BORDERTEXT;
size.x += (mintwidth / 2) + (maxtwidth / 2);
}
}
return size;
}
void wxSlider::DoSetSize(int x, int y, int w, int h, int sizeFlags)
{
int yborder = 0;
int minValWidth, maxValWidth, textheight;
int sliderBreadth;
int width = w;
if (GetWindowStyle() & wxSL_LABELS)
{
wxString text;
int ht, valValWidth;
// Get maximum text label width and height
text.Printf(wxT("%d"), ValueInvertOrNot( m_rangeMin ) );
GetTextExtent(text, &minValWidth, &textheight);
text.Printf(wxT("%d"), ValueInvertOrNot( m_rangeMax ) );
GetTextExtent(text, &maxValWidth, &ht);
if (ht > textheight)
textheight = ht;
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 (GetWindowStyle() & wxSL_VERTICAL)
// If vertical, use current value
text.Printf(wxT("%d"), (int)GetPeer()->GetValue());
else
// Use max so that the current value doesn't drift as centering would need to change
text.Printf(wxT("%d"), m_rangeMax);
GetTextExtent(text, &valValWidth, &ht);
yborder = textheight + wxSLIDER_BORDERTEXT;
// Get slider breadth
if (GetWindowStyle() & wxSL_AUTOTICKS)
sliderBreadth = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
else
sliderBreadth = wxSLIDER_DIMENSIONACROSS_ARROW;
if (GetWindowStyle() & wxSL_VERTICAL)
{
h = h - yborder;
if ( m_macMinimumStatic )
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 + sliderBreadth + wxSLIDER_BORDERTEXT, GetPosition().y + (h / 2) - (ht / 2));
}
else
{
if ( m_macMinimumStatic )
m_macMinimumStatic->Move(GetPosition().x, GetPosition().y + sliderBreadth + wxSLIDER_BORDERTEXT);
if ( m_macMaximumStatic )
m_macMaximumStatic->Move(GetPosition().x + w - maxValWidth, GetPosition().y + sliderBreadth + wxSLIDER_BORDERTEXT);
if ( m_macValueStatic )
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 its 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 = m_minWidth;
if (GetWindowStyle() & wxSL_LABELS)
{
// make sure we don't allow the entire control to be resized accidentally
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)
{
wxControl::DoMoveWindow( x, y, width, height );
}
// Common processing to invert slider values based on wxSL_INVERSE
int wxSlider::ValueInvertOrNot(int value) const
{
int result = 0;
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)
result = value;
else
result = (m_rangeMax + m_rangeMin) - value;
}
else // normal logic applies to HORIZONTAL sliders
{
result = wxSliderBase::ValueInvertOrNot(value);
}
return result;
}
#endif // wxUSE_SLIDER