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;
86 IndicatorState_Normal
,
87 IndicatorState_Pressed
, // this one is for check/radioboxes
88 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
89 IndicatorState_Disabled
,
90 IndicatorState_SelectedDisabled
, // only for the menus
96 IndicatorStatus_Checked
,
97 IndicatorStatus_Unchecked
,
101 // wxWin32Renderer: draw the GUI elements in Win32 style
102 // ----------------------------------------------------------------------------
104 class wxWin32Renderer
: public wxRenderer
108 enum wxArrowDirection
123 Arrow_InversedDisabled
,
127 enum wxFrameButtonType
130 FrameButton_Minimize
,
131 FrameButton_Maximize
,
138 wxWin32Renderer(const wxColourScheme
*scheme
);
140 // implement the base class pure virtuals
141 virtual void DrawBackground(wxDC
& dc
,
145 virtual void DrawLabel(wxDC
& dc
,
146 const wxString
& label
,
149 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
151 wxRect
*rectBounds
= NULL
);
152 virtual void DrawButtonLabel(wxDC
& dc
,
153 const wxString
& label
,
154 const wxBitmap
& image
,
157 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
159 wxRect
*rectBounds
= NULL
);
160 virtual void DrawBorder(wxDC
& dc
,
164 wxRect
*rectIn
= (wxRect
*)NULL
);
165 virtual void DrawHorizontalLine(wxDC
& dc
,
166 wxCoord y
, wxCoord x1
, wxCoord x2
);
167 virtual void DrawVerticalLine(wxDC
& dc
,
168 wxCoord x
, wxCoord y1
, wxCoord y2
);
169 virtual void DrawFrame(wxDC
& dc
,
170 const wxString
& label
,
173 int alignment
= wxALIGN_LEFT
,
174 int indexAccel
= -1);
175 virtual void DrawTextBorder(wxDC
& dc
,
179 wxRect
*rectIn
= (wxRect
*)NULL
);
180 virtual void DrawButtonBorder(wxDC
& dc
,
183 wxRect
*rectIn
= (wxRect
*)NULL
);
184 virtual void DrawArrow(wxDC
& dc
,
188 virtual void DrawScrollbarArrow(wxDC
& dc
,
192 { DrawArrow(dc
, dir
, rect
, flags
); }
193 virtual void DrawScrollbarThumb(wxDC
& dc
,
194 wxOrientation orient
,
197 virtual void DrawScrollbarShaft(wxDC
& dc
,
198 wxOrientation orient
,
201 virtual void DrawScrollCorner(wxDC
& dc
,
203 virtual void DrawItem(wxDC
& dc
,
204 const wxString
& label
,
207 virtual void DrawCheckItem(wxDC
& dc
,
208 const wxString
& label
,
209 const wxBitmap
& bitmap
,
212 virtual void DrawCheckButton(wxDC
& dc
,
213 const wxString
& label
,
214 const wxBitmap
& bitmap
,
217 wxAlignment align
= wxALIGN_LEFT
,
218 int indexAccel
= -1);
219 virtual void DrawRadioButton(wxDC
& dc
,
220 const wxString
& label
,
221 const wxBitmap
& bitmap
,
224 wxAlignment align
= wxALIGN_LEFT
,
225 int indexAccel
= -1);
226 virtual void DrawTextLine(wxDC
& dc
,
227 const wxString
& text
,
232 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
233 virtual void DrawTab(wxDC
& dc
,
236 const wxString
& label
,
237 const wxBitmap
& bitmap
= wxNullBitmap
,
239 int indexAccel
= -1);
241 virtual void DrawSliderShaft(wxDC
& dc
,
243 wxOrientation orient
,
245 wxRect
*rectShaft
= NULL
);
246 virtual void DrawSliderThumb(wxDC
& dc
,
248 wxOrientation orient
,
250 virtual void DrawSliderTicks(wxDC
& dc
,
252 const wxSize
& sizeThumb
,
253 wxOrientation orient
,
260 virtual void DrawMenuBarItem(wxDC
& dc
,
262 const wxString
& label
,
264 int indexAccel
= -1);
265 virtual void DrawMenuItem(wxDC
& dc
,
267 const wxMenuGeometryInfo
& geometryInfo
,
268 const wxString
& label
,
269 const wxString
& accel
,
270 const wxBitmap
& bitmap
= wxNullBitmap
,
272 int indexAccel
= -1);
273 virtual void DrawMenuSeparator(wxDC
& dc
,
275 const wxMenuGeometryInfo
& geomInfo
);
278 virtual void DrawFrameTitleBar(wxDC
& dc
,
280 const wxString
& title
,
283 int pressedButtons
= 0);
284 virtual void DrawFrameBorder(wxDC
& dc
,
287 virtual void DrawFrameBackground(wxDC
& dc
,
290 virtual void DrawFrameTitle(wxDC
& dc
,
292 const wxString
& title
,
294 virtual void DrawFrameIcon(wxDC
& dc
,
298 virtual void DrawFrameButton(wxDC
& dc
,
299 wxCoord x
, wxCoord y
,
302 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
303 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
304 virtual wxSize
GetFrameIconSize() const;
306 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
308 wxBitmap
*bmpPressed
,
309 wxBitmap
*bmpDisabled
);
311 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
312 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
313 virtual bool AreScrollbarsInsideBorder() const;
315 virtual wxSize
GetScrollbarArrowSize() const
316 { return m_sizeScrollbarArrow
; }
317 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
318 wxScrollBar::Element elem
,
319 int thumbPos
= -1) const;
320 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
321 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
322 const wxPoint
& pt
) const;
323 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
325 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
326 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
327 { return fontHeight
+ 2; }
328 virtual wxSize
GetCheckBitmapSize() const
329 { return wxSize(13, 13); }
330 virtual wxSize
GetRadioBitmapSize() const
331 { return wxSize(12, 12); }
332 virtual wxCoord
GetCheckItemMargin() const
335 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
337 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
339 wxCoord
*extraSpaceBeyond
);
341 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
342 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
344 virtual wxCoord
GetSliderDim() const { return 20; }
345 virtual wxCoord
GetSliderTickLen() const { return 4; }
346 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
347 wxOrientation orient
) const;
348 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
349 wxOrientation orient
) const;
350 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
353 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
354 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
355 const wxMenu
& menu
) const;
358 // helper of DrawLabel() and DrawCheckOrRadioButton()
359 void DoDrawLabel(wxDC
& dc
,
360 const wxString
& label
,
363 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
365 wxRect
*rectBounds
= NULL
,
366 const wxPoint
& focusOffset
367 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
369 // common part of DrawLabel() and DrawItem()
370 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
372 // DrawLabel() and DrawButtonLabel() helper
373 void DrawLabelShadow(wxDC
& dc
,
374 const wxString
& label
,
379 // DrawButtonBorder() helper
380 void DoDrawBackground(wxDC
& dc
,
384 // DrawBorder() helpers: all of them shift and clip the DC after drawing
387 // just draw a rectangle with the given pen
388 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
390 // draw the lower left part of rectangle
391 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
393 // draw the rectange using the first brush for the left and top sides and
394 // the second one for the bottom and right ones
395 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
396 const wxPen
& pen1
, const wxPen
& pen2
);
398 // draw the normal 3D border
399 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
401 // draw the sunken 3D border
402 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
404 // draw the border used for scrollbar arrows
405 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
407 // public DrawArrow()s helper
408 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
409 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
411 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
412 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
413 wxArrowDirection arrowDir
,
414 wxArrowStyle arrowStyle
);
416 // DrawCheckButton/DrawRadioButton helper
417 void DrawCheckOrRadioButton(wxDC
& dc
,
418 const wxString
& label
,
419 const wxBitmap
& bitmap
,
424 wxCoord focusOffsetY
);
426 // draw a normal or transposed line (useful for using the same code fo both
427 // horizontal and vertical widgets)
428 void DrawLine(wxDC
& dc
,
429 wxCoord x1
, wxCoord y1
,
430 wxCoord x2
, wxCoord y2
,
431 bool transpose
= FALSE
)
434 dc
.DrawLine(y1
, x1
, y2
, x2
);
436 dc
.DrawLine(x1
, y1
, x2
, y2
);
439 // get the standard check/radio button bitmap
440 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
441 wxBitmap
GetCheckBitmap(int flags
)
442 { return GetIndicator(IndicatorType_Check
, flags
); }
443 wxBitmap
GetRadioBitmap(int flags
)
444 { return GetIndicator(IndicatorType_Radio
, flags
); }
447 const wxColourScheme
*m_scheme
;
449 // the sizing parameters (TODO make them changeable)
450 wxSize m_sizeScrollbarArrow
;
452 // GDI objects we use for drawing
453 wxColour m_colDarkGrey
,
461 wxFont m_titlebarFont
;
464 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
466 // first row is for the normal state, second - for the disabled
467 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
470 // ----------------------------------------------------------------------------
471 // wxWin32InputHandler and derived classes: process the keyboard and mouse
472 // messages according to Windows standards
473 // ----------------------------------------------------------------------------
475 class wxWin32InputHandler
: public wxInputHandler
478 wxWin32InputHandler(wxWin32Renderer
*renderer
);
480 virtual bool HandleKey(wxInputConsumer
*control
,
481 const wxKeyEvent
& event
,
483 virtual bool HandleMouse(wxInputConsumer
*control
,
484 const wxMouseEvent
& event
);
487 wxWin32Renderer
*m_renderer
;
490 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
493 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
494 wxInputHandler
*handler
);
496 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
497 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
499 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
500 const wxControlAction
& action
);
503 virtual bool IsAllowedButton(int button
) { return button
== 1; }
505 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
507 // we don't highlight anything
510 // the first and last event which caused the thumb to move
511 wxMouseEvent m_eventStartDrag
,
514 // have we paused the scrolling because the mouse moved?
517 // we remember the interval of the timer to be able to restart it
521 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
524 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
525 : wxStdCheckboxInputHandler(handler
) { }
527 virtual bool HandleKey(wxInputConsumer
*control
,
528 const wxKeyEvent
& event
,
532 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
535 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
536 : wxStdTextCtrlInputHandler(handler
) { }
538 virtual bool HandleKey(wxInputConsumer
*control
,
539 const wxKeyEvent
& event
,
543 // ----------------------------------------------------------------------------
544 // wxWin32ColourScheme: uses (default) Win32 colours
545 // ----------------------------------------------------------------------------
547 class wxWin32ColourScheme
: public wxColourScheme
550 virtual wxColour
Get(StdColour col
) const;
551 virtual wxColour
GetBackground(wxWindow
*win
) const;
554 // ----------------------------------------------------------------------------
556 // ----------------------------------------------------------------------------
558 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
560 class wxWin32Theme
: public wxTheme
564 virtual ~wxWin32Theme();
566 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
567 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
568 virtual wxColourScheme
*GetColourScheme();
571 // get the default input handler
572 wxInputHandler
*GetDefaultInputHandler();
574 wxWin32Renderer
*m_renderer
;
576 // the names of the already created handlers and the handlers themselves
577 // (these arrays are synchronized)
578 wxSortedArrayString m_handlerNames
;
579 wxArrayHandlers m_handlers
;
581 wxWin32InputHandler
*m_handlerDefault
;
583 wxWin32ColourScheme
*m_scheme
;
585 WX_DECLARE_THEME(win32
)
588 // ----------------------------------------------------------------------------
590 // ----------------------------------------------------------------------------
592 // frame buttons bitmaps
594 static const char *frame_button_close_xpm
[] = {
609 static const char *frame_button_help_xpm
[] = {
624 static const char *frame_button_maximize_xpm
[] = {
639 static const char *frame_button_minimize_xpm
[] = {
654 static const char *frame_button_restore_xpm
[] = {
671 static const char *checked_menu_xpm
[] = {
672 /* columns rows colors chars-per-pixel */
688 static const char *selected_checked_menu_xpm
[] = {
689 /* columns rows colors chars-per-pixel */
705 static const char *disabled_checked_menu_xpm
[] = {
706 /* columns rows colors chars-per-pixel */
723 static const char *selected_disabled_checked_menu_xpm
[] = {
724 /* columns rows colors chars-per-pixel */
740 // checkbox and radiobox bitmaps below
742 static const char *checked_xpm
[] = {
743 /* columns rows colors chars-per-pixel */
766 static const char *pressed_checked_xpm
[] = {
767 /* columns rows colors chars-per-pixel */
789 static const char *pressed_disabled_checked_xpm
[] = {
790 /* columns rows colors chars-per-pixel */
812 static const char *checked_item_xpm
[] = {
813 /* columns rows colors chars-per-pixel */
834 static const char *unchecked_xpm
[] = {
835 /* columns rows colors chars-per-pixel */
858 static const char *pressed_unchecked_xpm
[] = {
859 /* columns rows colors chars-per-pixel */
881 static const char *unchecked_item_xpm
[] = {
882 /* columns rows colors chars-per-pixel */
902 static const char *checked_radio_xpm
[] = {
903 /* columns rows colors chars-per-pixel */
926 static const char *pressed_checked_radio_xpm
[] = {
927 /* columns rows colors chars-per-pixel */
950 static const char *pressed_disabled_checked_radio_xpm
[] = {
951 /* columns rows colors chars-per-pixel */
974 static const char *unchecked_radio_xpm
[] = {
975 /* columns rows colors chars-per-pixel */
998 static const char *pressed_unchecked_radio_xpm
[] = {
999 /* columns rows colors chars-per-pixel */
1022 static const char **
1023 bmpIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1028 { checked_xpm
, unchecked_xpm
},
1031 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1034 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1040 { checked_radio_xpm
, unchecked_radio_xpm
},
1043 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1046 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1052 { checked_menu_xpm
, NULL
},
1055 { selected_checked_menu_xpm
, NULL
},
1058 { disabled_checked_menu_xpm
, NULL
},
1060 // disabled selected state
1061 { selected_disabled_checked_menu_xpm
, NULL
},
1065 // ============================================================================
1067 // ============================================================================
1069 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1071 // ----------------------------------------------------------------------------
1073 // ----------------------------------------------------------------------------
1075 wxWin32Theme::wxWin32Theme()
1077 m_scheme
= new wxWin32ColourScheme
;
1078 m_renderer
= new wxWin32Renderer(m_scheme
);
1079 m_handlerDefault
= NULL
;
1082 wxWin32Theme::~wxWin32Theme()
1084 size_t count
= m_handlers
.GetCount();
1085 for ( size_t n
= 0; n
< count
; n
++ )
1087 if ( m_handlers
[n
] != m_handlerDefault
)
1088 delete m_handlers
[n
];
1091 delete m_handlerDefault
;
1097 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1099 if ( !m_handlerDefault
)
1101 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1104 return m_handlerDefault
;
1107 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1109 wxInputHandler
*handler
;
1110 int n
= m_handlerNames
.Index(control
);
1111 if ( n
== wxNOT_FOUND
)
1113 // create a new handler
1114 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1115 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1116 GetDefaultInputHandler());
1118 else if ( control
== wxINP_HANDLER_BUTTON
)
1119 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1120 #endif // wxUSE_BUTTON
1122 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1123 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1124 #endif // wxUSE_CHECKBOX
1126 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1127 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1128 #endif // wxUSE_COMBOBOX
1130 else if ( control
== wxINP_HANDLER_LISTBOX
)
1131 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1132 #endif // wxUSE_LISTBOX
1133 #if wxUSE_CHECKLISTBOX
1134 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1135 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1136 #endif // wxUSE_CHECKLISTBOX
1138 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1139 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1140 #endif // wxUSE_TEXTCTRL
1142 else if ( control
== wxINP_HANDLER_SLIDER
)
1143 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1144 #endif // wxUSE_SLIDER
1146 else if ( control
== wxINP_HANDLER_SPINBTN
)
1147 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1148 #endif // wxUSE_SPINBTN
1150 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1151 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1152 #endif // wxUSE_NOTEBOOK
1154 handler
= GetDefaultInputHandler();
1156 n
= m_handlerNames
.Add(control
);
1157 m_handlers
.Insert(handler
, n
);
1159 else // we already have it
1161 handler
= m_handlers
[n
];
1167 wxColourScheme
*wxWin32Theme::GetColourScheme()
1172 // ============================================================================
1173 // wxWin32ColourScheme
1174 // ============================================================================
1176 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1179 if ( win
->UseBgCol() )
1181 // use the user specified colour
1182 col
= win
->GetBackgroundColour();
1185 if ( win
->IsContainerWindow() )
1187 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1190 if ( !text
->IsEnabled() ) // not IsEditable()
1192 //else: execute code below
1197 // doesn't depend on the state
1203 int flags
= win
->GetStateFlags();
1205 // the colour set by the user should be used for the normal state
1206 // and for the states for which we don't have any specific colours
1207 if ( !col
.Ok() || (flags
!= 0) )
1209 if ( wxDynamicCast(win
, wxScrollBar
) )
1210 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1220 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1224 // use the system colours under Windows
1225 #if defined(__WXMSW__)
1226 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1228 case CONTROL_PRESSED
:
1229 case CONTROL_CURRENT
:
1230 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1232 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1234 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1235 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1237 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1238 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1240 #if defined(COLOR_3DDKSHADOW)
1241 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1243 case SHADOW_DARK
: return *wxBLACK
;
1246 case CONTROL_TEXT_DISABLED
:
1247 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1249 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1251 case CONTROL_TEXT_DISABLED_SHADOW
:
1252 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1254 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1255 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1256 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1258 // use the standard Windows colours elsewhere
1259 case WINDOW
: return *wxWHITE
;
1261 case CONTROL_PRESSED
:
1262 case CONTROL_CURRENT
:
1263 case CONTROL
: return wxColour(0xc0c0c0);
1265 case CONTROL_TEXT
: return *wxBLACK
;
1267 case SCROLLBAR
: return wxColour(0xe0e0e0);
1268 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1270 case HIGHLIGHT
: return wxColour(0x800000);
1271 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1273 case SHADOW_DARK
: return *wxBLACK
;
1275 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1276 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1278 case SHADOW_IN
: return wxColour(0xc0c0c0);
1280 case CONTROL_TEXT_DISABLED_SHADOW
:
1281 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1283 case TITLEBAR
: return wxColour(0xaeaaae);
1284 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1285 case TITLEBAR_TEXT
: return *wxWHITE
;
1290 wxFAIL_MSG(_T("invalid standard colour"));
1295 // ============================================================================
1297 // ============================================================================
1299 // ----------------------------------------------------------------------------
1301 // ----------------------------------------------------------------------------
1303 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1307 m_sizeScrollbarArrow
= wxSize(16, 16);
1309 // init colours and pens
1310 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1312 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1313 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1315 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1317 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1318 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1320 m_titlebarFont
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
1321 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1323 // init the arrow bitmaps
1324 static const size_t ARROW_WIDTH
= 7;
1325 static const size_t ARROW_LENGTH
= 4;
1328 wxMemoryDC dcNormal
,
1331 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1333 bool isVertical
= n
> Arrow_Right
;
1346 // disabled arrow is larger because of the shadow
1347 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1348 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1350 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1351 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1353 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1354 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1358 dcNormal
.SetPen(m_penBlack
);
1359 dcDisabled
.SetPen(m_penDarkGrey
);
1361 // calculate the position of the point of the arrow
1365 x1
= (ARROW_WIDTH
- 1)/2;
1366 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1370 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1371 y1
= (ARROW_WIDTH
- 1)/2;
1382 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1384 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1385 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1392 if ( n
== Arrow_Up
)
1403 else // left or right arrow
1408 if ( n
== Arrow_Left
)
1421 // draw the shadow for the disabled one
1422 dcDisabled
.SetPen(m_penHighlight
);
1427 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1431 x1
= ARROW_LENGTH
- 1;
1432 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1435 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1436 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1441 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1445 x1
= ARROW_WIDTH
- 1;
1447 x2
= (ARROW_WIDTH
- 1)/2;
1449 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1450 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1455 // create the inversed bitmap but only for the right arrow as we only
1456 // use it for the menus
1457 if ( n
== Arrow_Right
)
1459 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1460 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1462 dcInverse
.Blit(0, 0, w
, h
,
1465 dcInverse
.SelectObject(wxNullBitmap
);
1467 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1468 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1470 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1471 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1473 dcInverse
.Blit(0, 0, w
, h
,
1476 dcInverse
.SelectObject(wxNullBitmap
);
1478 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1479 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1482 dcNormal
.SelectObject(wxNullBitmap
);
1483 dcDisabled
.SelectObject(wxNullBitmap
);
1485 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1486 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1487 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1488 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1490 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1493 // init the frame buttons bitmaps
1494 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1495 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1496 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1497 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1498 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1501 // ----------------------------------------------------------------------------
1503 // ----------------------------------------------------------------------------
1506 The raised border in Win32 looks like this:
1508 IIIIIIIIIIIIIIIIIIIIIIB
1510 I GB I = white (HILIGHT)
1511 I GB H = light grey (LIGHT)
1512 I GB G = dark grey (SHADOI)
1513 I GB B = black (DKSHADOI)
1514 I GB I = hIghlight (COLOR_3DHILIGHT)
1516 IGGGGGGGGGGGGGGGGGGGGGB
1517 BBBBBBBBBBBBBBBBBBBBBBB
1519 The sunken border looks like this:
1521 GGGGGGGGGGGGGGGGGGGGGGI
1522 GBBBBBBBBBBBBBBBBBBBBHI
1529 GHHHHHHHHHHHHHHHHHHHHHI
1530 IIIIIIIIIIIIIIIIIIIIIII
1532 The static border (used for the controls which don't get focus) is like
1535 GGGGGGGGGGGGGGGGGGGGGGW
1543 WWWWWWWWWWWWWWWWWWWWWWW
1545 The most complicated is the double border:
1547 HHHHHHHHHHHHHHHHHHHHHHB
1548 HWWWWWWWWWWWWWWWWWWWWGB
1549 HWHHHHHHHHHHHHHHHHHHHGB
1554 HWHHHHHHHHHHHHHHHHHHHGB
1555 HGGGGGGGGGGGGGGGGGGGGGB
1556 BBBBBBBBBBBBBBBBBBBBBBB
1558 And the simple border is, well, simple:
1560 BBBBBBBBBBBBBBBBBBBBBBB
1569 BBBBBBBBBBBBBBBBBBBBBBB
1572 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1576 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1577 dc
.DrawRectangle(*rect
);
1583 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1585 // draw the bottom and right sides
1587 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1588 rect
->GetRight() + 1, rect
->GetBottom());
1589 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1590 rect
->GetRight(), rect
->GetBottom());
1597 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1598 const wxPen
& pen1
, const wxPen
& pen2
)
1600 // draw the rectangle
1602 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1603 rect
->GetLeft(), rect
->GetBottom());
1604 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1605 rect
->GetRight(), rect
->GetTop());
1607 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1608 rect
->GetRight(), rect
->GetBottom());
1609 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1610 rect
->GetRight() + 1, rect
->GetBottom());
1616 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1618 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1619 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1622 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1624 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1625 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1628 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1632 DrawRect(dc
, rect
, m_penDarkGrey
);
1634 // the arrow is usually drawn inside border of width 2 and is offset by
1635 // another pixel in both directions when it's pressed - as the border
1636 // in this case is more narrow as well, we have to adjust rect like
1644 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1645 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1649 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1651 const wxRect
& rectTotal
,
1652 int WXUNUSED(flags
),
1657 wxRect rect
= rectTotal
;
1661 case wxBORDER_SUNKEN
:
1662 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1664 DrawSunkenBorder(dc
, &rect
);
1668 case wxBORDER_STATIC
:
1669 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1672 case wxBORDER_RAISED
:
1673 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1675 DrawRaisedBorder(dc
, &rect
);
1679 case wxBORDER_DOUBLE
:
1680 DrawArrowBorder(dc
, &rect
);
1681 DrawRect(dc
, &rect
, m_penLightGrey
);
1684 case wxBORDER_SIMPLE
:
1685 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1687 DrawRect(dc
, &rect
, m_penBlack
);
1692 wxFAIL_MSG(_T("unknown border type"));
1695 case wxBORDER_DEFAULT
:
1704 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1709 case wxBORDER_RAISED
:
1710 case wxBORDER_SUNKEN
:
1711 width
= BORDER_THICKNESS
;
1714 case wxBORDER_SIMPLE
:
1715 case wxBORDER_STATIC
:
1719 case wxBORDER_DOUBLE
:
1724 wxFAIL_MSG(_T("unknown border type"));
1727 case wxBORDER_DEFAULT
:
1737 rect
.height
= width
;
1742 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1747 // ----------------------------------------------------------------------------
1749 // ----------------------------------------------------------------------------
1751 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1757 // text controls are not special under windows
1758 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1761 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1762 const wxRect
& rectTotal
,
1766 wxRect rect
= rectTotal
;
1768 if ( flags
& wxCONTROL_PRESSED
)
1770 // button pressed: draw a double border around it
1771 DrawRect(dc
, &rect
, m_penBlack
);
1772 DrawRect(dc
, &rect
, m_penDarkGrey
);
1776 // button not pressed
1778 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1780 // button either default or focused (or both): add an extra border around it
1781 DrawRect(dc
, &rect
, m_penBlack
);
1784 // now draw a normal button
1785 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1786 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1795 // ----------------------------------------------------------------------------
1797 // ----------------------------------------------------------------------------
1799 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1800 wxCoord y
, wxCoord x1
, wxCoord x2
)
1802 dc
.SetPen(m_penDarkGrey
);
1803 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1804 dc
.SetPen(m_penHighlight
);
1806 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1809 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1810 wxCoord x
, wxCoord y1
, wxCoord y2
)
1812 dc
.SetPen(m_penDarkGrey
);
1813 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1814 dc
.SetPen(m_penHighlight
);
1816 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1819 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1820 const wxString
& label
,
1826 wxCoord height
= 0; // of the label
1827 wxRect rectFrame
= rect
;
1828 if ( !label
.empty() )
1830 // the text should touch the top border of the rect, so the frame
1831 // itself should be lower
1832 dc
.GetTextExtent(label
, NULL
, &height
);
1833 rectFrame
.y
+= height
/ 2;
1834 rectFrame
.height
-= height
/ 2;
1836 // we have to draw each part of the frame individually as we can't
1837 // erase the background beyond the label as it might contain some
1838 // pixmap already, so drawing everything and then overwriting part of
1839 // the frame with label doesn't work
1841 // TODO: the +5 and space insertion should be customizable
1844 rectText
.x
= rectFrame
.x
+ 5;
1845 rectText
.y
= rect
.y
;
1846 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1847 rectText
.height
= height
;
1850 label2
<< _T(' ') << label
<< _T(' ');
1851 if ( indexAccel
!= -1 )
1853 // adjust it as we prepended a space
1858 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1860 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1864 // just draw the complete frame
1865 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1866 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1870 // ----------------------------------------------------------------------------
1872 // ----------------------------------------------------------------------------
1874 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1876 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1877 // pixels each while we really need dots here... PS_ALTERNATE might
1878 // work, but it is for NT 5 only
1880 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1882 // draw the pixels manually: note that to behave in the same manner as
1883 // DrawRect(), we must exclude the bottom and right borders from the
1885 wxCoord x1
= rect
.GetLeft(),
1887 x2
= rect
.GetRight(),
1888 y2
= rect
.GetBottom();
1890 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1892 // this seems to be closer than what Windows does than wxINVERT although
1893 // I'm still not sure if it's correct
1894 dc
.SetLogicalFunction(wxAND_REVERSE
);
1897 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1898 dc
.DrawPoint(z
, rect
.GetTop());
1900 wxCoord shift
= z
== x2
? 0 : 1;
1901 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1902 dc
.DrawPoint(x2
, z
);
1904 shift
= z
== y2
? 0 : 1;
1905 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1906 dc
.DrawPoint(z
, y2
);
1908 shift
= z
== x1
? 0 : 1;
1909 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
1910 dc
.DrawPoint(x1
, z
);
1912 dc
.SetLogicalFunction(wxCOPY
);
1916 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
1917 const wxString
& label
,
1922 // draw shadow of the text
1923 dc
.SetTextForeground(m_colHighlight
);
1924 wxRect rectShadow
= rect
;
1927 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1929 // make the text grey
1930 dc
.SetTextForeground(m_colDarkGrey
);
1933 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1934 const wxString
& label
,
1941 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
1944 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
1945 const wxString
& label
,
1951 const wxPoint
& focusOffset
)
1953 // the underscores are not drawn for focused controls in wxMSW
1954 if ( flags
& wxCONTROL_FOCUSED
)
1959 if ( flags
& wxCONTROL_DISABLED
)
1961 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
1962 // currently only can happen for a menu item and it seems that Windows
1963 // doesn't draw the shadow in this case, so we don't do it neither
1964 if ( flags
& wxCONTROL_SELECTED
)
1966 // just make the label text greyed out
1967 dc
.SetTextForeground(m_colDarkGrey
);
1969 else // draw normal disabled label
1971 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
1976 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
1978 if ( flags
& wxCONTROL_DISABLED
)
1980 // restore the fg colour
1981 dc
.SetTextForeground(*wxBLACK
);
1984 if ( flags
& wxCONTROL_FOCUSED
)
1986 if ( focusOffset
.x
|| focusOffset
.y
)
1988 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
1991 DrawFocusRect(dc
, rectLabel
);
1995 *rectBounds
= rectLabel
;
1998 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
1999 const wxString
& label
,
2000 const wxBitmap
& image
,
2007 // the underscores are not drawn for focused controls in wxMSW
2008 if ( flags
& wxCONTROL_PRESSED
)
2013 wxRect rectLabel
= rect
;
2014 if ( !label
.empty() )
2016 // shift the label if a button is pressed
2017 if ( flags
& wxCONTROL_PRESSED
)
2023 if ( flags
& wxCONTROL_DISABLED
)
2025 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2028 // leave enough space for the focus rectangle
2029 if ( flags
& wxCONTROL_FOCUSED
)
2031 rectLabel
.Inflate(-2);
2035 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2037 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2039 if ( flags
& wxCONTROL_PRESSED
)
2041 // the focus rectangle is never pressed, so undo the shift done
2049 DrawFocusRect(dc
, rectLabel
);
2053 // ----------------------------------------------------------------------------
2054 // (check)listbox items
2055 // ----------------------------------------------------------------------------
2057 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2058 const wxString
& label
,
2062 wxDCTextColourChanger
colChanger(dc
);
2064 if ( flags
& wxCONTROL_SELECTED
)
2066 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2068 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2069 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2070 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2071 dc
.DrawRectangle(rect
);
2074 wxRect rectText
= rect
;
2076 rectText
.width
-= 2;
2077 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2079 if ( flags
& wxCONTROL_FOCUSED
)
2081 DrawFocusRect(dc
, rect
);
2085 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2086 const wxString
& label
,
2087 const wxBitmap
& bitmap
,
2096 else // use default bitmap
2098 bmp
= wxBitmap(flags
& wxCONTROL_CHECKED
? checked_item_xpm
2099 : unchecked_item_xpm
);
2102 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2103 TRUE
/* use mask */);
2105 wxRect rectLabel
= rect
;
2106 int bmpWidth
= bmp
.GetWidth();
2107 rectLabel
.x
+= bmpWidth
;
2108 rectLabel
.width
-= bmpWidth
;
2110 DrawItem(dc
, label
, rectLabel
, flags
);
2113 // ----------------------------------------------------------------------------
2114 // check/radio buttons
2115 // ----------------------------------------------------------------------------
2117 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2119 IndicatorState indState
;
2120 if ( flags
& wxCONTROL_SELECTED
)
2121 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2122 : IndicatorState_Selected
;
2123 else if ( flags
& wxCONTROL_DISABLED
)
2124 indState
= IndicatorState_Disabled
;
2125 else if ( flags
& wxCONTROL_PRESSED
)
2126 indState
= IndicatorState_Pressed
;
2128 indState
= IndicatorState_Normal
;
2130 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2131 ? IndicatorStatus_Checked
2132 : IndicatorStatus_Unchecked
;
2134 const char **xpm
= bmpIndicators
[indType
][indState
][indStatus
];
2135 return xpm
? wxBitmap(xpm
) : wxNullBitmap
;
2138 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2139 const wxString
& label
,
2140 const wxBitmap
& bitmap
,
2145 wxCoord focusOffsetY
)
2147 // calculate the position of the bitmap and of the label
2148 wxCoord heightBmp
= bitmap
.GetHeight();
2150 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2153 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2154 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2156 // align label vertically with the bitmap - looks nicer like this
2157 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2159 // calc horz position
2160 if ( align
== wxALIGN_RIGHT
)
2162 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2163 rectLabel
.x
= rect
.x
+ 3;
2164 rectLabel
.SetRight(xBmp
);
2166 else // normal (checkbox to the left of the text) case
2169 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2170 rectLabel
.SetRight(rect
.GetRight());
2173 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2176 dc
, label
, rectLabel
,
2178 wxALIGN_LEFT
| wxALIGN_TOP
,
2180 NULL
, // we don't need bounding rect
2181 // use custom vert focus rect offset
2182 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2186 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2187 const wxString
& label
,
2188 const wxBitmap
& bitmap
,
2194 DrawCheckOrRadioButton(dc
, label
,
2195 bitmap
.Ok() ? bitmap
: GetRadioBitmap(flags
),
2196 rect
, flags
, align
, indexAccel
,
2197 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2200 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2201 const wxString
& label
,
2202 const wxBitmap
& bitmap
,
2208 DrawCheckOrRadioButton(dc
, label
,
2209 bitmap
.Ok() ? bitmap
: GetCheckBitmap(flags
),
2210 rect
, flags
, align
, indexAccel
,
2211 0); // no focus rect offset for checkboxes
2214 // ----------------------------------------------------------------------------
2216 // ----------------------------------------------------------------------------
2218 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2219 const wxString
& text
,
2225 // nothing special to do here
2226 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2229 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2231 // we don't draw them
2234 // ----------------------------------------------------------------------------
2236 // ----------------------------------------------------------------------------
2238 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2239 const wxRect
& rectOrig
,
2241 const wxString
& label
,
2242 const wxBitmap
& bitmap
,
2246 wxRect rect
= rectOrig
;
2248 // the current tab is drawn indented (to the top for default case) and
2249 // bigger than the other ones
2250 const wxSize indent
= GetTabIndent();
2251 if ( flags
& wxCONTROL_SELECTED
)
2256 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2260 rect
.Inflate(indent
.x
, 0);
2262 rect
.height
+= indent
.y
;
2266 rect
.Inflate(indent
.x
, 0);
2267 rect
.height
+= indent
.y
;
2272 wxFAIL_MSG(_T("TODO"));
2277 // draw the text, image and the focus around them (if necessary)
2278 wxRect rectLabel
= rect
;
2279 rectLabel
.Deflate(1, 1);
2280 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2281 flags
, wxALIGN_CENTRE
, indexAccel
);
2283 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2284 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2287 x2
= rect
.GetRight(),
2288 y2
= rect
.GetBottom();
2290 // FIXME: all this code will break if the tab indent or the border width,
2291 // it is tied to the fact that both of them are equal to 2
2296 dc
.SetPen(m_penHighlight
);
2297 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2298 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2299 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2301 dc
.SetPen(m_penBlack
);
2302 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2303 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2305 dc
.SetPen(m_penDarkGrey
);
2306 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2308 if ( flags
& wxCONTROL_SELECTED
)
2310 dc
.SetPen(m_penLightGrey
);
2312 // overwrite the part of the border below this tab
2313 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2315 // and the shadow of the tab to the left of us
2316 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2321 dc
.SetPen(m_penHighlight
);
2322 // we need to continue one pixel further to overwrite the corner of
2323 // the border for the selected tab
2324 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2326 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2328 dc
.SetPen(m_penBlack
);
2329 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2330 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2331 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2333 dc
.SetPen(m_penDarkGrey
);
2334 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2335 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2337 if ( flags
& wxCONTROL_SELECTED
)
2339 dc
.SetPen(m_penLightGrey
);
2341 // overwrite the part of the (double!) border above this tab
2342 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2343 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2345 // and the shadow of the tab to the left of us
2346 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2352 wxFAIL_MSG(_T("TODO"));
2356 // ----------------------------------------------------------------------------
2358 // ----------------------------------------------------------------------------
2360 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2361 wxOrientation orient
) const
2365 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2366 if ( orient
== wxHORIZONTAL
)
2368 size
.y
= rect
.height
- 6;
2369 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2373 size
.x
= rect
.width
- 6;
2374 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2380 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2381 wxOrientation orient
) const
2383 static const wxCoord SLIDER_MARGIN
= 6;
2385 wxRect rect
= rectOrig
;
2387 if ( orient
== wxHORIZONTAL
)
2389 // make the rect of minimal width and centre it
2390 rect
.height
= 2*BORDER_THICKNESS
;
2391 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2395 // leave margins on the sides
2396 rect
.Deflate(SLIDER_MARGIN
, 0);
2400 // same as above but in other direction
2401 rect
.width
= 2*BORDER_THICKNESS
;
2402 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2406 rect
.Deflate(0, SLIDER_MARGIN
);
2412 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2413 const wxRect
& rectOrig
,
2414 wxOrientation orient
,
2418 if ( flags
& wxCONTROL_FOCUSED
)
2420 DrawFocusRect(dc
, rectOrig
);
2423 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2428 DrawSunkenBorder(dc
, &rect
);
2431 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2433 wxOrientation orient
,
2437 we are drawing a shape of this form
2442 H DB where H is hightlight colour
2455 The interior of this shape is filled with the hatched brush if the thumb
2459 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2461 bool transpose
= orient
== wxVERTICAL
;
2463 wxCoord x
, y
, x2
, y2
;
2468 x2
= rect
.GetBottom();
2469 y2
= rect
.GetRight();
2475 x2
= rect
.GetRight();
2476 y2
= rect
.GetBottom();
2479 // the size of the pointed part of the thumb
2480 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2482 wxCoord x3
= x
+ sizeArrow
,
2483 y3
= y2
- sizeArrow
;
2485 dc
.SetPen(m_penHighlight
);
2486 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2487 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2488 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2490 dc
.SetPen(m_penBlack
);
2491 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2492 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2494 dc
.SetPen(m_penDarkGrey
);
2495 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2496 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2498 if ( flags
& wxCONTROL_PRESSED
)
2500 // TODO: MSW fills the entire area inside, not just the rect
2501 wxRect rectInt
= rect
;
2503 rectInt
.SetRight(y3
);
2505 rectInt
.SetBottom(y3
);
2508 static const char *stipple_xpm
[] = {
2509 /* columns rows colors chars-per-pixel */
2517 dc
.SetBrush(wxBrush(stipple_xpm
));
2519 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2520 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2521 dc
.SetPen(*wxTRANSPARENT_PEN
);
2522 dc
.DrawRectangle(rectInt
);
2526 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2528 const wxSize
& sizeThumb
,
2529 wxOrientation orient
,
2541 // the variable names correspond to horizontal case, but they can be used
2542 // for both orientations
2543 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2544 if ( orient
== wxHORIZONTAL
)
2546 x1
= rect
.GetLeft();
2547 x2
= rect
.GetRight();
2549 // draw from bottom to top to leave one pixel space between the ticks
2550 // and the slider as Windows do
2551 y1
= rect
.GetBottom();
2556 widthThumb
= sizeThumb
.x
;
2561 x2
= rect
.GetBottom();
2563 y1
= rect
.GetRight();
2564 y2
= rect
.GetLeft();
2568 widthThumb
= sizeThumb
.y
;
2571 // the first tick should be positioned in such way that a thumb drawn in
2572 // the first position points down directly to it
2573 x1
+= widthThumb
/ 2;
2574 x2
-= widthThumb
/ 2;
2576 // this also means that we have slightly less space for the ticks in
2577 // between the first and the last
2580 dc
.SetPen(m_penBlack
);
2582 int range
= end
- start
;
2583 for ( int n
= 0; n
< range
; n
+= step
)
2585 wxCoord x
= x1
+ (len
*n
) / range
;
2587 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2590 // always draw the line at the end position
2591 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2594 // ----------------------------------------------------------------------------
2596 // ----------------------------------------------------------------------------
2600 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2601 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2604 virtual wxSize
GetSize() const { return m_size
; }
2606 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2607 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2609 wxCoord
GetItemHeight() const { return m_heightItem
; }
2612 // the total size of the menu
2615 // the offset of the start of the menu item label
2618 // the offset of the start of the accel label
2621 // the height of a normal (not separator) item
2622 wxCoord m_heightItem
;
2624 friend wxMenuGeometryInfo
*wxWin32Renderer::
2625 GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2628 #endif // wxUSE_MENUS
2630 // FIXME: all constants are hardcoded but shouldn't be
2631 static const wxCoord MENU_LEFT_MARGIN
= 9;
2632 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2633 static const wxCoord MENU_VERT_MARGIN
= 3;
2635 // the margin around bitmap/check marks (on each side)
2636 static const wxCoord MENU_BMP_MARGIN
= 2;
2638 // the margin between the labels and accel strings
2639 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2641 // the separator height in pixels: in fact, strangely enough, the real height
2642 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2644 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2646 // the size of the standard checkmark bitmap
2647 static const wxCoord MENU_CHECK_SIZE
= 9;
2649 // we can't implement these methods without wxMenuGeometryInfo implementation
2650 // which we don't have if !wxUSE_MENUS
2653 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2654 const wxRect
& rectOrig
,
2655 const wxString
& label
,
2659 wxRect rect
= rectOrig
;
2662 wxDCTextColourChanger
colChanger(dc
);
2664 if ( flags
& wxCONTROL_SELECTED
)
2666 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2668 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2669 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2670 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2671 dc
.DrawRectangle(rect
);
2674 // don't draw the focus rect around menu bar items
2675 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2676 wxALIGN_CENTRE
, indexAccel
);
2679 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2681 const wxMenuGeometryInfo
& gi
,
2682 const wxString
& label
,
2683 const wxString
& accel
,
2684 const wxBitmap
& bitmap
,
2688 const wxWin32MenuGeometryInfo
& geometryInfo
=
2689 (const wxWin32MenuGeometryInfo
&)gi
;
2694 rect
.width
= geometryInfo
.GetSize().x
;
2695 rect
.height
= geometryInfo
.GetItemHeight();
2697 // draw the selected item specially
2698 wxDCTextColourChanger
colChanger(dc
);
2699 if ( flags
& wxCONTROL_SELECTED
)
2701 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2703 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2704 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2705 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2706 dc
.DrawRectangle(rect
);
2709 // draw the bitmap: use the bitmap provided or the standard checkmark for
2710 // the checkable items
2711 wxBitmap bmp
= bitmap
;
2712 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2714 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2719 rect
.SetRight(geometryInfo
.GetLabelOffset());
2720 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2724 rect
.x
= geometryInfo
.GetLabelOffset();
2725 rect
.SetRight(geometryInfo
.GetAccelOffset());
2727 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2729 // draw the accel string
2730 rect
.x
= geometryInfo
.GetAccelOffset();
2731 rect
.SetRight(geometryInfo
.GetSize().x
);
2733 // NB: no accel index here
2734 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2736 // draw the submenu indicator
2737 if ( flags
& wxCONTROL_ISSUBMENU
)
2739 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2740 rect
.width
= MENU_RIGHT_MARGIN
;
2742 wxArrowStyle arrowStyle
;
2743 if ( flags
& wxCONTROL_DISABLED
)
2744 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2746 else if ( flags
& wxCONTROL_SELECTED
)
2747 arrowStyle
= Arrow_Inversed
;
2749 arrowStyle
= Arrow_Normal
;
2751 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2755 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2757 const wxMenuGeometryInfo
& geomInfo
)
2759 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2762 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2764 wxSize size
= sizeText
;
2766 // FIXME: menubar height is configurable under Windows
2773 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2774 const wxMenu
& menu
) const
2776 // prepare the dc: for now we draw all the items with the system font
2778 dc
.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
2780 // the height of a normal item
2781 wxCoord heightText
= dc
.GetCharHeight();
2786 // the max length of label and accel strings: the menu width is the sum of
2787 // them, even if they're for different items (as the accels should be
2790 // the max length of the bitmap is never 0 as Windows always leaves enough
2791 // space for a check mark indicator
2792 wxCoord widthLabelMax
= 0,
2794 widthBmpMax
= MENU_LEFT_MARGIN
;
2796 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2798 node
= node
->GetNext() )
2800 // height of this item
2803 wxMenuItem
*item
= node
->GetData();
2804 if ( item
->IsSeparator() )
2806 h
= MENU_SEPARATOR_HEIGHT
;
2808 else // not separator
2813 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2814 if ( widthLabel
> widthLabelMax
)
2816 widthLabelMax
= widthLabel
;
2820 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2821 if ( widthAccel
> widthAccelMax
)
2823 widthAccelMax
= widthAccel
;
2826 const wxBitmap
& bmp
= item
->GetBitmap();
2829 wxCoord widthBmp
= bmp
.GetWidth();
2830 if ( widthBmp
> widthBmpMax
)
2831 widthBmpMax
= widthBmp
;
2833 //else if ( item->IsCheckable() ): no need to check for this as
2834 // MENU_LEFT_MARGIN is big enough to show the check mark
2837 h
+= 2*MENU_VERT_MARGIN
;
2839 // remember the item position and height
2840 item
->SetGeometry(height
, h
);
2845 // bundle the metrics into a struct and return it
2846 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2848 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2849 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2850 if ( widthAccelMax
> 0 )
2852 // if we actually have any accesl, add a margin
2853 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2856 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2858 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2859 gi
->m_size
.y
= height
;
2864 #else // !wxUSE_MENUS
2867 void wxWin32Renderer::DrawMenuBarItem(wxDC& WXUNUSED(dc),
2868 const wxRect& WXUNUSED(rectOrig),
2869 const wxString& WXUNUSED(label),
2870 int WXUNUSED(flags),
2871 int WXUNUSED(indexAccel))
2875 void wxWin32Renderer::DrawMenuItem(wxDC& WXUNUSED(dc),
2876 wxCoord WXUNUSED(y),
2877 const wxMenuGeometryInfo& WXUNUSED(gi),
2878 const wxString& WXUNUSED(label),
2879 const wxString& WXUNUSED(accel),
2880 const wxBitmap& WXUNUSED(bitmap),
2881 int WXUNUSED(flags),
2882 int WXUNUSED(indexAccel))
2886 void wxWin32Renderer::DrawMenuSeparator(wxDC& WXUNUSED(dc),
2887 wxCoord WXUNUSED(y),
2888 const wxMenuGeometryInfo& WXUNUSED(gi))
2892 wxSize wxWin32Renderer::GetMenuBarItemSize(const wxSize& size) const
2897 wxMenuGeometryInfo *
2898 wxWin32Renderer::GetMenuGeometry(wxWindow *WXUNUSED(win),
2899 const wxMenu& WXUNUSED(menu)) const
2905 #endif // wxUSE_MENUS/!wxUSE_MENUS
2907 // ----------------------------------------------------------------------------
2909 // ----------------------------------------------------------------------------
2911 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2913 wxBitmap
*bmpPressed
,
2914 wxBitmap
*bmpDisabled
)
2916 static const wxCoord widthCombo
= 16;
2917 static const wxCoord heightCombo
= 17;
2923 bmpNormal
->Create(widthCombo
, heightCombo
);
2924 dcMem
.SelectObject(*bmpNormal
);
2925 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2926 Arrow_Down
, Arrow_Normal
);
2931 bmpPressed
->Create(widthCombo
, heightCombo
);
2932 dcMem
.SelectObject(*bmpPressed
);
2933 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2934 Arrow_Down
, Arrow_Pressed
);
2939 bmpDisabled
->Create(widthCombo
, heightCombo
);
2940 dcMem
.SelectObject(*bmpDisabled
);
2941 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2942 Arrow_Down
, Arrow_Disabled
);
2946 // ----------------------------------------------------------------------------
2948 // ----------------------------------------------------------------------------
2950 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
2951 const wxColour
& col
,
2954 wxBrush
brush(col
, wxSOLID
);
2956 dc
.SetPen(*wxTRANSPARENT_PEN
);
2957 dc
.DrawRectangle(rect
);
2960 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
2961 const wxColour
& col
,
2965 // just fill it with the given or default bg colour
2966 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
2967 DoDrawBackground(dc
, colBg
, rect
);
2970 // ----------------------------------------------------------------------------
2972 // ----------------------------------------------------------------------------
2974 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
2979 // get the bitmap for this arrow
2980 wxArrowDirection arrowDir
;
2983 case wxLEFT
: arrowDir
= Arrow_Left
; break;
2984 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
2985 case wxUP
: arrowDir
= Arrow_Up
; break;
2986 case wxDOWN
: arrowDir
= Arrow_Down
; break;
2989 wxFAIL_MSG(_T("unknown arrow direction"));
2993 wxArrowStyle arrowStyle
;
2994 if ( flags
& wxCONTROL_PRESSED
)
2996 // can't be pressed and disabled
2997 arrowStyle
= Arrow_Pressed
;
3001 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3004 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3007 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3009 wxArrowDirection arrowDir
,
3010 wxArrowStyle arrowStyle
)
3012 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3014 // under Windows the arrows always have the same size so just centre it in
3015 // the provided rectangle
3016 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3017 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3019 // Windows does it like this...
3020 if ( arrowDir
== Arrow_Left
)
3024 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3027 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3028 const wxRect
& rectAll
,
3029 wxArrowDirection arrowDir
,
3030 wxArrowStyle arrowStyle
)
3032 wxRect rect
= rectAll
;
3033 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3034 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3035 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3038 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3039 wxOrientation orient
,
3043 // we don't use the flags, the thumb never changes appearance
3044 wxRect rectThumb
= rect
;
3045 DrawArrowBorder(dc
, &rectThumb
);
3046 DrawBackground(dc
, wxNullColour
, rectThumb
);
3049 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3050 wxOrientation orient
,
3051 const wxRect
& rectBar
,
3054 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3055 ? wxColourScheme::SCROLLBAR_PRESSED
3056 : wxColourScheme::SCROLLBAR
;
3057 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3060 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3062 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3065 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3066 wxScrollBar::Element elem
,
3069 return StandardGetScrollbarRect(scrollbar
, elem
,
3070 thumbPos
, m_sizeScrollbarArrow
);
3073 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3075 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3078 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3079 const wxPoint
& pt
) const
3081 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3084 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3087 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3090 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3093 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3096 // ----------------------------------------------------------------------------
3097 // top level windows
3098 // ----------------------------------------------------------------------------
3100 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3102 const wxString
& title
,
3107 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3109 DrawFrameBorder(dc
, rect
, flags
);
3111 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3113 DrawFrameBackground(dc
, rect
, flags
);
3114 if ( flags
& wxTOPLEVEL_ICON
)
3115 DrawFrameIcon(dc
, rect
, icon
, flags
);
3116 DrawFrameTitle(dc
, rect
, title
, flags
);
3118 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3120 x
= client
.GetRight() -2 - FRAME_BUTTON_WIDTH
;
3121 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3123 if ( flags
& wxTOPLEVEL_CLOSE_BUTTON
)
3125 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_CLOSE_BUTTON
);
3126 x
-= FRAME_BUTTON_WIDTH
+ 2;
3128 if ( flags
& wxTOPLEVEL_MAXIMIZE_BUTTON
)
3130 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_MAXIMIZE_BUTTON
);
3131 x
-= FRAME_BUTTON_WIDTH
;
3133 if ( flags
& wxTOPLEVEL_RESTORE_BUTTON
)
3135 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_RESTORE_BUTTON
);
3136 x
-= FRAME_BUTTON_WIDTH
;
3138 if ( flags
& wxTOPLEVEL_MINIMIZE_BUTTON
)
3140 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_MINIMIZE_BUTTON
);
3141 x
-= FRAME_BUTTON_WIDTH
;
3143 if ( flags
& wxTOPLEVEL_HELP_BUTTON
)
3145 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_HELP_BUTTON
);
3146 x
-= FRAME_BUTTON_WIDTH
;
3151 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3155 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3159 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3160 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3161 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3162 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3163 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3166 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3170 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3172 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3173 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3174 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3176 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3177 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3179 DrawBackground(dc
, col
, r
);
3182 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3184 const wxString
& title
,
3187 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3188 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3189 if ( flags
& wxTOPLEVEL_ICON
)
3190 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3194 dc
.SetFont(m_titlebarFont
);
3195 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
));
3196 dc
.DrawLabel(title
, wxNullBitmap
, r
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3199 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3204 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3205 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3208 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3209 wxCoord x
, wxCoord y
,
3213 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3215 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3216 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3217 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3222 case wxTOPLEVEL_CLOSE_BUTTON
: idx
= FrameButton_Close
; break;
3223 case wxTOPLEVEL_MAXIMIZE_BUTTON
: idx
= FrameButton_Maximize
; break;
3224 case wxTOPLEVEL_MINIMIZE_BUTTON
: idx
= FrameButton_Minimize
; break;
3225 case wxTOPLEVEL_RESTORE_BUTTON
: idx
= FrameButton_Restore
; break;
3226 case wxTOPLEVEL_HELP_BUTTON
: idx
= FrameButton_Help
; break;
3228 wxFAIL_MSG(wxT("incorrect button specification"));
3231 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3235 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3240 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3242 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3243 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3244 FRAME_BORDER_THICKNESS
;
3247 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3249 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3250 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3256 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3259 wxSize
s(clientSize
);
3261 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3263 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3264 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3265 FRAME_BORDER_THICKNESS
;
3269 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3270 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3275 wxSize
wxWin32Renderer::GetFrameIconSize() const
3277 return wxSize(16, 16);
3282 // ----------------------------------------------------------------------------
3283 // text control geometry
3284 // ----------------------------------------------------------------------------
3286 static inline int GetTextBorderWidth()
3291 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3294 wxRect rectTotal
= rect
;
3296 wxCoord widthBorder
= GetTextBorderWidth();
3297 rectTotal
.Inflate(widthBorder
);
3299 // this is what Windows does
3305 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3307 wxCoord
*extraSpaceBeyond
)
3309 wxRect rectText
= rect
;
3311 // undo GetTextTotalArea()
3312 if ( rectText
.height
> 0 )
3315 wxCoord widthBorder
= GetTextBorderWidth();
3316 rectText
.Inflate(-widthBorder
);
3318 if ( extraSpaceBeyond
)
3319 *extraSpaceBeyond
= 0;
3324 // ----------------------------------------------------------------------------
3326 // ----------------------------------------------------------------------------
3328 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3331 if ( wxDynamicCast(window
, wxScrollBar
) )
3333 // we only set the width of vert scrollbars and height of the
3335 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3336 size
->y
= m_sizeScrollbarArrow
.y
;
3338 size
->x
= m_sizeScrollbarArrow
.x
;
3340 // skip border width adjustments, they don't make sense for us
3343 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3346 if ( wxDynamicCast(window
, wxButton
) )
3348 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3350 // TODO: don't harcode all this
3351 size
->x
+= 3*window
->GetCharWidth();
3353 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3354 if ( size
->y
< heightBtn
- 8 )
3355 size
->y
= heightBtn
;
3360 // no border width adjustments for buttons
3363 #endif // wxUSE_BUTTON
3365 // take into account the border width
3366 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3367 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3368 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3371 // ============================================================================
3373 // ============================================================================
3375 // ----------------------------------------------------------------------------
3376 // wxWin32InputHandler
3377 // ----------------------------------------------------------------------------
3379 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3381 m_renderer
= renderer
;
3384 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3385 const wxKeyEvent
& event
,
3391 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3392 const wxMouseEvent
& event
)
3394 // clicking on the control gives it focus
3395 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
3397 control
->GetInputWindow()->SetFocus();
3405 // ----------------------------------------------------------------------------
3406 // wxWin32ScrollBarInputHandler
3407 // ----------------------------------------------------------------------------
3409 wxWin32ScrollBarInputHandler::
3410 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3411 wxInputHandler
*handler
)
3412 : wxStdScrollBarInputHandler(renderer
, handler
)
3414 m_scrollPaused
= FALSE
;
3418 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3419 const wxControlAction
& action
)
3421 // stop if went beyond the position of the original click (this can only
3422 // happen when we scroll by pages)
3424 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3426 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3427 != wxHT_SCROLLBAR_BAR_2
;
3429 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3431 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3432 != wxHT_SCROLLBAR_BAR_1
;
3437 StopScrolling(scrollbar
);
3439 scrollbar
->Refresh();
3444 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3447 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3448 const wxMouseEvent
& event
)
3450 // remember the current state
3451 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3453 // do process the message
3454 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3456 // analyse the changes
3457 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3459 // we just started dragging the thumb, remember its initial position to
3460 // be able to restore it if the drag is cancelled later
3461 m_eventStartDrag
= event
;
3467 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3468 const wxMouseEvent
& event
)
3470 // we don't highlight scrollbar elements, so there is no need to process
3471 // mouse move events normally - only do it while mouse is captured (i.e.
3472 // when we're dragging the thumb or pressing on something)
3473 if ( !m_winCapture
)
3476 if ( event
.Entering() )
3478 // we're not interested in this at all
3482 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3484 if ( m_scrollPaused
)
3486 // check if the mouse returned to its original location
3488 if ( event
.Leaving() )
3494 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3495 if ( ht
== m_htLast
)
3497 // yes it did, resume scrolling
3498 m_scrollPaused
= FALSE
;
3499 if ( m_timerScroll
)
3501 // we were scrolling by line/page, restart timer
3502 m_timerScroll
->Start(m_interval
);
3504 Press(scrollbar
, TRUE
);
3506 else // we were dragging the thumb
3508 // restore its last location
3509 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3515 else // normal case, scrolling hasn't been paused
3517 // if we're scrolling the scrollbar because the arrow or the shaft was
3518 // pressed, check that the mouse stays on the same scrollbar element
3520 if ( event
.Moving() )
3522 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3524 else // event.Leaving()
3529 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3530 // is still ok - we only want to catch the case when the mouse leaves
3531 // the scrollbar here
3532 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3534 ht
= wxHT_SCROLLBAR_THUMB
;
3537 if ( ht
!= m_htLast
)
3539 // what were we doing? 2 possibilities: either an arrow/shaft was
3540 // pressed in which case we have a timer and so we just stop it or
3541 // we were dragging the thumb
3542 if ( m_timerScroll
)
3545 m_interval
= m_timerScroll
->GetInterval();
3546 m_timerScroll
->Stop();
3547 m_scrollPaused
= TRUE
;
3549 // unpress the arrow
3550 Press(scrollbar
, FALSE
);
3552 else // we were dragging the thumb
3554 // remember the current thumb position to be able to restore it
3555 // if the mouse returns to it later
3556 m_eventLastDrag
= event
;
3558 // and restore the original position (before dragging) of the
3560 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3567 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
3570 // ----------------------------------------------------------------------------
3571 // wxWin32CheckboxInputHandler
3572 // ----------------------------------------------------------------------------
3574 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3575 const wxKeyEvent
& event
,
3580 wxControlAction action
;
3581 int keycode
= event
.GetKeyCode();
3585 action
= wxACTION_CHECKBOX_TOGGLE
;
3589 case WXK_NUMPAD_SUBTRACT
:
3590 action
= wxACTION_CHECKBOX_CHECK
;
3594 case WXK_NUMPAD_ADD
:
3595 case WXK_NUMPAD_EQUAL
:
3596 action
= wxACTION_CHECKBOX_CLEAR
;
3602 control
->PerformAction(action
);
3611 // ----------------------------------------------------------------------------
3612 // wxWin32TextCtrlInputHandler
3613 // ----------------------------------------------------------------------------
3615 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3616 const wxKeyEvent
& event
,
3619 // handle only MSW-specific text bindings here, the others are handled in
3623 int keycode
= event
.GetKeyCode();
3625 wxControlAction action
;
3626 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
3628 action
= wxACTION_TEXT_CUT
;
3630 else if ( keycode
== WXK_INSERT
)
3632 if ( event
.ControlDown() )
3633 action
= wxACTION_TEXT_COPY
;
3634 else if ( event
.ShiftDown() )
3635 action
= wxACTION_TEXT_PASTE
;
3638 if ( action
!= wxACTION_NONE
)
3640 control
->PerformAction(action
);
3646 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);