1 // Name: univ/themes/win32.cpp
2 // Purpose: wxUniversal theme implementing Win32-like LNF
3 // Author: Vadim Zeitlin
7 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows license
9 ///////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
30 #include "wx/window.h"
32 #include "wx/dcmemory.h"
34 #include "wx/button.h"
35 #include "wx/listbox.h"
36 #include "wx/checklst.h"
37 #include "wx/combobox.h"
38 #include "wx/scrolbar.h"
39 #include "wx/slider.h"
40 #include "wx/textctrl.h"
43 // for COLOR_* constants
44 #include "wx/msw/private.h"
48 #include "wx/notebook.h"
49 #include "wx/spinbutt.h"
50 #include "wx/settings.h"
53 #include "wx/univ/scrtimer.h"
54 #include "wx/toplevel.h"
55 #include "wx/univ/renderer.h"
56 #include "wx/univ/inphand.h"
57 #include "wx/univ/colschem.h"
58 #include "wx/univ/theme.h"
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 static const int BORDER_THICKNESS
= 2;
66 // the offset between the label and focus rect around it
67 static const int FOCUS_RECT_OFFSET_X
= 1;
68 static const int FOCUS_RECT_OFFSET_Y
= 1;
70 static const int FRAME_BORDER_THICKNESS
= 3;
71 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
72 static const int FRAME_TITLEBAR_HEIGHT
= 18;
73 static const int FRAME_BUTTON_WIDTH
= 16;
74 static const int FRAME_BUTTON_HEIGHT
= 14;
76 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
77 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
78 static const size_t STATUSBAR_GRIP_SIZE
=
79 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
91 IndicatorState_Normal
,
92 IndicatorState_Pressed
, // this one is for check/radioboxes
93 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
94 IndicatorState_Disabled
,
95 IndicatorState_SelectedDisabled
, // only for the menus
101 IndicatorStatus_Checked
,
102 IndicatorStatus_Unchecked
,
106 // wxWin32Renderer: draw the GUI elements in Win32 style
107 // ----------------------------------------------------------------------------
109 class wxWin32Renderer
: public wxRenderer
113 enum wxArrowDirection
128 Arrow_InversedDisabled
,
132 enum wxFrameButtonType
135 FrameButton_Minimize
,
136 FrameButton_Maximize
,
143 wxWin32Renderer(const wxColourScheme
*scheme
);
145 // implement the base class pure virtuals
146 virtual void DrawBackground(wxDC
& dc
,
150 virtual void DrawLabel(wxDC
& dc
,
151 const wxString
& label
,
154 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
156 wxRect
*rectBounds
= NULL
);
157 virtual void DrawButtonLabel(wxDC
& dc
,
158 const wxString
& label
,
159 const wxBitmap
& image
,
162 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
164 wxRect
*rectBounds
= NULL
);
165 virtual void DrawBorder(wxDC
& dc
,
169 wxRect
*rectIn
= (wxRect
*)NULL
);
170 virtual void DrawHorizontalLine(wxDC
& dc
,
171 wxCoord y
, wxCoord x1
, wxCoord x2
);
172 virtual void DrawVerticalLine(wxDC
& dc
,
173 wxCoord x
, wxCoord y1
, wxCoord y2
);
174 virtual void DrawFrame(wxDC
& dc
,
175 const wxString
& label
,
178 int alignment
= wxALIGN_LEFT
,
179 int indexAccel
= -1);
180 virtual void DrawTextBorder(wxDC
& dc
,
184 wxRect
*rectIn
= (wxRect
*)NULL
);
185 virtual void DrawButtonBorder(wxDC
& dc
,
188 wxRect
*rectIn
= (wxRect
*)NULL
);
189 virtual void DrawArrow(wxDC
& dc
,
193 virtual void DrawScrollbarArrow(wxDC
& dc
,
197 { DrawArrow(dc
, dir
, rect
, flags
); }
198 virtual void DrawScrollbarThumb(wxDC
& dc
,
199 wxOrientation orient
,
202 virtual void DrawScrollbarShaft(wxDC
& dc
,
203 wxOrientation orient
,
206 virtual void DrawScrollCorner(wxDC
& dc
,
208 virtual void DrawItem(wxDC
& dc
,
209 const wxString
& label
,
212 virtual void DrawCheckItem(wxDC
& dc
,
213 const wxString
& label
,
214 const wxBitmap
& bitmap
,
217 virtual void DrawCheckButton(wxDC
& dc
,
218 const wxString
& label
,
219 const wxBitmap
& bitmap
,
222 wxAlignment align
= wxALIGN_LEFT
,
223 int indexAccel
= -1);
224 virtual void DrawRadioButton(wxDC
& dc
,
225 const wxString
& label
,
226 const wxBitmap
& bitmap
,
229 wxAlignment align
= wxALIGN_LEFT
,
230 int indexAccel
= -1);
231 virtual void DrawTextLine(wxDC
& dc
,
232 const wxString
& text
,
237 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
238 virtual void DrawTab(wxDC
& dc
,
241 const wxString
& label
,
242 const wxBitmap
& bitmap
= wxNullBitmap
,
244 int indexAccel
= -1);
246 virtual void DrawSliderShaft(wxDC
& dc
,
248 wxOrientation orient
,
250 wxRect
*rectShaft
= NULL
);
251 virtual void DrawSliderThumb(wxDC
& dc
,
253 wxOrientation orient
,
255 virtual void DrawSliderTicks(wxDC
& dc
,
257 const wxSize
& sizeThumb
,
258 wxOrientation orient
,
264 virtual void DrawMenuBarItem(wxDC
& dc
,
266 const wxString
& label
,
268 int indexAccel
= -1);
269 virtual void DrawMenuItem(wxDC
& dc
,
271 const wxMenuGeometryInfo
& geometryInfo
,
272 const wxString
& label
,
273 const wxString
& accel
,
274 const wxBitmap
& bitmap
= wxNullBitmap
,
276 int indexAccel
= -1);
277 virtual void DrawMenuSeparator(wxDC
& dc
,
279 const wxMenuGeometryInfo
& geomInfo
);
281 virtual void DrawStatusField(wxDC
& dc
,
283 const wxString
& label
,
287 virtual void DrawFrameTitleBar(wxDC
& dc
,
289 const wxString
& title
,
292 int specialButton
= 0,
293 int specialButtonFlags
= 0);
294 virtual void DrawFrameBorder(wxDC
& dc
,
297 virtual void DrawFrameBackground(wxDC
& dc
,
300 virtual void DrawFrameTitle(wxDC
& dc
,
302 const wxString
& title
,
304 virtual void DrawFrameIcon(wxDC
& dc
,
308 virtual void DrawFrameButton(wxDC
& dc
,
309 wxCoord x
, wxCoord y
,
312 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
313 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
314 virtual wxSize
GetFrameMinSize(int flags
) const;
315 virtual wxSize
GetFrameIconSize() const;
316 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
318 virtual wxIcon
GetStdIcon(int which
) const;
320 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
322 wxBitmap
*bmpPressed
,
323 wxBitmap
*bmpDisabled
);
325 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
326 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
327 virtual bool AreScrollbarsInsideBorder() const;
329 virtual wxSize
GetScrollbarArrowSize() const
330 { return m_sizeScrollbarArrow
; }
331 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
332 wxScrollBar
::Element elem
,
333 int thumbPos
= -1) const;
334 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
335 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
336 const wxPoint
& pt
) const;
337 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
339 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
340 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
341 { return fontHeight
+ 2; }
342 virtual wxSize
GetCheckBitmapSize() const
343 { return wxSize(13, 13); }
344 virtual wxSize
GetRadioBitmapSize() const
345 { return wxSize(12, 12); }
346 virtual wxCoord
GetCheckItemMargin() const
349 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
351 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
353 wxCoord
*extraSpaceBeyond
);
355 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
356 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
358 virtual wxCoord
GetSliderDim() const { return 20; }
359 virtual wxCoord
GetSliderTickLen() const { return 4; }
360 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
361 wxOrientation orient
) const;
362 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
363 wxOrientation orient
) const;
364 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
366 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
367 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
368 const wxMenu
& menu
) const;
370 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
373 // helper of DrawLabel() and DrawCheckOrRadioButton()
374 void DoDrawLabel(wxDC
& dc
,
375 const wxString
& label
,
378 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
380 wxRect
*rectBounds
= NULL
,
381 const wxPoint
& focusOffset
382 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
384 // common part of DrawLabel() and DrawItem()
385 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
387 // DrawLabel() and DrawButtonLabel() helper
388 void DrawLabelShadow(wxDC
& dc
,
389 const wxString
& label
,
394 // DrawButtonBorder() helper
395 void DoDrawBackground(wxDC
& dc
,
399 // DrawBorder() helpers: all of them shift and clip the DC after drawing
402 // just draw a rectangle with the given pen
403 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
405 // draw the lower left part of rectangle
406 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
408 // draw the rectange using the first brush for the left and top sides and
409 // the second one for the bottom and right ones
410 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
411 const wxPen
& pen1
, const wxPen
& pen2
);
413 // draw the normal 3D border
414 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
416 // draw the sunken 3D border
417 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
419 // draw the border used for scrollbar arrows
420 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
422 // public DrawArrow()s helper
423 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
424 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
426 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
427 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
428 wxArrowDirection arrowDir
,
429 wxArrowStyle arrowStyle
);
431 // DrawCheckButton/DrawRadioButton helper
432 void DrawCheckOrRadioButton(wxDC
& dc
,
433 const wxString
& label
,
434 const wxBitmap
& bitmap
,
439 wxCoord focusOffsetY
);
441 // draw a normal or transposed line (useful for using the same code fo both
442 // horizontal and vertical widgets)
443 void DrawLine(wxDC
& dc
,
444 wxCoord x1
, wxCoord y1
,
445 wxCoord x2
, wxCoord y2
,
446 bool transpose
= FALSE
)
449 dc
.DrawLine(y1
, x1
, y2
, x2
);
451 dc
.DrawLine(x1
, y1
, x2
, y2
);
454 // get the standard check/radio button bitmap
455 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
456 wxBitmap
GetCheckBitmap(int flags
)
457 { return GetIndicator(IndicatorType_Check
, flags
); }
458 wxBitmap
GetRadioBitmap(int flags
)
459 { return GetIndicator(IndicatorType_Radio
, flags
); }
462 const wxColourScheme
*m_scheme
;
464 // the sizing parameters (TODO make them changeable)
465 wxSize m_sizeScrollbarArrow
;
467 // GDI objects we use for drawing
468 wxColour m_colDarkGrey
,
476 wxFont m_titlebarFont
;
479 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
481 // first row is for the normal state, second - for the disabled
482 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
485 // ----------------------------------------------------------------------------
486 // wxWin32InputHandler and derived classes: process the keyboard and mouse
487 // messages according to Windows standards
488 // ----------------------------------------------------------------------------
490 class wxWin32InputHandler
: public wxInputHandler
493 wxWin32InputHandler(wxWin32Renderer
*renderer
);
495 virtual bool HandleKey(wxInputConsumer
*control
,
496 const wxKeyEvent
& event
,
498 virtual bool HandleMouse(wxInputConsumer
*control
,
499 const wxMouseEvent
& event
);
502 wxWin32Renderer
*m_renderer
;
505 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
508 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
509 wxInputHandler
*handler
);
511 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
512 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
514 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
515 const wxControlAction
& action
);
518 virtual bool IsAllowedButton(int button
) { return button
== 1; }
520 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
522 // we don't highlight anything
525 // the first and last event which caused the thumb to move
526 wxMouseEvent m_eventStartDrag
,
529 // have we paused the scrolling because the mouse moved?
532 // we remember the interval of the timer to be able to restart it
536 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
539 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
540 : wxStdCheckboxInputHandler(handler
) { }
542 virtual bool HandleKey(wxInputConsumer
*control
,
543 const wxKeyEvent
& event
,
547 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
550 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
551 : wxStdTextCtrlInputHandler(handler
) { }
553 virtual bool HandleKey(wxInputConsumer
*control
,
554 const wxKeyEvent
& event
,
558 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
561 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
563 virtual bool HandleMouse(wxInputConsumer
*consumer
,
564 const wxMouseEvent
& event
);
566 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
567 const wxMouseEvent
& event
);
570 // is the given point over the statusbar grip?
571 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
574 // the cursor we had replaced with the resize one
575 wxCursor m_cursorOld
;
577 // was the mouse over the grip last time we checked?
581 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
584 wxWin32FrameInputHandler(wxInputHandler
*handler
)
585 : wxStdFrameInputHandler(handler
) { }
587 virtual bool HandleMouse(wxInputConsumer
*control
,
588 const wxMouseEvent
& event
);
591 // ----------------------------------------------------------------------------
592 // wxWin32ColourScheme: uses (default) Win32 colours
593 // ----------------------------------------------------------------------------
595 class wxWin32ColourScheme
: public wxColourScheme
598 virtual wxColour
Get(StdColour col
) const;
599 virtual wxColour
GetBackground(wxWindow
*win
) const;
602 // ----------------------------------------------------------------------------
604 // ----------------------------------------------------------------------------
606 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
608 class wxWin32Theme
: public wxTheme
612 virtual ~wxWin32Theme();
614 virtual wxRenderer
*GetRenderer();
615 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
616 virtual wxColourScheme
*GetColourScheme();
619 // get the default input handler
620 wxInputHandler
*GetDefaultInputHandler();
622 wxWin32Renderer
*m_renderer
;
624 // the names of the already created handlers and the handlers themselves
625 // (these arrays are synchronized)
626 wxSortedArrayString m_handlerNames
;
627 wxArrayHandlers m_handlers
;
629 wxWin32InputHandler
*m_handlerDefault
;
631 wxWin32ColourScheme
*m_scheme
;
633 WX_DECLARE_THEME(win32
)
636 // ----------------------------------------------------------------------------
638 // ----------------------------------------------------------------------------
640 // frame buttons bitmaps
642 static const char *frame_button_close_xpm
[] = {
657 static const char *frame_button_help_xpm
[] = {
672 static const char *frame_button_maximize_xpm
[] = {
687 static const char *frame_button_minimize_xpm
[] = {
702 static const char *frame_button_restore_xpm
[] = {
719 static const char *checked_menu_xpm
[] = {
720 /* columns rows colors chars-per-pixel */
736 static const char *selected_checked_menu_xpm
[] = {
737 /* columns rows colors chars-per-pixel */
753 static const char *disabled_checked_menu_xpm
[] = {
754 /* columns rows colors chars-per-pixel */
771 static const char *selected_disabled_checked_menu_xpm
[] = {
772 /* columns rows colors chars-per-pixel */
788 // checkbox and radiobox bitmaps below
790 static const char *checked_xpm
[] = {
791 /* columns rows colors chars-per-pixel */
814 static const char *pressed_checked_xpm
[] = {
815 /* columns rows colors chars-per-pixel */
837 static const char *pressed_disabled_checked_xpm
[] = {
838 /* columns rows colors chars-per-pixel */
860 static const char *checked_item_xpm
[] = {
861 /* columns rows colors chars-per-pixel */
882 static const char *unchecked_xpm
[] = {
883 /* columns rows colors chars-per-pixel */
906 static const char *pressed_unchecked_xpm
[] = {
907 /* columns rows colors chars-per-pixel */
929 static const char *unchecked_item_xpm
[] = {
930 /* columns rows colors chars-per-pixel */
950 static const char *checked_radio_xpm
[] = {
951 /* columns rows colors chars-per-pixel */
974 static const char *pressed_checked_radio_xpm
[] = {
975 /* columns rows colors chars-per-pixel */
998 static const char *pressed_disabled_checked_radio_xpm
[] = {
999 /* columns rows colors chars-per-pixel */
1022 static const char *unchecked_radio_xpm
[] = {
1023 /* columns rows colors chars-per-pixel */
1046 static const char *pressed_unchecked_radio_xpm
[] = {
1047 /* columns rows colors chars-per-pixel */
1070 static const char **
1071 bmpIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1076 { checked_xpm
, unchecked_xpm
},
1079 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1082 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1088 { checked_radio_xpm
, unchecked_radio_xpm
},
1091 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1094 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1100 { checked_menu_xpm
, NULL
},
1103 { selected_checked_menu_xpm
, NULL
},
1106 { disabled_checked_menu_xpm
, NULL
},
1108 // disabled selected state
1109 { selected_disabled_checked_menu_xpm
, NULL
},
1113 // ============================================================================
1115 // ============================================================================
1117 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1119 // ----------------------------------------------------------------------------
1121 // ----------------------------------------------------------------------------
1123 wxWin32Theme
::wxWin32Theme()
1127 m_handlerDefault
= NULL
;
1130 wxWin32Theme
::~wxWin32Theme()
1132 size_t count
= m_handlers
.GetCount();
1133 for ( size_t n
= 0; n
< count
; n
++ )
1135 if ( m_handlers
[n
] != m_handlerDefault
)
1136 delete m_handlers
[n
];
1139 delete m_handlerDefault
;
1145 wxRenderer
*wxWin32Theme
::GetRenderer()
1149 m_renderer
= new wxWin32Renderer(GetColourScheme());
1155 wxInputHandler
*wxWin32Theme
::GetDefaultInputHandler()
1157 if ( !m_handlerDefault
)
1159 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1162 return m_handlerDefault
;
1165 wxInputHandler
*wxWin32Theme
::GetInputHandler(const wxString
& control
)
1167 wxInputHandler
*handler
;
1168 int n
= m_handlerNames
.Index(control
);
1169 if ( n
== wxNOT_FOUND
)
1171 // create a new handler
1172 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1173 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1174 GetDefaultInputHandler());
1176 else if ( control
== wxINP_HANDLER_BUTTON
)
1177 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1178 #endif // wxUSE_BUTTON
1180 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1181 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1182 #endif // wxUSE_CHECKBOX
1184 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1185 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1186 #endif // wxUSE_COMBOBOX
1188 else if ( control
== wxINP_HANDLER_LISTBOX
)
1189 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1190 #endif // wxUSE_LISTBOX
1191 #if wxUSE_CHECKLISTBOX
1192 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1193 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1194 #endif // wxUSE_CHECKLISTBOX
1196 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1197 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1198 #endif // wxUSE_TEXTCTRL
1200 else if ( control
== wxINP_HANDLER_SLIDER
)
1201 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1202 #endif // wxUSE_SLIDER
1204 else if ( control
== wxINP_HANDLER_SPINBTN
)
1205 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1206 #endif // wxUSE_SPINBTN
1208 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1209 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1210 #endif // wxUSE_NOTEBOOK
1212 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1213 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1214 #endif // wxUSE_STATUSBAR
1215 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1216 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1218 handler
= GetDefaultInputHandler();
1220 n
= m_handlerNames
.Add(control
);
1221 m_handlers
.Insert(handler
, n
);
1223 else // we already have it
1225 handler
= m_handlers
[n
];
1231 wxColourScheme
*wxWin32Theme
::GetColourScheme()
1235 m_scheme
= new wxWin32ColourScheme
;
1240 // ============================================================================
1241 // wxWin32ColourScheme
1242 // ============================================================================
1244 wxColour wxWin32ColourScheme
::GetBackground(wxWindow
*win
) const
1247 if ( win
->UseBgCol() )
1249 // use the user specified colour
1250 col
= win
->GetBackgroundColour();
1253 if ( win
->IsContainerWindow() )
1255 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1258 if ( !text
->IsEnabled() ) // not IsEditable()
1260 //else: execute code below
1265 // doesn't depend on the state
1271 int flags
= win
->GetStateFlags();
1273 // the colour set by the user should be used for the normal state
1274 // and for the states for which we don't have any specific colours
1275 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1277 if ( wxDynamicCast(win
, wxScrollBar
) )
1278 col
= Get(flags
& wxCONTROL_PRESSED ? SCROLLBAR_PRESSED
1288 wxColour wxWin32ColourScheme
::Get(wxWin32ColourScheme
::StdColour col
) const
1292 // use the system colours under Windows
1293 #if defined(__WXMSW__)
1294 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1296 case CONTROL_PRESSED
:
1297 case CONTROL_CURRENT
:
1298 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1300 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1302 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1303 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1305 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1306 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1308 #if defined(COLOR_3DDKSHADOW)
1309 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1311 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1314 case CONTROL_TEXT_DISABLED
:
1315 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1317 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1319 case CONTROL_TEXT_DISABLED_SHADOW
:
1320 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1322 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1323 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1324 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1325 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1327 case DESKTOP
: return wxColour(0x808000);
1329 // use the standard Windows colours elsewhere
1330 case WINDOW
: return *wxWHITE
;
1332 case CONTROL_PRESSED
:
1333 case CONTROL_CURRENT
:
1334 case CONTROL
: return wxColour(0xc0c0c0);
1336 case CONTROL_TEXT
: return *wxBLACK
;
1338 case SCROLLBAR
: return wxColour(0xe0e0e0);
1339 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1341 case HIGHLIGHT
: return wxColour(0x800000);
1342 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1344 case SHADOW_DARK
: return *wxBLACK
;
1346 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1347 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1349 case SHADOW_IN
: return wxColour(0xc0c0c0);
1351 case CONTROL_TEXT_DISABLED_SHADOW
:
1352 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1354 case TITLEBAR
: return wxColour(0xaeaaae);
1355 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1356 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1357 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1359 case DESKTOP
: return wxColour(0x808000);
1362 case GAUGE
: return Get(HIGHLIGHT
);
1366 wxFAIL_MSG(_T("invalid standard colour"));
1371 // ============================================================================
1373 // ============================================================================
1375 // ----------------------------------------------------------------------------
1377 // ----------------------------------------------------------------------------
1379 wxWin32Renderer
::wxWin32Renderer(const wxColourScheme
*scheme
)
1383 m_sizeScrollbarArrow
= wxSize(16, 16);
1385 // init colours and pens
1386 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1388 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1389 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1391 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1393 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1394 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1396 m_titlebarFont
= wxSystemSettings
::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1397 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1399 // init the arrow bitmaps
1400 static const size_t ARROW_WIDTH
= 7;
1401 static const size_t ARROW_LENGTH
= 4;
1404 wxMemoryDC dcNormal
,
1407 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1409 bool isVertical
= n
> Arrow_Right
;
1422 // disabled arrow is larger because of the shadow
1423 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1424 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1426 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1427 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1429 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1430 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1434 dcNormal
.SetPen(m_penBlack
);
1435 dcDisabled
.SetPen(m_penDarkGrey
);
1437 // calculate the position of the point of the arrow
1441 x1
= (ARROW_WIDTH
- 1)/2;
1442 y1
= n
== Arrow_Up ?
0 : ARROW_LENGTH
- 1;
1446 x1
= n
== Arrow_Left ?
0 : ARROW_LENGTH
- 1;
1447 y1
= (ARROW_WIDTH
- 1)/2;
1458 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1460 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1461 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1468 if ( n
== Arrow_Up
)
1479 else // left or right arrow
1484 if ( n
== Arrow_Left
)
1497 // draw the shadow for the disabled one
1498 dcDisabled
.SetPen(m_penHighlight
);
1503 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1507 x1
= ARROW_LENGTH
- 1;
1508 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1511 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1512 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1517 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1521 x1
= ARROW_WIDTH
- 1;
1523 x2
= (ARROW_WIDTH
- 1)/2;
1525 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1526 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1531 // create the inversed bitmap but only for the right arrow as we only
1532 // use it for the menus
1533 if ( n
== Arrow_Right
)
1535 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1536 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1538 dcInverse
.Blit(0, 0, w
, h
,
1541 dcInverse
.SelectObject(wxNullBitmap
);
1543 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1544 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1546 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1547 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1549 dcInverse
.Blit(0, 0, w
, h
,
1552 dcInverse
.SelectObject(wxNullBitmap
);
1554 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1555 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1558 dcNormal
.SelectObject(wxNullBitmap
);
1559 dcDisabled
.SelectObject(wxNullBitmap
);
1561 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1562 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1563 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1564 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1566 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1569 // init the frame buttons bitmaps
1570 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1571 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1572 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1573 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1574 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1577 // ----------------------------------------------------------------------------
1579 // ----------------------------------------------------------------------------
1582 The raised border in Win32 looks like this:
1584 IIIIIIIIIIIIIIIIIIIIIIB
1586 I GB I = white (HILIGHT)
1587 I GB H = light grey (LIGHT)
1588 I GB G = dark grey (SHADOI)
1589 I GB B = black (DKSHADOI)
1590 I GB I = hIghlight (COLOR_3DHILIGHT)
1592 IGGGGGGGGGGGGGGGGGGGGGB
1593 BBBBBBBBBBBBBBBBBBBBBBB
1595 The sunken border looks like this:
1597 GGGGGGGGGGGGGGGGGGGGGGI
1598 GBBBBBBBBBBBBBBBBBBBBHI
1605 GHHHHHHHHHHHHHHHHHHHHHI
1606 IIIIIIIIIIIIIIIIIIIIIII
1608 The static border (used for the controls which don't get focus) is like
1611 GGGGGGGGGGGGGGGGGGGGGGW
1619 WWWWWWWWWWWWWWWWWWWWWWW
1621 The most complicated is the double border:
1623 HHHHHHHHHHHHHHHHHHHHHHB
1624 HWWWWWWWWWWWWWWWWWWWWGB
1625 HWHHHHHHHHHHHHHHHHHHHGB
1630 HWHHHHHHHHHHHHHHHHHHHGB
1631 HGGGGGGGGGGGGGGGGGGGGGB
1632 BBBBBBBBBBBBBBBBBBBBBBB
1634 And the simple border is, well, simple:
1636 BBBBBBBBBBBBBBBBBBBBBBB
1645 BBBBBBBBBBBBBBBBBBBBBBB
1648 void wxWin32Renderer
::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1652 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1653 dc
.DrawRectangle(*rect
);
1659 void wxWin32Renderer
::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1661 // draw the bottom and right sides
1663 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1664 rect
->GetRight() + 1, rect
->GetBottom());
1665 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1666 rect
->GetRight(), rect
->GetBottom());
1673 void wxWin32Renderer
::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1674 const wxPen
& pen1
, const wxPen
& pen2
)
1676 // draw the rectangle
1678 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1679 rect
->GetLeft(), rect
->GetBottom());
1680 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1681 rect
->GetRight(), rect
->GetTop());
1683 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1684 rect
->GetRight(), rect
->GetBottom());
1685 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1686 rect
->GetRight() + 1, rect
->GetBottom());
1692 void wxWin32Renderer
::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1694 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1695 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1698 void wxWin32Renderer
::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1700 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1701 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1704 void wxWin32Renderer
::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1708 DrawRect(dc
, rect
, m_penDarkGrey
);
1710 // the arrow is usually drawn inside border of width 2 and is offset by
1711 // another pixel in both directions when it's pressed - as the border
1712 // in this case is more narrow as well, we have to adjust rect like
1720 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1721 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1725 void wxWin32Renderer
::DrawBorder(wxDC
& dc
,
1727 const wxRect
& rectTotal
,
1728 int WXUNUSED(flags
),
1733 wxRect rect
= rectTotal
;
1737 case wxBORDER_SUNKEN
:
1738 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1740 DrawSunkenBorder(dc
, &rect
);
1744 case wxBORDER_STATIC
:
1745 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1748 case wxBORDER_RAISED
:
1749 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1751 DrawRaisedBorder(dc
, &rect
);
1755 case wxBORDER_DOUBLE
:
1756 DrawArrowBorder(dc
, &rect
);
1757 DrawRect(dc
, &rect
, m_penLightGrey
);
1760 case wxBORDER_SIMPLE
:
1761 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1763 DrawRect(dc
, &rect
, m_penBlack
);
1768 wxFAIL_MSG(_T("unknown border type"));
1771 case wxBORDER_DEFAULT
:
1780 wxRect wxWin32Renderer
::GetBorderDimensions(wxBorder border
) const
1785 case wxBORDER_RAISED
:
1786 case wxBORDER_SUNKEN
:
1787 width
= BORDER_THICKNESS
;
1790 case wxBORDER_SIMPLE
:
1791 case wxBORDER_STATIC
:
1795 case wxBORDER_DOUBLE
:
1800 wxFAIL_MSG(_T("unknown border type"));
1803 case wxBORDER_DEFAULT
:
1813 rect
.height
= width
;
1818 bool wxWin32Renderer
::AreScrollbarsInsideBorder() const
1823 // ----------------------------------------------------------------------------
1825 // ----------------------------------------------------------------------------
1827 void wxWin32Renderer
::DrawTextBorder(wxDC
& dc
,
1833 // text controls are not special under windows
1834 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1837 void wxWin32Renderer
::DrawButtonBorder(wxDC
& dc
,
1838 const wxRect
& rectTotal
,
1842 wxRect rect
= rectTotal
;
1844 if ( flags
& wxCONTROL_PRESSED
)
1846 // button pressed: draw a double border around it
1847 DrawRect(dc
, &rect
, m_penBlack
);
1848 DrawRect(dc
, &rect
, m_penDarkGrey
);
1852 // button not pressed
1854 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1856 // button either default or focused (or both): add an extra border around it
1857 DrawRect(dc
, &rect
, m_penBlack
);
1860 // now draw a normal button
1861 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1862 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1871 // ----------------------------------------------------------------------------
1873 // ----------------------------------------------------------------------------
1875 void wxWin32Renderer
::DrawHorizontalLine(wxDC
& dc
,
1876 wxCoord y
, wxCoord x1
, wxCoord x2
)
1878 dc
.SetPen(m_penDarkGrey
);
1879 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1880 dc
.SetPen(m_penHighlight
);
1882 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1885 void wxWin32Renderer
::DrawVerticalLine(wxDC
& dc
,
1886 wxCoord x
, wxCoord y1
, wxCoord y2
)
1888 dc
.SetPen(m_penDarkGrey
);
1889 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1890 dc
.SetPen(m_penHighlight
);
1892 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1895 void wxWin32Renderer
::DrawFrame(wxDC
& dc
,
1896 const wxString
& label
,
1902 wxCoord height
= 0; // of the label
1903 wxRect rectFrame
= rect
;
1904 if ( !label
.empty() )
1906 // the text should touch the top border of the rect, so the frame
1907 // itself should be lower
1908 dc
.GetTextExtent(label
, NULL
, &height
);
1909 rectFrame
.y
+= height
/ 2;
1910 rectFrame
.height
-= height
/ 2;
1912 // we have to draw each part of the frame individually as we can't
1913 // erase the background beyond the label as it might contain some
1914 // pixmap already, so drawing everything and then overwriting part of
1915 // the frame with label doesn't work
1917 // TODO: the +5 and space insertion should be customizable
1920 rectText
.x
= rectFrame
.x
+ 5;
1921 rectText
.y
= rect
.y
;
1922 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1923 rectText
.height
= height
;
1926 label2
<< _T(' ') << label
<< _T(' ');
1927 if ( indexAccel
!= -1 )
1929 // adjust it as we prepended a space
1934 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1936 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1940 // just draw the complete frame
1941 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1942 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1946 // ----------------------------------------------------------------------------
1948 // ----------------------------------------------------------------------------
1950 void wxWin32Renderer
::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1952 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1953 // pixels each while we really need dots here... PS_ALTERNATE might
1954 // work, but it is for NT 5 only
1956 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1958 // draw the pixels manually: note that to behave in the same manner as
1959 // DrawRect(), we must exclude the bottom and right borders from the
1961 wxCoord x1
= rect
.GetLeft(),
1963 x2
= rect
.GetRight(),
1964 y2
= rect
.GetBottom();
1966 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1968 // this seems to be closer than what Windows does than wxINVERT although
1969 // I'm still not sure if it's correct
1970 dc
.SetLogicalFunction(wxAND_REVERSE
);
1973 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1974 dc
.DrawPoint(z
, rect
.GetTop());
1976 wxCoord shift
= z
== x2 ?
0 : 1;
1977 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1978 dc
.DrawPoint(x2
, z
);
1980 shift
= z
== y2 ?
0 : 1;
1981 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1982 dc
.DrawPoint(z
, y2
);
1984 shift
= z
== x1 ?
0 : 1;
1985 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
1986 dc
.DrawPoint(x1
, z
);
1988 dc
.SetLogicalFunction(wxCOPY
);
1992 void wxWin32Renderer
::DrawLabelShadow(wxDC
& dc
,
1993 const wxString
& label
,
1998 // draw shadow of the text
1999 dc
.SetTextForeground(m_colHighlight
);
2000 wxRect rectShadow
= rect
;
2003 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2005 // make the text grey
2006 dc
.SetTextForeground(m_colDarkGrey
);
2009 void wxWin32Renderer
::DrawLabel(wxDC
& dc
,
2010 const wxString
& label
,
2017 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2020 void wxWin32Renderer
::DoDrawLabel(wxDC
& dc
,
2021 const wxString
& label
,
2027 const wxPoint
& focusOffset
)
2029 // the underscores are not drawn for focused controls in wxMSW
2030 if ( flags
& wxCONTROL_FOCUSED
)
2035 if ( flags
& wxCONTROL_DISABLED
)
2037 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2038 // currently only can happen for a menu item and it seems that Windows
2039 // doesn't draw the shadow in this case, so we don't do it neither
2040 if ( flags
& wxCONTROL_SELECTED
)
2042 // just make the label text greyed out
2043 dc
.SetTextForeground(m_colDarkGrey
);
2045 else // draw normal disabled label
2047 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2052 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2054 if ( flags
& wxCONTROL_DISABLED
)
2056 // restore the fg colour
2057 dc
.SetTextForeground(*wxBLACK
);
2060 if ( flags
& wxCONTROL_FOCUSED
)
2062 if ( focusOffset
.x
|| focusOffset
.y
)
2064 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2067 DrawFocusRect(dc
, rectLabel
);
2071 *rectBounds
= rectLabel
;
2074 void wxWin32Renderer
::DrawButtonLabel(wxDC
& dc
,
2075 const wxString
& label
,
2076 const wxBitmap
& image
,
2083 // the underscores are not drawn for focused controls in wxMSW
2084 if ( flags
& wxCONTROL_PRESSED
)
2089 wxRect rectLabel
= rect
;
2090 if ( !label
.empty() )
2092 // shift the label if a button is pressed
2093 if ( flags
& wxCONTROL_PRESSED
)
2099 if ( flags
& wxCONTROL_DISABLED
)
2101 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2104 // leave enough space for the focus rectangle
2105 if ( flags
& wxCONTROL_FOCUSED
)
2107 rectLabel
.Inflate(-2);
2111 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2113 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2115 if ( flags
& wxCONTROL_PRESSED
)
2117 // the focus rectangle is never pressed, so undo the shift done
2125 DrawFocusRect(dc
, rectLabel
);
2129 // ----------------------------------------------------------------------------
2130 // (check)listbox items
2131 // ----------------------------------------------------------------------------
2133 void wxWin32Renderer
::DrawItem(wxDC
& dc
,
2134 const wxString
& label
,
2138 wxDCTextColourChanger
colChanger(dc
);
2140 if ( flags
& wxCONTROL_SELECTED
)
2142 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2144 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2145 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2146 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2147 dc
.DrawRectangle(rect
);
2150 wxRect rectText
= rect
;
2152 rectText
.width
-= 2;
2153 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2155 if ( flags
& wxCONTROL_FOCUSED
)
2157 DrawFocusRect(dc
, rect
);
2161 void wxWin32Renderer
::DrawCheckItem(wxDC
& dc
,
2162 const wxString
& label
,
2163 const wxBitmap
& bitmap
,
2172 else // use default bitmap
2174 bmp
= wxBitmap(flags
& wxCONTROL_CHECKED ? checked_item_xpm
2175 : unchecked_item_xpm
);
2178 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2179 TRUE
/* use mask */);
2181 wxRect rectLabel
= rect
;
2182 int bmpWidth
= bmp
.GetWidth();
2183 rectLabel
.x
+= bmpWidth
;
2184 rectLabel
.width
-= bmpWidth
;
2186 DrawItem(dc
, label
, rectLabel
, flags
);
2189 // ----------------------------------------------------------------------------
2190 // check/radio buttons
2191 // ----------------------------------------------------------------------------
2193 wxBitmap wxWin32Renderer
::GetIndicator(IndicatorType indType
, int flags
)
2195 IndicatorState indState
;
2196 if ( flags
& wxCONTROL_SELECTED
)
2197 indState
= flags
& wxCONTROL_DISABLED ? IndicatorState_SelectedDisabled
2198 : IndicatorState_Selected
;
2199 else if ( flags
& wxCONTROL_DISABLED
)
2200 indState
= IndicatorState_Disabled
;
2201 else if ( flags
& wxCONTROL_PRESSED
)
2202 indState
= IndicatorState_Pressed
;
2204 indState
= IndicatorState_Normal
;
2206 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2207 ? IndicatorStatus_Checked
2208 : IndicatorStatus_Unchecked
;
2210 const char **xpm
= bmpIndicators
[indType
][indState
][indStatus
];
2217 return wxNullBitmap
;
2220 void wxWin32Renderer
::DrawCheckOrRadioButton(wxDC
& dc
,
2221 const wxString
& label
,
2222 const wxBitmap
& bitmap
,
2227 wxCoord focusOffsetY
)
2229 // calculate the position of the bitmap and of the label
2230 wxCoord heightBmp
= bitmap
.GetHeight();
2232 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2235 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2236 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2238 // align label vertically with the bitmap - looks nicer like this
2239 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2241 // calc horz position
2242 if ( align
== wxALIGN_RIGHT
)
2244 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2245 rectLabel
.x
= rect
.x
+ 3;
2246 rectLabel
.SetRight(xBmp
);
2248 else // normal (checkbox to the left of the text) case
2251 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2252 rectLabel
.SetRight(rect
.GetRight());
2255 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2258 dc
, label
, rectLabel
,
2260 wxALIGN_LEFT
| wxALIGN_TOP
,
2262 NULL
, // we don't need bounding rect
2263 // use custom vert focus rect offset
2264 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2268 void wxWin32Renderer
::DrawRadioButton(wxDC
& dc
,
2269 const wxString
& label
,
2270 const wxBitmap
& bitmap
,
2280 bmp
= GetRadioBitmap(flags
);
2282 DrawCheckOrRadioButton(dc
, label
,
2284 rect
, flags
, align
, indexAccel
,
2285 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2288 void wxWin32Renderer
::DrawCheckButton(wxDC
& dc
,
2289 const wxString
& label
,
2290 const wxBitmap
& bitmap
,
2300 bmp
= GetCheckBitmap(flags
);
2302 DrawCheckOrRadioButton(dc
, label
,
2304 rect
, flags
, align
, indexAccel
,
2305 0); // no focus rect offset for checkboxes
2308 // ----------------------------------------------------------------------------
2310 // ----------------------------------------------------------------------------
2312 void wxWin32Renderer
::DrawTextLine(wxDC
& dc
,
2313 const wxString
& text
,
2319 // nothing special to do here
2320 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2323 void wxWin32Renderer
::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2325 // we don't draw them
2328 // ----------------------------------------------------------------------------
2330 // ----------------------------------------------------------------------------
2332 void wxWin32Renderer
::DrawTab(wxDC
& dc
,
2333 const wxRect
& rectOrig
,
2335 const wxString
& label
,
2336 const wxBitmap
& bitmap
,
2340 wxRect rect
= rectOrig
;
2342 // the current tab is drawn indented (to the top for default case) and
2343 // bigger than the other ones
2344 const wxSize indent
= GetTabIndent();
2345 if ( flags
& wxCONTROL_SELECTED
)
2350 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2354 rect
.Inflate(indent
.x
, 0);
2356 rect
.height
+= indent
.y
;
2360 rect
.Inflate(indent
.x
, 0);
2361 rect
.height
+= indent
.y
;
2366 wxFAIL_MSG(_T("TODO"));
2371 // draw the text, image and the focus around them (if necessary)
2372 wxRect rectLabel
= rect
;
2373 rectLabel
.Deflate(1, 1);
2374 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2375 flags
, wxALIGN_CENTRE
, indexAccel
);
2377 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2378 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2381 x2
= rect
.GetRight(),
2382 y2
= rect
.GetBottom();
2384 // FIXME: all this code will break if the tab indent or the border width,
2385 // it is tied to the fact that both of them are equal to 2
2390 dc
.SetPen(m_penHighlight
);
2391 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2392 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2393 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2395 dc
.SetPen(m_penBlack
);
2396 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2397 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2399 dc
.SetPen(m_penDarkGrey
);
2400 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2402 if ( flags
& wxCONTROL_SELECTED
)
2404 dc
.SetPen(m_penLightGrey
);
2406 // overwrite the part of the border below this tab
2407 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2409 // and the shadow of the tab to the left of us
2410 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2415 dc
.SetPen(m_penHighlight
);
2416 // we need to continue one pixel further to overwrite the corner of
2417 // the border for the selected tab
2418 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED ?
1 : 0),
2420 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2422 dc
.SetPen(m_penBlack
);
2423 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2424 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2425 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2427 dc
.SetPen(m_penDarkGrey
);
2428 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2429 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2431 if ( flags
& wxCONTROL_SELECTED
)
2433 dc
.SetPen(m_penLightGrey
);
2435 // overwrite the part of the (double!) border above this tab
2436 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2437 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2439 // and the shadow of the tab to the left of us
2440 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2446 wxFAIL_MSG(_T("TODO"));
2450 // ----------------------------------------------------------------------------
2452 // ----------------------------------------------------------------------------
2454 wxSize wxWin32Renderer
::GetSliderThumbSize(const wxRect
& rect
,
2455 wxOrientation orient
) const
2459 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2460 if ( orient
== wxHORIZONTAL
)
2462 size
.y
= rect
.height
- 6;
2463 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2467 size
.x
= rect
.width
- 6;
2468 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2474 wxRect wxWin32Renderer
::GetSliderShaftRect(const wxRect
& rectOrig
,
2475 wxOrientation orient
) const
2477 static const wxCoord SLIDER_MARGIN
= 6;
2479 wxRect rect
= rectOrig
;
2481 if ( orient
== wxHORIZONTAL
)
2483 // make the rect of minimal width and centre it
2484 rect
.height
= 2*BORDER_THICKNESS
;
2485 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2489 // leave margins on the sides
2490 rect
.Deflate(SLIDER_MARGIN
, 0);
2494 // same as above but in other direction
2495 rect
.width
= 2*BORDER_THICKNESS
;
2496 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2500 rect
.Deflate(0, SLIDER_MARGIN
);
2506 void wxWin32Renderer
::DrawSliderShaft(wxDC
& dc
,
2507 const wxRect
& rectOrig
,
2508 wxOrientation orient
,
2512 if ( flags
& wxCONTROL_FOCUSED
)
2514 DrawFocusRect(dc
, rectOrig
);
2517 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2522 DrawSunkenBorder(dc
, &rect
);
2525 void wxWin32Renderer
::DrawSliderThumb(wxDC
& dc
,
2527 wxOrientation orient
,
2531 we are drawing a shape of this form
2536 H DB where H is hightlight colour
2549 The interior of this shape is filled with the hatched brush if the thumb
2553 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2555 bool transpose
= orient
== wxVERTICAL
;
2557 wxCoord x
, y
, x2
, y2
;
2562 x2
= rect
.GetBottom();
2563 y2
= rect
.GetRight();
2569 x2
= rect
.GetRight();
2570 y2
= rect
.GetBottom();
2573 // the size of the pointed part of the thumb
2574 wxCoord sizeArrow
= (transpose ? rect
.height
: rect
.width
) / 2;
2576 wxCoord x3
= x
+ sizeArrow
,
2577 y3
= y2
- sizeArrow
;
2579 dc
.SetPen(m_penHighlight
);
2580 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2581 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2582 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2584 dc
.SetPen(m_penBlack
);
2585 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2586 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2588 dc
.SetPen(m_penDarkGrey
);
2589 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2590 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2592 if ( flags
& wxCONTROL_PRESSED
)
2594 // TODO: MSW fills the entire area inside, not just the rect
2595 wxRect rectInt
= rect
;
2597 rectInt
.SetRight(y3
);
2599 rectInt
.SetBottom(y3
);
2602 #if !defined(__WXMGL__)
2603 static const char *stipple_xpm
[] = {
2604 /* columns rows colors chars-per-pixel */
2613 // VS: MGL can only do 8x8 stipple brushes
2614 static const char *stipple_xpm
[] = {
2615 /* columns rows colors chars-per-pixel */
2630 dc
.SetBrush(wxBrush(stipple_xpm
));
2632 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2633 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2634 dc
.SetPen(*wxTRANSPARENT_PEN
);
2635 dc
.DrawRectangle(rectInt
);
2639 void wxWin32Renderer
::DrawSliderTicks(wxDC
& dc
,
2641 const wxSize
& sizeThumb
,
2642 wxOrientation orient
,
2654 // the variable names correspond to horizontal case, but they can be used
2655 // for both orientations
2656 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2657 if ( orient
== wxHORIZONTAL
)
2659 x1
= rect
.GetLeft();
2660 x2
= rect
.GetRight();
2662 // draw from bottom to top to leave one pixel space between the ticks
2663 // and the slider as Windows do
2664 y1
= rect
.GetBottom();
2669 widthThumb
= sizeThumb
.x
;
2674 x2
= rect
.GetBottom();
2676 y1
= rect
.GetRight();
2677 y2
= rect
.GetLeft();
2681 widthThumb
= sizeThumb
.y
;
2684 // the first tick should be positioned in such way that a thumb drawn in
2685 // the first position points down directly to it
2686 x1
+= widthThumb
/ 2;
2687 x2
-= widthThumb
/ 2;
2689 // this also means that we have slightly less space for the ticks in
2690 // between the first and the last
2693 dc
.SetPen(m_penBlack
);
2695 int range
= end
- start
;
2696 for ( int n
= 0; n
< range
; n
+= step
)
2698 wxCoord x
= x1
+ (len
*n
) / range
;
2700 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2703 // always draw the line at the end position
2704 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2707 // ----------------------------------------------------------------------------
2709 // ----------------------------------------------------------------------------
2711 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2712 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2715 virtual wxSize
GetSize() const { return m_size
; }
2717 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2718 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2720 wxCoord
GetItemHeight() const { return m_heightItem
; }
2723 // the total size of the menu
2726 // the offset of the start of the menu item label
2729 // the offset of the start of the accel label
2732 // the height of a normal (not separator) item
2733 wxCoord m_heightItem
;
2735 friend wxMenuGeometryInfo
*
2736 wxWin32Renderer
::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2739 // FIXME: all constants are hardcoded but shouldn't be
2740 static const wxCoord MENU_LEFT_MARGIN
= 9;
2741 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2742 static const wxCoord MENU_VERT_MARGIN
= 3;
2744 // the margin around bitmap/check marks (on each side)
2745 static const wxCoord MENU_BMP_MARGIN
= 2;
2747 // the margin between the labels and accel strings
2748 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2750 // the separator height in pixels: in fact, strangely enough, the real height
2751 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2753 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2755 // the size of the standard checkmark bitmap
2756 static const wxCoord MENU_CHECK_SIZE
= 9;
2758 void wxWin32Renderer
::DrawMenuBarItem(wxDC
& dc
,
2759 const wxRect
& rectOrig
,
2760 const wxString
& label
,
2764 wxRect rect
= rectOrig
;
2767 wxDCTextColourChanger
colChanger(dc
);
2769 if ( flags
& wxCONTROL_SELECTED
)
2771 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2773 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2774 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2775 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2776 dc
.DrawRectangle(rect
);
2779 // don't draw the focus rect around menu bar items
2780 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2781 wxALIGN_CENTRE
, indexAccel
);
2784 void wxWin32Renderer
::DrawMenuItem(wxDC
& dc
,
2786 const wxMenuGeometryInfo
& gi
,
2787 const wxString
& label
,
2788 const wxString
& accel
,
2789 const wxBitmap
& bitmap
,
2793 const wxWin32MenuGeometryInfo
& geometryInfo
=
2794 (const wxWin32MenuGeometryInfo
&)gi
;
2799 rect
.width
= geometryInfo
.GetSize().x
;
2800 rect
.height
= geometryInfo
.GetItemHeight();
2802 // draw the selected item specially
2803 wxDCTextColourChanger
colChanger(dc
);
2804 if ( flags
& wxCONTROL_SELECTED
)
2806 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2808 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2809 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2810 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2811 dc
.DrawRectangle(rect
);
2814 // draw the bitmap: use the bitmap provided or the standard checkmark for
2815 // the checkable items
2816 wxBitmap bmp
= bitmap
;
2817 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2819 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2824 rect
.SetRight(geometryInfo
.GetLabelOffset());
2825 wxControlRenderer
::DrawBitmap(dc
, bmp
, rect
);
2829 rect
.x
= geometryInfo
.GetLabelOffset();
2830 rect
.SetRight(geometryInfo
.GetAccelOffset());
2832 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2834 // draw the accel string
2835 rect
.x
= geometryInfo
.GetAccelOffset();
2836 rect
.SetRight(geometryInfo
.GetSize().x
);
2838 // NB: no accel index here
2839 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2841 // draw the submenu indicator
2842 if ( flags
& wxCONTROL_ISSUBMENU
)
2844 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2845 rect
.width
= MENU_RIGHT_MARGIN
;
2847 wxArrowStyle arrowStyle
;
2848 if ( flags
& wxCONTROL_DISABLED
)
2849 arrowStyle
= flags
& wxCONTROL_SELECTED ? Arrow_InversedDisabled
2851 else if ( flags
& wxCONTROL_SELECTED
)
2852 arrowStyle
= Arrow_Inversed
;
2854 arrowStyle
= Arrow_Normal
;
2856 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2860 void wxWin32Renderer
::DrawMenuSeparator(wxDC
& dc
,
2862 const wxMenuGeometryInfo
& geomInfo
)
2864 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2867 wxSize wxWin32Renderer
::GetMenuBarItemSize(const wxSize
& sizeText
) const
2869 wxSize size
= sizeText
;
2871 // FIXME: menubar height is configurable under Windows
2878 wxMenuGeometryInfo
*wxWin32Renderer
::GetMenuGeometry(wxWindow
*win
,
2879 const wxMenu
& menu
) const
2881 // prepare the dc: for now we draw all the items with the system font
2883 dc
.SetFont(wxSystemSettings
::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2885 // the height of a normal item
2886 wxCoord heightText
= dc
.GetCharHeight();
2891 // the max length of label and accel strings: the menu width is the sum of
2892 // them, even if they're for different items (as the accels should be
2895 // the max length of the bitmap is never 0 as Windows always leaves enough
2896 // space for a check mark indicator
2897 wxCoord widthLabelMax
= 0,
2899 widthBmpMax
= MENU_LEFT_MARGIN
;
2901 for ( wxMenuItemList
::Node
*node
= menu
.GetMenuItems().GetFirst();
2903 node
= node
->GetNext() )
2905 // height of this item
2908 wxMenuItem
*item
= node
->GetData();
2909 if ( item
->IsSeparator() )
2911 h
= MENU_SEPARATOR_HEIGHT
;
2913 else // not separator
2918 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2919 if ( widthLabel
> widthLabelMax
)
2921 widthLabelMax
= widthLabel
;
2925 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2926 if ( widthAccel
> widthAccelMax
)
2928 widthAccelMax
= widthAccel
;
2931 const wxBitmap
& bmp
= item
->GetBitmap();
2934 wxCoord widthBmp
= bmp
.GetWidth();
2935 if ( widthBmp
> widthBmpMax
)
2936 widthBmpMax
= widthBmp
;
2938 //else if ( item->IsCheckable() ): no need to check for this as
2939 // MENU_LEFT_MARGIN is big enough to show the check mark
2942 h
+= 2*MENU_VERT_MARGIN
;
2944 // remember the item position and height
2945 item
->SetGeometry(height
, h
);
2950 // bundle the metrics into a struct and return it
2951 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2953 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2954 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2955 if ( widthAccelMax
> 0 )
2957 // if we actually have any accesl, add a margin
2958 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2961 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2963 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2964 gi
->m_size
.y
= height
;
2969 // ----------------------------------------------------------------------------
2971 // ----------------------------------------------------------------------------
2973 static const wxCoord STATBAR_BORDER_X
= 2;
2974 static const wxCoord STATBAR_BORDER_Y
= 2;
2976 wxSize wxWin32Renderer
::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2978 if ( borderBetweenFields
)
2979 *borderBetweenFields
= 2;
2981 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2984 void wxWin32Renderer
::DrawStatusField(wxDC
& dc
,
2986 const wxString
& label
,
2991 if ( flags
& wxCONTROL_ISDEFAULT
)
2993 // draw the size grip: it is a normal rect except that in the lower
2994 // right corner we have several bands which may be used for dragging
2995 // the status bar corner
2997 // each band consists of 4 stripes: m_penHighlight, double
2998 // m_penDarkGrey and transparent one
2999 wxCoord x2
= rect
.GetRight(),
3000 y2
= rect
.GetBottom();
3002 // draw the upper left part of the rect normally
3003 dc
.SetPen(m_penDarkGrey
);
3004 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3005 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3007 // draw the grey stripes of the grip
3009 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3010 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3012 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3013 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3016 // draw the white stripes
3017 dc
.SetPen(m_penHighlight
);
3018 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3019 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3021 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3024 // draw the remaining rect boundaries
3025 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3026 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3027 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3032 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3036 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3039 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3041 wxDCClipper
clipper(dc
, rectIn
);
3042 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3045 // ----------------------------------------------------------------------------
3047 // ----------------------------------------------------------------------------
3049 void wxWin32Renderer
::GetComboBitmaps(wxBitmap
*bmpNormal
,
3051 wxBitmap
*bmpPressed
,
3052 wxBitmap
*bmpDisabled
)
3054 static const wxCoord widthCombo
= 16;
3055 static const wxCoord heightCombo
= 17;
3061 bmpNormal
->Create(widthCombo
, heightCombo
);
3062 dcMem
.SelectObject(*bmpNormal
);
3063 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3064 Arrow_Down
, Arrow_Normal
);
3069 bmpPressed
->Create(widthCombo
, heightCombo
);
3070 dcMem
.SelectObject(*bmpPressed
);
3071 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3072 Arrow_Down
, Arrow_Pressed
);
3077 bmpDisabled
->Create(widthCombo
, heightCombo
);
3078 dcMem
.SelectObject(*bmpDisabled
);
3079 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3080 Arrow_Down
, Arrow_Disabled
);
3084 // ----------------------------------------------------------------------------
3086 // ----------------------------------------------------------------------------
3088 void wxWin32Renderer
::DoDrawBackground(wxDC
& dc
,
3089 const wxColour
& col
,
3092 wxBrush
brush(col
, wxSOLID
);
3094 dc
.SetPen(*wxTRANSPARENT_PEN
);
3095 dc
.DrawRectangle(rect
);
3098 void wxWin32Renderer
::DrawBackground(wxDC
& dc
,
3099 const wxColour
& col
,
3103 // just fill it with the given or default bg colour
3104 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3105 DoDrawBackground(dc
, colBg
, rect
);
3108 // ----------------------------------------------------------------------------
3110 // ----------------------------------------------------------------------------
3112 void wxWin32Renderer
::DrawArrow(wxDC
& dc
,
3117 // get the bitmap for this arrow
3118 wxArrowDirection arrowDir
;
3121 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3122 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3123 case wxUP
: arrowDir
= Arrow_Up
; break;
3124 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3127 wxFAIL_MSG(_T("unknown arrow direction"));
3131 wxArrowStyle arrowStyle
;
3132 if ( flags
& wxCONTROL_PRESSED
)
3134 // can't be pressed and disabled
3135 arrowStyle
= Arrow_Pressed
;
3139 arrowStyle
= flags
& wxCONTROL_DISABLED ? Arrow_Disabled
: Arrow_Normal
;
3142 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3145 void wxWin32Renderer
::DrawArrow(wxDC
& dc
,
3147 wxArrowDirection arrowDir
,
3148 wxArrowStyle arrowStyle
)
3150 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3152 // under Windows the arrows always have the same size so just centre it in
3153 // the provided rectangle
3154 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3155 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3157 // Windows does it like this...
3158 if ( arrowDir
== Arrow_Left
)
3162 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3165 void wxWin32Renderer
::DrawArrowButton(wxDC
& dc
,
3166 const wxRect
& rectAll
,
3167 wxArrowDirection arrowDir
,
3168 wxArrowStyle arrowStyle
)
3170 wxRect rect
= rectAll
;
3171 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3172 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3173 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3176 void wxWin32Renderer
::DrawScrollbarThumb(wxDC
& dc
,
3177 wxOrientation orient
,
3181 // we don't use the flags, the thumb never changes appearance
3182 wxRect rectThumb
= rect
;
3183 DrawArrowBorder(dc
, &rectThumb
);
3184 DrawBackground(dc
, wxNullColour
, rectThumb
);
3187 void wxWin32Renderer
::DrawScrollbarShaft(wxDC
& dc
,
3188 wxOrientation orient
,
3189 const wxRect
& rectBar
,
3192 wxColourScheme
::StdColour col
= flags
& wxCONTROL_PRESSED
3193 ? wxColourScheme
::SCROLLBAR_PRESSED
3194 : wxColourScheme
::SCROLLBAR
;
3195 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3198 void wxWin32Renderer
::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3200 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3203 wxRect wxWin32Renderer
::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3204 wxScrollBar
::Element elem
,
3207 return StandardGetScrollbarRect(scrollbar
, elem
,
3208 thumbPos
, m_sizeScrollbarArrow
);
3211 wxCoord wxWin32Renderer
::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3213 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3216 wxHitTest wxWin32Renderer
::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3217 const wxPoint
& pt
) const
3219 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3222 wxCoord wxWin32Renderer
::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3225 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3228 int wxWin32Renderer
::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3231 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3234 // ----------------------------------------------------------------------------
3235 // top level windows
3236 // ----------------------------------------------------------------------------
3238 int wxWin32Renderer
::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3240 wxRect client
= GetFrameClientArea(rect
, flags
);
3242 if ( client
.Inside(pt
) )
3243 return wxHT_TOPLEVEL_CLIENT_AREA
;
3245 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3247 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3249 if ( flags
& wxTOPLEVEL_ICON
)
3251 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3252 return wxHT_TOPLEVEL_ICON
;
3255 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3256 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3257 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3259 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3261 if ( btnRect
.Inside(pt
) )
3262 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3263 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3265 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3267 if ( btnRect
.Inside(pt
) )
3268 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3269 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3271 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3273 if ( btnRect
.Inside(pt
) )
3274 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3275 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3277 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3279 if ( btnRect
.Inside(pt
) )
3280 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3281 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3283 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3285 if ( btnRect
.Inside(pt
) )
3286 return wxHT_TOPLEVEL_BUTTON_HELP
;
3287 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3290 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3291 return wxHT_TOPLEVEL_TITLEBAR
;
3294 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3296 // we are certainly at one of borders, lets decide which one:
3299 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3300 if ( pt
.x
< client
.x
)
3301 border
|= wxHT_TOPLEVEL_BORDER_W
;
3302 else if ( pt
.x
>= client
.width
+ client
.x
)
3303 border
|= wxHT_TOPLEVEL_BORDER_E
;
3304 if ( pt
.y
< client
.y
)
3305 border
|= wxHT_TOPLEVEL_BORDER_N
;
3306 else if ( pt
.y
>= client
.height
+ client
.y
)
3307 border
|= wxHT_TOPLEVEL_BORDER_S
;
3311 return wxHT_NOWHERE
;
3314 void wxWin32Renderer
::DrawFrameTitleBar(wxDC
& dc
,
3316 const wxString
& title
,
3320 int specialButtonFlags
)
3322 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3324 DrawFrameBorder(dc
, rect
, flags
);
3326 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3328 DrawFrameBackground(dc
, rect
, flags
);
3329 if ( flags
& wxTOPLEVEL_ICON
)
3330 DrawFrameIcon(dc
, rect
, icon
, flags
);
3331 DrawFrameTitle(dc
, rect
, title
, flags
);
3333 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3335 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3336 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3338 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3340 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3341 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3342 specialButtonFlags
: 0);
3343 x
-= FRAME_BUTTON_WIDTH
+ 2;
3345 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3347 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3348 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3349 specialButtonFlags
: 0);
3350 x
-= FRAME_BUTTON_WIDTH
;
3352 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3354 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3355 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3356 specialButtonFlags
: 0);
3357 x
-= FRAME_BUTTON_WIDTH
;
3359 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3361 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3362 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3363 specialButtonFlags
: 0);
3364 x
-= FRAME_BUTTON_WIDTH
;
3366 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3368 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3369 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3370 specialButtonFlags
: 0);
3371 x
-= FRAME_BUTTON_WIDTH
;
3376 void wxWin32Renderer
::DrawFrameBorder(wxDC
& dc
,
3380 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3384 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3385 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3386 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3387 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3388 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3391 void wxWin32Renderer
::DrawFrameBackground(wxDC
& dc
,
3395 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3397 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3398 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3399 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3401 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3402 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3404 DrawBackground(dc
, col
, r
);
3407 void wxWin32Renderer
::DrawFrameTitle(wxDC
& dc
,
3409 const wxString
& title
,
3412 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3413 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3414 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3416 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3417 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3418 if ( flags
& wxTOPLEVEL_ICON
)
3420 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3421 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3429 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3430 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3431 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3432 r
.width
-= FRAME_BUTTON_WIDTH
;
3433 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3434 r
.width
-= FRAME_BUTTON_WIDTH
;
3435 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3436 r
.width
-= FRAME_BUTTON_WIDTH
;
3437 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3438 r
.width
-= FRAME_BUTTON_WIDTH
;
3440 dc
.SetFont(m_titlebarFont
);
3441 dc
.SetTextForeground(col
);
3444 dc
.GetTextExtent(title
, &textW
, NULL
);
3445 if ( textW
> r
.width
)
3447 // text is too big, let's shorten it and add "..." after it:
3448 size_t len
= title
.length();
3449 wxCoord WSoFar
, letterW
;
3451 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3452 if ( WSoFar
> r
.width
)
3454 // not enough space to draw anything
3460 for (size_t i
= 0; i
< len
; i
++)
3462 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3463 if ( letterW
+ WSoFar
> r
.width
)
3469 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3470 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3473 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3474 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3477 void wxWin32Renderer
::DrawFrameIcon(wxDC
& dc
,
3484 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3485 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3489 void wxWin32Renderer
::DrawFrameButton(wxDC
& dc
,
3490 wxCoord x
, wxCoord y
,
3494 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3499 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3500 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3501 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3502 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3503 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3505 wxFAIL_MSG(wxT("incorrect button specification"));
3508 if ( flags
& wxCONTROL_PRESSED
)
3510 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3511 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3512 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3513 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3517 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3518 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3519 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3520 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3525 wxRect wxWin32Renderer
::GetFrameClientArea(const wxRect
& rect
,
3530 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3532 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3533 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3534 FRAME_BORDER_THICKNESS
;
3537 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3539 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3540 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3546 wxSize wxWin32Renderer
::GetFrameTotalSize(const wxSize
& clientSize
,
3549 wxSize
s(clientSize
);
3551 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3553 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3554 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3555 FRAME_BORDER_THICKNESS
;
3559 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3560 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3565 wxSize wxWin32Renderer
::GetFrameMinSize(int flags
) const
3569 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3571 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3572 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3573 FRAME_BORDER_THICKNESS
;
3578 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3580 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3582 if ( flags
& wxTOPLEVEL_ICON
)
3583 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3584 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3585 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3586 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3587 s
.x
+= FRAME_BUTTON_WIDTH
;
3588 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3589 s
.x
+= FRAME_BUTTON_WIDTH
;
3590 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3591 s
.x
+= FRAME_BUTTON_WIDTH
;
3592 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3593 s
.x
+= FRAME_BUTTON_WIDTH
;
3599 wxSize wxWin32Renderer
::GetFrameIconSize() const
3601 return wxSize(16, 16);
3605 // ----------------------------------------------------------------------------
3607 // ----------------------------------------------------------------------------
3609 static char *error_xpm
[]={
3616 "...........########.............",
3617 "........###aaaaaaaa###..........",
3618 ".......#aaaaaaaaaaaaaa#.........",
3619 ".....##aaaaaaaaaaaaaaaa##.......",
3620 "....#aaaaaaaaaaaaaaaaaaaa#......",
3621 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3622 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3623 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3624 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3625 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3626 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3627 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3628 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3629 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3630 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3631 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3632 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3633 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3634 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3635 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3636 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3637 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3638 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3639 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3640 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3641 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3642 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3643 "......b#aaaaaaaaaaaaaa#bbbbb....",
3644 ".......b###aaaaaaaa###bbbbb.....",
3645 ".........bb########bbbbbb.......",
3646 "..........bbbbbbbbbbbbbb........",
3647 ".............bbbbbbbb..........."};
3649 static char *info_xpm
[]={
3657 "...........########.............",
3658 "........###abbbbbba###..........",
3659 "......##abbbbbbbbbbbba##........",
3660 ".....#abbbbbbbbbbbbbbbba#.......",
3661 "....#bbbbbbbaccccabbbbbbbd......",
3662 "...#bbbbbbbbccccccbbbbbbbbd.....",
3663 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3664 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3665 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3666 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3667 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3668 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3669 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3670 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3671 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3672 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3673 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3674 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3675 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3676 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3677 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3678 ".....dabbbbbbbbbbbbbbbbad####...",
3679 "......ddabbbbbbbbbbbbadd####....",
3680 ".......#dddabbbbbbaddd#####.....",
3681 "........###dddabbbd#######......",
3682 "..........####dbbbd#####........",
3683 ".............#dbbbd##...........",
3684 "...............dbbd##...........",
3685 "................dbd##...........",
3686 ".................dd##...........",
3687 "..................###...........",
3688 "...................##..........."};
3690 static char *question_xpm
[]={
3698 "...........########.............",
3699 "........###abbbbbba###..........",
3700 "......##abbbbbbbbbbbba##........",
3701 ".....#abbbbbbbbbbbbbbbba#.......",
3702 "....#bbbbbbbbbbbbbbbbbbbbc......",
3703 "...#bbbbbbbaddddddabbbbbbbc.....",
3704 "..#bbbbbbbadabbddddabbbbbbbc....",
3705 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3706 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3707 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3708 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3709 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3710 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3711 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3712 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3713 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3714 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3715 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3716 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3717 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3718 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3719 ".....cabbbbbbbbbbbbbbbbac####...",
3720 "......ccabbbbbbbbbbbbacc####....",
3721 ".......#cccabbbbbbaccc#####.....",
3722 "........###cccabbbc#######......",
3723 "..........####cbbbc#####........",
3724 ".............#cbbbc##...........",
3725 "...............cbbc##...........",
3726 "................cbc##...........",
3727 ".................cc##...........",
3728 "..................###...........",
3729 "...................##..........."};
3731 static char *warning_xpm
[]={
3739 ".............###................",
3740 "............#aabc...............",
3741 "...........#aaaabcd.............",
3742 "...........#aaaaacdd............",
3743 "..........#aaaaaabcdd...........",
3744 "..........#aaaaaaacdd...........",
3745 ".........#aaaaaaaabcdd..........",
3746 ".........#aaaaaaaaacdd..........",
3747 "........#aaaaaaaaaabcdd.........",
3748 "........#aaabcccbaaacdd.........",
3749 ".......#aaaacccccaaabcdd........",
3750 ".......#aaaacccccaaaacdd........",
3751 "......#aaaaacccccaaaabcdd.......",
3752 "......#aaaaacccccaaaaacdd.......",
3753 ".....#aaaaaacccccaaaaabcdd......",
3754 ".....#aaaaaa#ccc#aaaaaacdd......",
3755 "....#aaaaaaabcccbaaaaaabcdd.....",
3756 "....#aaaaaaaacccaaaaaaaacdd.....",
3757 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3758 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3759 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3760 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3761 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3762 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3763 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3764 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3765 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3766 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3767 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3768 "..#ccccccccccccccccccccccccddddd",
3769 "....ddddddddddddddddddddddddddd.",
3770 ".....ddddddddddddddddddddddddd.."};
3772 wxIcon wxWin32Renderer
::GetStdIcon(int which
) const
3776 case wxICON_INFORMATION
:
3777 return wxIcon(info_xpm
);
3779 case wxICON_QUESTION
:
3780 return wxIcon(question_xpm
);
3782 case wxICON_EXCLAMATION
:
3783 return wxIcon(warning_xpm
);
3786 wxFAIL_MSG(wxT("requested non existent standard icon"));
3787 // still fall through
3790 return wxIcon(error_xpm
);
3795 // ----------------------------------------------------------------------------
3796 // text control geometry
3797 // ----------------------------------------------------------------------------
3799 static inline int GetTextBorderWidth()
3804 wxRect wxWin32Renderer
::GetTextTotalArea(const wxTextCtrl
*text
,
3807 wxRect rectTotal
= rect
;
3809 wxCoord widthBorder
= GetTextBorderWidth();
3810 rectTotal
.Inflate(widthBorder
);
3812 // this is what Windows does
3818 wxRect wxWin32Renderer
::GetTextClientArea(const wxTextCtrl
*text
,
3820 wxCoord
*extraSpaceBeyond
)
3822 wxRect rectText
= rect
;
3824 // undo GetTextTotalArea()
3825 if ( rectText
.height
> 0 )
3828 wxCoord widthBorder
= GetTextBorderWidth();
3829 rectText
.Inflate(-widthBorder
);
3831 if ( extraSpaceBeyond
)
3832 *extraSpaceBeyond
= 0;
3837 // ----------------------------------------------------------------------------
3839 // ----------------------------------------------------------------------------
3841 void wxWin32Renderer
::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3844 if ( wxDynamicCast(window
, wxScrollBar
) )
3846 // we only set the width of vert scrollbars and height of the
3848 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3849 size
->y
= m_sizeScrollbarArrow
.y
;
3851 size
->x
= m_sizeScrollbarArrow
.x
;
3853 // skip border width adjustments, they don't make sense for us
3856 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3859 if ( wxDynamicCast(window
, wxButton
) )
3861 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3863 // TODO: don't harcode all this
3864 size
->x
+= 3*window
->GetCharWidth();
3866 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3867 if ( size
->y
< heightBtn
- 8 )
3868 size
->y
= heightBtn
;
3873 // no border width adjustments for buttons
3876 #endif // wxUSE_BUTTON
3878 // take into account the border width
3879 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3880 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3881 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3884 // ============================================================================
3886 // ============================================================================
3888 // ----------------------------------------------------------------------------
3889 // wxWin32InputHandler
3890 // ----------------------------------------------------------------------------
3892 wxWin32InputHandler
::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3894 m_renderer
= renderer
;
3897 bool wxWin32InputHandler
::HandleKey(wxInputConsumer
*control
,
3898 const wxKeyEvent
& event
,
3904 bool wxWin32InputHandler
::HandleMouse(wxInputConsumer
*control
,
3905 const wxMouseEvent
& event
)
3907 // clicking on the control gives it focus
3908 if ( event
.ButtonDown() )
3910 wxWindow
*win
= control
->GetInputWindow();
3911 if ( wxWindow
::FindFocus() != control
->GetInputWindow() )
3922 // ----------------------------------------------------------------------------
3923 // wxWin32ScrollBarInputHandler
3924 // ----------------------------------------------------------------------------
3926 wxWin32ScrollBarInputHandler
::
3927 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3928 wxInputHandler
*handler
)
3929 : wxStdScrollBarInputHandler(renderer
, handler
)
3931 m_scrollPaused
= FALSE
;
3935 bool wxWin32ScrollBarInputHandler
::OnScrollTimer(wxScrollBar
*scrollbar
,
3936 const wxControlAction
& action
)
3938 // stop if went beyond the position of the original click (this can only
3939 // happen when we scroll by pages)
3941 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3943 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3944 != wxHT_SCROLLBAR_BAR_2
;
3946 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3948 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3949 != wxHT_SCROLLBAR_BAR_1
;
3954 StopScrolling(scrollbar
);
3956 scrollbar
->Refresh();
3961 return wxStdScrollBarInputHandler
::OnScrollTimer(scrollbar
, action
);
3964 bool wxWin32ScrollBarInputHandler
::HandleMouse(wxInputConsumer
*control
,
3965 const wxMouseEvent
& event
)
3967 // remember the current state
3968 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3970 // do process the message
3971 bool rc
= wxStdScrollBarInputHandler
::HandleMouse(control
, event
);
3973 // analyse the changes
3974 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3976 // we just started dragging the thumb, remember its initial position to
3977 // be able to restore it if the drag is cancelled later
3978 m_eventStartDrag
= event
;
3984 bool wxWin32ScrollBarInputHandler
::HandleMouseMove(wxInputConsumer
*control
,
3985 const wxMouseEvent
& event
)
3987 // we don't highlight scrollbar elements, so there is no need to process
3988 // mouse move events normally - only do it while mouse is captured (i.e.
3989 // when we're dragging the thumb or pressing on something)
3990 if ( !m_winCapture
)
3993 if ( event
.Entering() )
3995 // we're not interested in this at all
3999 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4001 if ( m_scrollPaused
)
4003 // check if the mouse returned to its original location
4005 if ( event
.Leaving() )
4011 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4012 if ( ht
== m_htLast
)
4014 // yes it did, resume scrolling
4015 m_scrollPaused
= FALSE
;
4016 if ( m_timerScroll
)
4018 // we were scrolling by line/page, restart timer
4019 m_timerScroll
->Start(m_interval
);
4021 Press(scrollbar
, TRUE
);
4023 else // we were dragging the thumb
4025 // restore its last location
4026 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4032 else // normal case, scrolling hasn't been paused
4034 // if we're scrolling the scrollbar because the arrow or the shaft was
4035 // pressed, check that the mouse stays on the same scrollbar element
4037 if ( event
.Moving() )
4039 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4041 else // event.Leaving()
4046 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4047 // is still ok - we only want to catch the case when the mouse leaves
4048 // the scrollbar here
4049 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4051 ht
= wxHT_SCROLLBAR_THUMB
;
4054 if ( ht
!= m_htLast
)
4056 // what were we doing? 2 possibilities: either an arrow/shaft was
4057 // pressed in which case we have a timer and so we just stop it or
4058 // we were dragging the thumb
4059 if ( m_timerScroll
)
4062 m_interval
= m_timerScroll
->GetInterval();
4063 m_timerScroll
->Stop();
4064 m_scrollPaused
= TRUE
;
4066 // unpress the arrow
4067 Press(scrollbar
, FALSE
);
4069 else // we were dragging the thumb
4071 // remember the current thumb position to be able to restore it
4072 // if the mouse returns to it later
4073 m_eventLastDrag
= event
;
4075 // and restore the original position (before dragging) of the
4077 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4084 return wxStdScrollBarInputHandler
::HandleMouseMove(control
, event
);
4087 // ----------------------------------------------------------------------------
4088 // wxWin32CheckboxInputHandler
4089 // ----------------------------------------------------------------------------
4091 bool wxWin32CheckboxInputHandler
::HandleKey(wxInputConsumer
*control
,
4092 const wxKeyEvent
& event
,
4097 wxControlAction action
;
4098 int keycode
= event
.GetKeyCode();
4102 action
= wxACTION_CHECKBOX_TOGGLE
;
4106 case WXK_NUMPAD_SUBTRACT
:
4107 action
= wxACTION_CHECKBOX_CHECK
;
4111 case WXK_NUMPAD_ADD
:
4112 case WXK_NUMPAD_EQUAL
:
4113 action
= wxACTION_CHECKBOX_CLEAR
;
4119 control
->PerformAction(action
);
4128 // ----------------------------------------------------------------------------
4129 // wxWin32TextCtrlInputHandler
4130 // ----------------------------------------------------------------------------
4132 bool wxWin32TextCtrlInputHandler
::HandleKey(wxInputConsumer
*control
,
4133 const wxKeyEvent
& event
,
4136 // handle only MSW-specific text bindings here, the others are handled in
4140 int keycode
= event
.GetKeyCode();
4142 wxControlAction action
;
4143 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4145 action
= wxACTION_TEXT_CUT
;
4147 else if ( keycode
== WXK_INSERT
)
4149 if ( event
.ControlDown() )
4150 action
= wxACTION_TEXT_COPY
;
4151 else if ( event
.ShiftDown() )
4152 action
= wxACTION_TEXT_PASTE
;
4155 if ( action
!= wxACTION_NONE
)
4157 control
->PerformAction(action
);
4163 return wxStdTextCtrlInputHandler
::HandleKey(control
, event
, pressed
);
4166 // ----------------------------------------------------------------------------
4167 // wxWin32StatusBarInputHandler
4168 // ----------------------------------------------------------------------------
4170 wxWin32StatusBarInputHandler
::
4171 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4172 : wxStdInputHandler(handler
)
4177 bool wxWin32StatusBarInputHandler
::IsOnGrip(wxWindow
*statbar
,
4178 const wxPoint
& pt
) const
4180 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4181 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4183 wxSize sizeSbar
= statbar
->GetSize();
4185 return (sizeSbar
.x
- pt
.x
) < (wxCoord
)STATUSBAR_GRIP_SIZE
&&
4186 (sizeSbar
.y
- pt
.y
) < (wxCoord
)STATUSBAR_GRIP_SIZE
;
4192 bool wxWin32StatusBarInputHandler
::HandleMouse(wxInputConsumer
*consumer
,
4193 const wxMouseEvent
& event
)
4195 if ( event
.Button(1) )
4197 if ( event
.ButtonDown(1) )
4199 wxWindow
*statbar
= consumer
->GetInputWindow();
4201 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4203 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4207 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4208 wxHT_TOPLEVEL_BORDER_SE
);
4210 statbar
->SetCursor(m_cursorOld
);
4218 return wxStdInputHandler
::HandleMouse(consumer
, event
);
4221 bool wxWin32StatusBarInputHandler
::HandleMouseMove(wxInputConsumer
*consumer
,
4222 const wxMouseEvent
& event
)
4224 wxWindow
*statbar
= consumer
->GetInputWindow();
4226 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4227 if ( isOnGrip
!= m_isOnGrip
)
4229 m_isOnGrip
= isOnGrip
;
4232 m_cursorOld
= statbar
->GetCursor();
4233 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4237 statbar
->SetCursor(m_cursorOld
);
4241 return wxStdInputHandler
::HandleMouseMove(consumer
, event
);
4244 // ----------------------------------------------------------------------------
4245 // wxWin32FrameInputHandler
4246 // ----------------------------------------------------------------------------
4248 bool wxWin32FrameInputHandler
::HandleMouse(wxInputConsumer
*consumer
,
4249 const wxMouseEvent
& event
)
4251 if ( event
.LeftDClick() )
4253 wxTopLevelWindow
*tlw
=
4254 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4256 long hit
= tlw
->HitTest(event
.GetPosition());
4258 if ( hit
== wxHT_TOPLEVEL_TITLEBAR
)
4260 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4261 tlw
->IsMaximized() ?
4262 wxTOPLEVEL_BUTTON_RESTORE
:
4263 wxTOPLEVEL_BUTTON_MAXIMIZE
);
4268 return wxStdFrameInputHandler
::HandleMouse(consumer
, event
);