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 specialButton
= 0,
284 int specialButtonFlags
= 0);
285 virtual void DrawFrameBorder(wxDC
& dc
,
288 virtual void DrawFrameBackground(wxDC
& dc
,
291 virtual void DrawFrameTitle(wxDC
& dc
,
293 const wxString
& title
,
295 virtual void DrawFrameIcon(wxDC
& dc
,
299 virtual void DrawFrameButton(wxDC
& dc
,
300 wxCoord x
, wxCoord y
,
303 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
304 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
305 virtual wxSize
GetFrameIconSize() const;
306 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
308 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
310 wxBitmap
*bmpPressed
,
311 wxBitmap
*bmpDisabled
);
313 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
314 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
315 virtual bool AreScrollbarsInsideBorder() const;
317 virtual wxSize
GetScrollbarArrowSize() const
318 { return m_sizeScrollbarArrow
; }
319 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
320 wxScrollBar::Element elem
,
321 int thumbPos
= -1) const;
322 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
323 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
324 const wxPoint
& pt
) const;
325 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
327 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
328 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
329 { return fontHeight
+ 2; }
330 virtual wxSize
GetCheckBitmapSize() const
331 { return wxSize(13, 13); }
332 virtual wxSize
GetRadioBitmapSize() const
333 { return wxSize(12, 12); }
334 virtual wxCoord
GetCheckItemMargin() const
337 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
339 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
341 wxCoord
*extraSpaceBeyond
);
343 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
344 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
346 virtual wxCoord
GetSliderDim() const { return 20; }
347 virtual wxCoord
GetSliderTickLen() const { return 4; }
348 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
349 wxOrientation orient
) const;
350 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
351 wxOrientation orient
) const;
352 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
355 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
356 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
357 const wxMenu
& menu
) const;
360 // helper of DrawLabel() and DrawCheckOrRadioButton()
361 void DoDrawLabel(wxDC
& dc
,
362 const wxString
& label
,
365 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
367 wxRect
*rectBounds
= NULL
,
368 const wxPoint
& focusOffset
369 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
371 // common part of DrawLabel() and DrawItem()
372 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
374 // DrawLabel() and DrawButtonLabel() helper
375 void DrawLabelShadow(wxDC
& dc
,
376 const wxString
& label
,
381 // DrawButtonBorder() helper
382 void DoDrawBackground(wxDC
& dc
,
386 // DrawBorder() helpers: all of them shift and clip the DC after drawing
389 // just draw a rectangle with the given pen
390 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
392 // draw the lower left part of rectangle
393 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
395 // draw the rectange using the first brush for the left and top sides and
396 // the second one for the bottom and right ones
397 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
398 const wxPen
& pen1
, const wxPen
& pen2
);
400 // draw the normal 3D border
401 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
403 // draw the sunken 3D border
404 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
406 // draw the border used for scrollbar arrows
407 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
409 // public DrawArrow()s helper
410 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
411 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
413 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
414 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
415 wxArrowDirection arrowDir
,
416 wxArrowStyle arrowStyle
);
418 // DrawCheckButton/DrawRadioButton helper
419 void DrawCheckOrRadioButton(wxDC
& dc
,
420 const wxString
& label
,
421 const wxBitmap
& bitmap
,
426 wxCoord focusOffsetY
);
428 // draw a normal or transposed line (useful for using the same code fo both
429 // horizontal and vertical widgets)
430 void DrawLine(wxDC
& dc
,
431 wxCoord x1
, wxCoord y1
,
432 wxCoord x2
, wxCoord y2
,
433 bool transpose
= FALSE
)
436 dc
.DrawLine(y1
, x1
, y2
, x2
);
438 dc
.DrawLine(x1
, y1
, x2
, y2
);
441 // get the standard check/radio button bitmap
442 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
443 wxBitmap
GetCheckBitmap(int flags
)
444 { return GetIndicator(IndicatorType_Check
, flags
); }
445 wxBitmap
GetRadioBitmap(int flags
)
446 { return GetIndicator(IndicatorType_Radio
, flags
); }
449 const wxColourScheme
*m_scheme
;
451 // the sizing parameters (TODO make them changeable)
452 wxSize m_sizeScrollbarArrow
;
454 // GDI objects we use for drawing
455 wxColour m_colDarkGrey
,
463 wxFont m_titlebarFont
;
466 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
468 // first row is for the normal state, second - for the disabled
469 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
472 // ----------------------------------------------------------------------------
473 // wxWin32InputHandler and derived classes: process the keyboard and mouse
474 // messages according to Windows standards
475 // ----------------------------------------------------------------------------
477 class wxWin32InputHandler
: public wxInputHandler
480 wxWin32InputHandler(wxWin32Renderer
*renderer
);
482 virtual bool HandleKey(wxInputConsumer
*control
,
483 const wxKeyEvent
& event
,
485 virtual bool HandleMouse(wxInputConsumer
*control
,
486 const wxMouseEvent
& event
);
489 wxWin32Renderer
*m_renderer
;
492 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
495 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
496 wxInputHandler
*handler
);
498 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
499 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
501 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
502 const wxControlAction
& action
);
505 virtual bool IsAllowedButton(int button
) { return button
== 1; }
507 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
509 // we don't highlight anything
512 // the first and last event which caused the thumb to move
513 wxMouseEvent m_eventStartDrag
,
516 // have we paused the scrolling because the mouse moved?
519 // we remember the interval of the timer to be able to restart it
523 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
526 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
527 : wxStdCheckboxInputHandler(handler
) { }
529 virtual bool HandleKey(wxInputConsumer
*control
,
530 const wxKeyEvent
& event
,
534 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
537 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
538 : wxStdTextCtrlInputHandler(handler
) { }
540 virtual bool HandleKey(wxInputConsumer
*control
,
541 const wxKeyEvent
& event
,
545 // ----------------------------------------------------------------------------
546 // wxWin32ColourScheme: uses (default) Win32 colours
547 // ----------------------------------------------------------------------------
549 class wxWin32ColourScheme
: public wxColourScheme
552 virtual wxColour
Get(StdColour col
) const;
553 virtual wxColour
GetBackground(wxWindow
*win
) const;
556 // ----------------------------------------------------------------------------
558 // ----------------------------------------------------------------------------
560 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
562 class wxWin32Theme
: public wxTheme
566 virtual ~wxWin32Theme();
568 virtual wxRenderer
*GetRenderer() { return m_renderer
; }
569 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
570 virtual wxColourScheme
*GetColourScheme();
573 // get the default input handler
574 wxInputHandler
*GetDefaultInputHandler();
576 wxWin32Renderer
*m_renderer
;
578 // the names of the already created handlers and the handlers themselves
579 // (these arrays are synchronized)
580 wxSortedArrayString m_handlerNames
;
581 wxArrayHandlers m_handlers
;
583 wxWin32InputHandler
*m_handlerDefault
;
585 wxWin32ColourScheme
*m_scheme
;
587 WX_DECLARE_THEME(win32
)
590 // ----------------------------------------------------------------------------
592 // ----------------------------------------------------------------------------
594 // frame buttons bitmaps
596 static const char *frame_button_close_xpm
[] = {
611 static const char *frame_button_help_xpm
[] = {
626 static const char *frame_button_maximize_xpm
[] = {
641 static const char *frame_button_minimize_xpm
[] = {
656 static const char *frame_button_restore_xpm
[] = {
673 static const char *checked_menu_xpm
[] = {
674 /* columns rows colors chars-per-pixel */
690 static const char *selected_checked_menu_xpm
[] = {
691 /* columns rows colors chars-per-pixel */
707 static const char *disabled_checked_menu_xpm
[] = {
708 /* columns rows colors chars-per-pixel */
725 static const char *selected_disabled_checked_menu_xpm
[] = {
726 /* columns rows colors chars-per-pixel */
742 // checkbox and radiobox bitmaps below
744 static const char *checked_xpm
[] = {
745 /* columns rows colors chars-per-pixel */
768 static const char *pressed_checked_xpm
[] = {
769 /* columns rows colors chars-per-pixel */
791 static const char *pressed_disabled_checked_xpm
[] = {
792 /* columns rows colors chars-per-pixel */
814 static const char *checked_item_xpm
[] = {
815 /* columns rows colors chars-per-pixel */
836 static const char *unchecked_xpm
[] = {
837 /* columns rows colors chars-per-pixel */
860 static const char *pressed_unchecked_xpm
[] = {
861 /* columns rows colors chars-per-pixel */
883 static const char *unchecked_item_xpm
[] = {
884 /* columns rows colors chars-per-pixel */
904 static const char *checked_radio_xpm
[] = {
905 /* columns rows colors chars-per-pixel */
928 static const char *pressed_checked_radio_xpm
[] = {
929 /* columns rows colors chars-per-pixel */
952 static const char *pressed_disabled_checked_radio_xpm
[] = {
953 /* columns rows colors chars-per-pixel */
976 static const char *unchecked_radio_xpm
[] = {
977 /* columns rows colors chars-per-pixel */
1000 static const char *pressed_unchecked_radio_xpm
[] = {
1001 /* columns rows colors chars-per-pixel */
1024 static const char **
1025 bmpIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1030 { checked_xpm
, unchecked_xpm
},
1033 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1036 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1042 { checked_radio_xpm
, unchecked_radio_xpm
},
1045 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1048 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1054 { checked_menu_xpm
, NULL
},
1057 { selected_checked_menu_xpm
, NULL
},
1060 { disabled_checked_menu_xpm
, NULL
},
1062 // disabled selected state
1063 { selected_disabled_checked_menu_xpm
, NULL
},
1067 // ============================================================================
1069 // ============================================================================
1071 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1073 // ----------------------------------------------------------------------------
1075 // ----------------------------------------------------------------------------
1077 wxWin32Theme::wxWin32Theme()
1079 m_scheme
= new wxWin32ColourScheme
;
1080 m_renderer
= new wxWin32Renderer(m_scheme
);
1081 m_handlerDefault
= NULL
;
1084 wxWin32Theme::~wxWin32Theme()
1086 size_t count
= m_handlers
.GetCount();
1087 for ( size_t n
= 0; n
< count
; n
++ )
1089 if ( m_handlers
[n
] != m_handlerDefault
)
1090 delete m_handlers
[n
];
1093 delete m_handlerDefault
;
1099 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1101 if ( !m_handlerDefault
)
1103 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1106 return m_handlerDefault
;
1109 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1111 wxInputHandler
*handler
;
1112 int n
= m_handlerNames
.Index(control
);
1113 if ( n
== wxNOT_FOUND
)
1115 // create a new handler
1116 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1117 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1118 GetDefaultInputHandler());
1120 else if ( control
== wxINP_HANDLER_BUTTON
)
1121 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1122 #endif // wxUSE_BUTTON
1124 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1125 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1126 #endif // wxUSE_CHECKBOX
1128 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1129 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1130 #endif // wxUSE_COMBOBOX
1132 else if ( control
== wxINP_HANDLER_LISTBOX
)
1133 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1134 #endif // wxUSE_LISTBOX
1135 #if wxUSE_CHECKLISTBOX
1136 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1137 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1138 #endif // wxUSE_CHECKLISTBOX
1140 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1141 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1142 #endif // wxUSE_TEXTCTRL
1144 else if ( control
== wxINP_HANDLER_SLIDER
)
1145 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1146 #endif // wxUSE_SLIDER
1148 else if ( control
== wxINP_HANDLER_SPINBTN
)
1149 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1150 #endif // wxUSE_SPINBTN
1152 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1153 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1154 #endif // wxUSE_NOTEBOOK
1155 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1156 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
1158 handler
= GetDefaultInputHandler();
1160 n
= m_handlerNames
.Add(control
);
1161 m_handlers
.Insert(handler
, n
);
1163 else // we already have it
1165 handler
= m_handlers
[n
];
1171 wxColourScheme
*wxWin32Theme::GetColourScheme()
1176 // ============================================================================
1177 // wxWin32ColourScheme
1178 // ============================================================================
1180 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1183 if ( win
->UseBgCol() )
1185 // use the user specified colour
1186 col
= win
->GetBackgroundColour();
1189 if ( win
->IsContainerWindow() )
1191 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1194 if ( !text
->IsEnabled() ) // not IsEditable()
1196 //else: execute code below
1201 // doesn't depend on the state
1207 int flags
= win
->GetStateFlags();
1209 // the colour set by the user should be used for the normal state
1210 // and for the states for which we don't have any specific colours
1211 if ( !col
.Ok() || (flags
!= 0) )
1213 if ( wxDynamicCast(win
, wxScrollBar
) )
1214 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1224 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1228 // use the system colours under Windows
1229 #if defined(__WXMSW__)
1230 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1232 case CONTROL_PRESSED
:
1233 case CONTROL_CURRENT
:
1234 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1236 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1238 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1239 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1241 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1242 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1244 #if defined(COLOR_3DDKSHADOW)
1245 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1247 case SHADOW_DARK
: return *wxBLACK
;
1250 case CONTROL_TEXT_DISABLED
:
1251 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1253 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1255 case CONTROL_TEXT_DISABLED_SHADOW
:
1256 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1258 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1259 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1260 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1262 // use the standard Windows colours elsewhere
1263 case WINDOW
: return *wxWHITE
;
1265 case CONTROL_PRESSED
:
1266 case CONTROL_CURRENT
:
1267 case CONTROL
: return wxColour(0xc0c0c0);
1269 case CONTROL_TEXT
: return *wxBLACK
;
1271 case SCROLLBAR
: return wxColour(0xe0e0e0);
1272 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1274 case HIGHLIGHT
: return wxColour(0x800000);
1275 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1277 case SHADOW_DARK
: return *wxBLACK
;
1279 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1280 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1282 case SHADOW_IN
: return wxColour(0xc0c0c0);
1284 case CONTROL_TEXT_DISABLED_SHADOW
:
1285 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1287 case TITLEBAR
: return wxColour(0xaeaaae);
1288 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1289 case TITLEBAR_TEXT
: return *wxWHITE
;
1294 wxFAIL_MSG(_T("invalid standard colour"));
1299 // ============================================================================
1301 // ============================================================================
1303 // ----------------------------------------------------------------------------
1305 // ----------------------------------------------------------------------------
1307 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1311 m_sizeScrollbarArrow
= wxSize(16, 16);
1313 // init colours and pens
1314 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1316 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1317 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1319 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1321 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1322 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1324 m_titlebarFont
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
1325 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1327 // init the arrow bitmaps
1328 static const size_t ARROW_WIDTH
= 7;
1329 static const size_t ARROW_LENGTH
= 4;
1332 wxMemoryDC dcNormal
,
1335 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1337 bool isVertical
= n
> Arrow_Right
;
1350 // disabled arrow is larger because of the shadow
1351 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1352 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1354 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1355 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1357 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1358 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1362 dcNormal
.SetPen(m_penBlack
);
1363 dcDisabled
.SetPen(m_penDarkGrey
);
1365 // calculate the position of the point of the arrow
1369 x1
= (ARROW_WIDTH
- 1)/2;
1370 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1374 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1375 y1
= (ARROW_WIDTH
- 1)/2;
1386 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1388 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1389 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1396 if ( n
== Arrow_Up
)
1407 else // left or right arrow
1412 if ( n
== Arrow_Left
)
1425 // draw the shadow for the disabled one
1426 dcDisabled
.SetPen(m_penHighlight
);
1431 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1435 x1
= ARROW_LENGTH
- 1;
1436 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1439 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1440 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1445 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1449 x1
= ARROW_WIDTH
- 1;
1451 x2
= (ARROW_WIDTH
- 1)/2;
1453 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1454 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1459 // create the inversed bitmap but only for the right arrow as we only
1460 // use it for the menus
1461 if ( n
== Arrow_Right
)
1463 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1464 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1466 dcInverse
.Blit(0, 0, w
, h
,
1469 dcInverse
.SelectObject(wxNullBitmap
);
1471 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1472 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1474 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1475 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1477 dcInverse
.Blit(0, 0, w
, h
,
1480 dcInverse
.SelectObject(wxNullBitmap
);
1482 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1483 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1486 dcNormal
.SelectObject(wxNullBitmap
);
1487 dcDisabled
.SelectObject(wxNullBitmap
);
1489 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1490 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1491 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1492 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1494 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1497 // init the frame buttons bitmaps
1498 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1499 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1500 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1501 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1502 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1505 // ----------------------------------------------------------------------------
1507 // ----------------------------------------------------------------------------
1510 The raised border in Win32 looks like this:
1512 IIIIIIIIIIIIIIIIIIIIIIB
1514 I GB I = white (HILIGHT)
1515 I GB H = light grey (LIGHT)
1516 I GB G = dark grey (SHADOI)
1517 I GB B = black (DKSHADOI)
1518 I GB I = hIghlight (COLOR_3DHILIGHT)
1520 IGGGGGGGGGGGGGGGGGGGGGB
1521 BBBBBBBBBBBBBBBBBBBBBBB
1523 The sunken border looks like this:
1525 GGGGGGGGGGGGGGGGGGGGGGI
1526 GBBBBBBBBBBBBBBBBBBBBHI
1533 GHHHHHHHHHHHHHHHHHHHHHI
1534 IIIIIIIIIIIIIIIIIIIIIII
1536 The static border (used for the controls which don't get focus) is like
1539 GGGGGGGGGGGGGGGGGGGGGGW
1547 WWWWWWWWWWWWWWWWWWWWWWW
1549 The most complicated is the double border:
1551 HHHHHHHHHHHHHHHHHHHHHHB
1552 HWWWWWWWWWWWWWWWWWWWWGB
1553 HWHHHHHHHHHHHHHHHHHHHGB
1558 HWHHHHHHHHHHHHHHHHHHHGB
1559 HGGGGGGGGGGGGGGGGGGGGGB
1560 BBBBBBBBBBBBBBBBBBBBBBB
1562 And the simple border is, well, simple:
1564 BBBBBBBBBBBBBBBBBBBBBBB
1573 BBBBBBBBBBBBBBBBBBBBBBB
1576 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1580 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1581 dc
.DrawRectangle(*rect
);
1587 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1589 // draw the bottom and right sides
1591 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1592 rect
->GetRight() + 1, rect
->GetBottom());
1593 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1594 rect
->GetRight(), rect
->GetBottom());
1601 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1602 const wxPen
& pen1
, const wxPen
& pen2
)
1604 // draw the rectangle
1606 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1607 rect
->GetLeft(), rect
->GetBottom());
1608 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1609 rect
->GetRight(), rect
->GetTop());
1611 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1612 rect
->GetRight(), rect
->GetBottom());
1613 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1614 rect
->GetRight() + 1, rect
->GetBottom());
1620 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1622 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1623 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1626 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1628 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1629 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1632 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1636 DrawRect(dc
, rect
, m_penDarkGrey
);
1638 // the arrow is usually drawn inside border of width 2 and is offset by
1639 // another pixel in both directions when it's pressed - as the border
1640 // in this case is more narrow as well, we have to adjust rect like
1648 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1649 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1653 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1655 const wxRect
& rectTotal
,
1656 int WXUNUSED(flags
),
1661 wxRect rect
= rectTotal
;
1665 case wxBORDER_SUNKEN
:
1666 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1668 DrawSunkenBorder(dc
, &rect
);
1672 case wxBORDER_STATIC
:
1673 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1676 case wxBORDER_RAISED
:
1677 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1679 DrawRaisedBorder(dc
, &rect
);
1683 case wxBORDER_DOUBLE
:
1684 DrawArrowBorder(dc
, &rect
);
1685 DrawRect(dc
, &rect
, m_penLightGrey
);
1688 case wxBORDER_SIMPLE
:
1689 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1691 DrawRect(dc
, &rect
, m_penBlack
);
1696 wxFAIL_MSG(_T("unknown border type"));
1699 case wxBORDER_DEFAULT
:
1708 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1713 case wxBORDER_RAISED
:
1714 case wxBORDER_SUNKEN
:
1715 width
= BORDER_THICKNESS
;
1718 case wxBORDER_SIMPLE
:
1719 case wxBORDER_STATIC
:
1723 case wxBORDER_DOUBLE
:
1728 wxFAIL_MSG(_T("unknown border type"));
1731 case wxBORDER_DEFAULT
:
1741 rect
.height
= width
;
1746 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1751 // ----------------------------------------------------------------------------
1753 // ----------------------------------------------------------------------------
1755 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1761 // text controls are not special under windows
1762 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1765 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1766 const wxRect
& rectTotal
,
1770 wxRect rect
= rectTotal
;
1772 if ( flags
& wxCONTROL_PRESSED
)
1774 // button pressed: draw a double border around it
1775 DrawRect(dc
, &rect
, m_penBlack
);
1776 DrawRect(dc
, &rect
, m_penDarkGrey
);
1780 // button not pressed
1782 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1784 // button either default or focused (or both): add an extra border around it
1785 DrawRect(dc
, &rect
, m_penBlack
);
1788 // now draw a normal button
1789 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1790 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1799 // ----------------------------------------------------------------------------
1801 // ----------------------------------------------------------------------------
1803 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1804 wxCoord y
, wxCoord x1
, wxCoord x2
)
1806 dc
.SetPen(m_penDarkGrey
);
1807 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1808 dc
.SetPen(m_penHighlight
);
1810 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1813 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1814 wxCoord x
, wxCoord y1
, wxCoord y2
)
1816 dc
.SetPen(m_penDarkGrey
);
1817 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1818 dc
.SetPen(m_penHighlight
);
1820 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1823 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1824 const wxString
& label
,
1830 wxCoord height
= 0; // of the label
1831 wxRect rectFrame
= rect
;
1832 if ( !label
.empty() )
1834 // the text should touch the top border of the rect, so the frame
1835 // itself should be lower
1836 dc
.GetTextExtent(label
, NULL
, &height
);
1837 rectFrame
.y
+= height
/ 2;
1838 rectFrame
.height
-= height
/ 2;
1840 // we have to draw each part of the frame individually as we can't
1841 // erase the background beyond the label as it might contain some
1842 // pixmap already, so drawing everything and then overwriting part of
1843 // the frame with label doesn't work
1845 // TODO: the +5 and space insertion should be customizable
1848 rectText
.x
= rectFrame
.x
+ 5;
1849 rectText
.y
= rect
.y
;
1850 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1851 rectText
.height
= height
;
1854 label2
<< _T(' ') << label
<< _T(' ');
1855 if ( indexAccel
!= -1 )
1857 // adjust it as we prepended a space
1862 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1864 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1868 // just draw the complete frame
1869 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1870 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1874 // ----------------------------------------------------------------------------
1876 // ----------------------------------------------------------------------------
1878 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1880 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1881 // pixels each while we really need dots here... PS_ALTERNATE might
1882 // work, but it is for NT 5 only
1884 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1886 // draw the pixels manually: note that to behave in the same manner as
1887 // DrawRect(), we must exclude the bottom and right borders from the
1889 wxCoord x1
= rect
.GetLeft(),
1891 x2
= rect
.GetRight(),
1892 y2
= rect
.GetBottom();
1894 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1896 // this seems to be closer than what Windows does than wxINVERT although
1897 // I'm still not sure if it's correct
1898 dc
.SetLogicalFunction(wxAND_REVERSE
);
1901 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1902 dc
.DrawPoint(z
, rect
.GetTop());
1904 wxCoord shift
= z
== x2
? 0 : 1;
1905 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1906 dc
.DrawPoint(x2
, z
);
1908 shift
= z
== y2
? 0 : 1;
1909 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1910 dc
.DrawPoint(z
, y2
);
1912 shift
= z
== x1
? 0 : 1;
1913 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
1914 dc
.DrawPoint(x1
, z
);
1916 dc
.SetLogicalFunction(wxCOPY
);
1920 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
1921 const wxString
& label
,
1926 // draw shadow of the text
1927 dc
.SetTextForeground(m_colHighlight
);
1928 wxRect rectShadow
= rect
;
1931 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1933 // make the text grey
1934 dc
.SetTextForeground(m_colDarkGrey
);
1937 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1938 const wxString
& label
,
1945 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
1948 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
1949 const wxString
& label
,
1955 const wxPoint
& focusOffset
)
1957 // the underscores are not drawn for focused controls in wxMSW
1958 if ( flags
& wxCONTROL_FOCUSED
)
1963 if ( flags
& wxCONTROL_DISABLED
)
1965 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
1966 // currently only can happen for a menu item and it seems that Windows
1967 // doesn't draw the shadow in this case, so we don't do it neither
1968 if ( flags
& wxCONTROL_SELECTED
)
1970 // just make the label text greyed out
1971 dc
.SetTextForeground(m_colDarkGrey
);
1973 else // draw normal disabled label
1975 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
1980 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
1982 if ( flags
& wxCONTROL_DISABLED
)
1984 // restore the fg colour
1985 dc
.SetTextForeground(*wxBLACK
);
1988 if ( flags
& wxCONTROL_FOCUSED
)
1990 if ( focusOffset
.x
|| focusOffset
.y
)
1992 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
1995 DrawFocusRect(dc
, rectLabel
);
1999 *rectBounds
= rectLabel
;
2002 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2003 const wxString
& label
,
2004 const wxBitmap
& image
,
2011 // the underscores are not drawn for focused controls in wxMSW
2012 if ( flags
& wxCONTROL_PRESSED
)
2017 wxRect rectLabel
= rect
;
2018 if ( !label
.empty() )
2020 // shift the label if a button is pressed
2021 if ( flags
& wxCONTROL_PRESSED
)
2027 if ( flags
& wxCONTROL_DISABLED
)
2029 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2032 // leave enough space for the focus rectangle
2033 if ( flags
& wxCONTROL_FOCUSED
)
2035 rectLabel
.Inflate(-2);
2039 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2041 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2043 if ( flags
& wxCONTROL_PRESSED
)
2045 // the focus rectangle is never pressed, so undo the shift done
2053 DrawFocusRect(dc
, rectLabel
);
2057 // ----------------------------------------------------------------------------
2058 // (check)listbox items
2059 // ----------------------------------------------------------------------------
2061 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2062 const wxString
& label
,
2066 wxDCTextColourChanger
colChanger(dc
);
2068 if ( flags
& wxCONTROL_SELECTED
)
2070 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2072 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2073 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2074 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2075 dc
.DrawRectangle(rect
);
2078 wxRect rectText
= rect
;
2080 rectText
.width
-= 2;
2081 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2083 if ( flags
& wxCONTROL_FOCUSED
)
2085 DrawFocusRect(dc
, rect
);
2089 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2090 const wxString
& label
,
2091 const wxBitmap
& bitmap
,
2100 else // use default bitmap
2102 bmp
= wxBitmap(flags
& wxCONTROL_CHECKED
? checked_item_xpm
2103 : unchecked_item_xpm
);
2106 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2107 TRUE
/* use mask */);
2109 wxRect rectLabel
= rect
;
2110 int bmpWidth
= bmp
.GetWidth();
2111 rectLabel
.x
+= bmpWidth
;
2112 rectLabel
.width
-= bmpWidth
;
2114 DrawItem(dc
, label
, rectLabel
, flags
);
2117 // ----------------------------------------------------------------------------
2118 // check/radio buttons
2119 // ----------------------------------------------------------------------------
2121 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2123 IndicatorState indState
;
2124 if ( flags
& wxCONTROL_SELECTED
)
2125 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2126 : IndicatorState_Selected
;
2127 else if ( flags
& wxCONTROL_DISABLED
)
2128 indState
= IndicatorState_Disabled
;
2129 else if ( flags
& wxCONTROL_PRESSED
)
2130 indState
= IndicatorState_Pressed
;
2132 indState
= IndicatorState_Normal
;
2134 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2135 ? IndicatorStatus_Checked
2136 : IndicatorStatus_Unchecked
;
2138 const char **xpm
= bmpIndicators
[indType
][indState
][indStatus
];
2139 return xpm
? wxBitmap(xpm
) : wxNullBitmap
;
2142 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2143 const wxString
& label
,
2144 const wxBitmap
& bitmap
,
2149 wxCoord focusOffsetY
)
2151 // calculate the position of the bitmap and of the label
2152 wxCoord heightBmp
= bitmap
.GetHeight();
2154 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2157 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2158 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2160 // align label vertically with the bitmap - looks nicer like this
2161 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2163 // calc horz position
2164 if ( align
== wxALIGN_RIGHT
)
2166 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2167 rectLabel
.x
= rect
.x
+ 3;
2168 rectLabel
.SetRight(xBmp
);
2170 else // normal (checkbox to the left of the text) case
2173 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2174 rectLabel
.SetRight(rect
.GetRight());
2177 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2180 dc
, label
, rectLabel
,
2182 wxALIGN_LEFT
| wxALIGN_TOP
,
2184 NULL
, // we don't need bounding rect
2185 // use custom vert focus rect offset
2186 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2190 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2191 const wxString
& label
,
2192 const wxBitmap
& bitmap
,
2198 DrawCheckOrRadioButton(dc
, label
,
2199 bitmap
.Ok() ? bitmap
: GetRadioBitmap(flags
),
2200 rect
, flags
, align
, indexAccel
,
2201 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2204 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2205 const wxString
& label
,
2206 const wxBitmap
& bitmap
,
2212 DrawCheckOrRadioButton(dc
, label
,
2213 bitmap
.Ok() ? bitmap
: GetCheckBitmap(flags
),
2214 rect
, flags
, align
, indexAccel
,
2215 0); // no focus rect offset for checkboxes
2218 // ----------------------------------------------------------------------------
2220 // ----------------------------------------------------------------------------
2222 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2223 const wxString
& text
,
2229 // nothing special to do here
2230 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2233 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2235 // we don't draw them
2238 // ----------------------------------------------------------------------------
2240 // ----------------------------------------------------------------------------
2242 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2243 const wxRect
& rectOrig
,
2245 const wxString
& label
,
2246 const wxBitmap
& bitmap
,
2250 wxRect rect
= rectOrig
;
2252 // the current tab is drawn indented (to the top for default case) and
2253 // bigger than the other ones
2254 const wxSize indent
= GetTabIndent();
2255 if ( flags
& wxCONTROL_SELECTED
)
2260 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2264 rect
.Inflate(indent
.x
, 0);
2266 rect
.height
+= indent
.y
;
2270 rect
.Inflate(indent
.x
, 0);
2271 rect
.height
+= indent
.y
;
2276 wxFAIL_MSG(_T("TODO"));
2281 // draw the text, image and the focus around them (if necessary)
2282 wxRect rectLabel
= rect
;
2283 rectLabel
.Deflate(1, 1);
2284 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2285 flags
, wxALIGN_CENTRE
, indexAccel
);
2287 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2288 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2291 x2
= rect
.GetRight(),
2292 y2
= rect
.GetBottom();
2294 // FIXME: all this code will break if the tab indent or the border width,
2295 // it is tied to the fact that both of them are equal to 2
2300 dc
.SetPen(m_penHighlight
);
2301 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2302 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2303 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2305 dc
.SetPen(m_penBlack
);
2306 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2307 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2309 dc
.SetPen(m_penDarkGrey
);
2310 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2312 if ( flags
& wxCONTROL_SELECTED
)
2314 dc
.SetPen(m_penLightGrey
);
2316 // overwrite the part of the border below this tab
2317 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2319 // and the shadow of the tab to the left of us
2320 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2325 dc
.SetPen(m_penHighlight
);
2326 // we need to continue one pixel further to overwrite the corner of
2327 // the border for the selected tab
2328 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2330 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2332 dc
.SetPen(m_penBlack
);
2333 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2334 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2335 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2337 dc
.SetPen(m_penDarkGrey
);
2338 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2339 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2341 if ( flags
& wxCONTROL_SELECTED
)
2343 dc
.SetPen(m_penLightGrey
);
2345 // overwrite the part of the (double!) border above this tab
2346 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2347 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2349 // and the shadow of the tab to the left of us
2350 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2356 wxFAIL_MSG(_T("TODO"));
2360 // ----------------------------------------------------------------------------
2362 // ----------------------------------------------------------------------------
2364 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2365 wxOrientation orient
) const
2369 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2370 if ( orient
== wxHORIZONTAL
)
2372 size
.y
= rect
.height
- 6;
2373 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2377 size
.x
= rect
.width
- 6;
2378 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2384 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2385 wxOrientation orient
) const
2387 static const wxCoord SLIDER_MARGIN
= 6;
2389 wxRect rect
= rectOrig
;
2391 if ( orient
== wxHORIZONTAL
)
2393 // make the rect of minimal width and centre it
2394 rect
.height
= 2*BORDER_THICKNESS
;
2395 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2399 // leave margins on the sides
2400 rect
.Deflate(SLIDER_MARGIN
, 0);
2404 // same as above but in other direction
2405 rect
.width
= 2*BORDER_THICKNESS
;
2406 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2410 rect
.Deflate(0, SLIDER_MARGIN
);
2416 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2417 const wxRect
& rectOrig
,
2418 wxOrientation orient
,
2422 if ( flags
& wxCONTROL_FOCUSED
)
2424 DrawFocusRect(dc
, rectOrig
);
2427 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2432 DrawSunkenBorder(dc
, &rect
);
2435 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2437 wxOrientation orient
,
2441 we are drawing a shape of this form
2446 H DB where H is hightlight colour
2459 The interior of this shape is filled with the hatched brush if the thumb
2463 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2465 bool transpose
= orient
== wxVERTICAL
;
2467 wxCoord x
, y
, x2
, y2
;
2472 x2
= rect
.GetBottom();
2473 y2
= rect
.GetRight();
2479 x2
= rect
.GetRight();
2480 y2
= rect
.GetBottom();
2483 // the size of the pointed part of the thumb
2484 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2486 wxCoord x3
= x
+ sizeArrow
,
2487 y3
= y2
- sizeArrow
;
2489 dc
.SetPen(m_penHighlight
);
2490 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2491 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2492 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2494 dc
.SetPen(m_penBlack
);
2495 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2496 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2498 dc
.SetPen(m_penDarkGrey
);
2499 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2500 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2502 if ( flags
& wxCONTROL_PRESSED
)
2504 // TODO: MSW fills the entire area inside, not just the rect
2505 wxRect rectInt
= rect
;
2507 rectInt
.SetRight(y3
);
2509 rectInt
.SetBottom(y3
);
2512 static const char *stipple_xpm
[] = {
2513 /* columns rows colors chars-per-pixel */
2521 dc
.SetBrush(wxBrush(stipple_xpm
));
2523 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2524 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2525 dc
.SetPen(*wxTRANSPARENT_PEN
);
2526 dc
.DrawRectangle(rectInt
);
2530 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2532 const wxSize
& sizeThumb
,
2533 wxOrientation orient
,
2545 // the variable names correspond to horizontal case, but they can be used
2546 // for both orientations
2547 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2548 if ( orient
== wxHORIZONTAL
)
2550 x1
= rect
.GetLeft();
2551 x2
= rect
.GetRight();
2553 // draw from bottom to top to leave one pixel space between the ticks
2554 // and the slider as Windows do
2555 y1
= rect
.GetBottom();
2560 widthThumb
= sizeThumb
.x
;
2565 x2
= rect
.GetBottom();
2567 y1
= rect
.GetRight();
2568 y2
= rect
.GetLeft();
2572 widthThumb
= sizeThumb
.y
;
2575 // the first tick should be positioned in such way that a thumb drawn in
2576 // the first position points down directly to it
2577 x1
+= widthThumb
/ 2;
2578 x2
-= widthThumb
/ 2;
2580 // this also means that we have slightly less space for the ticks in
2581 // between the first and the last
2584 dc
.SetPen(m_penBlack
);
2586 int range
= end
- start
;
2587 for ( int n
= 0; n
< range
; n
+= step
)
2589 wxCoord x
= x1
+ (len
*n
) / range
;
2591 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2594 // always draw the line at the end position
2595 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2598 // ----------------------------------------------------------------------------
2600 // ----------------------------------------------------------------------------
2604 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2605 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2608 virtual wxSize
GetSize() const { return m_size
; }
2610 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2611 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2613 wxCoord
GetItemHeight() const { return m_heightItem
; }
2616 // the total size of the menu
2619 // the offset of the start of the menu item label
2622 // the offset of the start of the accel label
2625 // the height of a normal (not separator) item
2626 wxCoord m_heightItem
;
2628 friend wxMenuGeometryInfo
*wxWin32Renderer::
2629 GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2632 #endif // wxUSE_MENUS
2634 // FIXME: all constants are hardcoded but shouldn't be
2635 static const wxCoord MENU_LEFT_MARGIN
= 9;
2636 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2637 static const wxCoord MENU_VERT_MARGIN
= 3;
2639 // the margin around bitmap/check marks (on each side)
2640 static const wxCoord MENU_BMP_MARGIN
= 2;
2642 // the margin between the labels and accel strings
2643 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2645 // the separator height in pixels: in fact, strangely enough, the real height
2646 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2648 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2650 // the size of the standard checkmark bitmap
2651 static const wxCoord MENU_CHECK_SIZE
= 9;
2653 // we can't implement these methods without wxMenuGeometryInfo implementation
2654 // which we don't have if !wxUSE_MENUS
2657 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2658 const wxRect
& rectOrig
,
2659 const wxString
& label
,
2663 wxRect rect
= rectOrig
;
2666 wxDCTextColourChanger
colChanger(dc
);
2668 if ( flags
& wxCONTROL_SELECTED
)
2670 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2672 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2673 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2674 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2675 dc
.DrawRectangle(rect
);
2678 // don't draw the focus rect around menu bar items
2679 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2680 wxALIGN_CENTRE
, indexAccel
);
2683 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2685 const wxMenuGeometryInfo
& gi
,
2686 const wxString
& label
,
2687 const wxString
& accel
,
2688 const wxBitmap
& bitmap
,
2692 const wxWin32MenuGeometryInfo
& geometryInfo
=
2693 (const wxWin32MenuGeometryInfo
&)gi
;
2698 rect
.width
= geometryInfo
.GetSize().x
;
2699 rect
.height
= geometryInfo
.GetItemHeight();
2701 // draw the selected item specially
2702 wxDCTextColourChanger
colChanger(dc
);
2703 if ( flags
& wxCONTROL_SELECTED
)
2705 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2707 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2708 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2709 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2710 dc
.DrawRectangle(rect
);
2713 // draw the bitmap: use the bitmap provided or the standard checkmark for
2714 // the checkable items
2715 wxBitmap bmp
= bitmap
;
2716 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2718 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2723 rect
.SetRight(geometryInfo
.GetLabelOffset());
2724 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2728 rect
.x
= geometryInfo
.GetLabelOffset();
2729 rect
.SetRight(geometryInfo
.GetAccelOffset());
2731 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2733 // draw the accel string
2734 rect
.x
= geometryInfo
.GetAccelOffset();
2735 rect
.SetRight(geometryInfo
.GetSize().x
);
2737 // NB: no accel index here
2738 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2740 // draw the submenu indicator
2741 if ( flags
& wxCONTROL_ISSUBMENU
)
2743 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2744 rect
.width
= MENU_RIGHT_MARGIN
;
2746 wxArrowStyle arrowStyle
;
2747 if ( flags
& wxCONTROL_DISABLED
)
2748 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2750 else if ( flags
& wxCONTROL_SELECTED
)
2751 arrowStyle
= Arrow_Inversed
;
2753 arrowStyle
= Arrow_Normal
;
2755 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2759 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2761 const wxMenuGeometryInfo
& geomInfo
)
2763 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2766 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2768 wxSize size
= sizeText
;
2770 // FIXME: menubar height is configurable under Windows
2777 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2778 const wxMenu
& menu
) const
2780 // prepare the dc: for now we draw all the items with the system font
2782 dc
.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
2784 // the height of a normal item
2785 wxCoord heightText
= dc
.GetCharHeight();
2790 // the max length of label and accel strings: the menu width is the sum of
2791 // them, even if they're for different items (as the accels should be
2794 // the max length of the bitmap is never 0 as Windows always leaves enough
2795 // space for a check mark indicator
2796 wxCoord widthLabelMax
= 0,
2798 widthBmpMax
= MENU_LEFT_MARGIN
;
2800 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2802 node
= node
->GetNext() )
2804 // height of this item
2807 wxMenuItem
*item
= node
->GetData();
2808 if ( item
->IsSeparator() )
2810 h
= MENU_SEPARATOR_HEIGHT
;
2812 else // not separator
2817 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2818 if ( widthLabel
> widthLabelMax
)
2820 widthLabelMax
= widthLabel
;
2824 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2825 if ( widthAccel
> widthAccelMax
)
2827 widthAccelMax
= widthAccel
;
2830 const wxBitmap
& bmp
= item
->GetBitmap();
2833 wxCoord widthBmp
= bmp
.GetWidth();
2834 if ( widthBmp
> widthBmpMax
)
2835 widthBmpMax
= widthBmp
;
2837 //else if ( item->IsCheckable() ): no need to check for this as
2838 // MENU_LEFT_MARGIN is big enough to show the check mark
2841 h
+= 2*MENU_VERT_MARGIN
;
2843 // remember the item position and height
2844 item
->SetGeometry(height
, h
);
2849 // bundle the metrics into a struct and return it
2850 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2852 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2853 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2854 if ( widthAccelMax
> 0 )
2856 // if we actually have any accesl, add a margin
2857 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2860 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2862 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2863 gi
->m_size
.y
= height
;
2868 #else // !wxUSE_MENUS
2871 void wxWin32Renderer::DrawMenuBarItem(wxDC& WXUNUSED(dc),
2872 const wxRect& WXUNUSED(rectOrig),
2873 const wxString& WXUNUSED(label),
2874 int WXUNUSED(flags),
2875 int WXUNUSED(indexAccel))
2879 void wxWin32Renderer::DrawMenuItem(wxDC& WXUNUSED(dc),
2880 wxCoord WXUNUSED(y),
2881 const wxMenuGeometryInfo& WXUNUSED(gi),
2882 const wxString& WXUNUSED(label),
2883 const wxString& WXUNUSED(accel),
2884 const wxBitmap& WXUNUSED(bitmap),
2885 int WXUNUSED(flags),
2886 int WXUNUSED(indexAccel))
2890 void wxWin32Renderer::DrawMenuSeparator(wxDC& WXUNUSED(dc),
2891 wxCoord WXUNUSED(y),
2892 const wxMenuGeometryInfo& WXUNUSED(gi))
2896 wxSize wxWin32Renderer::GetMenuBarItemSize(const wxSize& size) const
2901 wxMenuGeometryInfo *
2902 wxWin32Renderer::GetMenuGeometry(wxWindow *WXUNUSED(win),
2903 const wxMenu& WXUNUSED(menu)) const
2909 #endif // wxUSE_MENUS/!wxUSE_MENUS
2911 // ----------------------------------------------------------------------------
2913 // ----------------------------------------------------------------------------
2915 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2917 wxBitmap
*bmpPressed
,
2918 wxBitmap
*bmpDisabled
)
2920 static const wxCoord widthCombo
= 16;
2921 static const wxCoord heightCombo
= 17;
2927 bmpNormal
->Create(widthCombo
, heightCombo
);
2928 dcMem
.SelectObject(*bmpNormal
);
2929 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2930 Arrow_Down
, Arrow_Normal
);
2935 bmpPressed
->Create(widthCombo
, heightCombo
);
2936 dcMem
.SelectObject(*bmpPressed
);
2937 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2938 Arrow_Down
, Arrow_Pressed
);
2943 bmpDisabled
->Create(widthCombo
, heightCombo
);
2944 dcMem
.SelectObject(*bmpDisabled
);
2945 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2946 Arrow_Down
, Arrow_Disabled
);
2950 // ----------------------------------------------------------------------------
2952 // ----------------------------------------------------------------------------
2954 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
2955 const wxColour
& col
,
2958 wxBrush
brush(col
, wxSOLID
);
2960 dc
.SetPen(*wxTRANSPARENT_PEN
);
2961 dc
.DrawRectangle(rect
);
2964 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
2965 const wxColour
& col
,
2969 // just fill it with the given or default bg colour
2970 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
2971 DoDrawBackground(dc
, colBg
, rect
);
2974 // ----------------------------------------------------------------------------
2976 // ----------------------------------------------------------------------------
2978 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
2983 // get the bitmap for this arrow
2984 wxArrowDirection arrowDir
;
2987 case wxLEFT
: arrowDir
= Arrow_Left
; break;
2988 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
2989 case wxUP
: arrowDir
= Arrow_Up
; break;
2990 case wxDOWN
: arrowDir
= Arrow_Down
; break;
2993 wxFAIL_MSG(_T("unknown arrow direction"));
2997 wxArrowStyle arrowStyle
;
2998 if ( flags
& wxCONTROL_PRESSED
)
3000 // can't be pressed and disabled
3001 arrowStyle
= Arrow_Pressed
;
3005 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3008 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3011 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3013 wxArrowDirection arrowDir
,
3014 wxArrowStyle arrowStyle
)
3016 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3018 // under Windows the arrows always have the same size so just centre it in
3019 // the provided rectangle
3020 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3021 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3023 // Windows does it like this...
3024 if ( arrowDir
== Arrow_Left
)
3028 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3031 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3032 const wxRect
& rectAll
,
3033 wxArrowDirection arrowDir
,
3034 wxArrowStyle arrowStyle
)
3036 wxRect rect
= rectAll
;
3037 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3038 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3039 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3042 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3043 wxOrientation orient
,
3047 // we don't use the flags, the thumb never changes appearance
3048 wxRect rectThumb
= rect
;
3049 DrawArrowBorder(dc
, &rectThumb
);
3050 DrawBackground(dc
, wxNullColour
, rectThumb
);
3053 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3054 wxOrientation orient
,
3055 const wxRect
& rectBar
,
3058 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3059 ? wxColourScheme::SCROLLBAR_PRESSED
3060 : wxColourScheme::SCROLLBAR
;
3061 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3064 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3066 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3069 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3070 wxScrollBar::Element elem
,
3073 return StandardGetScrollbarRect(scrollbar
, elem
,
3074 thumbPos
, m_sizeScrollbarArrow
);
3077 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3079 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3082 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3083 const wxPoint
& pt
) const
3085 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3088 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3091 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3094 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3097 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3100 // ----------------------------------------------------------------------------
3101 // top level windows
3102 // ----------------------------------------------------------------------------
3104 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3106 wxRect client
= GetFrameClientArea(rect
, flags
);
3108 if ( client
.Inside(pt
) )
3109 return wxHT_TOPLEVEL_CLIENT_AREA
;
3111 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3113 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3115 if ( flags
& wxTOPLEVEL_ICON
)
3117 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3118 return wxHT_TOPLEVEL_ICON
;
3121 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3122 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3123 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3125 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3127 if ( btnRect
.Inside(pt
) )
3128 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3129 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3131 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3133 if ( btnRect
.Inside(pt
) )
3134 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3135 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3137 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3139 if ( btnRect
.Inside(pt
) )
3140 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3141 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3143 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3145 if ( btnRect
.Inside(pt
) )
3146 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3147 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3149 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3151 if ( btnRect
.Inside(pt
) )
3152 return wxHT_TOPLEVEL_BUTTON_HELP
;
3153 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3156 if ( pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3157 return wxHT_TOPLEVEL_TITLEBAR
;
3160 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3162 // we are certainly at one of borders, lets decide which one:
3164 wxCoord midX
= client
.x
+ client
.width
/2,
3165 midY
= client
.y
+ client
.height
/2;
3167 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3169 border
|= wxHT_TOPLEVEL_BORDER_W
;
3171 border
|= wxHT_TOPLEVEL_BORDER_E
;
3173 border
|= wxHT_TOPLEVEL_BORDER_N
;
3175 border
|= wxHT_TOPLEVEL_BORDER_S
;
3179 return wxHT_NOWHERE
;
3182 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3184 const wxString
& title
,
3188 int specialButtonFlags
)
3190 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3192 DrawFrameBorder(dc
, rect
, flags
);
3194 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3196 DrawFrameBackground(dc
, rect
, flags
);
3197 if ( flags
& wxTOPLEVEL_ICON
)
3198 DrawFrameIcon(dc
, rect
, icon
, flags
);
3199 DrawFrameTitle(dc
, rect
, title
, flags
);
3201 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3203 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3204 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3206 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3208 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3209 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3210 specialButtonFlags
: 0);
3211 x
-= FRAME_BUTTON_WIDTH
+ 2;
3213 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3215 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3216 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3217 specialButtonFlags
: 0);
3218 x
-= FRAME_BUTTON_WIDTH
;
3220 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3222 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3223 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3224 specialButtonFlags
: 0);
3225 x
-= FRAME_BUTTON_WIDTH
;
3227 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3229 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3230 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3231 specialButtonFlags
: 0);
3232 x
-= FRAME_BUTTON_WIDTH
;
3234 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3236 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3237 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3238 specialButtonFlags
: 0);
3239 x
-= FRAME_BUTTON_WIDTH
;
3244 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3248 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3252 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3253 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3254 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3255 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3256 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3259 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3263 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3265 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3266 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3267 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3269 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3270 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3272 DrawBackground(dc
, col
, r
);
3275 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3277 const wxString
& title
,
3280 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3281 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3282 if ( flags
& wxTOPLEVEL_ICON
)
3283 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3287 dc
.SetFont(m_titlebarFont
);
3288 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
));
3289 dc
.DrawLabel(title
, wxNullBitmap
, r
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3292 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3299 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3300 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3304 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3305 wxCoord x
, wxCoord y
,
3309 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3314 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3315 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3316 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3317 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3318 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3320 wxFAIL_MSG(wxT("incorrect button specification"));
3323 if ( flags
& wxCONTROL_PRESSED
)
3325 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3326 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3327 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3328 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3332 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3333 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3334 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3335 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3340 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3345 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3347 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3348 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3349 FRAME_BORDER_THICKNESS
;
3352 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3354 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3355 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3361 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3364 wxSize
s(clientSize
);
3366 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3368 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3369 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3370 FRAME_BORDER_THICKNESS
;
3374 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3375 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3380 wxSize
wxWin32Renderer::GetFrameIconSize() const
3382 return wxSize(16, 16);
3387 // ----------------------------------------------------------------------------
3388 // text control geometry
3389 // ----------------------------------------------------------------------------
3391 static inline int GetTextBorderWidth()
3396 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3399 wxRect rectTotal
= rect
;
3401 wxCoord widthBorder
= GetTextBorderWidth();
3402 rectTotal
.Inflate(widthBorder
);
3404 // this is what Windows does
3410 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3412 wxCoord
*extraSpaceBeyond
)
3414 wxRect rectText
= rect
;
3416 // undo GetTextTotalArea()
3417 if ( rectText
.height
> 0 )
3420 wxCoord widthBorder
= GetTextBorderWidth();
3421 rectText
.Inflate(-widthBorder
);
3423 if ( extraSpaceBeyond
)
3424 *extraSpaceBeyond
= 0;
3429 // ----------------------------------------------------------------------------
3431 // ----------------------------------------------------------------------------
3433 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3436 if ( wxDynamicCast(window
, wxScrollBar
) )
3438 // we only set the width of vert scrollbars and height of the
3440 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3441 size
->y
= m_sizeScrollbarArrow
.y
;
3443 size
->x
= m_sizeScrollbarArrow
.x
;
3445 // skip border width adjustments, they don't make sense for us
3448 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3451 if ( wxDynamicCast(window
, wxButton
) )
3453 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3455 // TODO: don't harcode all this
3456 size
->x
+= 3*window
->GetCharWidth();
3458 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3459 if ( size
->y
< heightBtn
- 8 )
3460 size
->y
= heightBtn
;
3465 // no border width adjustments for buttons
3468 #endif // wxUSE_BUTTON
3470 // take into account the border width
3471 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3472 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3473 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3476 // ============================================================================
3478 // ============================================================================
3480 // ----------------------------------------------------------------------------
3481 // wxWin32InputHandler
3482 // ----------------------------------------------------------------------------
3484 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3486 m_renderer
= renderer
;
3489 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3490 const wxKeyEvent
& event
,
3496 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3497 const wxMouseEvent
& event
)
3499 // clicking on the control gives it focus
3500 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
3502 control
->GetInputWindow()->SetFocus();
3510 // ----------------------------------------------------------------------------
3511 // wxWin32ScrollBarInputHandler
3512 // ----------------------------------------------------------------------------
3514 wxWin32ScrollBarInputHandler::
3515 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3516 wxInputHandler
*handler
)
3517 : wxStdScrollBarInputHandler(renderer
, handler
)
3519 m_scrollPaused
= FALSE
;
3523 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3524 const wxControlAction
& action
)
3526 // stop if went beyond the position of the original click (this can only
3527 // happen when we scroll by pages)
3529 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3531 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3532 != wxHT_SCROLLBAR_BAR_2
;
3534 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3536 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3537 != wxHT_SCROLLBAR_BAR_1
;
3542 StopScrolling(scrollbar
);
3544 scrollbar
->Refresh();
3549 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3552 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3553 const wxMouseEvent
& event
)
3555 // remember the current state
3556 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3558 // do process the message
3559 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3561 // analyse the changes
3562 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3564 // we just started dragging the thumb, remember its initial position to
3565 // be able to restore it if the drag is cancelled later
3566 m_eventStartDrag
= event
;
3572 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3573 const wxMouseEvent
& event
)
3575 // we don't highlight scrollbar elements, so there is no need to process
3576 // mouse move events normally - only do it while mouse is captured (i.e.
3577 // when we're dragging the thumb or pressing on something)
3578 if ( !m_winCapture
)
3581 if ( event
.Entering() )
3583 // we're not interested in this at all
3587 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3589 if ( m_scrollPaused
)
3591 // check if the mouse returned to its original location
3593 if ( event
.Leaving() )
3599 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3600 if ( ht
== m_htLast
)
3602 // yes it did, resume scrolling
3603 m_scrollPaused
= FALSE
;
3604 if ( m_timerScroll
)
3606 // we were scrolling by line/page, restart timer
3607 m_timerScroll
->Start(m_interval
);
3609 Press(scrollbar
, TRUE
);
3611 else // we were dragging the thumb
3613 // restore its last location
3614 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3620 else // normal case, scrolling hasn't been paused
3622 // if we're scrolling the scrollbar because the arrow or the shaft was
3623 // pressed, check that the mouse stays on the same scrollbar element
3625 if ( event
.Moving() )
3627 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3629 else // event.Leaving()
3634 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3635 // is still ok - we only want to catch the case when the mouse leaves
3636 // the scrollbar here
3637 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3639 ht
= wxHT_SCROLLBAR_THUMB
;
3642 if ( ht
!= m_htLast
)
3644 // what were we doing? 2 possibilities: either an arrow/shaft was
3645 // pressed in which case we have a timer and so we just stop it or
3646 // we were dragging the thumb
3647 if ( m_timerScroll
)
3650 m_interval
= m_timerScroll
->GetInterval();
3651 m_timerScroll
->Stop();
3652 m_scrollPaused
= TRUE
;
3654 // unpress the arrow
3655 Press(scrollbar
, FALSE
);
3657 else // we were dragging the thumb
3659 // remember the current thumb position to be able to restore it
3660 // if the mouse returns to it later
3661 m_eventLastDrag
= event
;
3663 // and restore the original position (before dragging) of the
3665 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3672 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
3675 // ----------------------------------------------------------------------------
3676 // wxWin32CheckboxInputHandler
3677 // ----------------------------------------------------------------------------
3679 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3680 const wxKeyEvent
& event
,
3685 wxControlAction action
;
3686 int keycode
= event
.GetKeyCode();
3690 action
= wxACTION_CHECKBOX_TOGGLE
;
3694 case WXK_NUMPAD_SUBTRACT
:
3695 action
= wxACTION_CHECKBOX_CHECK
;
3699 case WXK_NUMPAD_ADD
:
3700 case WXK_NUMPAD_EQUAL
:
3701 action
= wxACTION_CHECKBOX_CLEAR
;
3707 control
->PerformAction(action
);
3716 // ----------------------------------------------------------------------------
3717 // wxWin32TextCtrlInputHandler
3718 // ----------------------------------------------------------------------------
3720 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3721 const wxKeyEvent
& event
,
3724 // handle only MSW-specific text bindings here, the others are handled in
3728 int keycode
= event
.GetKeyCode();
3730 wxControlAction action
;
3731 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
3733 action
= wxACTION_TEXT_CUT
;
3735 else if ( keycode
== WXK_INSERT
)
3737 if ( event
.ControlDown() )
3738 action
= wxACTION_TEXT_COPY
;
3739 else if ( event
.ShiftDown() )
3740 action
= wxACTION_TEXT_PASTE
;
3743 if ( action
!= wxACTION_NONE
)
3745 control
->PerformAction(action
);
3751 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);