1 // Name: univ/themes/win32.cpp
2 // Purpose: wxUniversal theme implementing Win32-like LNF
3 // Author: Vadim Zeitlin
7 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows license
9 ///////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
30 #include "wx/window.h"
32 #include "wx/dcmemory.h"
34 #include "wx/button.h"
35 #include "wx/listbox.h"
36 #include "wx/checklst.h"
37 #include "wx/combobox.h"
38 #include "wx/scrolbar.h"
39 #include "wx/slider.h"
40 #include "wx/textctrl.h"
43 // for COLOR_* constants
44 #include "wx/msw/private.h"
48 #include "wx/notebook.h"
49 #include "wx/spinbutt.h"
50 #include "wx/settings.h"
53 #include "wx/univ/scrtimer.h"
54 #include "wx/toplevel.h"
55 #include "wx/univ/renderer.h"
56 #include "wx/univ/inphand.h"
57 #include "wx/univ/colschem.h"
58 #include "wx/univ/theme.h"
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 static const int BORDER_THICKNESS
= 2;
66 // the offset between the label and focus rect around it
67 static const int FOCUS_RECT_OFFSET_X
= 1;
68 static const int FOCUS_RECT_OFFSET_Y
= 1;
70 static const int FRAME_BORDER_THICKNESS
= 3;
71 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
72 static const int FRAME_TITLEBAR_HEIGHT
= 18;
73 static const int FRAME_BUTTON_WIDTH
= 16;
74 static const int FRAME_BUTTON_HEIGHT
= 14;
76 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
77 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
78 static const size_t STATUSBAR_GRIP_SIZE
=
79 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
91 IndicatorState_Normal
,
92 IndicatorState_Pressed
, // this one is for check/radioboxes
93 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
94 IndicatorState_Disabled
,
95 IndicatorState_SelectedDisabled
, // only for the menus
101 IndicatorStatus_Checked
,
102 IndicatorStatus_Unchecked
,
106 // wxWin32Renderer: draw the GUI elements in Win32 style
107 // ----------------------------------------------------------------------------
109 class wxWin32Renderer
: public wxRenderer
113 enum wxArrowDirection
128 Arrow_InversedDisabled
,
132 enum wxFrameButtonType
135 FrameButton_Minimize
,
136 FrameButton_Maximize
,
143 wxWin32Renderer(const wxColourScheme
*scheme
);
145 // implement the base class pure virtuals
146 virtual void DrawBackground(wxDC
& dc
,
150 virtual void DrawLabel(wxDC
& dc
,
151 const wxString
& label
,
154 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
156 wxRect
*rectBounds
= NULL
);
157 virtual void DrawButtonLabel(wxDC
& dc
,
158 const wxString
& label
,
159 const wxBitmap
& image
,
162 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
164 wxRect
*rectBounds
= NULL
);
165 virtual void DrawBorder(wxDC
& dc
,
169 wxRect
*rectIn
= (wxRect
*)NULL
);
170 virtual void DrawHorizontalLine(wxDC
& dc
,
171 wxCoord y
, wxCoord x1
, wxCoord x2
);
172 virtual void DrawVerticalLine(wxDC
& dc
,
173 wxCoord x
, wxCoord y1
, wxCoord y2
);
174 virtual void DrawFrame(wxDC
& dc
,
175 const wxString
& label
,
178 int alignment
= wxALIGN_LEFT
,
179 int indexAccel
= -1);
180 virtual void DrawTextBorder(wxDC
& dc
,
184 wxRect
*rectIn
= (wxRect
*)NULL
);
185 virtual void DrawButtonBorder(wxDC
& dc
,
188 wxRect
*rectIn
= (wxRect
*)NULL
);
189 virtual void DrawArrow(wxDC
& dc
,
193 virtual void DrawScrollbarArrow(wxDC
& dc
,
197 { DrawArrow(dc
, dir
, rect
, flags
); }
198 virtual void DrawScrollbarThumb(wxDC
& dc
,
199 wxOrientation orient
,
202 virtual void DrawScrollbarShaft(wxDC
& dc
,
203 wxOrientation orient
,
206 virtual void DrawScrollCorner(wxDC
& dc
,
208 virtual void DrawItem(wxDC
& dc
,
209 const wxString
& label
,
212 virtual void DrawCheckItem(wxDC
& dc
,
213 const wxString
& label
,
214 const wxBitmap
& bitmap
,
217 virtual void DrawCheckButton(wxDC
& dc
,
218 const wxString
& label
,
219 const wxBitmap
& bitmap
,
222 wxAlignment align
= wxALIGN_LEFT
,
223 int indexAccel
= -1);
224 virtual void DrawRadioButton(wxDC
& dc
,
225 const wxString
& label
,
226 const wxBitmap
& bitmap
,
229 wxAlignment align
= wxALIGN_LEFT
,
230 int indexAccel
= -1);
231 virtual void DrawTextLine(wxDC
& dc
,
232 const wxString
& text
,
237 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
238 virtual void DrawTab(wxDC
& dc
,
241 const wxString
& label
,
242 const wxBitmap
& bitmap
= wxNullBitmap
,
244 int indexAccel
= -1);
246 virtual void DrawSliderShaft(wxDC
& dc
,
248 wxOrientation orient
,
250 wxRect
*rectShaft
= NULL
);
251 virtual void DrawSliderThumb(wxDC
& dc
,
253 wxOrientation orient
,
255 virtual void DrawSliderTicks(wxDC
& dc
,
257 const wxSize
& sizeThumb
,
258 wxOrientation orient
,
264 virtual void DrawMenuBarItem(wxDC
& dc
,
266 const wxString
& label
,
268 int indexAccel
= -1);
269 virtual void DrawMenuItem(wxDC
& dc
,
271 const wxMenuGeometryInfo
& geometryInfo
,
272 const wxString
& label
,
273 const wxString
& accel
,
274 const wxBitmap
& bitmap
= wxNullBitmap
,
276 int indexAccel
= -1);
277 virtual void DrawMenuSeparator(wxDC
& dc
,
279 const wxMenuGeometryInfo
& geomInfo
);
281 virtual void DrawStatusField(wxDC
& dc
,
283 const wxString
& label
,
287 virtual void DrawFrameTitleBar(wxDC
& dc
,
289 const wxString
& title
,
292 int specialButton
= 0,
293 int specialButtonFlags
= 0);
294 virtual void DrawFrameBorder(wxDC
& dc
,
297 virtual void DrawFrameBackground(wxDC
& dc
,
300 virtual void DrawFrameTitle(wxDC
& dc
,
302 const wxString
& title
,
304 virtual void DrawFrameIcon(wxDC
& dc
,
308 virtual void DrawFrameButton(wxDC
& dc
,
309 wxCoord x
, wxCoord y
,
312 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
313 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
314 virtual wxSize
GetFrameIconSize() const;
315 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
317 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
319 wxBitmap
*bmpPressed
,
320 wxBitmap
*bmpDisabled
);
322 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
323 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
324 virtual bool AreScrollbarsInsideBorder() const;
326 virtual wxSize
GetScrollbarArrowSize() const
327 { return m_sizeScrollbarArrow
; }
328 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
329 wxScrollBar::Element elem
,
330 int thumbPos
= -1) const;
331 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
332 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
333 const wxPoint
& pt
) const;
334 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
336 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
337 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
338 { return fontHeight
+ 2; }
339 virtual wxSize
GetCheckBitmapSize() const
340 { return wxSize(13, 13); }
341 virtual wxSize
GetRadioBitmapSize() const
342 { return wxSize(12, 12); }
343 virtual wxCoord
GetCheckItemMargin() const
346 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
348 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
350 wxCoord
*extraSpaceBeyond
);
352 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
353 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
355 virtual wxCoord
GetSliderDim() const { return 20; }
356 virtual wxCoord
GetSliderTickLen() const { return 4; }
357 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
358 wxOrientation orient
) const;
359 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
360 wxOrientation orient
) const;
361 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
363 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
364 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
365 const wxMenu
& menu
) const;
367 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
370 // helper of DrawLabel() and DrawCheckOrRadioButton()
371 void DoDrawLabel(wxDC
& dc
,
372 const wxString
& label
,
375 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
377 wxRect
*rectBounds
= NULL
,
378 const wxPoint
& focusOffset
379 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
381 // common part of DrawLabel() and DrawItem()
382 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
384 // DrawLabel() and DrawButtonLabel() helper
385 void DrawLabelShadow(wxDC
& dc
,
386 const wxString
& label
,
391 // DrawButtonBorder() helper
392 void DoDrawBackground(wxDC
& dc
,
396 // DrawBorder() helpers: all of them shift and clip the DC after drawing
399 // just draw a rectangle with the given pen
400 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
402 // draw the lower left part of rectangle
403 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
405 // draw the rectange using the first brush for the left and top sides and
406 // the second one for the bottom and right ones
407 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
408 const wxPen
& pen1
, const wxPen
& pen2
);
410 // draw the normal 3D border
411 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
413 // draw the sunken 3D border
414 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
416 // draw the border used for scrollbar arrows
417 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
419 // public DrawArrow()s helper
420 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
421 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
423 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
424 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
425 wxArrowDirection arrowDir
,
426 wxArrowStyle arrowStyle
);
428 // DrawCheckButton/DrawRadioButton helper
429 void DrawCheckOrRadioButton(wxDC
& dc
,
430 const wxString
& label
,
431 const wxBitmap
& bitmap
,
436 wxCoord focusOffsetY
);
438 // draw a normal or transposed line (useful for using the same code fo both
439 // horizontal and vertical widgets)
440 void DrawLine(wxDC
& dc
,
441 wxCoord x1
, wxCoord y1
,
442 wxCoord x2
, wxCoord y2
,
443 bool transpose
= FALSE
)
446 dc
.DrawLine(y1
, x1
, y2
, x2
);
448 dc
.DrawLine(x1
, y1
, x2
, y2
);
451 // get the standard check/radio button bitmap
452 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
453 wxBitmap
GetCheckBitmap(int flags
)
454 { return GetIndicator(IndicatorType_Check
, flags
); }
455 wxBitmap
GetRadioBitmap(int flags
)
456 { return GetIndicator(IndicatorType_Radio
, flags
); }
459 const wxColourScheme
*m_scheme
;
461 // the sizing parameters (TODO make them changeable)
462 wxSize m_sizeScrollbarArrow
;
464 // GDI objects we use for drawing
465 wxColour m_colDarkGrey
,
473 wxFont m_titlebarFont
;
476 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
478 // first row is for the normal state, second - for the disabled
479 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
482 // ----------------------------------------------------------------------------
483 // wxWin32InputHandler and derived classes: process the keyboard and mouse
484 // messages according to Windows standards
485 // ----------------------------------------------------------------------------
487 class wxWin32InputHandler
: public wxInputHandler
490 wxWin32InputHandler(wxWin32Renderer
*renderer
);
492 virtual bool HandleKey(wxInputConsumer
*control
,
493 const wxKeyEvent
& event
,
495 virtual bool HandleMouse(wxInputConsumer
*control
,
496 const wxMouseEvent
& event
);
499 wxWin32Renderer
*m_renderer
;
502 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
505 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
506 wxInputHandler
*handler
);
508 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
509 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
511 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
512 const wxControlAction
& action
);
515 virtual bool IsAllowedButton(int button
) { return button
== 1; }
517 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
519 // we don't highlight anything
522 // the first and last event which caused the thumb to move
523 wxMouseEvent m_eventStartDrag
,
526 // have we paused the scrolling because the mouse moved?
529 // we remember the interval of the timer to be able to restart it
533 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
536 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
537 : wxStdCheckboxInputHandler(handler
) { }
539 virtual bool HandleKey(wxInputConsumer
*control
,
540 const wxKeyEvent
& event
,
544 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
547 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
548 : wxStdTextCtrlInputHandler(handler
) { }
550 virtual bool HandleKey(wxInputConsumer
*control
,
551 const wxKeyEvent
& event
,
555 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
558 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
560 virtual bool HandleMouse(wxInputConsumer
*consumer
,
561 const wxMouseEvent
& event
);
563 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
564 const wxMouseEvent
& event
);
567 // is the given point over the statusbar grip?
568 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
571 // the cursor we had replaced with the resize one
572 wxCursor m_cursorOld
;
574 // was the mouse over the grip last time we checked?
578 // ----------------------------------------------------------------------------
579 // wxWin32ColourScheme: uses (default) Win32 colours
580 // ----------------------------------------------------------------------------
582 class wxWin32ColourScheme
: public wxColourScheme
585 virtual wxColour
Get(StdColour col
) const;
586 virtual wxColour
GetBackground(wxWindow
*win
) const;
589 // ----------------------------------------------------------------------------
591 // ----------------------------------------------------------------------------
593 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
595 class wxWin32Theme
: public wxTheme
599 virtual ~wxWin32Theme();
601 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
602 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
603 virtual wxColourScheme
*GetColourScheme();
606 // get the default input handler
607 wxInputHandler
*GetDefaultInputHandler();
609 wxWin32Renderer
*m_renderer
;
611 // the names of the already created handlers and the handlers themselves
612 // (these arrays are synchronized)
613 wxSortedArrayString m_handlerNames
;
614 wxArrayHandlers m_handlers
;
616 wxWin32InputHandler
*m_handlerDefault
;
618 wxWin32ColourScheme
*m_scheme
;
620 WX_DECLARE_THEME(win32
)
623 // ----------------------------------------------------------------------------
625 // ----------------------------------------------------------------------------
627 // frame buttons bitmaps
629 static const char *frame_button_close_xpm
[] = {
644 static const char *frame_button_help_xpm
[] = {
659 static const char *frame_button_maximize_xpm
[] = {
674 static const char *frame_button_minimize_xpm
[] = {
689 static const char *frame_button_restore_xpm
[] = {
706 static const char *checked_menu_xpm
[] = {
707 /* columns rows colors chars-per-pixel */
723 static const char *selected_checked_menu_xpm
[] = {
724 /* columns rows colors chars-per-pixel */
740 static const char *disabled_checked_menu_xpm
[] = {
741 /* columns rows colors chars-per-pixel */
758 static const char *selected_disabled_checked_menu_xpm
[] = {
759 /* columns rows colors chars-per-pixel */
775 // checkbox and radiobox bitmaps below
777 static const char *checked_xpm
[] = {
778 /* columns rows colors chars-per-pixel */
801 static const char *pressed_checked_xpm
[] = {
802 /* columns rows colors chars-per-pixel */
824 static const char *pressed_disabled_checked_xpm
[] = {
825 /* columns rows colors chars-per-pixel */
847 static const char *checked_item_xpm
[] = {
848 /* columns rows colors chars-per-pixel */
869 static const char *unchecked_xpm
[] = {
870 /* columns rows colors chars-per-pixel */
893 static const char *pressed_unchecked_xpm
[] = {
894 /* columns rows colors chars-per-pixel */
916 static const char *unchecked_item_xpm
[] = {
917 /* columns rows colors chars-per-pixel */
937 static const char *checked_radio_xpm
[] = {
938 /* columns rows colors chars-per-pixel */
961 static const char *pressed_checked_radio_xpm
[] = {
962 /* columns rows colors chars-per-pixel */
985 static const char *pressed_disabled_checked_radio_xpm
[] = {
986 /* columns rows colors chars-per-pixel */
1009 static const char *unchecked_radio_xpm
[] = {
1010 /* columns rows colors chars-per-pixel */
1033 static const char *pressed_unchecked_radio_xpm
[] = {
1034 /* columns rows colors chars-per-pixel */
1057 static const char **
1058 bmpIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1063 { checked_xpm
, unchecked_xpm
},
1066 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1069 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1075 { checked_radio_xpm
, unchecked_radio_xpm
},
1078 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1081 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1087 { checked_menu_xpm
, NULL
},
1090 { selected_checked_menu_xpm
, NULL
},
1093 { disabled_checked_menu_xpm
, NULL
},
1095 // disabled selected state
1096 { selected_disabled_checked_menu_xpm
, NULL
},
1100 // ============================================================================
1102 // ============================================================================
1104 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1106 // ----------------------------------------------------------------------------
1108 // ----------------------------------------------------------------------------
1110 wxWin32Theme::wxWin32Theme()
1112 m_scheme
= new wxWin32ColourScheme
;
1113 m_renderer
= new wxWin32Renderer(m_scheme
);
1114 m_handlerDefault
= NULL
;
1117 wxWin32Theme::~wxWin32Theme()
1119 size_t count
= m_handlers
.GetCount();
1120 for ( size_t n
= 0; n
< count
; n
++ )
1122 if ( m_handlers
[n
] != m_handlerDefault
)
1123 delete m_handlers
[n
];
1126 delete m_handlerDefault
;
1132 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1134 if ( !m_handlerDefault
)
1136 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1139 return m_handlerDefault
;
1142 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1144 wxInputHandler
*handler
;
1145 int n
= m_handlerNames
.Index(control
);
1146 if ( n
== wxNOT_FOUND
)
1148 // create a new handler
1149 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1150 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1151 GetDefaultInputHandler());
1153 else if ( control
== wxINP_HANDLER_BUTTON
)
1154 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1155 #endif // wxUSE_BUTTON
1157 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1158 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1159 #endif // wxUSE_CHECKBOX
1161 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1162 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1163 #endif // wxUSE_COMBOBOX
1165 else if ( control
== wxINP_HANDLER_LISTBOX
)
1166 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1167 #endif // wxUSE_LISTBOX
1168 #if wxUSE_CHECKLISTBOX
1169 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1170 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1171 #endif // wxUSE_CHECKLISTBOX
1173 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1174 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1175 #endif // wxUSE_TEXTCTRL
1177 else if ( control
== wxINP_HANDLER_SLIDER
)
1178 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1179 #endif // wxUSE_SLIDER
1181 else if ( control
== wxINP_HANDLER_SPINBTN
)
1182 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1183 #endif // wxUSE_SPINBTN
1185 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1186 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1187 #endif // wxUSE_NOTEBOOK
1189 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1190 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1191 #endif // wxUSE_STATUSBAR
1192 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1193 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
1195 handler
= GetDefaultInputHandler();
1197 n
= m_handlerNames
.Add(control
);
1198 m_handlers
.Insert(handler
, n
);
1200 else // we already have it
1202 handler
= m_handlers
[n
];
1208 wxColourScheme
*wxWin32Theme::GetColourScheme()
1213 // ============================================================================
1214 // wxWin32ColourScheme
1215 // ============================================================================
1217 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1220 if ( win
->UseBgCol() )
1222 // use the user specified colour
1223 col
= win
->GetBackgroundColour();
1226 if ( win
->IsContainerWindow() )
1228 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1231 if ( !text
->IsEnabled() ) // not IsEditable()
1233 //else: execute code below
1238 // doesn't depend on the state
1244 int flags
= win
->GetStateFlags();
1246 // the colour set by the user should be used for the normal state
1247 // and for the states for which we don't have any specific colours
1248 if ( !col
.Ok() || (flags
!= 0) )
1250 if ( wxDynamicCast(win
, wxScrollBar
) )
1251 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1261 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1265 // use the system colours under Windows
1266 #if defined(__WXMSW__)
1267 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1269 case CONTROL_PRESSED
:
1270 case CONTROL_CURRENT
:
1271 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1273 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1275 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1276 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1278 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1279 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1281 #if defined(COLOR_3DDKSHADOW)
1282 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1284 case SHADOW_DARK
: return *wxBLACK
;
1287 case CONTROL_TEXT_DISABLED
:
1288 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1290 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1292 case CONTROL_TEXT_DISABLED_SHADOW
:
1293 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1295 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1296 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1297 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1299 // use the standard Windows colours elsewhere
1300 case WINDOW
: return *wxWHITE
;
1302 case CONTROL_PRESSED
:
1303 case CONTROL_CURRENT
:
1304 case CONTROL
: return wxColour(0xc0c0c0);
1306 case CONTROL_TEXT
: return *wxBLACK
;
1308 case SCROLLBAR
: return wxColour(0xe0e0e0);
1309 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1311 case HIGHLIGHT
: return wxColour(0x800000);
1312 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1314 case SHADOW_DARK
: return *wxBLACK
;
1316 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1317 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1319 case SHADOW_IN
: return wxColour(0xc0c0c0);
1321 case CONTROL_TEXT_DISABLED_SHADOW
:
1322 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1324 case TITLEBAR
: return wxColour(0xaeaaae);
1325 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1326 case TITLEBAR_TEXT
: return *wxWHITE
;
1331 wxFAIL_MSG(_T("invalid standard colour"));
1336 // ============================================================================
1338 // ============================================================================
1340 // ----------------------------------------------------------------------------
1342 // ----------------------------------------------------------------------------
1344 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1348 m_sizeScrollbarArrow
= wxSize(16, 16);
1350 // init colours and pens
1351 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1353 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1354 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1356 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1358 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1359 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1361 m_titlebarFont
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
1362 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1364 // init the arrow bitmaps
1365 static const size_t ARROW_WIDTH
= 7;
1366 static const size_t ARROW_LENGTH
= 4;
1369 wxMemoryDC dcNormal
,
1372 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1374 bool isVertical
= n
> Arrow_Right
;
1387 // disabled arrow is larger because of the shadow
1388 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1389 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1391 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1392 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1394 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1395 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1399 dcNormal
.SetPen(m_penBlack
);
1400 dcDisabled
.SetPen(m_penDarkGrey
);
1402 // calculate the position of the point of the arrow
1406 x1
= (ARROW_WIDTH
- 1)/2;
1407 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1411 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1412 y1
= (ARROW_WIDTH
- 1)/2;
1423 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1425 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1426 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1433 if ( n
== Arrow_Up
)
1444 else // left or right arrow
1449 if ( n
== Arrow_Left
)
1462 // draw the shadow for the disabled one
1463 dcDisabled
.SetPen(m_penHighlight
);
1468 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1472 x1
= ARROW_LENGTH
- 1;
1473 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1476 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1477 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1482 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1486 x1
= ARROW_WIDTH
- 1;
1488 x2
= (ARROW_WIDTH
- 1)/2;
1490 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1491 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1496 // create the inversed bitmap but only for the right arrow as we only
1497 // use it for the menus
1498 if ( n
== Arrow_Right
)
1500 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1501 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1503 dcInverse
.Blit(0, 0, w
, h
,
1506 dcInverse
.SelectObject(wxNullBitmap
);
1508 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1509 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1511 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1512 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1514 dcInverse
.Blit(0, 0, w
, h
,
1517 dcInverse
.SelectObject(wxNullBitmap
);
1519 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1520 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1523 dcNormal
.SelectObject(wxNullBitmap
);
1524 dcDisabled
.SelectObject(wxNullBitmap
);
1526 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1527 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1528 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1529 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1531 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1534 // init the frame buttons bitmaps
1535 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1536 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1537 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1538 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1539 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1542 // ----------------------------------------------------------------------------
1544 // ----------------------------------------------------------------------------
1547 The raised border in Win32 looks like this:
1549 IIIIIIIIIIIIIIIIIIIIIIB
1551 I GB I = white (HILIGHT)
1552 I GB H = light grey (LIGHT)
1553 I GB G = dark grey (SHADOI)
1554 I GB B = black (DKSHADOI)
1555 I GB I = hIghlight (COLOR_3DHILIGHT)
1557 IGGGGGGGGGGGGGGGGGGGGGB
1558 BBBBBBBBBBBBBBBBBBBBBBB
1560 The sunken border looks like this:
1562 GGGGGGGGGGGGGGGGGGGGGGI
1563 GBBBBBBBBBBBBBBBBBBBBHI
1570 GHHHHHHHHHHHHHHHHHHHHHI
1571 IIIIIIIIIIIIIIIIIIIIIII
1573 The static border (used for the controls which don't get focus) is like
1576 GGGGGGGGGGGGGGGGGGGGGGW
1584 WWWWWWWWWWWWWWWWWWWWWWW
1586 The most complicated is the double border:
1588 HHHHHHHHHHHHHHHHHHHHHHB
1589 HWWWWWWWWWWWWWWWWWWWWGB
1590 HWHHHHHHHHHHHHHHHHHHHGB
1595 HWHHHHHHHHHHHHHHHHHHHGB
1596 HGGGGGGGGGGGGGGGGGGGGGB
1597 BBBBBBBBBBBBBBBBBBBBBBB
1599 And the simple border is, well, simple:
1601 BBBBBBBBBBBBBBBBBBBBBBB
1610 BBBBBBBBBBBBBBBBBBBBBBB
1613 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1617 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1618 dc
.DrawRectangle(*rect
);
1624 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1626 // draw the bottom and right sides
1628 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1629 rect
->GetRight() + 1, rect
->GetBottom());
1630 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1631 rect
->GetRight(), rect
->GetBottom());
1638 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1639 const wxPen
& pen1
, const wxPen
& pen2
)
1641 // draw the rectangle
1643 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1644 rect
->GetLeft(), rect
->GetBottom());
1645 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1646 rect
->GetRight(), rect
->GetTop());
1648 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1649 rect
->GetRight(), rect
->GetBottom());
1650 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1651 rect
->GetRight() + 1, rect
->GetBottom());
1657 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1659 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1660 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1663 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1665 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1666 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1669 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1673 DrawRect(dc
, rect
, m_penDarkGrey
);
1675 // the arrow is usually drawn inside border of width 2 and is offset by
1676 // another pixel in both directions when it's pressed - as the border
1677 // in this case is more narrow as well, we have to adjust rect like
1685 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1686 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1690 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1692 const wxRect
& rectTotal
,
1693 int WXUNUSED(flags
),
1698 wxRect rect
= rectTotal
;
1702 case wxBORDER_SUNKEN
:
1703 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1705 DrawSunkenBorder(dc
, &rect
);
1709 case wxBORDER_STATIC
:
1710 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1713 case wxBORDER_RAISED
:
1714 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1716 DrawRaisedBorder(dc
, &rect
);
1720 case wxBORDER_DOUBLE
:
1721 DrawArrowBorder(dc
, &rect
);
1722 DrawRect(dc
, &rect
, m_penLightGrey
);
1725 case wxBORDER_SIMPLE
:
1726 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1728 DrawRect(dc
, &rect
, m_penBlack
);
1733 wxFAIL_MSG(_T("unknown border type"));
1736 case wxBORDER_DEFAULT
:
1745 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1750 case wxBORDER_RAISED
:
1751 case wxBORDER_SUNKEN
:
1752 width
= BORDER_THICKNESS
;
1755 case wxBORDER_SIMPLE
:
1756 case wxBORDER_STATIC
:
1760 case wxBORDER_DOUBLE
:
1765 wxFAIL_MSG(_T("unknown border type"));
1768 case wxBORDER_DEFAULT
:
1778 rect
.height
= width
;
1783 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1788 // ----------------------------------------------------------------------------
1790 // ----------------------------------------------------------------------------
1792 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1798 // text controls are not special under windows
1799 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1802 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1803 const wxRect
& rectTotal
,
1807 wxRect rect
= rectTotal
;
1809 if ( flags
& wxCONTROL_PRESSED
)
1811 // button pressed: draw a double border around it
1812 DrawRect(dc
, &rect
, m_penBlack
);
1813 DrawRect(dc
, &rect
, m_penDarkGrey
);
1817 // button not pressed
1819 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1821 // button either default or focused (or both): add an extra border around it
1822 DrawRect(dc
, &rect
, m_penBlack
);
1825 // now draw a normal button
1826 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1827 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1836 // ----------------------------------------------------------------------------
1838 // ----------------------------------------------------------------------------
1840 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1841 wxCoord y
, wxCoord x1
, wxCoord x2
)
1843 dc
.SetPen(m_penDarkGrey
);
1844 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1845 dc
.SetPen(m_penHighlight
);
1847 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1850 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1851 wxCoord x
, wxCoord y1
, wxCoord y2
)
1853 dc
.SetPen(m_penDarkGrey
);
1854 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1855 dc
.SetPen(m_penHighlight
);
1857 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1860 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1861 const wxString
& label
,
1867 wxCoord height
= 0; // of the label
1868 wxRect rectFrame
= rect
;
1869 if ( !label
.empty() )
1871 // the text should touch the top border of the rect, so the frame
1872 // itself should be lower
1873 dc
.GetTextExtent(label
, NULL
, &height
);
1874 rectFrame
.y
+= height
/ 2;
1875 rectFrame
.height
-= height
/ 2;
1877 // we have to draw each part of the frame individually as we can't
1878 // erase the background beyond the label as it might contain some
1879 // pixmap already, so drawing everything and then overwriting part of
1880 // the frame with label doesn't work
1882 // TODO: the +5 and space insertion should be customizable
1885 rectText
.x
= rectFrame
.x
+ 5;
1886 rectText
.y
= rect
.y
;
1887 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1888 rectText
.height
= height
;
1891 label2
<< _T(' ') << label
<< _T(' ');
1892 if ( indexAccel
!= -1 )
1894 // adjust it as we prepended a space
1899 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1901 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1905 // just draw the complete frame
1906 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1907 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1911 // ----------------------------------------------------------------------------
1913 // ----------------------------------------------------------------------------
1915 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1917 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1918 // pixels each while we really need dots here... PS_ALTERNATE might
1919 // work, but it is for NT 5 only
1921 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1923 // draw the pixels manually: note that to behave in the same manner as
1924 // DrawRect(), we must exclude the bottom and right borders from the
1926 wxCoord x1
= rect
.GetLeft(),
1928 x2
= rect
.GetRight(),
1929 y2
= rect
.GetBottom();
1931 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1933 // this seems to be closer than what Windows does than wxINVERT although
1934 // I'm still not sure if it's correct
1935 dc
.SetLogicalFunction(wxAND_REVERSE
);
1938 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1939 dc
.DrawPoint(z
, rect
.GetTop());
1941 wxCoord shift
= z
== x2
? 0 : 1;
1942 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1943 dc
.DrawPoint(x2
, z
);
1945 shift
= z
== y2
? 0 : 1;
1946 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1947 dc
.DrawPoint(z
, y2
);
1949 shift
= z
== x1
? 0 : 1;
1950 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
1951 dc
.DrawPoint(x1
, z
);
1953 dc
.SetLogicalFunction(wxCOPY
);
1957 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
1958 const wxString
& label
,
1963 // draw shadow of the text
1964 dc
.SetTextForeground(m_colHighlight
);
1965 wxRect rectShadow
= rect
;
1968 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1970 // make the text grey
1971 dc
.SetTextForeground(m_colDarkGrey
);
1974 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1975 const wxString
& label
,
1982 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
1985 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
1986 const wxString
& label
,
1992 const wxPoint
& focusOffset
)
1994 // the underscores are not drawn for focused controls in wxMSW
1995 if ( flags
& wxCONTROL_FOCUSED
)
2000 if ( flags
& wxCONTROL_DISABLED
)
2002 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2003 // currently only can happen for a menu item and it seems that Windows
2004 // doesn't draw the shadow in this case, so we don't do it neither
2005 if ( flags
& wxCONTROL_SELECTED
)
2007 // just make the label text greyed out
2008 dc
.SetTextForeground(m_colDarkGrey
);
2010 else // draw normal disabled label
2012 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2017 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2019 if ( flags
& wxCONTROL_DISABLED
)
2021 // restore the fg colour
2022 dc
.SetTextForeground(*wxBLACK
);
2025 if ( flags
& wxCONTROL_FOCUSED
)
2027 if ( focusOffset
.x
|| focusOffset
.y
)
2029 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2032 DrawFocusRect(dc
, rectLabel
);
2036 *rectBounds
= rectLabel
;
2039 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2040 const wxString
& label
,
2041 const wxBitmap
& image
,
2048 // the underscores are not drawn for focused controls in wxMSW
2049 if ( flags
& wxCONTROL_PRESSED
)
2054 wxRect rectLabel
= rect
;
2055 if ( !label
.empty() )
2057 // shift the label if a button is pressed
2058 if ( flags
& wxCONTROL_PRESSED
)
2064 if ( flags
& wxCONTROL_DISABLED
)
2066 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2069 // leave enough space for the focus rectangle
2070 if ( flags
& wxCONTROL_FOCUSED
)
2072 rectLabel
.Inflate(-2);
2076 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2078 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2080 if ( flags
& wxCONTROL_PRESSED
)
2082 // the focus rectangle is never pressed, so undo the shift done
2090 DrawFocusRect(dc
, rectLabel
);
2094 // ----------------------------------------------------------------------------
2095 // (check)listbox items
2096 // ----------------------------------------------------------------------------
2098 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2099 const wxString
& label
,
2103 wxDCTextColourChanger
colChanger(dc
);
2105 if ( flags
& wxCONTROL_SELECTED
)
2107 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2109 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2110 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2111 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2112 dc
.DrawRectangle(rect
);
2115 wxRect rectText
= rect
;
2117 rectText
.width
-= 2;
2118 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2120 if ( flags
& wxCONTROL_FOCUSED
)
2122 DrawFocusRect(dc
, rect
);
2126 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2127 const wxString
& label
,
2128 const wxBitmap
& bitmap
,
2137 else // use default bitmap
2139 bmp
= wxBitmap(flags
& wxCONTROL_CHECKED
? checked_item_xpm
2140 : unchecked_item_xpm
);
2143 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2144 TRUE
/* use mask */);
2146 wxRect rectLabel
= rect
;
2147 int bmpWidth
= bmp
.GetWidth();
2148 rectLabel
.x
+= bmpWidth
;
2149 rectLabel
.width
-= bmpWidth
;
2151 DrawItem(dc
, label
, rectLabel
, flags
);
2154 // ----------------------------------------------------------------------------
2155 // check/radio buttons
2156 // ----------------------------------------------------------------------------
2158 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2160 IndicatorState indState
;
2161 if ( flags
& wxCONTROL_SELECTED
)
2162 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2163 : IndicatorState_Selected
;
2164 else if ( flags
& wxCONTROL_DISABLED
)
2165 indState
= IndicatorState_Disabled
;
2166 else if ( flags
& wxCONTROL_PRESSED
)
2167 indState
= IndicatorState_Pressed
;
2169 indState
= IndicatorState_Normal
;
2171 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2172 ? IndicatorStatus_Checked
2173 : IndicatorStatus_Unchecked
;
2175 const char **xpm
= bmpIndicators
[indType
][indState
][indStatus
];
2176 return xpm
? wxBitmap(xpm
) : wxNullBitmap
;
2179 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2180 const wxString
& label
,
2181 const wxBitmap
& bitmap
,
2186 wxCoord focusOffsetY
)
2188 // calculate the position of the bitmap and of the label
2189 wxCoord heightBmp
= bitmap
.GetHeight();
2191 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2194 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2195 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2197 // align label vertically with the bitmap - looks nicer like this
2198 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2200 // calc horz position
2201 if ( align
== wxALIGN_RIGHT
)
2203 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2204 rectLabel
.x
= rect
.x
+ 3;
2205 rectLabel
.SetRight(xBmp
);
2207 else // normal (checkbox to the left of the text) case
2210 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2211 rectLabel
.SetRight(rect
.GetRight());
2214 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2217 dc
, label
, rectLabel
,
2219 wxALIGN_LEFT
| wxALIGN_TOP
,
2221 NULL
, // we don't need bounding rect
2222 // use custom vert focus rect offset
2223 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2227 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2228 const wxString
& label
,
2229 const wxBitmap
& bitmap
,
2235 DrawCheckOrRadioButton(dc
, label
,
2236 bitmap
.Ok() ? bitmap
: GetRadioBitmap(flags
),
2237 rect
, flags
, align
, indexAccel
,
2238 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2241 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2242 const wxString
& label
,
2243 const wxBitmap
& bitmap
,
2249 DrawCheckOrRadioButton(dc
, label
,
2250 bitmap
.Ok() ? bitmap
: GetCheckBitmap(flags
),
2251 rect
, flags
, align
, indexAccel
,
2252 0); // no focus rect offset for checkboxes
2255 // ----------------------------------------------------------------------------
2257 // ----------------------------------------------------------------------------
2259 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2260 const wxString
& text
,
2266 // nothing special to do here
2267 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2270 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2272 // we don't draw them
2275 // ----------------------------------------------------------------------------
2277 // ----------------------------------------------------------------------------
2279 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2280 const wxRect
& rectOrig
,
2282 const wxString
& label
,
2283 const wxBitmap
& bitmap
,
2287 wxRect rect
= rectOrig
;
2289 // the current tab is drawn indented (to the top for default case) and
2290 // bigger than the other ones
2291 const wxSize indent
= GetTabIndent();
2292 if ( flags
& wxCONTROL_SELECTED
)
2297 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2301 rect
.Inflate(indent
.x
, 0);
2303 rect
.height
+= indent
.y
;
2307 rect
.Inflate(indent
.x
, 0);
2308 rect
.height
+= indent
.y
;
2313 wxFAIL_MSG(_T("TODO"));
2318 // draw the text, image and the focus around them (if necessary)
2319 wxRect rectLabel
= rect
;
2320 rectLabel
.Deflate(1, 1);
2321 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2322 flags
, wxALIGN_CENTRE
, indexAccel
);
2324 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2325 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2328 x2
= rect
.GetRight(),
2329 y2
= rect
.GetBottom();
2331 // FIXME: all this code will break if the tab indent or the border width,
2332 // it is tied to the fact that both of them are equal to 2
2337 dc
.SetPen(m_penHighlight
);
2338 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2339 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2340 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2342 dc
.SetPen(m_penBlack
);
2343 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2344 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2346 dc
.SetPen(m_penDarkGrey
);
2347 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2349 if ( flags
& wxCONTROL_SELECTED
)
2351 dc
.SetPen(m_penLightGrey
);
2353 // overwrite the part of the border below this tab
2354 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2356 // and the shadow of the tab to the left of us
2357 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2362 dc
.SetPen(m_penHighlight
);
2363 // we need to continue one pixel further to overwrite the corner of
2364 // the border for the selected tab
2365 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2367 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2369 dc
.SetPen(m_penBlack
);
2370 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2371 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2372 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2374 dc
.SetPen(m_penDarkGrey
);
2375 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2376 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2378 if ( flags
& wxCONTROL_SELECTED
)
2380 dc
.SetPen(m_penLightGrey
);
2382 // overwrite the part of the (double!) border above this tab
2383 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2384 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2386 // and the shadow of the tab to the left of us
2387 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2393 wxFAIL_MSG(_T("TODO"));
2397 // ----------------------------------------------------------------------------
2399 // ----------------------------------------------------------------------------
2401 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2402 wxOrientation orient
) const
2406 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2407 if ( orient
== wxHORIZONTAL
)
2409 size
.y
= rect
.height
- 6;
2410 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2414 size
.x
= rect
.width
- 6;
2415 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2421 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2422 wxOrientation orient
) const
2424 static const wxCoord SLIDER_MARGIN
= 6;
2426 wxRect rect
= rectOrig
;
2428 if ( orient
== wxHORIZONTAL
)
2430 // make the rect of minimal width and centre it
2431 rect
.height
= 2*BORDER_THICKNESS
;
2432 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2436 // leave margins on the sides
2437 rect
.Deflate(SLIDER_MARGIN
, 0);
2441 // same as above but in other direction
2442 rect
.width
= 2*BORDER_THICKNESS
;
2443 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2447 rect
.Deflate(0, SLIDER_MARGIN
);
2453 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2454 const wxRect
& rectOrig
,
2455 wxOrientation orient
,
2459 if ( flags
& wxCONTROL_FOCUSED
)
2461 DrawFocusRect(dc
, rectOrig
);
2464 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2469 DrawSunkenBorder(dc
, &rect
);
2472 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2474 wxOrientation orient
,
2478 we are drawing a shape of this form
2483 H DB where H is hightlight colour
2496 The interior of this shape is filled with the hatched brush if the thumb
2500 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2502 bool transpose
= orient
== wxVERTICAL
;
2504 wxCoord x
, y
, x2
, y2
;
2509 x2
= rect
.GetBottom();
2510 y2
= rect
.GetRight();
2516 x2
= rect
.GetRight();
2517 y2
= rect
.GetBottom();
2520 // the size of the pointed part of the thumb
2521 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2523 wxCoord x3
= x
+ sizeArrow
,
2524 y3
= y2
- sizeArrow
;
2526 dc
.SetPen(m_penHighlight
);
2527 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2528 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2529 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2531 dc
.SetPen(m_penBlack
);
2532 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2533 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2535 dc
.SetPen(m_penDarkGrey
);
2536 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2537 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2539 if ( flags
& wxCONTROL_PRESSED
)
2541 // TODO: MSW fills the entire area inside, not just the rect
2542 wxRect rectInt
= rect
;
2544 rectInt
.SetRight(y3
);
2546 rectInt
.SetBottom(y3
);
2549 static const char *stipple_xpm
[] = {
2550 /* columns rows colors chars-per-pixel */
2558 dc
.SetBrush(wxBrush(stipple_xpm
));
2560 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2561 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2562 dc
.SetPen(*wxTRANSPARENT_PEN
);
2563 dc
.DrawRectangle(rectInt
);
2567 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2569 const wxSize
& sizeThumb
,
2570 wxOrientation orient
,
2582 // the variable names correspond to horizontal case, but they can be used
2583 // for both orientations
2584 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2585 if ( orient
== wxHORIZONTAL
)
2587 x1
= rect
.GetLeft();
2588 x2
= rect
.GetRight();
2590 // draw from bottom to top to leave one pixel space between the ticks
2591 // and the slider as Windows do
2592 y1
= rect
.GetBottom();
2597 widthThumb
= sizeThumb
.x
;
2602 x2
= rect
.GetBottom();
2604 y1
= rect
.GetRight();
2605 y2
= rect
.GetLeft();
2609 widthThumb
= sizeThumb
.y
;
2612 // the first tick should be positioned in such way that a thumb drawn in
2613 // the first position points down directly to it
2614 x1
+= widthThumb
/ 2;
2615 x2
-= widthThumb
/ 2;
2617 // this also means that we have slightly less space for the ticks in
2618 // between the first and the last
2621 dc
.SetPen(m_penBlack
);
2623 int range
= end
- start
;
2624 for ( int n
= 0; n
< range
; n
+= step
)
2626 wxCoord x
= x1
+ (len
*n
) / range
;
2628 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2631 // always draw the line at the end position
2632 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2635 // ----------------------------------------------------------------------------
2637 // ----------------------------------------------------------------------------
2639 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2640 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2643 virtual wxSize
GetSize() const { return m_size
; }
2645 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2646 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2648 wxCoord
GetItemHeight() const { return m_heightItem
; }
2651 // the total size of the menu
2654 // the offset of the start of the menu item label
2657 // the offset of the start of the accel label
2660 // the height of a normal (not separator) item
2661 wxCoord m_heightItem
;
2663 friend wxMenuGeometryInfo
*
2664 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2667 // FIXME: all constants are hardcoded but shouldn't be
2668 static const wxCoord MENU_LEFT_MARGIN
= 9;
2669 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2670 static const wxCoord MENU_VERT_MARGIN
= 3;
2672 // the margin around bitmap/check marks (on each side)
2673 static const wxCoord MENU_BMP_MARGIN
= 2;
2675 // the margin between the labels and accel strings
2676 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2678 // the separator height in pixels: in fact, strangely enough, the real height
2679 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2681 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2683 // the size of the standard checkmark bitmap
2684 static const wxCoord MENU_CHECK_SIZE
= 9;
2686 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2687 const wxRect
& rectOrig
,
2688 const wxString
& label
,
2692 wxRect rect
= rectOrig
;
2695 wxDCTextColourChanger
colChanger(dc
);
2697 if ( flags
& wxCONTROL_SELECTED
)
2699 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2701 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2702 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2703 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2704 dc
.DrawRectangle(rect
);
2707 // don't draw the focus rect around menu bar items
2708 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2709 wxALIGN_CENTRE
, indexAccel
);
2712 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2714 const wxMenuGeometryInfo
& gi
,
2715 const wxString
& label
,
2716 const wxString
& accel
,
2717 const wxBitmap
& bitmap
,
2721 const wxWin32MenuGeometryInfo
& geometryInfo
=
2722 (const wxWin32MenuGeometryInfo
&)gi
;
2727 rect
.width
= geometryInfo
.GetSize().x
;
2728 rect
.height
= geometryInfo
.GetItemHeight();
2730 // draw the selected item specially
2731 wxDCTextColourChanger
colChanger(dc
);
2732 if ( flags
& wxCONTROL_SELECTED
)
2734 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2736 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2737 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2738 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2739 dc
.DrawRectangle(rect
);
2742 // draw the bitmap: use the bitmap provided or the standard checkmark for
2743 // the checkable items
2744 wxBitmap bmp
= bitmap
;
2745 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2747 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2752 rect
.SetRight(geometryInfo
.GetLabelOffset());
2753 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2757 rect
.x
= geometryInfo
.GetLabelOffset();
2758 rect
.SetRight(geometryInfo
.GetAccelOffset());
2760 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2762 // draw the accel string
2763 rect
.x
= geometryInfo
.GetAccelOffset();
2764 rect
.SetRight(geometryInfo
.GetSize().x
);
2766 // NB: no accel index here
2767 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2769 // draw the submenu indicator
2770 if ( flags
& wxCONTROL_ISSUBMENU
)
2772 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2773 rect
.width
= MENU_RIGHT_MARGIN
;
2775 wxArrowStyle arrowStyle
;
2776 if ( flags
& wxCONTROL_DISABLED
)
2777 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2779 else if ( flags
& wxCONTROL_SELECTED
)
2780 arrowStyle
= Arrow_Inversed
;
2782 arrowStyle
= Arrow_Normal
;
2784 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2788 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2790 const wxMenuGeometryInfo
& geomInfo
)
2792 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2795 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2797 wxSize size
= sizeText
;
2799 // FIXME: menubar height is configurable under Windows
2806 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2807 const wxMenu
& menu
) const
2809 // prepare the dc: for now we draw all the items with the system font
2811 dc
.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
2813 // the height of a normal item
2814 wxCoord heightText
= dc
.GetCharHeight();
2819 // the max length of label and accel strings: the menu width is the sum of
2820 // them, even if they're for different items (as the accels should be
2823 // the max length of the bitmap is never 0 as Windows always leaves enough
2824 // space for a check mark indicator
2825 wxCoord widthLabelMax
= 0,
2827 widthBmpMax
= MENU_LEFT_MARGIN
;
2829 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2831 node
= node
->GetNext() )
2833 // height of this item
2836 wxMenuItem
*item
= node
->GetData();
2837 if ( item
->IsSeparator() )
2839 h
= MENU_SEPARATOR_HEIGHT
;
2841 else // not separator
2846 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2847 if ( widthLabel
> widthLabelMax
)
2849 widthLabelMax
= widthLabel
;
2853 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2854 if ( widthAccel
> widthAccelMax
)
2856 widthAccelMax
= widthAccel
;
2859 const wxBitmap
& bmp
= item
->GetBitmap();
2862 wxCoord widthBmp
= bmp
.GetWidth();
2863 if ( widthBmp
> widthBmpMax
)
2864 widthBmpMax
= widthBmp
;
2866 //else if ( item->IsCheckable() ): no need to check for this as
2867 // MENU_LEFT_MARGIN is big enough to show the check mark
2870 h
+= 2*MENU_VERT_MARGIN
;
2872 // remember the item position and height
2873 item
->SetGeometry(height
, h
);
2878 // bundle the metrics into a struct and return it
2879 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2881 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2882 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2883 if ( widthAccelMax
> 0 )
2885 // if we actually have any accesl, add a margin
2886 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2889 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2891 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2892 gi
->m_size
.y
= height
;
2897 // ----------------------------------------------------------------------------
2899 // ----------------------------------------------------------------------------
2901 static const wxCoord STATBAR_BORDER_X
= 2;
2902 static const wxCoord STATBAR_BORDER_Y
= 2;
2904 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2906 if ( borderBetweenFields
)
2907 *borderBetweenFields
= 2;
2909 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2912 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2914 const wxString
& label
,
2919 if ( flags
& wxCONTROL_ISDEFAULT
)
2921 // draw the size grip: it is a normal rect except that in the lower
2922 // right corner we have several bands which may be used for dragging
2923 // the status bar corner
2925 // each band consists of 4 stripes: m_penHighlight, double
2926 // m_penDarkGrey and transparent one
2927 wxCoord x2
= rect
.GetRight(),
2928 y2
= rect
.GetBottom();
2930 // draw the upper left part of the rect normally
2931 dc
.SetPen(m_penDarkGrey
);
2932 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
2933 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
2935 // draw the grey stripes of the grip
2937 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
2938 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2940 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2941 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
2944 // draw the white stripes
2945 dc
.SetPen(m_penHighlight
);
2946 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
2947 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2949 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2952 // draw the remaining rect boundaries
2953 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
2954 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
2955 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
2960 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
2964 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
2967 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2969 wxDCClipper
clipper(dc
, rectIn
);
2970 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
2973 // ----------------------------------------------------------------------------
2975 // ----------------------------------------------------------------------------
2977 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2979 wxBitmap
*bmpPressed
,
2980 wxBitmap
*bmpDisabled
)
2982 static const wxCoord widthCombo
= 16;
2983 static const wxCoord heightCombo
= 17;
2989 bmpNormal
->Create(widthCombo
, heightCombo
);
2990 dcMem
.SelectObject(*bmpNormal
);
2991 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2992 Arrow_Down
, Arrow_Normal
);
2997 bmpPressed
->Create(widthCombo
, heightCombo
);
2998 dcMem
.SelectObject(*bmpPressed
);
2999 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3000 Arrow_Down
, Arrow_Pressed
);
3005 bmpDisabled
->Create(widthCombo
, heightCombo
);
3006 dcMem
.SelectObject(*bmpDisabled
);
3007 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3008 Arrow_Down
, Arrow_Disabled
);
3012 // ----------------------------------------------------------------------------
3014 // ----------------------------------------------------------------------------
3016 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3017 const wxColour
& col
,
3020 wxBrush
brush(col
, wxSOLID
);
3022 dc
.SetPen(*wxTRANSPARENT_PEN
);
3023 dc
.DrawRectangle(rect
);
3026 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3027 const wxColour
& col
,
3031 // just fill it with the given or default bg colour
3032 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3033 DoDrawBackground(dc
, colBg
, rect
);
3036 // ----------------------------------------------------------------------------
3038 // ----------------------------------------------------------------------------
3040 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3045 // get the bitmap for this arrow
3046 wxArrowDirection arrowDir
;
3049 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3050 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3051 case wxUP
: arrowDir
= Arrow_Up
; break;
3052 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3055 wxFAIL_MSG(_T("unknown arrow direction"));
3059 wxArrowStyle arrowStyle
;
3060 if ( flags
& wxCONTROL_PRESSED
)
3062 // can't be pressed and disabled
3063 arrowStyle
= Arrow_Pressed
;
3067 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3070 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3073 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3075 wxArrowDirection arrowDir
,
3076 wxArrowStyle arrowStyle
)
3078 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3080 // under Windows the arrows always have the same size so just centre it in
3081 // the provided rectangle
3082 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3083 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3085 // Windows does it like this...
3086 if ( arrowDir
== Arrow_Left
)
3090 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3093 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3094 const wxRect
& rectAll
,
3095 wxArrowDirection arrowDir
,
3096 wxArrowStyle arrowStyle
)
3098 wxRect rect
= rectAll
;
3099 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3100 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3101 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3104 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3105 wxOrientation orient
,
3109 // we don't use the flags, the thumb never changes appearance
3110 wxRect rectThumb
= rect
;
3111 DrawArrowBorder(dc
, &rectThumb
);
3112 DrawBackground(dc
, wxNullColour
, rectThumb
);
3115 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3116 wxOrientation orient
,
3117 const wxRect
& rectBar
,
3120 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3121 ? wxColourScheme::SCROLLBAR_PRESSED
3122 : wxColourScheme::SCROLLBAR
;
3123 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3126 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3128 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3131 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3132 wxScrollBar::Element elem
,
3135 return StandardGetScrollbarRect(scrollbar
, elem
,
3136 thumbPos
, m_sizeScrollbarArrow
);
3139 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3141 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3144 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3145 const wxPoint
& pt
) const
3147 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3150 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3153 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3156 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3159 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3162 // ----------------------------------------------------------------------------
3163 // top level windows
3164 // ----------------------------------------------------------------------------
3166 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3168 wxRect client
= GetFrameClientArea(rect
, flags
);
3170 if ( client
.Inside(pt
) )
3171 return wxHT_TOPLEVEL_CLIENT_AREA
;
3173 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3175 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3177 if ( flags
& wxTOPLEVEL_ICON
)
3179 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3180 return wxHT_TOPLEVEL_ICON
;
3183 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3184 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3185 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3187 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3189 if ( btnRect
.Inside(pt
) )
3190 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3191 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3193 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3195 if ( btnRect
.Inside(pt
) )
3196 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3197 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3199 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3201 if ( btnRect
.Inside(pt
) )
3202 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3203 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3205 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3207 if ( btnRect
.Inside(pt
) )
3208 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3209 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3211 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3213 if ( btnRect
.Inside(pt
) )
3214 return wxHT_TOPLEVEL_BUTTON_HELP
;
3215 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3218 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3219 return wxHT_TOPLEVEL_TITLEBAR
;
3222 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3224 // we are certainly at one of borders, lets decide which one:
3227 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3228 if ( pt
.x
< client
.x
)
3229 border
|= wxHT_TOPLEVEL_BORDER_W
;
3230 else if ( pt
.x
>= client
.width
+ client
.x
)
3231 border
|= wxHT_TOPLEVEL_BORDER_E
;
3232 if ( pt
.y
< client
.y
)
3233 border
|= wxHT_TOPLEVEL_BORDER_N
;
3234 else if ( pt
.y
>= client
.height
+ client
.y
)
3235 border
|= wxHT_TOPLEVEL_BORDER_S
;
3239 return wxHT_NOWHERE
;
3242 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3244 const wxString
& title
,
3248 int specialButtonFlags
)
3250 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3252 DrawFrameBorder(dc
, rect
, flags
);
3254 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3256 DrawFrameBackground(dc
, rect
, flags
);
3257 if ( flags
& wxTOPLEVEL_ICON
)
3258 DrawFrameIcon(dc
, rect
, icon
, flags
);
3259 DrawFrameTitle(dc
, rect
, title
, flags
);
3261 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3263 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3264 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3266 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3268 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3269 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3270 specialButtonFlags
: 0);
3271 x
-= FRAME_BUTTON_WIDTH
+ 2;
3273 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3275 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3276 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3277 specialButtonFlags
: 0);
3278 x
-= FRAME_BUTTON_WIDTH
;
3280 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3282 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3283 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3284 specialButtonFlags
: 0);
3285 x
-= FRAME_BUTTON_WIDTH
;
3287 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3289 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3290 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3291 specialButtonFlags
: 0);
3292 x
-= FRAME_BUTTON_WIDTH
;
3294 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3296 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3297 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3298 specialButtonFlags
: 0);
3299 x
-= FRAME_BUTTON_WIDTH
;
3304 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3308 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3312 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3313 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3314 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3315 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3316 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3319 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3323 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3325 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3326 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3327 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3329 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3330 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3332 DrawBackground(dc
, col
, r
);
3335 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3337 const wxString
& title
,
3340 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3341 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3342 if ( flags
& wxTOPLEVEL_ICON
)
3343 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3347 dc
.SetFont(m_titlebarFont
);
3348 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
));
3349 dc
.DrawLabel(title
, wxNullBitmap
, r
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3352 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3359 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3360 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3364 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3365 wxCoord x
, wxCoord y
,
3369 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3374 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3375 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3376 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3377 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3378 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3380 wxFAIL_MSG(wxT("incorrect button specification"));
3383 if ( flags
& wxCONTROL_PRESSED
)
3385 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3386 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3387 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3388 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3392 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3393 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3394 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3395 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3400 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3405 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3407 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3408 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3409 FRAME_BORDER_THICKNESS
;
3412 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3414 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3415 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3421 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3424 wxSize
s(clientSize
);
3426 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3428 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3429 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3430 FRAME_BORDER_THICKNESS
;
3434 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3435 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3440 wxSize
wxWin32Renderer::GetFrameIconSize() const
3442 return wxSize(16, 16);
3447 // ----------------------------------------------------------------------------
3448 // text control geometry
3449 // ----------------------------------------------------------------------------
3451 static inline int GetTextBorderWidth()
3456 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3459 wxRect rectTotal
= rect
;
3461 wxCoord widthBorder
= GetTextBorderWidth();
3462 rectTotal
.Inflate(widthBorder
);
3464 // this is what Windows does
3470 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3472 wxCoord
*extraSpaceBeyond
)
3474 wxRect rectText
= rect
;
3476 // undo GetTextTotalArea()
3477 if ( rectText
.height
> 0 )
3480 wxCoord widthBorder
= GetTextBorderWidth();
3481 rectText
.Inflate(-widthBorder
);
3483 if ( extraSpaceBeyond
)
3484 *extraSpaceBeyond
= 0;
3489 // ----------------------------------------------------------------------------
3491 // ----------------------------------------------------------------------------
3493 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3496 if ( wxDynamicCast(window
, wxScrollBar
) )
3498 // we only set the width of vert scrollbars and height of the
3500 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3501 size
->y
= m_sizeScrollbarArrow
.y
;
3503 size
->x
= m_sizeScrollbarArrow
.x
;
3505 // skip border width adjustments, they don't make sense for us
3508 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3511 if ( wxDynamicCast(window
, wxButton
) )
3513 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3515 // TODO: don't harcode all this
3516 size
->x
+= 3*window
->GetCharWidth();
3518 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3519 if ( size
->y
< heightBtn
- 8 )
3520 size
->y
= heightBtn
;
3525 // no border width adjustments for buttons
3528 #endif // wxUSE_BUTTON
3530 // take into account the border width
3531 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3532 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3533 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3536 // ============================================================================
3538 // ============================================================================
3540 // ----------------------------------------------------------------------------
3541 // wxWin32InputHandler
3542 // ----------------------------------------------------------------------------
3544 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3546 m_renderer
= renderer
;
3549 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3550 const wxKeyEvent
& event
,
3556 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3557 const wxMouseEvent
& event
)
3559 // clicking on the control gives it focus
3560 if ( event
.ButtonDown() )
3562 wxWindow
*win
= control
->GetInputWindow();
3563 if ( wxWindow::FindFocus() != control
->GetInputWindow() )
3574 // ----------------------------------------------------------------------------
3575 // wxWin32ScrollBarInputHandler
3576 // ----------------------------------------------------------------------------
3578 wxWin32ScrollBarInputHandler::
3579 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3580 wxInputHandler
*handler
)
3581 : wxStdScrollBarInputHandler(renderer
, handler
)
3583 m_scrollPaused
= FALSE
;
3587 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3588 const wxControlAction
& action
)
3590 // stop if went beyond the position of the original click (this can only
3591 // happen when we scroll by pages)
3593 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3595 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3596 != wxHT_SCROLLBAR_BAR_2
;
3598 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3600 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3601 != wxHT_SCROLLBAR_BAR_1
;
3606 StopScrolling(scrollbar
);
3608 scrollbar
->Refresh();
3613 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3616 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3617 const wxMouseEvent
& event
)
3619 // remember the current state
3620 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3622 // do process the message
3623 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3625 // analyse the changes
3626 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3628 // we just started dragging the thumb, remember its initial position to
3629 // be able to restore it if the drag is cancelled later
3630 m_eventStartDrag
= event
;
3636 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3637 const wxMouseEvent
& event
)
3639 // we don't highlight scrollbar elements, so there is no need to process
3640 // mouse move events normally - only do it while mouse is captured (i.e.
3641 // when we're dragging the thumb or pressing on something)
3642 if ( !m_winCapture
)
3645 if ( event
.Entering() )
3647 // we're not interested in this at all
3651 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3653 if ( m_scrollPaused
)
3655 // check if the mouse returned to its original location
3657 if ( event
.Leaving() )
3663 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3664 if ( ht
== m_htLast
)
3666 // yes it did, resume scrolling
3667 m_scrollPaused
= FALSE
;
3668 if ( m_timerScroll
)
3670 // we were scrolling by line/page, restart timer
3671 m_timerScroll
->Start(m_interval
);
3673 Press(scrollbar
, TRUE
);
3675 else // we were dragging the thumb
3677 // restore its last location
3678 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3684 else // normal case, scrolling hasn't been paused
3686 // if we're scrolling the scrollbar because the arrow or the shaft was
3687 // pressed, check that the mouse stays on the same scrollbar element
3689 if ( event
.Moving() )
3691 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3693 else // event.Leaving()
3698 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3699 // is still ok - we only want to catch the case when the mouse leaves
3700 // the scrollbar here
3701 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3703 ht
= wxHT_SCROLLBAR_THUMB
;
3706 if ( ht
!= m_htLast
)
3708 // what were we doing? 2 possibilities: either an arrow/shaft was
3709 // pressed in which case we have a timer and so we just stop it or
3710 // we were dragging the thumb
3711 if ( m_timerScroll
)
3714 m_interval
= m_timerScroll
->GetInterval();
3715 m_timerScroll
->Stop();
3716 m_scrollPaused
= TRUE
;
3718 // unpress the arrow
3719 Press(scrollbar
, FALSE
);
3721 else // we were dragging the thumb
3723 // remember the current thumb position to be able to restore it
3724 // if the mouse returns to it later
3725 m_eventLastDrag
= event
;
3727 // and restore the original position (before dragging) of the
3729 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3736 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
3739 // ----------------------------------------------------------------------------
3740 // wxWin32CheckboxInputHandler
3741 // ----------------------------------------------------------------------------
3743 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3744 const wxKeyEvent
& event
,
3749 wxControlAction action
;
3750 int keycode
= event
.GetKeyCode();
3754 action
= wxACTION_CHECKBOX_TOGGLE
;
3758 case WXK_NUMPAD_SUBTRACT
:
3759 action
= wxACTION_CHECKBOX_CHECK
;
3763 case WXK_NUMPAD_ADD
:
3764 case WXK_NUMPAD_EQUAL
:
3765 action
= wxACTION_CHECKBOX_CLEAR
;
3771 control
->PerformAction(action
);
3780 // ----------------------------------------------------------------------------
3781 // wxWin32TextCtrlInputHandler
3782 // ----------------------------------------------------------------------------
3784 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3785 const wxKeyEvent
& event
,
3788 // handle only MSW-specific text bindings here, the others are handled in
3792 int keycode
= event
.GetKeyCode();
3794 wxControlAction action
;
3795 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
3797 action
= wxACTION_TEXT_CUT
;
3799 else if ( keycode
== WXK_INSERT
)
3801 if ( event
.ControlDown() )
3802 action
= wxACTION_TEXT_COPY
;
3803 else if ( event
.ShiftDown() )
3804 action
= wxACTION_TEXT_PASTE
;
3807 if ( action
!= wxACTION_NONE
)
3809 control
->PerformAction(action
);
3815 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
3818 // ----------------------------------------------------------------------------
3819 // wxWin32StatusBarInputHandler
3820 // ----------------------------------------------------------------------------
3822 wxWin32StatusBarInputHandler::
3823 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
3824 : wxStdInputHandler(handler
)
3829 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
3830 const wxPoint
& pt
) const
3832 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
3833 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
3835 wxSize sizeSbar
= statbar
->GetSize();
3837 return (sizeSbar
.x
- pt
.x
) < STATUSBAR_GRIP_SIZE
&&
3838 (sizeSbar
.y
- pt
.y
) < STATUSBAR_GRIP_SIZE
;
3844 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
3845 const wxMouseEvent
& event
)
3847 if ( event
.Button(1) )
3849 if ( event
.ButtonDown(1) )
3851 wxWindow
*statbar
= consumer
->GetInputWindow();
3853 if ( IsOnGrip(statbar
, event
.GetPosition()) )
3855 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
3859 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
3860 wxHT_TOPLEVEL_BORDER_SE
);
3862 statbar
->SetCursor(m_cursorOld
);
3870 return wxStdInputHandler::HandleMouse(consumer
, event
);
3873 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
3874 const wxMouseEvent
& event
)
3876 wxWindow
*statbar
= consumer
->GetInputWindow();
3878 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
3879 if ( isOnGrip
!= m_isOnGrip
)
3881 m_isOnGrip
= isOnGrip
;
3884 m_cursorOld
= statbar
->GetCursor();
3885 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
3889 statbar
->SetCursor(m_cursorOld
);
3893 return wxStdInputHandler::HandleMouseMove(consumer
, event
);