From 6766e5d1368b2231500e320cd082332a63b15a3c Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Fri, 24 Jan 2003 11:23:52 +0000 Subject: [PATCH] Applied patch [ 621451 ] Fixed version of wxSlider class Otto Wyss This patch corrects several bugs in the wxSlider class for the wxUniversal/MSW port. It affects the files "slider.h", "slider.cpp", "win32.cpp" and "gtk.cpp" (and others). The slider should now work as expected. A simple test program can be downloaded from "http://dpartialmirror.sourceforge.net/Test/". git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18897 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/univ/renderer.h | 42 ++-- include/wx/univ/slider.h | 8 +- src/univ/slider.cpp | 338 ++++++++++++++++--------------- src/univ/themes/gtk.cpp | 29 ++- src/univ/themes/win32.cpp | 395 ++++++++++++++++++++++++------------- 5 files changed, 492 insertions(+), 320 deletions(-) diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index f6fe94b515..e11bf8c883 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -228,25 +228,29 @@ public: // 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, @@ -405,10 +409,13 @@ public: // 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) @@ -637,25 +644,29 @@ public: 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, @@ -778,11 +789,14 @@ public: 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 diff --git a/include/wx/univ/slider.h b/include/wx/univ/slider.h index a5e51055f0..729f68b562 100644 --- a/include/wx/univ/slider.h +++ b/include/wx/univ/slider.h @@ -95,10 +95,14 @@ public: { 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; } diff --git a/src/univ/slider.cpp b/src/univ/slider.cpp index 8381f531a6..adfa70db53 100644 --- a/src/univ/slider.cpp +++ b/src/univ/slider.cpp @@ -183,21 +183,16 @@ bool wxSlider::ChangeValueBy(int 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, _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()); @@ -266,14 +261,14 @@ int wxSlider::GetMax() const 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; } @@ -293,8 +288,8 @@ int wxSlider::GetPageSize() const { 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; @@ -302,7 +297,7 @@ int wxSlider::GetPageSize() const 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 @@ -316,13 +311,17 @@ void wxSlider::SetThumbLength(int lenPixels) 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; } // ---------------------------------------------------------------------------- @@ -331,6 +330,8 @@ int wxSlider::GetThumbLength() const void wxSlider::SetTickFreq(int n, int WXUNUSED(dummy)) { + wxCHECK_RET (n > 0, _T("invalid slider tick frequency")); + if ( n != m_tickFreq ) { m_tickFreq = n; @@ -364,7 +365,9 @@ wxSize wxSlider::CalcLabelSize() const 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 @@ -386,6 +389,10 @@ wxSize wxSlider::DoGetBestClientSize() const if ( HasTicks() ) { wxCoord lenTick = GetRenderer()->GetSliderTickLen(); + if (style & wxSL_BOTH) + { + lenTick = 2 * lenTick; + } if ( IsVert() ) size.x += lenTick; @@ -398,10 +405,14 @@ wxSize wxSlider::DoGetBestClientSize() const { 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; @@ -457,110 +468,102 @@ void wxSlider::CalcGeometry() | 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()); } // ---------------------------------------------------------------------------- @@ -569,7 +572,7 @@ wxSize wxSlider::GetThumbSize() const 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, @@ -620,30 +623,37 @@ 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; } @@ -662,47 +672,57 @@ void wxSlider::DoDraw(wxControlRenderer *renderer) 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()); @@ -714,18 +734,6 @@ void wxSlider::DoDraw(wxControlRenderer *renderer) } } -void wxSlider::RefreshThumb() -{ - wxRect rectThumb, rectLabel; - CalcThumbRect(NULL, &rectThumb, &rectLabel); - - Refresh(TRUE /* erase background */, &rectThumb); - if ( HasLabels() ) - { - Refresh(TRUE, &rectLabel); - } -} - // ---------------------------------------------------------------------------- // wxSlider input processing // ---------------------------------------------------------------------------- @@ -734,7 +742,7 @@ bool wxSlider::PerformAction(const wxControlAction& action, long numArg, const wxString& strArg) { - if ( action == wxACTION_SLIDER_START ) + if ( action == wxACTION_SLIDER_START ) { ChangeValueTo(m_min); } @@ -748,19 +756,19 @@ bool wxSlider::PerformAction(const wxControlAction& action, } 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 ) { @@ -790,36 +798,37 @@ wxScrollThumb::Shaft wxSlider::HitTest(const wxPoint& pt) const 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; } @@ -881,23 +890,44 @@ void wxSlider::SetShaftPartState(wxScrollThumb::Shaft shaftPart, 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() @@ -921,7 +951,7 @@ bool wxStdSliderButtonInputHandler::HandleKey(wxInputConsumer *consumer, const wxKeyEvent& event, bool pressed) { - if ( pressed ) + if ( pressed ) { int keycode = event.GetKeyCode(); @@ -929,19 +959,19 @@ bool wxStdSliderButtonInputHandler::HandleKey(wxInputConsumer *consumer, 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; diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index b3a5c59d4a..9ad98cbcd5 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -184,21 +184,25 @@ public: 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 } @@ -305,8 +309,11 @@ public: 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); } @@ -1865,13 +1872,14 @@ void wxGTKRenderer::DrawTab(wxDC& dc, // ---------------------------------------------------------------------------- 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); @@ -1887,15 +1895,19 @@ wxSize wxGTKRenderer::GetSliderThumbSize(const wxRect& rect, } 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; @@ -1922,7 +1934,8 @@ void wxGTKRenderer::DrawSliderShaft(wxDC& dc, void wxGTKRenderer::DrawSliderThumb(wxDC& dc, const wxRect& rectOrig, wxOrientation orient, - int flags) + int flags, + long style) { // draw the thumb border wxRect rect = rectOrig; diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index 085a672638..9dfdf2fc88 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -80,6 +80,10 @@ static const size_t WIDTH_STATUSBAR_GRIP_BAND = 4; 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, @@ -253,21 +257,25 @@ public: 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, @@ -366,11 +374,14 @@ public: 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); } @@ -2571,52 +2582,80 @@ void wxWin32Renderer::DrawTab(wxDC& dc, // ---------------------------------------------------------------------------- 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; @@ -2624,19 +2663,37 @@ wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig, 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); } @@ -2644,26 +2701,31 @@ void wxWin32Renderer::DrawSliderShaft(wxDC& dc, 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. @@ -2671,51 +2733,81 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc, 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__) @@ -2757,73 +2849,80 @@ void wxWin32Renderer::DrawSliderThumb(wxDC& dc, 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); + } } // ---------------------------------------------------------------------------- @@ -3987,6 +4086,18 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window) 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; } -- 2.47.2