Files
wxWidgets/src/univ/slider.cpp
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

1099 lines
28 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: src/univ/slider.cpp
// Purpose: implementation of the universal version of wxSlider
// Author: Vadim Zeitlin
// Modified by:
// Created: 09.02.01
// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
/*
There is some discrepancy in wxSL_LABELS style handling between wxMSW and
wxGTK: the latter handles it natively and shows only the current value of
the slider on the side corresponding to wxSL_TOP/BOTTOM/LEFT/RIGHT style
given (which can be combined with wxSL_HORIZONTAL/VERTICAL) while wxMSW
emulates this somehow and shows the min and max values near the ends of the
slider and the current value in a separate static box nearby.
We currently follow wxGTK except that wxSL_HORIZONTAL slider can only have
the label displayed on top or bottom of it and wxSL_VERTICAL - to the left
or right.
What we really need is probably a more fine grain control on labels, i.e. we
should be able to select if we show nothing at all, the current value only
or the value and the limits - the current approach is just that of the
lowest common denominator.
TODO:
+0. add ticks support
1. support for all orientations
2. draw the slider thumb highlighted when it is dragged
?3. manual ticks support?
*/
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_SLIDER
#include "wx/slider.h"
#ifndef WX_PRECOMP
#include "wx/dc.h"
#endif
#include "wx/univ/renderer.h"
#include "wx/univ/inphand.h"
#include "wx/univ/theme.h"
// ----------------------------------------------------------------------------
// wxStdSliderInputHandler: default slider input handling
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxStdSliderInputHandler : public wxStdInputHandler
{
public:
// default ctor
wxStdSliderInputHandler(wxInputHandler *inphand)
: wxStdInputHandler(inphand)
{
}
// base class methods
virtual bool HandleKey(wxInputConsumer *consumer,
const wxKeyEvent& event,
bool pressed);
virtual bool HandleMouse(wxInputConsumer *consumer,
const wxMouseEvent& event);
virtual bool HandleMouseMove(wxInputConsumer *consumer,
const wxMouseEvent& event);
virtual bool HandleFocus(wxInputConsumer *consumer, const wxFocusEvent& event);
};
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// the margin between the slider and the label (FIXME: hardcoded)
static const wxCoord SLIDER_LABEL_MARGIN = 2;
// ============================================================================
// implementation of wxSlider
// ============================================================================
BEGIN_EVENT_TABLE(wxSlider, wxControl)
EVT_SIZE(wxSlider::OnSize)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// wxSlider creation
// ----------------------------------------------------------------------------
#ifdef __VISUALC__
// warning C4355: 'this' : used in base member initializer list
#pragma warning(disable:4355)
#endif
wxSlider::wxSlider()
: m_thumb(this)
{
Init();
}
wxSlider::wxSlider(wxWindow *parent,
wxWindowID id,
int value, int minValue, int maxValue,
const wxPoint& pos,
const wxSize& size,
long style,
const wxValidator& validator,
const wxString& name)
: m_thumb(this)
{
Init();
(void)Create(parent, id, value, minValue, maxValue,
pos, size, style, validator, name);
}
#ifdef __VISUALC__
// warning C4355: 'this' : used in base member initializer list
#pragma warning(default:4355)
#endif
void wxSlider::Init()
{
m_min =
m_max =
m_value = 0;
m_tickFreq = 1;
m_lineSize =
m_pageSize = 0;
m_thumbSize = 0;
m_thumbFlags = 0;
}
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)
{
if ( !wxSliderBase::Create(parent, id, pos, size, style,
validator, name) )
return false;
SetRange(minValue, maxValue);
SetValue(value);
// call this after setting the range as the best size depends (at least if
// we have wxSL_LABELS style) on the range
SetInitialSize(size);
CreateInputHandler(wxINP_HANDLER_SLIDER);
return true;
}
// ----------------------------------------------------------------------------
// wxSlider range and value
// ----------------------------------------------------------------------------
int wxSlider::GetValue() const
{
return m_value;
}
int wxSlider::NormalizeValue(int value) const
{
if ( value < m_min )
return m_min;
else if ( value > m_max )
return m_max;
else
return value;
}
bool wxSlider::ChangeValueBy(int inc)
{
return ChangeValueTo(NormalizeValue(m_value + inc));
}
bool wxSlider::ChangeValueTo(int value)
{
// check if the value is going to change at all
if (value == m_value)
return false;
// this method is protected and we should only call it with normalized
// value!
wxCHECK_MSG( IsInRange(value), false, wxT("invalid slider value") );
m_value = value;
Refresh();
// generate the events: both a specific scroll event and a command event
wxScrollEvent eventScroll(wxEVT_SCROLL_CHANGED, GetId());
eventScroll.SetPosition(m_value);
eventScroll.SetEventObject( this );
(void)GetEventHandler()->ProcessEvent(eventScroll);
wxCommandEvent event(wxEVT_SLIDER, GetId());
event.SetInt(m_value);
event.SetEventObject(this);
(void)GetEventHandler()->ProcessEvent(event);
return true;
}
void wxSlider::SetValue(int value)
{
value = NormalizeValue(value);
if ( m_value != value )
{
m_value = value;
Refresh();
}
}
void wxSlider::SetRange(int minValue, int maxValue)
{
if ( minValue > maxValue )
{
// swap them, we always want min to be less than max
int tmp = minValue;
minValue = maxValue;
maxValue = tmp;
}
if ( m_min != minValue || m_max != maxValue )
{
m_min = minValue;
m_max = maxValue;
// reset the value to make sure it is in the new range
SetValue(m_value);
// the size of the label rect might have changed
if ( HasLabels() )
{
CalcGeometry();
}
Refresh();
}
//else: nothing changed
}
int wxSlider::GetMin() const
{
return m_min;
}
int wxSlider::GetMax() const
{
return m_max;
}
// ----------------------------------------------------------------------------
// wxSlider line/page/thumb size
// ----------------------------------------------------------------------------
void wxSlider::SetLineSize(int lineSize)
{
wxCHECK_RET( lineSize >= 0, wxT("invalid slider line size") );
m_lineSize = lineSize;
}
void wxSlider::SetPageSize(int pageSize)
{
wxCHECK_RET( pageSize >= 0, wxT("invalid slider page size") );
m_pageSize = pageSize;
}
int wxSlider::GetLineSize() const
{
if ( !m_lineSize )
{
// the default line increment is 1
wxConstCast(this, wxSlider)->m_lineSize = 1;
}
return m_lineSize;
}
int wxSlider::GetPageSize() const
{
if ( !m_pageSize )
{
// the default page increment is m_tickFreq
wxConstCast(this, wxSlider)->m_pageSize = m_tickFreq;
}
return m_pageSize;
}
void wxSlider::SetThumbLength(int lenPixels)
{
wxCHECK_RET( lenPixels >= 0, wxT("invalid slider thumb size") );
// use m_thumbSize here directly and not GetThumbLength() to avoid setting
// it to the default value as we don't need it
if ( lenPixels != m_thumbSize )
{
m_thumbSize = lenPixels;
Refresh();
}
}
int wxSlider::GetThumbLength() const
{
wxSize sz = GetDefaultThumbSize();
int len = (IsVert() ? sz.x : sz.y);
if (m_thumbSize > len)
{
return m_thumbSize;
}
else
{
return len;
}
}
// ----------------------------------------------------------------------------
// wxSlider ticks
// ----------------------------------------------------------------------------
void wxSlider::DoSetTickFreq(int n)
{
wxCHECK_RET (n > 0, wxT("invalid slider tick frequency"));
if ( n != m_tickFreq )
{
m_tickFreq = n;
Refresh();
}
}
// ----------------------------------------------------------------------------
// wxSlider geometry
// ----------------------------------------------------------------------------
wxSize wxSlider::CalcLabelSize() const
{
wxSize size;
// there is no sense in trying to calc the labels size if we haven't got
// any, the caller must check for it
wxCHECK_MSG( HasLabels(), size, wxT("shouldn't be called") );
wxCoord w1, h1, w2, h2;
GetTextExtent(FormatValue(m_min), &w1, &h1);
GetTextExtent(FormatValue(m_max), &w2, &h2);
size.x = wxMax(w1, w2);
size.y = wxMax(h1, h2);
return size;
}
wxSize wxSlider::DoGetBestClientSize() const
{
// this dimension is completely arbitrary
static const wxCoord SLIDER_WIDTH = 40;
long style = GetWindowStyle();
// first calculate the size of the slider itself: i.e. the shaft and the
// thumb
wxCoord height = GetRenderer()->GetSliderDim();
wxSize size;
if ( IsVert() )
{
size.x = height;
size.y = SLIDER_WIDTH;
}
else // horizontal
{
size.x = SLIDER_WIDTH;
size.y = height;
}
// add space for ticks
if ( HasTicks() )
{
wxCoord lenTick = GetRenderer()->GetSliderTickLen();
if (style & wxSL_BOTH)
{
lenTick = 2 * lenTick;
}
if ( IsVert() )
size.x += lenTick;
else
size.y += lenTick;
}
// if we have the label, reserve enough space for it
if ( HasLabels() )
{
wxSize sizeLabels = CalcLabelSize();
if (style & (wxSL_LEFT|wxSL_RIGHT))
{
size.x += sizeLabels.x + SLIDER_LABEL_MARGIN;
}
else if (style & (wxSL_TOP|wxSL_BOTTOM))
{
size.y += sizeLabels.y + SLIDER_LABEL_MARGIN;
}
}
return size;
}
void wxSlider::OnSize(wxSizeEvent& event)
{
CalcGeometry();
event.Skip();
}
const wxRect& wxSlider::GetSliderRect() const
{
if ( m_rectSlider.width < 0 )
{
wxConstCast(this, wxSlider)->CalcGeometry();
}
return m_rectSlider;
}
void wxSlider::CalcGeometry()
{
/*
recalc the label and slider positions, this looks like this for
wxSL_HORIZONTAL | wxSL_TOP slider:
LLL lll
-------------------------
| T | <-- this is the slider rect
| HHHHHHHHHHHHHHHTHHHHH |
| T |
| * * * * * * * *|
-------------------------
LLL is m_rectLabel as calculated here and lll is the real rect used for
label drawing in OnDraw() (TTT indicated the thumb position and *s are
the ticks)
in the wxSL_VERTICAL | wxSL_RIGHT case the picture is like this:
------ LLL
| H |
| H *|
| H |
| H *|
| H |
| H *|
| H |
|TTT*| lll
| H |
| H *|
------
*/
long style = GetWindowStyle();
// initialize to the full client rect
wxRect rectTotal = GetClientRect();
m_rectSlider = rectTotal;
wxSize sizeThumb = GetThumbSize();
// Labels reduce the size of the slider rect
if ( HasLabels() )
{
wxSize sizeLabels = CalcLabelSize();
m_rectLabel = wxRect(rectTotal.GetPosition(), sizeLabels);
if (style & wxSL_TOP)
{
// shrink and offset the slider to the bottom
m_rectSlider.y += sizeLabels.y + SLIDER_LABEL_MARGIN;
m_rectSlider.height -= sizeLabels.y + SLIDER_LABEL_MARGIN;
}
else if (style & wxSL_BOTTOM)
{
// shrink the slider and move the label to the bottom
m_rectSlider.height -= sizeLabels.y + SLIDER_LABEL_MARGIN;
m_rectLabel.y += m_rectSlider.height + SLIDER_LABEL_MARGIN;
}
else if (style & wxSL_LEFT)
{
// shrink and offset the slider to the right
m_rectSlider.x += sizeLabels.x + SLIDER_LABEL_MARGIN;
m_rectSlider.width -= sizeLabels.x + SLIDER_LABEL_MARGIN;
}
else if (style & wxSL_RIGHT)
{
// shrink the slider and move the label to the right
m_rectSlider.width -= sizeLabels.x + SLIDER_LABEL_MARGIN;
m_rectLabel.x += m_rectSlider.width + SLIDER_LABEL_MARGIN;
}
}
// calculate ticks too
if ( HasTicks() )
{
wxCoord lenTick = GetRenderer()->GetSliderTickLen();
// it
m_rectTicks = GetShaftRect();
if ( IsVert() )
{
if (style & (wxSL_LEFT|wxSL_BOTH))
{
m_rectTicks.x = m_rectSlider.x;
}
else
{ // wxSL_RIGHT
m_rectTicks.x = m_rectSlider.x + m_rectSlider.width - lenTick;
}
m_rectTicks.width = lenTick;
}
else // horizontal
{
if (style & (wxSL_TOP|wxSL_BOTH))
{
m_rectTicks.y = m_rectSlider.y;
}
else
{ // wxSL_BOTTOM
m_rectTicks.y = m_rectSlider.y + m_rectSlider.height - lenTick;
}
m_rectTicks.height = lenTick;
}
}
// slider is never smaller than thumb size unless rectTotal
if ( IsVert() )
{
wxCoord width = wxMin ( rectTotal.width, sizeThumb.x );
m_rectSlider.width = wxMax ( m_rectSlider.width, width );
}
else
{
wxCoord height = wxMin ( rectTotal.height, sizeThumb.y );
m_rectSlider.height = wxMax ( m_rectSlider.height, height );
}
}
wxSize wxSlider::GetDefaultThumbSize() const
{
// Default size has no styles (arrows)
return GetRenderer()->GetSliderThumbSize(GetSliderRect(), 0, GetOrientation());
}
wxSize wxSlider::GetThumbSize() const
{
return GetRenderer()->GetSliderThumbSize(GetSliderRect(), m_thumbSize, GetOrientation());
}
// ----------------------------------------------------------------------------
// wxSlider thumb geometry
// ----------------------------------------------------------------------------
wxRect wxSlider::GetShaftRect() const
{
return GetRenderer()->GetSliderShaftRect(m_rectSlider, m_thumbSize, GetOrientation(), GetWindowStyle());
}
void wxSlider::CalcThumbRect(const wxRect *rectShaftIn,
wxRect *rectThumbOut,
wxRect *rectLabelOut,
int value) const
{
if ( value == INVALID_THUMB_VALUE )
{
// use the current if not specified
value = m_value;
}
bool isVertical = IsVert();
wxRect rectShaft;
if ( rectShaftIn )
{
rectShaft = *rectShaftIn;
}
else // no shaft rect provided, calc it
{
rectShaft = GetShaftRect();
}
wxCoord lenShaft,
lenThumb;
wxCoord *p;
wxRect rectThumb(rectShaft.GetPosition(), GetThumbSize());
if ( isVertical )
{
rectThumb.x += (rectShaft.width - rectThumb.width) / 2;
lenThumb = rectThumb.height;
lenShaft = rectShaft.height;
p = &rectThumb.y;
}
else // horz
{
rectThumb.y += (rectShaft.height - rectThumb.height) / 2;
lenThumb = rectThumb.width;
lenShaft = rectShaft.width;
p = &rectThumb.x;
}
// the thumb must always be entirely inside the shaft limits, so the max
// position is not at lenShaft but at lenShaft - thumbSize
if ( m_max != m_min )
{
if ( isVertical )
{
*p += ((lenShaft - lenThumb)*(m_max - value))/(m_max - m_min);
}
else
{ // horz
*p += ((lenShaft - lenThumb)*(value - m_min))/(m_max - m_min);
}
}
// calc the label rect
if ( HasLabels() && rectLabelOut )
{
long style = GetWindowStyle();
wxRect rectLabel = m_rectLabel;
// centre the label relatively to the thumb position
if (style & (wxSL_TOP|wxSL_BOTTOM))
{
rectLabel.x = rectThumb.x + (rectThumb.width - m_rectLabel.width)/2;
}
else if (style & (wxSL_LEFT|wxSL_RIGHT))
{
rectLabel.y = rectThumb.y + (rectThumb.height - m_rectLabel.height)/2;
}
*rectLabelOut = rectLabel;
}
if ( rectThumbOut )
*rectThumbOut = rectThumb;
}
// ----------------------------------------------------------------------------
// wxSlider drawing
// ----------------------------------------------------------------------------
wxString wxSlider::FormatValue(int value) const
{
return wxString::Format(wxT("%d"), value);
}
void wxSlider::DoDraw(wxControlRenderer *renderer)
{
wxRenderer *rend = GetRenderer();
wxDC& dc = renderer->GetDC();
wxRect rectUpdate = GetUpdateClientRect();
wxOrientation orient = GetOrientation();
int flags = GetStateFlags();
long style = GetWindowStyle();
wxSize sz = GetThumbSize();
int len = IsVert() ? sz.x : sz.y;
// first draw the shaft
wxRect rectShaft = rend->GetSliderShaftRect(m_rectSlider, len, orient, style);
if ( rectUpdate.Intersects(rectShaft) )
{
rend->DrawSliderShaft(dc, m_rectSlider, len, orient, flags, style);
}
// calculate the thumb position in pixels and draw it
wxRect rectThumb, rectLabel;
CalcThumbRect(&rectShaft, &rectThumb, &rectLabel);
// then draw the ticks
if ( HasTicks() && rectUpdate.Intersects(m_rectTicks) )
{
rend->DrawSliderTicks(dc, m_rectSlider, len, orient,
m_min, m_max, m_tickFreq, flags, style);
}
// then draw the thumb
if ( rectUpdate.Intersects(rectThumb) )
{
rend->DrawSliderThumb(dc, rectThumb, orient, flags | m_thumbFlags, style);
}
// finally, draw the label near the thumb
if ( HasLabels() && rectUpdate.Intersects(rectLabel) )
{
// align it to be close to the shaft
int align = 0;
if (style & wxSL_TOP)
{
align = wxALIGN_CENTRE_HORIZONTAL|wxALIGN_TOP;
}
else if (style & wxSL_BOTTOM)
{
align = wxALIGN_CENTRE_HORIZONTAL|wxALIGN_BOTTOM;
}
else if (style & wxSL_LEFT)
{
align = wxALIGN_CENTRE_VERTICAL|wxALIGN_LEFT;
}
else if (style & wxSL_RIGHT)
{
align = wxALIGN_CENTRE_VERTICAL|wxALIGN_RIGHT;
}
dc.SetFont(GetFont());
dc.SetTextForeground(GetForegroundColour());
// the slider label is never drawn focused
rend->DrawLabel(dc, FormatValue(m_value), rectLabel,
flags & ~wxCONTROL_FOCUSED, align);
}
}
// ----------------------------------------------------------------------------
// wxSlider input processing
// ----------------------------------------------------------------------------
bool wxSlider::PerformAction(const wxControlAction& action,
long numArg,
const wxString& strArg)
{
wxEventType scrollEvent = wxEVT_NULL;
int value;
bool valueChanged = true;
if ( action == wxACTION_SLIDER_START )
{
scrollEvent = wxEVT_SCROLL_TOP;
value = m_min;
}
else if ( action == wxACTION_SLIDER_END )
{
scrollEvent = wxEVT_SCROLL_BOTTOM;
value = m_max;
}
else if ( action == wxACTION_SLIDER_PAGE_CHANGE )
{
value = NormalizeValue(m_value + numArg * GetPageSize());
}
else if ( action == wxACTION_SLIDER_LINE_UP )
{
scrollEvent = wxEVT_SCROLL_LINEUP;
value = NormalizeValue(m_value + +GetLineSize());
}
else if ( action == wxACTION_SLIDER_LINE_DOWN )
{
scrollEvent = wxEVT_SCROLL_LINEDOWN;
value = NormalizeValue(m_value + -GetLineSize());
}
else if ( action == wxACTION_SLIDER_PAGE_UP )
{
scrollEvent = wxEVT_SCROLL_PAGEUP;
value = NormalizeValue(m_value + +GetPageSize());
}
else if ( action == wxACTION_SLIDER_PAGE_DOWN )
{
scrollEvent = wxEVT_SCROLL_PAGEDOWN;
value = NormalizeValue(m_value + -GetPageSize());
}
else if ( action == wxACTION_SLIDER_THUMB_DRAG ||
action == wxACTION_SLIDER_THUMB_MOVE )
{
scrollEvent = wxEVT_SCROLL_THUMBTRACK;
// we shouldn't generate a command event about this change but we still
// should update our value and the slider appearance
valueChanged = false;
m_value =
value = (int)numArg;
Refresh();
}
else if ( action == wxACTION_SLIDER_THUMB_RELEASE )
{
scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
value = (int)numArg;
}
else
{
return wxControl::PerformAction(action, numArg, strArg);
}
// update wxSlider current value and generate wxCommandEvent, except while
// dragging the thumb
if ( valueChanged )
ChangeValueTo(value);
// also generate more precise wxScrollEvent if applicable
if ( scrollEvent != wxEVT_NULL )
{
wxScrollEvent event(scrollEvent, GetId());
event.SetPosition(value);
event.SetEventObject( this );
GetEventHandler()->ProcessEvent(event);
}
return true;
}
/* static */
wxInputHandler *wxSlider::GetStdInputHandler(wxInputHandler *handlerDef)
{
static wxStdSliderInputHandler s_handler(handlerDef);
return &s_handler;
}
// ----------------------------------------------------------------------------
// wxSlider implementation of wxControlWithThumb interface
// ----------------------------------------------------------------------------
wxScrollThumb::Shaft wxSlider::HitTest(const wxPoint& pt) const
{
wxRect rectShaft = GetShaftRect();
wxRect rectThumb;
CalcThumbRect(&rectShaft, &rectThumb, NULL);
// check for possible shaft or thumb hit
if (!rectShaft.Contains(pt) && !rectThumb.Contains(pt))
{
return wxScrollThumb::Shaft_None;
}
// the position to test and the start and end of the thumb
wxCoord x, x1, x2, x3, x4;
if (IsVert())
{
x = pt.y;
x1 = rectThumb.GetBottom();
x2 = rectShaft.GetBottom();
x3 = rectShaft.GetTop();
x4 = rectThumb.GetTop();
}
else
{ // horz
x = pt.x;
x1 = rectShaft.GetLeft();
x2 = rectThumb.GetLeft();
x3 = rectThumb.GetRight();
x4 = rectShaft.GetRight();
}
if ((x1 <= x) && (x < x2))
{
// or to the left
return wxScrollThumb::Shaft_Above;
}
if ((x3 < x) && (x <= x4)) {
// or to the right
return wxScrollThumb::Shaft_Below;
}
// where else can it be?
return wxScrollThumb::Shaft_Thumb;
}
wxCoord wxSlider::ThumbPosToPixel() const
{
wxRect rectThumb;
CalcThumbRect(NULL, &rectThumb, NULL);
return IsVert() ? rectThumb.y : rectThumb.x;
}
int wxSlider::PixelToThumbPos(wxCoord x) const
{
wxRect rectShaft = GetShaftRect();
wxSize sizeThumb = GetThumbSize();
wxCoord x0, len;
if ( IsVert() )
{
x0 = rectShaft.y;
len = rectShaft.height - sizeThumb.y;
}
else // horz
{
x0 = rectShaft.x;
len = rectShaft.width - sizeThumb.x;
}
int pos = m_min;
if ( len > 0 )
{
if ( x > x0 )
{
pos += ((x - x0) * (m_max - m_min)) / len;
if ( pos > m_max )
pos = m_max;
}
//else: x <= x0, leave pos = min
}
return pos;
}
void wxSlider::SetShaftPartState(wxScrollThumb::Shaft shaftPart,
int flag,
bool set)
{
// for now we ignore the flags for the shaft as no renderer uses them
// anyhow
if ( shaftPart == wxScrollThumb::Shaft_Thumb )
{
if ( set )
m_thumbFlags |= flag;
else
m_thumbFlags &= ~flag;
Refresh();
}
}
void wxSlider::OnThumbDragStart(int pos)
{
if (IsVert())
{
PerformAction(wxACTION_SLIDER_THUMB_DRAG, m_max - pos);
}
else
{
PerformAction(wxACTION_SLIDER_THUMB_DRAG, pos);
}
}
void wxSlider::OnThumbDrag(int pos)
{
if (IsVert())
{
PerformAction(wxACTION_SLIDER_THUMB_MOVE, m_max - pos);
}
else
{
PerformAction(wxACTION_SLIDER_THUMB_MOVE, pos);
}
}
void wxSlider::OnThumbDragEnd(int pos)
{
if (IsVert())
{
PerformAction(wxACTION_SLIDER_THUMB_RELEASE, m_max - pos);
}
else
{
PerformAction(wxACTION_SLIDER_THUMB_RELEASE, pos);
}
}
void wxSlider::OnPageScrollStart()
{
// we do nothing here
}
bool wxSlider::OnPageScroll(int pageInc)
{
int value = GetValue();
PerformAction(wxACTION_SLIDER_PAGE_CHANGE, pageInc);
return GetValue() != value;
}
// ----------------------------------------------------------------------------
// wxStdSliderInputHandler
// ----------------------------------------------------------------------------
bool wxStdSliderInputHandler::HandleKey(wxInputConsumer *consumer,
const wxKeyEvent& event,
bool pressed)
{
if ( pressed )
{
int keycode = event.GetKeyCode();
wxControlAction action;
switch ( keycode )
{
case WXK_HOME:
action = wxACTION_SLIDER_END;
break;
case WXK_END:
action = wxACTION_SLIDER_START;
break;
case WXK_RIGHT:
case WXK_UP:
action = wxACTION_SLIDER_LINE_UP;
break;
case WXK_LEFT:
case WXK_DOWN:
action = wxACTION_SLIDER_LINE_DOWN;
break;
case WXK_PAGEUP:
action = wxACTION_SLIDER_PAGE_UP;
break;
case WXK_PAGEDOWN:
action = wxACTION_SLIDER_PAGE_DOWN;
break;
}
if ( !action.IsEmpty() )
{
consumer->PerformAction(action);
return true;
}
}
return wxStdInputHandler::HandleKey(consumer, event, pressed);
}
bool wxStdSliderInputHandler::HandleMouse(wxInputConsumer *consumer,
const wxMouseEvent& event)
{
wxSlider *slider = wxStaticCast(consumer->GetInputWindow(), wxSlider);
if ( slider->GetThumb().HandleMouse(event) )
{
// processed by the thumb
return false;
}
return wxStdInputHandler::HandleMouse(consumer, event);
}
bool wxStdSliderInputHandler::HandleMouseMove(wxInputConsumer *consumer,
const wxMouseEvent& event)
{
wxSlider *slider = wxStaticCast(consumer->GetInputWindow(), wxSlider);
if ( slider->GetThumb().HandleMouseMove(event) )
{
// processed by the thumb
return false;
}
return wxStdInputHandler::HandleMouseMove(consumer, event);
}
bool
wxStdSliderInputHandler::HandleFocus(wxInputConsumer * WXUNUSED(consumer),
const wxFocusEvent& WXUNUSED(event))
{
// slider appearance changes when it gets/loses focus
return true;
}
#endif // wxUSE_SLIDER