// draw the slider shaft
virtual void DrawSliderShaft(wxDC& dc,
const wxRect& rect,
+ int lenThumb,
wxOrientation orient,
int flags = 0,
+ long style = 0,
wxRect *rectShaft = NULL) = 0;
// draw the slider thumb
virtual void DrawSliderThumb(wxDC& dc,
const wxRect& rect,
wxOrientation orient,
- int flags = 0) = 0;
+ int flags = 0,
+ long style = 0) = 0;
// draw the slider ticks
virtual void DrawSliderTicks(wxDC& dc,
const wxRect& rect,
- const wxSize& sizeThumb,
+ int lenThumb,
wxOrientation orient,
int start,
int end,
int step = 1,
- int flags = 0) = 0;
+ int flags = 0,
+ long style = 0) = 0;
// draw a menu bar item
virtual void DrawMenuBarItem(wxDC& dc,
// get the slider shaft rect from the total slider rect
virtual wxRect GetSliderShaftRect(const wxRect& rect,
- wxOrientation orient) const = 0;
+ int lenThumb,
+ wxOrientation orient,
+ long style = 0) const = 0;
// get the size of the slider thumb for the given total slider rect
virtual wxSize GetSliderThumbSize(const wxRect& rect,
+ int lenThumb,
wxOrientation orient) const = 0;
// get the size of one progress bar step (in horz and vertical directions)
virtual void DrawSliderShaft(wxDC& dc,
const wxRect& rect,
+ int lenThumb,
wxOrientation orient,
int flags = 0,
+ long style = 0,
wxRect *rectShaft = NULL)
- { m_renderer->DrawSliderShaft(dc, rect, orient, flags, rectShaft); }
+ { m_renderer->DrawSliderShaft(dc, rect, lenThumb, orient, flags, style, rectShaft); }
virtual void DrawSliderThumb(wxDC& dc,
const wxRect& rect,
wxOrientation orient,
- int flags = 0)
- { m_renderer->DrawSliderThumb(dc, rect, orient, flags); }
+ int flags = 0,
+ long style = 0)
+ { m_renderer->DrawSliderThumb(dc, rect, orient, flags, style); }
virtual void DrawSliderTicks(wxDC& dc,
const wxRect& rect,
- const wxSize& sizeThumb,
+ int lenThumb,
wxOrientation orient,
int start,
int end,
int step = 1,
- int flags = 0)
- { m_renderer->DrawSliderTicks(dc, rect, sizeThumb, orient,
- start, end, step, flags); }
+ int flags = 0,
+ long style = 0)
+ { m_renderer->DrawSliderTicks(dc, rect, lenThumb, orient,
+ start, end, start, flags, style); }
virtual void DrawMenuBarItem(wxDC& dc,
const wxRect& rect,
virtual wxCoord GetSliderTickLen() const
{ return m_renderer->GetSliderTickLen(); }
virtual wxRect GetSliderShaftRect(const wxRect& rect,
- wxOrientation orient) const
- { return m_renderer->GetSliderShaftRect(rect, orient); }
+ int lenThumb,
+ wxOrientation orient,
+ long style = 0) const
+ { return m_renderer->GetSliderShaftRect(rect, lenThumb, orient, style); }
virtual wxSize GetSliderThumbSize(const wxRect& rect,
+ int lenThumb,
wxOrientation orient) const
- { return m_renderer->GetSliderThumbSize(rect, orient); }
+ { return m_renderer->GetSliderThumbSize(rect, lenThumb, orient); }
virtual wxSize GetProgressBarStep() const
{ return m_renderer->GetProgressBarStep(); }
virtual wxSize GetMenuBarItemSize(const wxSize& sizeText) const
{ return IsVert() ? wxVERTICAL : wxHORIZONTAL; }
// do we have labels?
- bool HasLabels() const { return (GetWindowStyle() & wxSL_LABELS) != 0; }
+ bool HasLabels() const
+ { return ((GetWindowStyle() & wxSL_LABELS) != 0) &
+ ((GetWindowStyle() & (wxSL_TOP|wxSL_BOTTOM|wxSL_LEFT|wxSL_RIGHT)) != 0); }
// do we have ticks?
- bool HasTicks() const { return (GetWindowStyle() & wxSL_TICKS) != 0; }
+ bool HasTicks() const
+ { return ((GetWindowStyle() & wxSL_TICKS) != 0) &
+ ((GetWindowStyle() & (wxSL_TOP|wxSL_BOTTOM|wxSL_LEFT|wxSL_RIGHT|wxSL_BOTH)) != 0); }
// implement wxControlWithThumb interface
virtual wxWindow *GetWindow() { return this; }
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, _T("invalid slider value") );
- // check if the value is going to change at all
- if ( value == m_value )
- return FALSE;
-
- // refresh the old thumb position
- RefreshThumb();
-
m_value = value;
- // and the new one
- RefreshThumb();
+ Refresh();
// generate the event
wxCommandEvent event(wxEVT_COMMAND_SLIDER_UPDATED, GetId());
void wxSlider::SetLineSize(int lineSize)
{
- wxCHECK_RET( lineSize > 0, _T("invalid slider line size") );
+ wxCHECK_RET( lineSize >= 0, _T("invalid slider line size") );
m_lineSize = lineSize;
}
void wxSlider::SetPageSize(int pageSize)
{
- wxCHECK_RET( pageSize > 0, _T("invalid slider page size") );
+ wxCHECK_RET( pageSize >= 0, _T("invalid slider page size") );
m_pageSize = pageSize;
}
{
if ( !m_pageSize )
{
- // the default page increment is 1/10 of the range
- wxConstCast(this, wxSlider)->m_pageSize = (m_max - m_min) / 10;
+ // 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, _T("invalid slider thumb size") );
+ wxCHECK_RET( lenPixels >= 0, _T("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
int wxSlider::GetThumbLength() const
{
- if ( !m_thumbSize )
+ wxSize sz = GetDefaultThumbSize();
+ int len = (IsVert() ? sz.x : sz.y);
+ if (m_thumbSize > len)
+ {
+ return m_thumbSize;
+ }
+ else
{
- wxSize sz = GetDefaultThumbSize();
- return IsVert() ? sz.y : sz.x;
+ return len;
}
- return m_thumbSize;
}
// ----------------------------------------------------------------------------
void wxSlider::SetTickFreq(int n, int WXUNUSED(dummy))
{
+ wxCHECK_RET (n > 0, _T("invalid slider tick frequency"));
+
if ( n != m_tickFreq )
{
m_tickFreq = n;
wxSize wxSlider::DoGetBestClientSize() const
{
// this dimension is completely arbitrary
- static const wxCoord SLIDER_WIDTH = 100;
+ static const wxCoord SLIDER_WIDTH = 40;
+
+ long style = GetWindowStyle();
// first calculate the size of the slider itself: i.e. the shaft and the
// thumb
if ( HasTicks() )
{
wxCoord lenTick = GetRenderer()->GetSliderTickLen();
+ if (style & wxSL_BOTH)
+ {
+ lenTick = 2 * lenTick;
+ }
if ( IsVert() )
size.x += lenTick;
{
wxSize sizeLabels = CalcLabelSize();
- if ( IsVert() )
+ if (style & (wxSL_LEFT|wxSL_RIGHT))
+ {
size.x += sizeLabels.x + SLIDER_LABEL_MARGIN;
- else
+ }
+ else if (style & (wxSL_TOP|wxSL_BOTTOM))
+ {
size.y += sizeLabels.y + SLIDER_LABEL_MARGIN;
+ }
}
return size;
| 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();
+ wxSize sizeLabels = CalcLabelSize();
- m_rectSlider = rectTotal;
m_rectLabel = wxRect(rectTotal.GetPosition(), sizeLabels);
- // split the rect
- if ( IsVert() )
+ if (style & wxSL_TOP)
{
- sizeLabels.x += SLIDER_LABEL_MARGIN;
-
- if ( GetWindowStyle() & wxSL_LEFT )
- {
- // shrink and offset the slider to the right
- m_rectSlider.x += sizeLabels.x;
- m_rectSlider.width -= sizeLabels.x;
- }
- else // wxSL_RIGHT
- {
- // just shrink the slider and move the label to the right
- m_rectSlider.width -= sizeLabels.x;
-
- m_rectLabel.x += m_rectSlider.width + SLIDER_LABEL_MARGIN;
- }
+ // 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 // horizontal
+ else if (style & wxSL_BOTTOM)
{
- // same logic as above but x/y are trasnposed
- sizeLabels.y += SLIDER_LABEL_MARGIN;
-
- if ( GetWindowStyle() & wxSL_TOP )
- {
- m_rectSlider.y += sizeLabels.y;
- m_rectSlider.height -= sizeLabels.y;
- }
- else // wxSL_BOTTOM
- {
- m_rectSlider.height -= sizeLabels.y;
-
- m_rectLabel.y += m_rectSlider.height + SLIDER_LABEL_MARGIN;
- }
+ // 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;
}
- }
- else // no labels
- {
- // the slider takes the whole client rect
- m_rectSlider = rectTotal;
}
- // now adjust for ticks too
+ // calculate ticks too
if ( HasTicks() )
{
wxCoord lenTick = GetRenderer()->GetSliderTickLen();
- if ( IsVert() )
- {
- m_rectSlider.width -= lenTick;
- }
- else // horizontal
- {
- m_rectSlider.height -= lenTick;
- }
-
- // note that we must compute m_rectSlider first as GetShaftRect() uses
// it
m_rectTicks = GetShaftRect();
if ( IsVert() )
{
- m_rectTicks.x = m_rectSlider.x + m_rectSlider.width;
+ 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
{
- m_rectTicks.y = m_rectSlider.y + m_rectSlider.height;
+ 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
{
- return GetRenderer()->GetSliderThumbSize(GetSliderRect(), GetOrientation());
+ // Default size has no styles (arrows)
+ return GetRenderer()->GetSliderThumbSize(GetSliderRect(), 0, GetOrientation());
}
wxSize wxSlider::GetThumbSize() const
{
- wxSize sizeThumb = GetDefaultThumbSize();
-
- // if we have our own thumb length (set by the user), use it instead of the
- // default value
- if ( m_thumbSize )
- {
- if ( IsVert() )
- sizeThumb.y = m_thumbSize;
- else
- sizeThumb.x = m_thumbSize;
- }
-
- return sizeThumb;
+ return GetRenderer()->GetSliderThumbSize(GetSliderRect(), m_thumbSize, GetOrientation());
}
// ----------------------------------------------------------------------------
wxRect wxSlider::GetShaftRect() const
{
- return GetRenderer()->GetSliderShaftRect(m_rectSlider, GetOrientation());
+ return GetRenderer()->GetSliderShaftRect(m_rectSlider, m_thumbSize, GetOrientation(), GetWindowStyle());
}
void wxSlider::CalcThumbRect(const wxRect *rectShaftIn,
// position is not at lenShaft but at lenShaft - thumbSize
if ( m_max != m_min )
{
- *p += ((lenShaft - lenThumb)*(value - m_min))/(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 ( isVertical )
+ if (style & (wxSL_TOP|wxSL_BOTTOM))
{
- rectLabel.y =
- rectThumb.y + (rectThumb.height - m_rectLabel.height)/2;
+ rectLabel.x = rectThumb.x + (rectThumb.width - m_rectLabel.width)/2;
}
- else // horz
+ else if (style & (wxSL_LEFT|wxSL_RIGHT))
{
- rectLabel.x =
- rectThumb.x + (rectThumb.width - m_rectLabel.width)/2;
+ rectLabel.y = rectThumb.y + (rectThumb.height - m_rectLabel.height)/2;
}
*rectLabelOut = rectLabel;
}
if ( rectThumbOut )
+
*rectThumbOut = rectThumb;
}
wxDC& dc = renderer->GetDC();
wxRect rectUpdate = GetUpdateClientRect();
- bool isVertical = IsVert();
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, orient);
+ wxRect rectShaft = rend->GetSliderShaftRect(m_rectSlider, len, orient, style);
if ( rectUpdate.Intersects(rectShaft) )
{
- rend->DrawSliderShaft(dc, m_rectSlider, orient, flags);
+ 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);
- if ( rectUpdate.Intersects(rectThumb) )
+ // then draw the ticks
+ if ( HasTicks() && rectUpdate.Intersects(m_rectTicks) )
{
- rend->DrawSliderThumb(dc, rectThumb, orient, flags | m_thumbFlags);
+ rend->DrawSliderTicks(dc, m_rectSlider, len, orient,
+ m_min, m_max, m_tickFreq, flags, style);
}
- // then draw the ticks
- if ( HasTicks() && rectUpdate.Intersects(m_rectTicks) )
+ // then draw the thumb
+ if ( rectUpdate.Intersects(rectThumb) )
{
- rend->DrawSliderTicks(dc, m_rectTicks, rectThumb.GetSize(), orient,
- m_min, m_max, m_tickFreq);
+ 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;
- if ( isVertical )
+ int align = 0;
+ if (style & wxSL_TOP)
{
- align = wxALIGN_CENTRE_VERTICAL |
- (GetWindowStyle() & wxSL_RIGHT ? wxALIGN_LEFT
- : wxALIGN_RIGHT);
+ align = wxALIGN_CENTRE_HORIZONTAL|wxALIGN_TOP;
}
- else // horz
+ else if (style & wxSL_BOTTOM)
{
- align = wxALIGN_CENTRE;
+ 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());
}
}
-void wxSlider::RefreshThumb()
-{
- wxRect rectThumb, rectLabel;
- CalcThumbRect(NULL, &rectThumb, &rectLabel);
-
- Refresh(TRUE /* erase background */, &rectThumb);
- if ( HasLabels() )
- {
- Refresh(TRUE, &rectLabel);
- }
-}
-
// ----------------------------------------------------------------------------
// wxSlider input processing
// ----------------------------------------------------------------------------
long numArg,
const wxString& strArg)
{
- if ( action == wxACTION_SLIDER_START )
+ if ( action == wxACTION_SLIDER_START )
{
ChangeValueTo(m_min);
}
}
else if ( action == wxACTION_SLIDER_LINE_UP )
{
- ChangeValueBy(-GetLineSize());
+ ChangeValueBy(+GetLineSize());
}
- else if ( action == wxACTION_SLIDER_PAGE_UP )
+ else if ( action == wxACTION_SLIDER_LINE_DOWN )
{
- return PerformAction(wxACTION_SLIDER_PAGE_CHANGE, -1);
+ ChangeValueBy(-GetLineSize());
}
- else if ( action == wxACTION_SLIDER_LINE_DOWN )
+ else if ( action == wxACTION_SLIDER_PAGE_UP )
{
- ChangeValueBy(GetLineSize());
+ ChangeValueBy(+GetPageSize());
}
else if ( action == wxACTION_SLIDER_PAGE_DOWN )
{
- return PerformAction(wxACTION_SLIDER_PAGE_CHANGE, 1);
+ ChangeValueBy(-GetPageSize());
}
else if ( action == wxACTION_SLIDER_THUMB_DRAG )
{
wxRect rectThumb;
CalcThumbRect(&rectShaft, &rectThumb, NULL);
- // check for possible shaft or thumb hit
- if (!rectShaft.Inside(pt) && !rectThumb.Inside(pt))
+ // check for possible shaft or thumb hit
+ if (!rectShaft.Inside(pt) && !rectThumb.Inside(pt))
{
return wxScrollThumb::Shaft_None;
}
-
// the position to test and the start and end of the thumb
- wxCoord x, x1, x2;
- if ( IsVert() )
+ wxCoord x, x1, x2, x3, x4;
+ if (IsVert())
{
x = pt.y;
- x1 = rectThumb.GetTop();
- x2 = rectThumb.GetBottom();
+ x1 = rectThumb.GetBottom();
+ x2 = rectShaft.GetBottom();
+ x3 = rectShaft.GetTop();
+ x4 = rectThumb.GetTop();
}
- else // horz
- {
+ else
+ { // horz
x = pt.x;
- x1 = rectThumb.GetLeft();
- x2 = rectThumb.GetRight();
+ x1 = rectShaft.GetLeft();
+ x2 = rectThumb.GetLeft();
+ x3 = rectThumb.GetRight();
+ x4 = rectShaft.GetRight();
}
-
- if ( x < x1 )
+ if ((x1 <= x) & (x < x2))
{
// or to the left
return wxScrollThumb::Shaft_Above;
}
- if ( x > x2 )
- {
+ if ((x3 < x) & (x <= x4)) {
// or to the right
return wxScrollThumb::Shaft_Below;
}
else
m_thumbFlags &= ~flag;
- RefreshThumb();
+ Refresh();
}
}
void wxSlider::OnThumbDragStart(int pos)
{
- PerformAction(wxACTION_SLIDER_THUMB_DRAG, pos);
+ if (IsVert())
+ {
+ PerformAction(wxACTION_SLIDER_THUMB_DRAG, m_max - pos);
+ }
+ else
+ {
+ PerformAction(wxACTION_SLIDER_THUMB_DRAG, pos);
+ }
}
void wxSlider::OnThumbDrag(int pos)
{
- PerformAction(wxACTION_SLIDER_THUMB_MOVE, pos);
+ if (IsVert())
+ {
+ PerformAction(wxACTION_SLIDER_THUMB_MOVE, m_max - pos);
+ }
+ else
+ {
+ PerformAction(wxACTION_SLIDER_THUMB_MOVE, pos);
+ }
}
void wxSlider::OnThumbDragEnd(int pos)
{
- PerformAction(wxACTION_SLIDER_THUMB_RELEASE, pos);
+ if (IsVert())
+ {
+ PerformAction(wxACTION_SLIDER_THUMB_RELEASE, m_max - pos);
+ }
+ else
+ {
+ PerformAction(wxACTION_SLIDER_THUMB_RELEASE, pos);
+ }
}
void wxSlider::OnPageScrollStart()
const wxKeyEvent& event,
bool pressed)
{
- if ( pressed )
+ if ( pressed )
{
int keycode = event.GetKeyCode();
switch ( keycode )
{
case WXK_HOME:
- action = wxACTION_SLIDER_START;
+ action = wxACTION_SLIDER_END;
break;
case WXK_END:
- action = wxACTION_SLIDER_END;
+ action = wxACTION_SLIDER_START;
break;
- case WXK_LEFT:
+ case WXK_RIGHT:
case WXK_UP:
action = wxACTION_SLIDER_LINE_UP;
break;
- case WXK_RIGHT:
+ case WXK_LEFT:
case WXK_DOWN:
action = wxACTION_SLIDER_LINE_DOWN;
break;
virtual void DrawSliderShaft(wxDC& dc,
const wxRect& rect,
+ int lenThumb,
wxOrientation orient,
int flags = 0,
+ long style = 0,
wxRect *rectShaft = NULL);
virtual void DrawSliderThumb(wxDC& dc,
const wxRect& rect,
wxOrientation orient,
- int flags = 0);
+ int flags = 0,
+ long style = 0);
virtual void DrawSliderTicks(wxDC& dc,
const wxRect& rect,
- const wxSize& sizeThumb,
+ int lenThumb,
wxOrientation orient,
int start,
int end,
- int step,
- int flags)
+ int step = 1,
+ int flags = 0,
+ long style = 0)
{
// we don't have the ticks in GTK version
}
virtual wxCoord GetSliderDim() const { return 15; }
virtual wxCoord GetSliderTickLen() const { return 0; }
virtual wxRect GetSliderShaftRect(const wxRect& rect,
- wxOrientation orient) const;
+ int lenThumb,
+ wxOrientation orient,
+ long style = 0) const;
virtual wxSize GetSliderThumbSize(const wxRect& rect,
+ int lenThumb,
wxOrientation orient) const;
virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
// ----------------------------------------------------------------------------
wxSize wxGTKRenderer::GetSliderThumbSize(const wxRect& rect,
+ int lenThumb,
wxOrientation orient) const
{
static const wxCoord SLIDER_THUMB_LENGTH = 30;
wxSize size;
- wxRect rectShaft = GetSliderShaftRect(rect, orient);
+ wxRect rectShaft = GetSliderShaftRect(rect, lenThumb, orient);
if ( orient == wxHORIZONTAL )
{
size.x = wxMin(SLIDER_THUMB_LENGTH, rectShaft.width);
}
wxRect wxGTKRenderer::GetSliderShaftRect(const wxRect& rect,
- wxOrientation WXUNUSED(orient)) const
+ int lenThumb,
+ wxOrientation WXUNUSED(orient),
+ long style) const
{
return rect.Deflate(2*BORDER_THICKNESS, 2*BORDER_THICKNESS);
}
void wxGTKRenderer::DrawSliderShaft(wxDC& dc,
const wxRect& rectOrig,
+ int lenThumb,
wxOrientation orient,
int flags,
+ long style,
wxRect *rectShaft)
{
wxRect rect = rectOrig;
void wxGTKRenderer::DrawSliderThumb(wxDC& dc,
const wxRect& rectOrig,
wxOrientation orient,
- int flags)
+ int flags,
+ long style)
{
// draw the thumb border
wxRect rect = rectOrig;
static const size_t STATUSBAR_GRIP_SIZE =
WIDTH_STATUSBAR_GRIP_BAND*NUM_STATUSBAR_GRIP_BANDS;
+static const wxCoord SLIDER_MARGIN = 6; // margin around slider
+static const wxCoord SLIDER_THUMB_LENGTH = 18;
+static const wxCoord SLIDER_TICK_LENGTH = 6;
+
enum IndicatorType
{
IndicatorType_Check,
virtual void DrawSliderShaft(wxDC& dc,
const wxRect& rect,
+ int lenThumb,
wxOrientation orient,
int flags = 0,
+ long style = 0,
wxRect *rectShaft = NULL);
virtual void DrawSliderThumb(wxDC& dc,
const wxRect& rect,
wxOrientation orient,
- int flags = 0);
+ int flags = 0,
+ long style = 0);
virtual void DrawSliderTicks(wxDC& dc,
const wxRect& rect,
- const wxSize& sizeThumb,
+ int lenThumb,
wxOrientation orient,
int start,
int end,
int step = 1,
- int flags = 0);
+ int flags = 0,
+ long style = 0);
virtual void DrawMenuBarItem(wxDC& dc,
const wxRect& rect,
virtual wxSize GetTabIndent() const { return wxSize(2, 2); }
virtual wxSize GetTabPadding() const { return wxSize(6, 5); }
- virtual wxCoord GetSliderDim() const { return 20; }
- virtual wxCoord GetSliderTickLen() const { return 4; }
+ virtual wxCoord GetSliderDim() const { return SLIDER_THUMB_LENGTH + 2*BORDER_THICKNESS; }
+ virtual wxCoord GetSliderTickLen() const { return SLIDER_TICK_LENGTH; }
virtual wxRect GetSliderShaftRect(const wxRect& rect,
- wxOrientation orient) const;
+ int lenThumb,
+ wxOrientation orient,
+ long style = 0) const;
virtual wxSize GetSliderThumbSize(const wxRect& rect,
+ int lenThumb,
wxOrientation orient) const;
virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
// ----------------------------------------------------------------------------
wxSize wxWin32Renderer::GetSliderThumbSize(const wxRect& rect,
+ int lenThumb,
wxOrientation orient) const
{
wxSize size;
+ wxCoord width = wxMax (lenThumb, SLIDER_THUMB_LENGTH) / 2;
+ wxCoord height = wxMax (lenThumb, SLIDER_THUMB_LENGTH);
- wxRect rectShaft = GetSliderShaftRect(rect, orient);
- if ( orient == wxHORIZONTAL )
+ if (orient == wxHORIZONTAL)
{
- size.y = rect.height - 6;
- size.x = wxMin(size.y / 2, rectShaft.width);
+ size.x = width;
+ size.y = height;
}
- else // vertical
- {
- size.x = rect.width - 6;
- size.y = wxMin(size.x / 2, rectShaft.height);
+ else
+ { // == wxVERTICAL
+ size.x = height;
+ size.y = width;
}
return size;
}
wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
- wxOrientation orient) const
+ int lenThumb,
+ wxOrientation orient,
+ long style) const
{
- static const wxCoord SLIDER_MARGIN = 6;
+ bool transpose = (orient == wxVERTICAL);
+ bool left = ((style & wxSL_AUTOTICKS) != 0) &
+ (((style & wxSL_TOP) != 0) & !transpose |
+ ((style & wxSL_LEFT) != 0) & transpose |
+ ((style & wxSL_BOTH) != 0));
+ bool right = ((style & wxSL_AUTOTICKS) != 0) &
+ (((style & wxSL_BOTTOM) != 0) & !transpose |
+ ((style & wxSL_RIGHT) != 0) & transpose |
+ ((style & wxSL_BOTH) != 0));
wxRect rect = rectOrig;
- if ( orient == wxHORIZONTAL )
- {
- // make the rect of minimal width and centre it
- rect.height = 2*BORDER_THICKNESS;
- rect.y = rectOrig.y + (rectOrig.height - rect.height) / 2;
- if ( rect.y < 0 )
- rect.y = 0;
+ wxSize sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
- // leave margins on the sides
- rect.Deflate(SLIDER_MARGIN, 0);
+ if (orient == wxHORIZONTAL) {
+ rect.x += SLIDER_MARGIN;
+ if (left & right)
+ {
+ rect.y += wxMax ((rect.height - 2*BORDER_THICKNESS) / 2, sizeThumb.y/2);
+ }
+ else if (left)
+ {
+ rect.y += wxMax ((rect.height - 2*BORDER_THICKNESS - sizeThumb.y/2), sizeThumb.y/2);
+ }
+ else
+ {
+ rect.y += sizeThumb.y/2;
+ }
+ rect.width -= 2*SLIDER_MARGIN;
+ rect.height = 2*BORDER_THICKNESS;
}
- else // vertical
- {
- // same as above but in other direction
+ else
+ { // == wxVERTICAL
+ rect.y += SLIDER_MARGIN;
+ if (left & right)
+ {
+ rect.x += wxMax ((rect.width - 2*BORDER_THICKNESS) / 2, sizeThumb.x/2);
+ }
+ else if (left)
+ {
+ rect.x += wxMax ((rect.width - 2*BORDER_THICKNESS - sizeThumb.x/2), sizeThumb.x/2);
+ }
+ else
+ {
+ rect.x += sizeThumb.x/2;
+ }
rect.width = 2*BORDER_THICKNESS;
- rect.x = rectOrig.x + (rectOrig.width - rect.width) / 2;
- if ( rect.x < 0 )
- rect.x = 0;
-
- rect.Deflate(0, SLIDER_MARGIN);
+ rect.height -= 2*SLIDER_MARGIN;
}
return rect;
void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
const wxRect& rectOrig,
+ int lenThumb,
wxOrientation orient,
int flags,
+ long style,
wxRect *rectShaft)
{
- if ( flags & wxCONTROL_FOCUSED )
- {
+ /* show shaft geometry
+
+ shaft
+ +-------------+
+ | |
+ | XXX | <-- x1
+ | XXX |
+ | XXX |
+ | XXX |
+ | XXX | <-- x2
+ | |
+ +-------------+
+
+ ^ ^
+ | |
+ y1 y2
+ */
+
+ if (flags & wxCONTROL_FOCUSED) {
DrawFocusRect(dc, rectOrig);
}
- wxRect rect = GetSliderShaftRect(rectOrig, orient);
+ wxRect rect = GetSliderShaftRect(rectOrig, lenThumb, orient, style);
- if ( rectShaft )
- *rectShaft = rect;
+ if (rectShaft) *rectShaft = rect;
DrawSunkenBorder(dc, &rect);
}
void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
const wxRect& rect,
wxOrientation orient,
- int flags)
+ int flags,
+ long style)
{
- /*
- we are drawing a shape of this form
-
- HHHHHHB <--- y
- H DB
- H DB
- H DB where H is hightlight colour
- H DB D dark grey
- H DB B black
- H DB
- H DB <--- y3
- H DB
- HDB
- B <--- y2
-
- ^ ^ ^
- | | |
- x x3 x2
+ /* show thumb geometry
+
+ H <--- y1
+ H H B
+ H H B
+ H H B <--- y3
+ H D B
+ H D B
+ H D B
+ H D B where H is hightlight colour
+ H D B D dark grey
+ H D B B black
+ H D B
+ H D B
+ H D B <--- y4
+ H D B
+ H D B
+ B <--- y2
+
+ ^ ^ ^
+ | | |
+ x1 x3 x2
The interior of this shape is filled with the hatched brush if the thumb
is pressed.
DrawBackground(dc, wxNullColour, rect, flags);
- bool transpose = orient == wxVERTICAL;
+ bool transpose = (orient == wxVERTICAL);
+ bool left = ((style & wxSL_AUTOTICKS) != 0) &
+ (((style & wxSL_TOP) != 0) & !transpose |
+ ((style & wxSL_LEFT) != 0) & transpose) &
+ ((style & wxSL_BOTH) == 0);
+ bool right = ((style & wxSL_AUTOTICKS) != 0) &
+ (((style & wxSL_BOTTOM) != 0) & !transpose |
+ ((style & wxSL_RIGHT) != 0) & transpose) &
+ ((style & wxSL_BOTH) == 0);
+
+ wxCoord sizeArrow = (transpose ? rect.height : rect.width) / 2;
+ wxCoord c = ((transpose ? rect.height : rect.width) - 2*sizeArrow);
+
+ wxCoord x1, x2, x3, y1, y2, y3, y4;
+ x1 = (transpose ? rect.y : rect.x);
+ x2 = (transpose ? rect.GetBottom() : rect.GetRight());
+ x3 = (x1-1+c) + sizeArrow;
+ y1 = (transpose ? rect.x : rect.y);
+ y2 = (transpose ? rect.GetRight() : rect.GetBottom());
+ y3 = (left ? (y1-1+c) + sizeArrow : y1);
+ y4 = (right ? (y2+1-c) - sizeArrow : y2);
- wxCoord x, y, x2, y2;
- if ( transpose )
+ dc.SetPen(m_penBlack);
+ if (left) {
+ DrawLine(dc, x3+1-c, y1, x2, y3, transpose);
+ }
+ DrawLine(dc, x2, y3, x2, y4, transpose);
+ if (right)
{
- x = rect.y;
- y = rect.x;
- x2 = rect.GetBottom();
- y2 = rect.GetRight();
+ DrawLine(dc, x3+1-c, y2, x2, y4, transpose);
}
else
{
- x = rect.x;
- y = rect.y;
- x2 = rect.GetRight();
- y2 = rect.GetBottom();
+ DrawLine(dc, x1, y2, x2, y2, transpose);
}
- // the size of the pointed part of the thumb
- wxCoord sizeArrow = (transpose ? rect.height : rect.width) / 2;
-
- wxCoord x3 = x + sizeArrow,
- y3 = y2 - sizeArrow;
-
- dc.SetPen(m_penHighlight);
- DrawLine(dc, x, y, x2, y, transpose);
- DrawLine(dc, x, y + 1, x, y2 - sizeArrow, transpose);
- DrawLine(dc, x, y3, x3, y2, transpose);
-
- dc.SetPen(m_penBlack);
- DrawLine(dc, x3, y2, x2, y3, transpose);
- DrawLine(dc, x2, y3, x2, y - 1, transpose);
-
dc.SetPen(m_penDarkGrey);
- DrawLine(dc, x3, y2 - 1, x2 - 1, y3, transpose);
- DrawLine(dc, x2 - 1, y3, x2 - 1, y, transpose);
+ DrawLine(dc, x2-1, y3+1, x2-1, y4-1, transpose);
+ if (right) {
+ DrawLine(dc, x3+1-c, y2-1, x2-1, y4, transpose);
+ }
+ else
+ {
+ DrawLine(dc, x1+1, y2-1, x2-1, y2-1, transpose);
+ }
- if ( flags & wxCONTROL_PRESSED )
+ dc.SetPen(m_penHighlight);
+ if (left)
+ {
+ DrawLine(dc, x1, y3, x3, y1, transpose);
+ DrawLine(dc, x3+1-c, y1+1, x2-1, y3, transpose);
+ }
+ else
+ {
+ DrawLine(dc, x1, y1, x2, y1, transpose);
+ }
+ DrawLine(dc, x1, y3, x1, y4, transpose);
+ if (right)
{
+ DrawLine(dc, x1, y4, x3+c, y2+c, transpose);
+ }
+
+ if (flags & wxCONTROL_PRESSED) {
// TODO: MSW fills the entire area inside, not just the rect
wxRect rectInt = rect;
- if ( transpose )
- rectInt.SetRight(y3);
+ if ( transpose )
+ {
+ rectInt.SetLeft(y3);
+ rectInt.SetRight(y4);
+ }
else
- rectInt.SetBottom(y3);
+ {
+ rectInt.SetTop(y3);
+ rectInt.SetBottom(y4);
+ }
rectInt.Deflate(2);
#if !defined(__WXMGL__)
void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
const wxRect& rect,
- const wxSize& sizeThumb,
+ int lenThumb,
wxOrientation orient,
int start,
int end,
int step,
- int flags)
+ int flags,
+ long style)
{
- if ( end == start )
- {
- // empty slider?
- return;
- }
-
- // this would lead to an infinite loop below
- wxCHECK_RET( step > 1, _T("invalid step in wxRenderer::DrawSliderTicks") );
-
- // the variable names correspond to horizontal case, but they can be used
- // for both orientations
- wxCoord x1, x2, y1, y2, len, widthThumb;
- if ( orient == wxHORIZONTAL )
- {
- x1 = rect.GetLeft();
- x2 = rect.GetRight();
-
- // draw from bottom to top to leave one pixel space between the ticks
- // and the slider as Windows do
- y1 = rect.GetBottom();
- y2 = rect.GetTop();
-
- len = rect.width;
-
- widthThumb = sizeThumb.x;
- }
- else // vertical
- {
- x1 = rect.GetTop();
- x2 = rect.GetBottom();
-
- y1 = rect.GetRight();
- y2 = rect.GetLeft();
-
- len = rect.height;
-
- widthThumb = sizeThumb.y;
- }
-
- // the first tick should be positioned in such way that a thumb drawn in
- // the first position points down directly to it
- x1 += widthThumb / 2;
- x2 -= widthThumb / 2;
+ /* show ticks geometry
+
+ left right
+ ticks shaft ticks
+ ---- XX ---- <-- x1
+ ---- XX ----
+ ---- XX ----
+ ---- XX ---- <-- x2
+
+ ^ ^ ^ ^
+ | | | |
+ y3 y1 y2 y4
+ */
- // this also means that we have slightly less space for the ticks in
- // between the first and the last
- len -= widthThumb;
+ // empty slider?
+ if (end == start) return;
+
+ bool transpose = (orient == wxVERTICAL);
+ bool left = ((style & wxSL_AUTOTICKS) != 0) &
+ (((style & wxSL_TOP) != 0) & !transpose |
+ ((style & wxSL_LEFT) != 0) & transpose |
+ ((style & wxSL_BOTH) != 0));
+ bool right = ((style & wxSL_AUTOTICKS) != 0) &
+ (((style & wxSL_BOTTOM) != 0) & !transpose |
+ ((style & wxSL_RIGHT) != 0) & transpose |
+ ((style & wxSL_BOTH) != 0));
+
+ // default thumb size
+ wxSize sizeThumb = GetSliderThumbSize (rect, 0, orient);
+ wxCoord defaultLen = (transpose ? sizeThumb.x : sizeThumb.y);
+
+ // normal thumb size
+ sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
+ wxCoord widthThumb = (transpose ? sizeThumb.y : sizeThumb.x);
+
+ wxRect rectShaft = GetSliderShaftRect (rect, lenThumb, orient, style);
+
+ wxCoord x1, x2, y1, y2, y3, y4 , len;
+ x1 = (transpose ? rectShaft.y : rectShaft.x) + widthThumb/2;
+ x2 = (transpose ? rectShaft.GetBottom() : rectShaft.GetRight()) - widthThumb/2;
+ y1 = (transpose ? rectShaft.x : rectShaft.y) - defaultLen/2;
+ y2 = (transpose ? rectShaft.GetRight() : rectShaft.GetBottom()) + defaultLen/2;
+ y3 = (transpose ? rect.x : rect.y);
+ y4 = (transpose ? rect.GetRight() : rect.GetBottom());
+ len = x2 - x1;
dc.SetPen(m_penBlack);
int range = end - start;
- for ( int n = 0; n < range; n += step )
- {
+ for ( int n = 0; n < range; n += step ) {
wxCoord x = x1 + (len*n) / range;
- DrawLine(dc, x, y1, x, y2, orient == wxVERTICAL);
+ if (left & (y1 > y3)) {
+ DrawLine(dc, x, y1, x, y3, orient == wxVERTICAL);
+ }
+ if (right & (y4 > y2)) {
+ DrawLine(dc, x, y2, x, y4, orient == wxVERTICAL);
+ }
}
-
// always draw the line at the end position
- DrawLine(dc, x2, y1, x2, y2, orient == wxVERTICAL);
+ if (left & (y1 > y3)) {
+ DrawLine(dc, x2, y1, x2, y3, orient == wxVERTICAL);
+ }
+ if (right & (y4 > y2)) {
+ DrawLine(dc, x2, y2, x2, y4, orient == wxVERTICAL);
+ }
}
// ----------------------------------------------------------------------------
size->y += 9;
}
+ // for compatibility with other ports, the buttons default size is never
+ // less than the standard one, but not when display not PDAs.
+ if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA)
+ {
+ if ( !(window->GetWindowStyle() & wxBU_EXACTFIT) )
+ {
+ wxSize szDef = wxButton::GetDefaultSize();
+ if ( size->x < szDef.x )
+ size->x = szDef.x;
+ }
+ }
+
// no border width adjustments for buttons
return;
}