1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/stdrend.cpp
3 // Purpose: implementation of wxStdRenderer
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
29 #include "wx/univ/stdrend.h"
30 #include "wx/univ/colschem.h"
32 // ============================================================================
33 // wxStdRenderer implementation
34 // ============================================================================
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 wxStdRenderer::wxStdRenderer(const wxColourScheme
*scheme
)
43 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
));
44 m_penDarkGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_OUT
));
45 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
));
46 m_penHighlight
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
));
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
54 wxStdRenderer::DrawSolidRect(wxDC
& dc
, const wxColour
& col
, const wxRect
& rect
)
56 wxBrush
brush(col
, wxSOLID
);
58 dc
.SetPen(*wxTRANSPARENT_PEN
);
59 dc
.DrawRectangle(rect
);
62 void wxStdRenderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
66 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
67 dc
.DrawRectangle(*rect
);
73 void wxStdRenderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
74 const wxPen
& pen1
, const wxPen
& pen2
)
78 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
79 rect
->GetLeft(), rect
->GetBottom());
80 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
81 rect
->GetRight(), rect
->GetTop());
83 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
84 rect
->GetRight(), rect
->GetBottom());
85 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
86 rect
->GetRight() + 1, rect
->GetBottom());
92 // ----------------------------------------------------------------------------
93 // translate various flags into corresponding renderer constants
94 // ----------------------------------------------------------------------------
97 void wxStdRenderer::GetIndicatorsFromFlags(int flags
,
98 IndicatorState
& state
,
99 IndicatorStatus
& status
)
101 if ( flags
& wxCONTROL_SELECTED
)
102 state
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
103 : IndicatorState_Selected
;
104 else if ( flags
& wxCONTROL_DISABLED
)
105 state
= IndicatorState_Disabled
;
106 else if ( flags
& wxCONTROL_PRESSED
)
107 state
= IndicatorState_Pressed
;
109 state
= IndicatorState_Normal
;
111 status
= flags
& wxCONTROL_CHECKED
? IndicatorStatus_Checked
112 : flags
& wxCONTROL_UNDETERMINED
113 ? IndicatorStatus_Undetermined
114 : IndicatorStatus_Unchecked
;
118 wxStdRenderer::ArrowDirection
wxStdRenderer::GetArrowDirection(wxDirection dir
)
135 wxFAIL_MSG(_T("unknown arrow direction"));
141 // ----------------------------------------------------------------------------
143 // ----------------------------------------------------------------------------
145 void wxStdRenderer::DrawBackground(wxDC
& dc
,
151 wxColour colBg
= col
.Ok() ? col
152 : window
? m_scheme
->GetBackground(window
)
153 : wxSCHEME_COLOUR(m_scheme
, CONTROL
);
155 DrawSolidRect(dc
, colBg
, rect
);
159 void wxStdRenderer::DrawButtonSurface(wxDC
& dc
,
164 DrawBackground(dc
, col
, rect
, flags
);
167 // ----------------------------------------------------------------------------
169 // ----------------------------------------------------------------------------
171 void wxStdRenderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
173 // draw the pixels manually because the "dots" in wxPen with wxDOT style
174 // may be short traits and not really dots
176 // note that to behave in the same manner as DrawRect(), we must exclude
177 // the bottom and right borders from the rectangle
178 wxCoord x1
= rect
.GetLeft(),
180 x2
= rect
.GetRight(),
181 y2
= rect
.GetBottom();
183 dc
.SetPen(m_penBlack
);
185 // this seems to be closer than what Windows does than wxINVERT although
186 // I'm still not sure if it's correct
187 dc
.SetLogicalFunction(wxAND_REVERSE
);
190 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
191 dc
.DrawPoint(z
, rect
.GetTop());
193 wxCoord shift
= z
== x2
? 0 : 1;
194 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
197 shift
= z
== y2
? 0 : 1;
198 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
201 shift
= z
== x1
? 0 : 1;
202 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
205 dc
.SetLogicalFunction(wxCOPY
);
208 void wxStdRenderer::DrawLabel(wxDC
& dc
,
209 const wxString
& label
,
216 DrawButtonLabel(dc
, label
, wxNullBitmap
, rect
, flags
,
217 alignment
, indexAccel
, rectBounds
);
220 void wxStdRenderer::DrawButtonLabel(wxDC
& dc
,
221 const wxString
& label
,
222 const wxBitmap
& image
,
229 wxRect rectLabel
= rect
;
230 if ( !label
.empty() && (flags
& wxCONTROL_DISABLED
) )
232 if ( flags
& wxCONTROL_PRESSED
)
234 // shift the label if a button is pressed
235 rectLabel
.Offset(1, 1);
238 // draw shadow of the text
239 dc
.SetTextForeground(m_penHighlight
.GetColour());
240 wxRect rectShadow
= rect
;
241 rectShadow
.Offset(1, 1);
242 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
244 // make the main label text grey
245 dc
.SetTextForeground(m_penDarkGrey
.GetColour());
247 if ( flags
& wxCONTROL_FOCUSED
)
249 // leave enough space for the focus rect
250 rectLabel
.Inflate(-2);
254 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
256 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
258 rectLabel
.Inflate(-1);
260 DrawFocusRect(dc
, rectLabel
);
264 // ----------------------------------------------------------------------------
266 // ----------------------------------------------------------------------------
269 We implement standard-looking 3D borders which have the following appearance:
273 WWWWWWWWWWWWWWWWWWWWWWB
274 WHHHHHHHHHHHHHHHHHHHHGB
275 WH GB W = white (HILIGHT)
276 WH GB H = light grey (LIGHT)
277 WH GB G = dark grey (SHADOI)
278 WH GB B = black (DKSHADOI)
281 WGGGGGGGGGGGGGGGGGGGGGB
282 BBBBBBBBBBBBBBBBBBBBBBB
284 The sunken border looks like this:
286 GGGGGGGGGGGGGGGGGGGGGGW
287 GBBBBBBBBBBBBBBBBBBBBHW
294 GHHHHHHHHHHHHHHHHHHHHHW
295 WWWWWWWWWWWWWWWWWWWWWWW
297 The static border (used for the controls which don't get focus) is like
300 GGGGGGGGGGGGGGGGGGGGGGW
308 WWWWWWWWWWWWWWWWWWWWWWW
310 The most complicated is the double border which is a combination of special
311 "anti-sunken" border and an extra border inside it:
313 HHHHHHHHHHHHHHHHHHHHHHB
314 HWWWWWWWWWWWWWWWWWWWWGB
315 HWHHHHHHHHHHHHHHHHHHHGB
320 HWHHHHHHHHHHHHHHHHHHHGB
321 HGGGGGGGGGGGGGGGGGGGGGB
322 BBBBBBBBBBBBBBBBBBBBBBB
324 And the simple border is, well, simple:
326 BBBBBBBBBBBBBBBBBBBBBBB
335 BBBBBBBBBBBBBBBBBBBBBBB
338 void wxStdRenderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
340 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
341 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
344 void wxStdRenderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
346 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
347 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
350 void wxStdRenderer::DrawAntiSunkenBorder(wxDC
& dc
, wxRect
*rect
)
352 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
353 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
356 void wxStdRenderer::DrawFrameBorder(wxDC
& dc
, wxRect
*rect
)
358 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
359 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
362 void wxStdRenderer::DrawBorder(wxDC
& dc
,
364 const wxRect
& rectTotal
,
368 wxRect rect
= rectTotal
;
372 case wxBORDER_SUNKEN
:
373 DrawSunkenBorder(dc
, &rect
);
376 case wxBORDER_DOUBLE
:
377 DrawAntiSunkenBorder(dc
, &rect
);
378 DrawRect(dc
, &rect
, m_penLightGrey
);
381 case wxBORDER_STATIC
:
382 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
385 case wxBORDER_RAISED
:
386 DrawRaisedBorder(dc
, &rect
);
389 case wxBORDER_SIMPLE
:
390 DrawRect(dc
, &rect
, m_penBlack
);
394 wxFAIL_MSG(_T("unknown border type"));
397 case wxBORDER_DEFAULT
:
406 wxRect
wxStdRenderer::GetBorderDimensions(wxBorder border
) const
411 case wxBORDER_SIMPLE
:
412 case wxBORDER_STATIC
:
416 case wxBORDER_RAISED
:
417 case wxBORDER_SUNKEN
:
421 case wxBORDER_DOUBLE
:
426 wxFAIL_MSG(_T("unknown border type"));
429 case wxBORDER_DEFAULT
:
444 void wxStdRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
446 // take into account the border width
447 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
448 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
449 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
452 bool wxStdRenderer::AreScrollbarsInsideBorder() const
457 wxCoord
wxStdRenderer::GetListboxItemHeight(wxCoord fontHeight
)
459 return fontHeight
+ 2;
462 void wxStdRenderer::DrawTextBorder(wxDC
& dc
,
468 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
471 // ----------------------------------------------------------------------------
473 // ----------------------------------------------------------------------------
476 wxStdRenderer::DrawHorizontalLine(wxDC
& dc
, wxCoord y
, wxCoord x1
, wxCoord x2
)
478 dc
.SetPen(m_penDarkGrey
);
479 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
481 dc
.SetPen(m_penHighlight
);
483 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
487 wxStdRenderer::DrawVerticalLine(wxDC
& dc
, wxCoord x
, wxCoord y1
, wxCoord y2
)
489 dc
.SetPen(m_penDarkGrey
);
490 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
492 dc
.SetPen(m_penHighlight
);
494 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
497 void wxStdRenderer::DrawFrameWithoutLabel(wxDC
& dc
,
498 const wxRect
& rectFrame
,
499 const wxRect
& rectLabel
)
501 // draw left, bottom and right lines entirely
502 DrawVerticalLine(dc
, rectFrame
.GetLeft(),
503 rectFrame
.GetTop(), rectFrame
.GetBottom() - 2);
504 DrawHorizontalLine(dc
, rectFrame
.GetBottom() - 1,
505 rectFrame
.GetLeft(), rectFrame
.GetRight());
506 DrawVerticalLine(dc
, rectFrame
.GetRight() - 1,
507 rectFrame
.GetTop(), rectFrame
.GetBottom() - 1);
509 // and 2 parts of the top line
510 DrawHorizontalLine(dc
, rectFrame
.GetTop(),
511 rectFrame
.GetLeft() + 1, rectLabel
.GetLeft());
512 DrawHorizontalLine(dc
, rectFrame
.GetTop(),
513 rectLabel
.GetRight(), rectFrame
.GetRight() - 2);
516 void wxStdRenderer::DrawFrameWithLabel(wxDC
& dc
,
517 const wxString
& label
,
518 const wxRect
& rectFrame
,
519 const wxRect
& rectText
,
525 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
527 DrawFrameWithoutLabel(dc
, rectFrame
, rectLabel
);
530 void wxStdRenderer::DrawFrame(wxDC
& dc
,
531 const wxString
& label
,
537 wxCoord height
= 0; // of the label
538 wxRect rectFrame
= rect
;
539 if ( !label
.empty() )
541 // the text should touch the top border of the rect, so the frame
542 // itself should be lower
543 dc
.GetTextExtent(label
, NULL
, &height
);
544 rectFrame
.y
+= height
/ 2;
545 rectFrame
.height
-= height
/ 2;
547 // we have to draw each part of the frame individually as we can't
548 // erase the background beyond the label as it might contain some
549 // pixmap already, so drawing everything and then overwriting part of
550 // the frame with label doesn't work
552 // TODO: the +5 shouldn't be hard coded
554 rectText
.x
= rectFrame
.x
+ 5;
556 rectText
.width
= rectFrame
.width
- 7; // +2 border width
557 rectText
.height
= height
;
559 DrawFrameWithLabel(dc
, label
, rectFrame
, rectText
, flags
,
560 alignment
, indexAccel
);
564 DrawFrameBorder(dc
, &rectFrame
);
568 void wxStdRenderer::DrawItem(wxDC
& dc
,
569 const wxString
& label
,
573 wxDCTextColourChanger
colChanger(dc
);
575 if ( flags
& wxCONTROL_SELECTED
)
577 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
579 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
582 dc
.DrawRectangle(rect
);
585 wxRect rectText
= rect
;
588 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
590 if ( flags
& wxCONTROL_FOCUSED
)
592 DrawFocusRect(dc
, rect
);
596 void wxStdRenderer::DrawCheckItemBitmap(wxDC
& dc
,
597 const wxBitmap
& bitmap
,
601 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rect
, flags
);
604 void wxStdRenderer::DrawCheckItem(wxDC
& dc
,
605 const wxString
& label
,
606 const wxBitmap
& bitmap
,
610 wxRect rectBitmap
= rect
;
611 rectBitmap
.width
= GetCheckBitmapSize().x
;
612 DrawCheckItemBitmap(dc
, bitmap
, rectBitmap
, flags
);
614 wxRect rectLabel
= rect
;
615 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
616 rectLabel
.x
+= shift
;
617 rectLabel
.width
-= shift
;
618 DrawItem(dc
, label
, rectLabel
, flags
);
621 // ----------------------------------------------------------------------------
622 // check and radio bitmaps
623 // ----------------------------------------------------------------------------
625 void wxStdRenderer::DrawCheckButton(wxDC
& dc
,
626 const wxString
& label
,
627 const wxBitmap
& bitmap
,
633 wxBitmap
bmp(bitmap
.Ok() ? bitmap
: GetCheckBitmap(flags
));
635 DrawCheckOrRadioButton(dc
, label
, bmp
, rect
, flags
, align
, indexAccel
);
638 void wxStdRenderer::DrawRadioButton(wxDC
& dc
,
639 const wxString
& label
,
640 const wxBitmap
& bitmap
,
646 wxBitmap
bmp(bitmap
.Ok() ? bitmap
: GetRadioBitmap(flags
));
648 DrawCheckOrRadioButton(dc
, label
, bmp
, rect
, flags
, align
, indexAccel
);
651 void wxStdRenderer::DrawCheckOrRadioButton(wxDC
& dc
,
652 const wxString
& label
,
653 const wxBitmap
& bitmap
,
659 // calculate the position of the bitmap and of the label
660 wxCoord heightBmp
= bitmap
.GetHeight();
662 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
665 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
666 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
668 // align label vertically with the bitmap - looks nicer like this
669 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
671 // calc horz position
672 if ( align
== wxALIGN_RIGHT
)
674 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
675 rectLabel
.x
= rect
.x
+ 3;
676 rectLabel
.SetRight(xBmp
);
678 else // normal (checkbox to the left of the text) case
681 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
682 rectLabel
.SetRight(rect
.GetRight());
685 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
687 DrawLabel(dc
, label
, rectLabel
, flags
,
688 wxALIGN_LEFT
| wxALIGN_TOP
, indexAccel
);
693 void wxStdRenderer::DrawTextLine(wxDC
& dc
,
694 const wxString
& text
,
700 if ( (selStart
== -1) || !(flags
& wxCONTROL_FOCUSED
) )
702 // just draw it as is
703 dc
.DrawText(text
, rect
.x
, rect
.y
);
705 else // we have selection
710 // draw the part before selection
711 wxString
s(text
, (size_t)selStart
);
714 dc
.DrawText(s
, x
, rect
.y
);
716 dc
.GetTextExtent(s
, &width
, NULL
);
720 // draw the selection itself
721 s
= wxString(text
.c_str() + selStart
, text
.c_str() + selEnd
);
724 wxColour colFg
= dc
.GetTextForeground(),
725 colBg
= dc
.GetTextBackground();
726 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
727 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
));
728 dc
.SetBackgroundMode(wxSOLID
);
730 dc
.DrawText(s
, x
, rect
.y
);
731 dc
.GetTextExtent(s
, &width
, NULL
);
734 dc
.SetBackgroundMode(wxTRANSPARENT
);
735 dc
.SetTextBackground(colBg
);
736 dc
.SetTextForeground(colFg
);
739 // draw the final part
740 s
= text
.c_str() + selEnd
;
743 dc
.DrawText(s
, x
, rect
.y
);
748 void wxStdRenderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
749 const wxRect
& WXUNUSED(rect
))
751 // nothing by default
754 int wxStdRenderer::GetTextBorderWidth(const wxTextCtrl
* WXUNUSED(text
)) const
760 wxStdRenderer::GetTextTotalArea(const wxTextCtrl
*text
, const wxRect
& rect
) const
762 wxRect rectTotal
= rect
;
763 rectTotal
.Inflate(GetTextBorderWidth(text
));
767 wxRect
wxStdRenderer::GetTextClientArea(const wxTextCtrl
*text
,
769 wxCoord
*extraSpaceBeyond
) const
771 wxRect rectText
= rect
;
772 rectText
.Deflate(GetTextBorderWidth(text
));
774 if ( extraSpaceBeyond
)
775 *extraSpaceBeyond
= 0;
780 #endif // wxUSE_TEXTCTRL
782 // ----------------------------------------------------------------------------
783 // scrollbars drawing
784 // ----------------------------------------------------------------------------
786 void wxStdRenderer::DrawScrollbarArrow(wxDC
& dc
,
791 DrawArrow(dc
, dir
, rect
, flags
);
794 void wxStdRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
796 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
799 // ----------------------------------------------------------------------------
800 // scrollbars geometry
801 // ----------------------------------------------------------------------------
806 void wxStdRenderer::GetScrollBarThumbSize(wxCoord length
,
813 // the thumb can't be made less than this number of pixels
814 static const wxCoord thumbMinWidth
= 8; // FIXME: should be configurable
816 *thumbStart
= (length
*thumbPos
) / range
;
817 *thumbEnd
= (length
*(thumbPos
+ thumbSize
)) / range
;
819 if ( *thumbEnd
- *thumbStart
< thumbMinWidth
)
821 // adjust the end if possible
822 if ( *thumbStart
<= length
- thumbMinWidth
)
824 // yes, just make it wider
825 *thumbEnd
= *thumbStart
+ thumbMinWidth
;
827 else // it is at the bottom of the scrollbar
829 // so move it a bit up
830 *thumbStart
= length
- thumbMinWidth
;
836 wxRect
wxStdRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
837 wxScrollBar::Element elem
,
840 if ( thumbPos
== -1 )
842 thumbPos
= scrollbar
->GetThumbPosition();
845 const wxSize sizeArrow
= GetScrollbarArrowSize();
847 wxSize sizeTotal
= scrollbar
->GetClientSize();
848 wxCoord
*start
, *width
;
849 wxCoord length
, arrow
;
851 if ( scrollbar
->IsVertical() )
854 rect
.width
= sizeTotal
.x
;
855 length
= sizeTotal
.y
;
857 width
= &rect
.height
;
863 rect
.height
= sizeTotal
.y
;
864 length
= sizeTotal
.x
;
872 case wxScrollBar::Element_Arrow_Line_1
:
877 case wxScrollBar::Element_Arrow_Line_2
:
878 *start
= length
- arrow
;
882 case wxScrollBar::Element_Arrow_Page_1
:
883 case wxScrollBar::Element_Arrow_Page_2
:
884 // we don't have them at all
887 case wxScrollBar::Element_Thumb
:
888 case wxScrollBar::Element_Bar_1
:
889 case wxScrollBar::Element_Bar_2
:
890 // we need to calculate the thumb position - do it
893 wxCoord thumbStart
, thumbEnd
;
894 int range
= scrollbar
->GetRange();
902 GetScrollBarThumbSize(length
,
904 scrollbar
->GetThumbSize(),
910 if ( elem
== wxScrollBar::Element_Thumb
)
913 *width
= thumbEnd
- thumbStart
;
915 else if ( elem
== wxScrollBar::Element_Bar_1
)
920 else // elem == wxScrollBar::Element_Bar_2
923 *width
= length
- thumbEnd
;
926 // everything is relative to the start of the shaft so far
931 case wxScrollBar::Element_Max
:
933 wxFAIL_MSG( _T("unknown scrollbar element") );
939 wxCoord
wxStdRenderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
941 const wxSize sizeArrowSB
= GetScrollbarArrowSize();
943 wxCoord sizeArrow
, sizeTotal
;
944 if ( scrollbar
->GetWindowStyle() & wxVERTICAL
)
946 sizeArrow
= sizeArrowSB
.y
;
947 sizeTotal
= scrollbar
->GetSize().y
;
951 sizeArrow
= sizeArrowSB
.x
;
952 sizeTotal
= scrollbar
->GetSize().x
;
955 return sizeTotal
- 2*sizeArrow
;
959 wxStdRenderer::HitTestScrollbar(const wxScrollBar
*scrollbar
, const wxPoint
& pt
) const
961 // we only need to work with either x or y coord depending on the
962 // orientation, choose one (but still check the other one to verify if the
963 // mouse is in the window at all)
964 const wxSize sizeArrowSB
= GetScrollbarArrowSize();
966 wxCoord coord
, sizeArrow
, sizeTotal
;
967 wxSize size
= scrollbar
->GetSize();
968 if ( scrollbar
->GetWindowStyle() & wxVERTICAL
)
970 if ( pt
.x
< 0 || pt
.x
> size
.x
)
974 sizeArrow
= sizeArrowSB
.y
;
979 if ( pt
.y
< 0 || pt
.y
> size
.y
)
983 sizeArrow
= sizeArrowSB
.x
;
987 // test for the arrows first as it's faster
988 if ( coord
< 0 || coord
> sizeTotal
)
992 else if ( coord
< sizeArrow
)
994 return wxHT_SCROLLBAR_ARROW_LINE_1
;
996 else if ( coord
> sizeTotal
- sizeArrow
)
998 return wxHT_SCROLLBAR_ARROW_LINE_2
;
1002 // calculate the thumb position in pixels
1003 sizeTotal
-= 2*sizeArrow
;
1004 wxCoord thumbStart
, thumbEnd
;
1005 int range
= scrollbar
->GetRange();
1008 // clicking the scrollbar without range has no effect
1009 return wxHT_NOWHERE
;
1013 GetScrollBarThumbSize(sizeTotal
,
1014 scrollbar
->GetThumbPosition(),
1015 scrollbar
->GetThumbSize(),
1021 // now compare with the thumb position
1023 if ( coord
< thumbStart
)
1024 return wxHT_SCROLLBAR_BAR_1
;
1025 else if ( coord
> thumbEnd
)
1026 return wxHT_SCROLLBAR_BAR_2
;
1028 return wxHT_SCROLLBAR_THUMB
;
1034 wxStdRenderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
, int thumbPos
)
1036 int range
= scrollbar
->GetRange();
1039 // the only valid position anyhow
1043 if ( thumbPos
== -1 )
1045 // by default use the current thumb position
1046 thumbPos
= scrollbar
->GetThumbPosition();
1049 const wxSize sizeArrow
= GetScrollbarArrowSize();
1050 return (thumbPos
*GetScrollbarSize(scrollbar
)) / range
1051 + (scrollbar
->IsVertical() ? sizeArrow
.y
: sizeArrow
.x
);
1054 int wxStdRenderer::PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
)
1056 const wxSize sizeArrow
= GetScrollbarArrowSize();
1057 return ((coord
- (scrollbar
->IsVertical() ? sizeArrow
.y
: sizeArrow
.x
)) *
1058 scrollbar
->GetRange() ) / GetScrollbarSize(scrollbar
);
1061 #endif // wxUSE_SCROLLBAR
1063 // ----------------------------------------------------------------------------
1065 // ----------------------------------------------------------------------------
1069 wxSize
wxStdRenderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
1071 if ( borderBetweenFields
)
1072 *borderBetweenFields
= 2;
1074 return wxSize(2, 2);
1077 void wxStdRenderer::DrawStatusField(wxDC
& dc
,
1079 const wxString
& label
,
1085 if ( style
== wxSB_RAISED
)
1086 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
1087 else if ( style
!= wxSB_FLAT
)
1088 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
1090 rectIn
.Deflate(GetStatusBarBorders(NULL
));
1092 wxDCClipper
clipper(dc
, rectIn
);
1093 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
1096 #endif // wxUSE_STATUSBAR