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
,
2277 DrawCheckOrRadioButton(dc
, label
,
2279 rect
, flags
, align
, indexAccel
,
2280 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2283 wxBitmap
rbitmap(GetRadioBitmap(flags
));
2284 DrawCheckOrRadioButton(dc
, label
,
2286 rect
, flags
, align
, indexAccel
,
2287 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2291 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2292 const wxString
& label
,
2293 const wxBitmap
& bitmap
,
2300 DrawCheckOrRadioButton(dc
, label
,
2302 rect
, flags
, align
, indexAccel
,
2303 0); // no focus rect offset for checkboxes
2306 wxBitmap
cbitmap(GetCheckBitmap(flags
));
2307 DrawCheckOrRadioButton(dc
, label
,
2309 rect
, flags
, align
, indexAccel
,
2310 0); // no focus rect offset for checkboxes
2314 // ----------------------------------------------------------------------------
2316 // ----------------------------------------------------------------------------
2318 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2319 const wxString
& text
,
2325 // nothing special to do here
2326 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2329 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2331 // we don't draw them
2334 // ----------------------------------------------------------------------------
2336 // ----------------------------------------------------------------------------
2338 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2339 const wxRect
& rectOrig
,
2341 const wxString
& label
,
2342 const wxBitmap
& bitmap
,
2346 wxRect rect
= rectOrig
;
2348 // the current tab is drawn indented (to the top for default case) and
2349 // bigger than the other ones
2350 const wxSize indent
= GetTabIndent();
2351 if ( flags
& wxCONTROL_SELECTED
)
2356 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2360 rect
.Inflate(indent
.x
, 0);
2362 rect
.height
+= indent
.y
;
2366 rect
.Inflate(indent
.x
, 0);
2367 rect
.height
+= indent
.y
;
2372 wxFAIL_MSG(_T("TODO"));
2377 // draw the text, image and the focus around them (if necessary)
2378 wxRect rectLabel
= rect
;
2379 rectLabel
.Deflate(1, 1);
2380 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2381 flags
, wxALIGN_CENTRE
, indexAccel
);
2383 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2384 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2387 x2
= rect
.GetRight(),
2388 y2
= rect
.GetBottom();
2390 // FIXME: all this code will break if the tab indent or the border width,
2391 // it is tied to the fact that both of them are equal to 2
2396 dc
.SetPen(m_penHighlight
);
2397 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2398 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2399 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2401 dc
.SetPen(m_penBlack
);
2402 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2403 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2405 dc
.SetPen(m_penDarkGrey
);
2406 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2408 if ( flags
& wxCONTROL_SELECTED
)
2410 dc
.SetPen(m_penLightGrey
);
2412 // overwrite the part of the border below this tab
2413 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2415 // and the shadow of the tab to the left of us
2416 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2421 dc
.SetPen(m_penHighlight
);
2422 // we need to continue one pixel further to overwrite the corner of
2423 // the border for the selected tab
2424 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2426 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2428 dc
.SetPen(m_penBlack
);
2429 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2430 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2431 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2433 dc
.SetPen(m_penDarkGrey
);
2434 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2435 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2437 if ( flags
& wxCONTROL_SELECTED
)
2439 dc
.SetPen(m_penLightGrey
);
2441 // overwrite the part of the (double!) border above this tab
2442 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2443 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2445 // and the shadow of the tab to the left of us
2446 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2452 wxFAIL_MSG(_T("TODO"));
2456 // ----------------------------------------------------------------------------
2458 // ----------------------------------------------------------------------------
2460 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2461 wxOrientation orient
) const
2465 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2466 if ( orient
== wxHORIZONTAL
)
2468 size
.y
= rect
.height
- 6;
2469 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2473 size
.x
= rect
.width
- 6;
2474 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2480 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2481 wxOrientation orient
) const
2483 static const wxCoord SLIDER_MARGIN
= 6;
2485 wxRect rect
= rectOrig
;
2487 if ( orient
== wxHORIZONTAL
)
2489 // make the rect of minimal width and centre it
2490 rect
.height
= 2*BORDER_THICKNESS
;
2491 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2495 // leave margins on the sides
2496 rect
.Deflate(SLIDER_MARGIN
, 0);
2500 // same as above but in other direction
2501 rect
.width
= 2*BORDER_THICKNESS
;
2502 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2506 rect
.Deflate(0, SLIDER_MARGIN
);
2512 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2513 const wxRect
& rectOrig
,
2514 wxOrientation orient
,
2518 if ( flags
& wxCONTROL_FOCUSED
)
2520 DrawFocusRect(dc
, rectOrig
);
2523 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2528 DrawSunkenBorder(dc
, &rect
);
2531 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2533 wxOrientation orient
,
2537 we are drawing a shape of this form
2542 H DB where H is hightlight colour
2555 The interior of this shape is filled with the hatched brush if the thumb
2559 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2561 bool transpose
= orient
== wxVERTICAL
;
2563 wxCoord x
, y
, x2
, y2
;
2568 x2
= rect
.GetBottom();
2569 y2
= rect
.GetRight();
2575 x2
= rect
.GetRight();
2576 y2
= rect
.GetBottom();
2579 // the size of the pointed part of the thumb
2580 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2582 wxCoord x3
= x
+ sizeArrow
,
2583 y3
= y2
- sizeArrow
;
2585 dc
.SetPen(m_penHighlight
);
2586 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2587 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2588 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2590 dc
.SetPen(m_penBlack
);
2591 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2592 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2594 dc
.SetPen(m_penDarkGrey
);
2595 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2596 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2598 if ( flags
& wxCONTROL_PRESSED
)
2600 // TODO: MSW fills the entire area inside, not just the rect
2601 wxRect rectInt
= rect
;
2603 rectInt
.SetRight(y3
);
2605 rectInt
.SetBottom(y3
);
2608 #if !defined(__WXMGL__)
2609 static const char *stipple_xpm
[] = {
2610 /* columns rows colors chars-per-pixel */
2619 // VS: MGL can only do 8x8 stipple brushes
2620 static const char *stipple_xpm
[] = {
2621 /* columns rows colors chars-per-pixel */
2636 dc
.SetBrush(wxBrush(stipple_xpm
));
2638 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2639 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2640 dc
.SetPen(*wxTRANSPARENT_PEN
);
2641 dc
.DrawRectangle(rectInt
);
2645 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2647 const wxSize
& sizeThumb
,
2648 wxOrientation orient
,
2660 // the variable names correspond to horizontal case, but they can be used
2661 // for both orientations
2662 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2663 if ( orient
== wxHORIZONTAL
)
2665 x1
= rect
.GetLeft();
2666 x2
= rect
.GetRight();
2668 // draw from bottom to top to leave one pixel space between the ticks
2669 // and the slider as Windows do
2670 y1
= rect
.GetBottom();
2675 widthThumb
= sizeThumb
.x
;
2680 x2
= rect
.GetBottom();
2682 y1
= rect
.GetRight();
2683 y2
= rect
.GetLeft();
2687 widthThumb
= sizeThumb
.y
;
2690 // the first tick should be positioned in such way that a thumb drawn in
2691 // the first position points down directly to it
2692 x1
+= widthThumb
/ 2;
2693 x2
-= widthThumb
/ 2;
2695 // this also means that we have slightly less space for the ticks in
2696 // between the first and the last
2699 dc
.SetPen(m_penBlack
);
2701 int range
= end
- start
;
2702 for ( int n
= 0; n
< range
; n
+= step
)
2704 wxCoord x
= x1
+ (len
*n
) / range
;
2706 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2709 // always draw the line at the end position
2710 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2713 // ----------------------------------------------------------------------------
2715 // ----------------------------------------------------------------------------
2717 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2718 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2721 virtual wxSize
GetSize() const { return m_size
; }
2723 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2724 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2726 wxCoord
GetItemHeight() const { return m_heightItem
; }
2729 // the total size of the menu
2732 // the offset of the start of the menu item label
2735 // the offset of the start of the accel label
2738 // the height of a normal (not separator) item
2739 wxCoord m_heightItem
;
2741 friend wxMenuGeometryInfo
*
2742 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2745 // FIXME: all constants are hardcoded but shouldn't be
2746 static const wxCoord MENU_LEFT_MARGIN
= 9;
2747 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2748 static const wxCoord MENU_VERT_MARGIN
= 3;
2750 // the margin around bitmap/check marks (on each side)
2751 static const wxCoord MENU_BMP_MARGIN
= 2;
2753 // the margin between the labels and accel strings
2754 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2756 // the separator height in pixels: in fact, strangely enough, the real height
2757 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2759 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2761 // the size of the standard checkmark bitmap
2762 static const wxCoord MENU_CHECK_SIZE
= 9;
2764 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2765 const wxRect
& rectOrig
,
2766 const wxString
& label
,
2770 wxRect rect
= rectOrig
;
2773 wxDCTextColourChanger
colChanger(dc
);
2775 if ( flags
& wxCONTROL_SELECTED
)
2777 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2779 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2780 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2781 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2782 dc
.DrawRectangle(rect
);
2785 // don't draw the focus rect around menu bar items
2786 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2787 wxALIGN_CENTRE
, indexAccel
);
2790 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2792 const wxMenuGeometryInfo
& gi
,
2793 const wxString
& label
,
2794 const wxString
& accel
,
2795 const wxBitmap
& bitmap
,
2799 const wxWin32MenuGeometryInfo
& geometryInfo
=
2800 (const wxWin32MenuGeometryInfo
&)gi
;
2805 rect
.width
= geometryInfo
.GetSize().x
;
2806 rect
.height
= geometryInfo
.GetItemHeight();
2808 // draw the selected item specially
2809 wxDCTextColourChanger
colChanger(dc
);
2810 if ( flags
& wxCONTROL_SELECTED
)
2812 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2814 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2815 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2816 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2817 dc
.DrawRectangle(rect
);
2820 // draw the bitmap: use the bitmap provided or the standard checkmark for
2821 // the checkable items
2822 wxBitmap bmp
= bitmap
;
2823 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2825 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2830 rect
.SetRight(geometryInfo
.GetLabelOffset());
2831 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2835 rect
.x
= geometryInfo
.GetLabelOffset();
2836 rect
.SetRight(geometryInfo
.GetAccelOffset());
2838 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2840 // draw the accel string
2841 rect
.x
= geometryInfo
.GetAccelOffset();
2842 rect
.SetRight(geometryInfo
.GetSize().x
);
2844 // NB: no accel index here
2845 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2847 // draw the submenu indicator
2848 if ( flags
& wxCONTROL_ISSUBMENU
)
2850 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2851 rect
.width
= MENU_RIGHT_MARGIN
;
2853 wxArrowStyle arrowStyle
;
2854 if ( flags
& wxCONTROL_DISABLED
)
2855 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2857 else if ( flags
& wxCONTROL_SELECTED
)
2858 arrowStyle
= Arrow_Inversed
;
2860 arrowStyle
= Arrow_Normal
;
2862 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2866 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2868 const wxMenuGeometryInfo
& geomInfo
)
2870 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2873 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2875 wxSize size
= sizeText
;
2877 // FIXME: menubar height is configurable under Windows
2884 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2885 const wxMenu
& menu
) const
2887 // prepare the dc: for now we draw all the items with the system font
2889 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2891 // the height of a normal item
2892 wxCoord heightText
= dc
.GetCharHeight();
2897 // the max length of label and accel strings: the menu width is the sum of
2898 // them, even if they're for different items (as the accels should be
2901 // the max length of the bitmap is never 0 as Windows always leaves enough
2902 // space for a check mark indicator
2903 wxCoord widthLabelMax
= 0,
2905 widthBmpMax
= MENU_LEFT_MARGIN
;
2907 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2909 node
= node
->GetNext() )
2911 // height of this item
2914 wxMenuItem
*item
= node
->GetData();
2915 if ( item
->IsSeparator() )
2917 h
= MENU_SEPARATOR_HEIGHT
;
2919 else // not separator
2924 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2925 if ( widthLabel
> widthLabelMax
)
2927 widthLabelMax
= widthLabel
;
2931 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2932 if ( widthAccel
> widthAccelMax
)
2934 widthAccelMax
= widthAccel
;
2937 const wxBitmap
& bmp
= item
->GetBitmap();
2940 wxCoord widthBmp
= bmp
.GetWidth();
2941 if ( widthBmp
> widthBmpMax
)
2942 widthBmpMax
= widthBmp
;
2944 //else if ( item->IsCheckable() ): no need to check for this as
2945 // MENU_LEFT_MARGIN is big enough to show the check mark
2948 h
+= 2*MENU_VERT_MARGIN
;
2950 // remember the item position and height
2951 item
->SetGeometry(height
, h
);
2956 // bundle the metrics into a struct and return it
2957 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2959 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2960 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2961 if ( widthAccelMax
> 0 )
2963 // if we actually have any accesl, add a margin
2964 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2967 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2969 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2970 gi
->m_size
.y
= height
;
2975 // ----------------------------------------------------------------------------
2977 // ----------------------------------------------------------------------------
2979 static const wxCoord STATBAR_BORDER_X
= 2;
2980 static const wxCoord STATBAR_BORDER_Y
= 2;
2982 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2984 if ( borderBetweenFields
)
2985 *borderBetweenFields
= 2;
2987 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2990 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2992 const wxString
& label
,
2997 if ( flags
& wxCONTROL_ISDEFAULT
)
2999 // draw the size grip: it is a normal rect except that in the lower
3000 // right corner we have several bands which may be used for dragging
3001 // the status bar corner
3003 // each band consists of 4 stripes: m_penHighlight, double
3004 // m_penDarkGrey and transparent one
3005 wxCoord x2
= rect
.GetRight(),
3006 y2
= rect
.GetBottom();
3008 // draw the upper left part of the rect normally
3009 dc
.SetPen(m_penDarkGrey
);
3010 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3011 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3013 // draw the grey stripes of the grip
3015 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3016 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3018 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3019 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3022 // draw the white stripes
3023 dc
.SetPen(m_penHighlight
);
3024 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3025 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3027 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3030 // draw the remaining rect boundaries
3031 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3032 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3033 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3038 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3042 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3045 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3047 wxDCClipper
clipper(dc
, rectIn
);
3048 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3051 // ----------------------------------------------------------------------------
3053 // ----------------------------------------------------------------------------
3055 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3057 wxBitmap
*bmpPressed
,
3058 wxBitmap
*bmpDisabled
)
3060 static const wxCoord widthCombo
= 16;
3061 static const wxCoord heightCombo
= 17;
3067 bmpNormal
->Create(widthCombo
, heightCombo
);
3068 dcMem
.SelectObject(*bmpNormal
);
3069 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3070 Arrow_Down
, Arrow_Normal
);
3075 bmpPressed
->Create(widthCombo
, heightCombo
);
3076 dcMem
.SelectObject(*bmpPressed
);
3077 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3078 Arrow_Down
, Arrow_Pressed
);
3083 bmpDisabled
->Create(widthCombo
, heightCombo
);
3084 dcMem
.SelectObject(*bmpDisabled
);
3085 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3086 Arrow_Down
, Arrow_Disabled
);
3090 // ----------------------------------------------------------------------------
3092 // ----------------------------------------------------------------------------
3094 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3095 const wxColour
& col
,
3098 wxBrush
brush(col
, wxSOLID
);
3100 dc
.SetPen(*wxTRANSPARENT_PEN
);
3101 dc
.DrawRectangle(rect
);
3104 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3105 const wxColour
& col
,
3109 // just fill it with the given or default bg colour
3110 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3111 DoDrawBackground(dc
, colBg
, rect
);
3114 // ----------------------------------------------------------------------------
3116 // ----------------------------------------------------------------------------
3118 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3123 // get the bitmap for this arrow
3124 wxArrowDirection arrowDir
;
3127 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3128 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3129 case wxUP
: arrowDir
= Arrow_Up
; break;
3130 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3133 wxFAIL_MSG(_T("unknown arrow direction"));
3137 wxArrowStyle arrowStyle
;
3138 if ( flags
& wxCONTROL_PRESSED
)
3140 // can't be pressed and disabled
3141 arrowStyle
= Arrow_Pressed
;
3145 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3148 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3151 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3153 wxArrowDirection arrowDir
,
3154 wxArrowStyle arrowStyle
)
3156 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3158 // under Windows the arrows always have the same size so just centre it in
3159 // the provided rectangle
3160 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3161 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3163 // Windows does it like this...
3164 if ( arrowDir
== Arrow_Left
)
3168 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3171 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3172 const wxRect
& rectAll
,
3173 wxArrowDirection arrowDir
,
3174 wxArrowStyle arrowStyle
)
3176 wxRect rect
= rectAll
;
3177 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3178 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3179 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3182 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3183 wxOrientation orient
,
3187 // we don't use the flags, the thumb never changes appearance
3188 wxRect rectThumb
= rect
;
3189 DrawArrowBorder(dc
, &rectThumb
);
3190 DrawBackground(dc
, wxNullColour
, rectThumb
);
3193 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3194 wxOrientation orient
,
3195 const wxRect
& rectBar
,
3198 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3199 ? wxColourScheme::SCROLLBAR_PRESSED
3200 : wxColourScheme::SCROLLBAR
;
3201 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3204 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3206 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3209 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3210 wxScrollBar::Element elem
,
3213 return StandardGetScrollbarRect(scrollbar
, elem
,
3214 thumbPos
, m_sizeScrollbarArrow
);
3217 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3219 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3222 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3223 const wxPoint
& pt
) const
3225 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3228 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3231 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3234 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3237 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3240 // ----------------------------------------------------------------------------
3241 // top level windows
3242 // ----------------------------------------------------------------------------
3244 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3246 wxRect client
= GetFrameClientArea(rect
, flags
);
3248 if ( client
.Inside(pt
) )
3249 return wxHT_TOPLEVEL_CLIENT_AREA
;
3251 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3253 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3255 if ( flags
& wxTOPLEVEL_ICON
)
3257 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3258 return wxHT_TOPLEVEL_ICON
;
3261 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3262 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3263 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3265 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3267 if ( btnRect
.Inside(pt
) )
3268 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3269 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3271 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3273 if ( btnRect
.Inside(pt
) )
3274 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3275 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3277 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3279 if ( btnRect
.Inside(pt
) )
3280 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3281 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3283 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3285 if ( btnRect
.Inside(pt
) )
3286 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3287 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3289 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3291 if ( btnRect
.Inside(pt
) )
3292 return wxHT_TOPLEVEL_BUTTON_HELP
;
3293 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3296 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3297 return wxHT_TOPLEVEL_TITLEBAR
;
3300 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3302 // we are certainly at one of borders, lets decide which one:
3305 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3306 if ( pt
.x
< client
.x
)
3307 border
|= wxHT_TOPLEVEL_BORDER_W
;
3308 else if ( pt
.x
>= client
.width
+ client
.x
)
3309 border
|= wxHT_TOPLEVEL_BORDER_E
;
3310 if ( pt
.y
< client
.y
)
3311 border
|= wxHT_TOPLEVEL_BORDER_N
;
3312 else if ( pt
.y
>= client
.height
+ client
.y
)
3313 border
|= wxHT_TOPLEVEL_BORDER_S
;
3317 return wxHT_NOWHERE
;
3320 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3322 const wxString
& title
,
3326 int specialButtonFlags
)
3328 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3330 DrawFrameBorder(dc
, rect
, flags
);
3332 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3334 DrawFrameBackground(dc
, rect
, flags
);
3335 if ( flags
& wxTOPLEVEL_ICON
)
3336 DrawFrameIcon(dc
, rect
, icon
, flags
);
3337 DrawFrameTitle(dc
, rect
, title
, flags
);
3339 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3341 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3342 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3344 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3346 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3347 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3348 specialButtonFlags
: 0);
3349 x
-= FRAME_BUTTON_WIDTH
+ 2;
3351 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3353 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3354 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3355 specialButtonFlags
: 0);
3356 x
-= FRAME_BUTTON_WIDTH
;
3358 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3360 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3361 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3362 specialButtonFlags
: 0);
3363 x
-= FRAME_BUTTON_WIDTH
;
3365 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3367 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3368 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3369 specialButtonFlags
: 0);
3370 x
-= FRAME_BUTTON_WIDTH
;
3372 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3374 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3375 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3376 specialButtonFlags
: 0);
3377 x
-= FRAME_BUTTON_WIDTH
;
3382 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3386 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3390 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3391 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3392 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3393 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3394 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3397 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3401 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3403 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3404 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3405 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3407 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3408 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3410 DrawBackground(dc
, col
, r
);
3413 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3415 const wxString
& title
,
3418 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3419 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3420 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3422 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3423 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3424 if ( flags
& wxTOPLEVEL_ICON
)
3426 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3427 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3435 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3436 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3437 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3438 r
.width
-= FRAME_BUTTON_WIDTH
;
3439 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3440 r
.width
-= FRAME_BUTTON_WIDTH
;
3441 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3442 r
.width
-= FRAME_BUTTON_WIDTH
;
3443 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3444 r
.width
-= FRAME_BUTTON_WIDTH
;
3446 dc
.SetFont(m_titlebarFont
);
3447 dc
.SetTextForeground(col
);
3450 dc
.GetTextExtent(title
, &textW
, NULL
);
3451 if ( textW
> r
.width
)
3453 // text is too big, let's shorten it and add "..." after it:
3454 size_t len
= title
.length();
3455 wxCoord WSoFar
, letterW
;
3457 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3458 if ( WSoFar
> r
.width
)
3460 // not enough space to draw anything
3466 for (size_t i
= 0; i
< len
; i
++)
3468 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3469 if ( letterW
+ WSoFar
> r
.width
)
3475 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3476 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3479 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3480 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3483 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3490 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3491 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3495 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3496 wxCoord x
, wxCoord y
,
3500 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3505 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3506 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3507 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3508 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3509 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3511 wxFAIL_MSG(wxT("incorrect button specification"));
3514 if ( flags
& wxCONTROL_PRESSED
)
3516 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3517 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3518 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3519 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3523 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3524 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3525 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3526 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3531 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3536 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3538 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3539 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3540 FRAME_BORDER_THICKNESS
;
3543 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3545 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3546 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3552 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3555 wxSize
s(clientSize
);
3557 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3559 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3560 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3561 FRAME_BORDER_THICKNESS
;
3565 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3566 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3571 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3575 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3577 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3578 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3579 FRAME_BORDER_THICKNESS
;
3584 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3586 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3588 if ( flags
& wxTOPLEVEL_ICON
)
3589 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3590 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3591 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3592 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3593 s
.x
+= FRAME_BUTTON_WIDTH
;
3594 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3595 s
.x
+= FRAME_BUTTON_WIDTH
;
3596 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3597 s
.x
+= FRAME_BUTTON_WIDTH
;
3598 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3599 s
.x
+= FRAME_BUTTON_WIDTH
;
3605 wxSize
wxWin32Renderer::GetFrameIconSize() const
3607 return wxSize(16, 16);
3611 // ----------------------------------------------------------------------------
3613 // ----------------------------------------------------------------------------
3615 static char *error_xpm
[]={
3622 "...........########.............",
3623 "........###aaaaaaaa###..........",
3624 ".......#aaaaaaaaaaaaaa#.........",
3625 ".....##aaaaaaaaaaaaaaaa##.......",
3626 "....#aaaaaaaaaaaaaaaaaaaa#......",
3627 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3628 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3629 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3630 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3631 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3632 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3633 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3634 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3635 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3636 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3637 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3638 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3639 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3640 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3641 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3642 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3643 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3644 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3645 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3646 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3647 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3648 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3649 "......b#aaaaaaaaaaaaaa#bbbbb....",
3650 ".......b###aaaaaaaa###bbbbb.....",
3651 ".........bb########bbbbbb.......",
3652 "..........bbbbbbbbbbbbbb........",
3653 ".............bbbbbbbb..........."};
3655 static char *info_xpm
[]={
3663 "...........########.............",
3664 "........###abbbbbba###..........",
3665 "......##abbbbbbbbbbbba##........",
3666 ".....#abbbbbbbbbbbbbbbba#.......",
3667 "....#bbbbbbbaccccabbbbbbbd......",
3668 "...#bbbbbbbbccccccbbbbbbbbd.....",
3669 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3670 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3671 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3672 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3673 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3674 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3675 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3676 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3677 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3678 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3679 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3680 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3681 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3682 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3683 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3684 ".....dabbbbbbbbbbbbbbbbad####...",
3685 "......ddabbbbbbbbbbbbadd####....",
3686 ".......#dddabbbbbbaddd#####.....",
3687 "........###dddabbbd#######......",
3688 "..........####dbbbd#####........",
3689 ".............#dbbbd##...........",
3690 "...............dbbd##...........",
3691 "................dbd##...........",
3692 ".................dd##...........",
3693 "..................###...........",
3694 "...................##..........."};
3696 static char *question_xpm
[]={
3704 "...........########.............",
3705 "........###abbbbbba###..........",
3706 "......##abbbbbbbbbbbba##........",
3707 ".....#abbbbbbbbbbbbbbbba#.......",
3708 "....#bbbbbbbbbbbbbbbbbbbbc......",
3709 "...#bbbbbbbaddddddabbbbbbbc.....",
3710 "..#bbbbbbbadabbddddabbbbbbbc....",
3711 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3712 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3713 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3714 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3715 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3716 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3717 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3718 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3719 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3720 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3721 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3722 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3723 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3724 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3725 ".....cabbbbbbbbbbbbbbbbac####...",
3726 "......ccabbbbbbbbbbbbacc####....",
3727 ".......#cccabbbbbbaccc#####.....",
3728 "........###cccabbbc#######......",
3729 "..........####cbbbc#####........",
3730 ".............#cbbbc##...........",
3731 "...............cbbc##...........",
3732 "................cbc##...........",
3733 ".................cc##...........",
3734 "..................###...........",
3735 "...................##..........."};
3737 static char *warning_xpm
[]={
3745 ".............###................",
3746 "............#aabc...............",
3747 "...........#aaaabcd.............",
3748 "...........#aaaaacdd............",
3749 "..........#aaaaaabcdd...........",
3750 "..........#aaaaaaacdd...........",
3751 ".........#aaaaaaaabcdd..........",
3752 ".........#aaaaaaaaacdd..........",
3753 "........#aaaaaaaaaabcdd.........",
3754 "........#aaabcccbaaacdd.........",
3755 ".......#aaaacccccaaabcdd........",
3756 ".......#aaaacccccaaaacdd........",
3757 "......#aaaaacccccaaaabcdd.......",
3758 "......#aaaaacccccaaaaacdd.......",
3759 ".....#aaaaaacccccaaaaabcdd......",
3760 ".....#aaaaaa#ccc#aaaaaacdd......",
3761 "....#aaaaaaabcccbaaaaaabcdd.....",
3762 "....#aaaaaaaacccaaaaaaaacdd.....",
3763 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3764 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3765 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3766 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3767 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3768 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3769 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3770 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3771 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3772 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3773 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3774 "..#ccccccccccccccccccccccccddddd",
3775 "....ddddddddddddddddddddddddddd.",
3776 ".....ddddddddddddddddddddddddd.."};
3778 wxIcon
wxWin32Renderer::GetStdIcon(int which
) const
3782 case wxICON_INFORMATION
:
3783 return wxIcon(info_xpm
);
3785 case wxICON_QUESTION
:
3786 return wxIcon(question_xpm
);
3788 case wxICON_EXCLAMATION
:
3789 return wxIcon(warning_xpm
);
3792 wxFAIL_MSG(wxT("requested non existent standard icon"));
3793 // still fall through
3796 return wxIcon(error_xpm
);
3801 // ----------------------------------------------------------------------------
3802 // text control geometry
3803 // ----------------------------------------------------------------------------
3805 static inline int GetTextBorderWidth()
3810 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3813 wxRect rectTotal
= rect
;
3815 wxCoord widthBorder
= GetTextBorderWidth();
3816 rectTotal
.Inflate(widthBorder
);
3818 // this is what Windows does
3824 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3826 wxCoord
*extraSpaceBeyond
)
3828 wxRect rectText
= rect
;
3830 // undo GetTextTotalArea()
3831 if ( rectText
.height
> 0 )
3834 wxCoord widthBorder
= GetTextBorderWidth();
3835 rectText
.Inflate(-widthBorder
);
3837 if ( extraSpaceBeyond
)
3838 *extraSpaceBeyond
= 0;
3843 // ----------------------------------------------------------------------------
3845 // ----------------------------------------------------------------------------
3847 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3850 if ( wxDynamicCast(window
, wxScrollBar
) )
3852 // we only set the width of vert scrollbars and height of the
3854 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3855 size
->y
= m_sizeScrollbarArrow
.y
;
3857 size
->x
= m_sizeScrollbarArrow
.x
;
3859 // skip border width adjustments, they don't make sense for us
3862 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3865 if ( wxDynamicCast(window
, wxButton
) )
3867 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3869 // TODO: don't harcode all this
3870 size
->x
+= 3*window
->GetCharWidth();
3872 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3873 if ( size
->y
< heightBtn
- 8 )
3874 size
->y
= heightBtn
;
3879 // no border width adjustments for buttons
3882 #endif // wxUSE_BUTTON
3884 // take into account the border width
3885 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3886 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3887 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3890 // ============================================================================
3892 // ============================================================================
3894 // ----------------------------------------------------------------------------
3895 // wxWin32InputHandler
3896 // ----------------------------------------------------------------------------
3898 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3900 m_renderer
= renderer
;
3903 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3904 const wxKeyEvent
& event
,
3910 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3911 const wxMouseEvent
& event
)
3913 // clicking on the control gives it focus
3914 if ( event
.ButtonDown() )
3916 wxWindow
*win
= control
->GetInputWindow();
3917 if ( wxWindow::FindFocus() != control
->GetInputWindow() )
3928 // ----------------------------------------------------------------------------
3929 // wxWin32ScrollBarInputHandler
3930 // ----------------------------------------------------------------------------
3932 wxWin32ScrollBarInputHandler::
3933 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3934 wxInputHandler
*handler
)
3935 : wxStdScrollBarInputHandler(renderer
, handler
)
3937 m_scrollPaused
= FALSE
;
3941 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3942 const wxControlAction
& action
)
3944 // stop if went beyond the position of the original click (this can only
3945 // happen when we scroll by pages)
3947 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3949 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3950 != wxHT_SCROLLBAR_BAR_2
;
3952 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3954 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3955 != wxHT_SCROLLBAR_BAR_1
;
3960 StopScrolling(scrollbar
);
3962 scrollbar
->Refresh();
3967 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3970 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3971 const wxMouseEvent
& event
)
3973 // remember the current state
3974 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3976 // do process the message
3977 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3979 // analyse the changes
3980 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3982 // we just started dragging the thumb, remember its initial position to
3983 // be able to restore it if the drag is cancelled later
3984 m_eventStartDrag
= event
;
3990 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3991 const wxMouseEvent
& event
)
3993 // we don't highlight scrollbar elements, so there is no need to process
3994 // mouse move events normally - only do it while mouse is captured (i.e.
3995 // when we're dragging the thumb or pressing on something)
3996 if ( !m_winCapture
)
3999 if ( event
.Entering() )
4001 // we're not interested in this at all
4005 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4007 if ( m_scrollPaused
)
4009 // check if the mouse returned to its original location
4011 if ( event
.Leaving() )
4017 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4018 if ( ht
== m_htLast
)
4020 // yes it did, resume scrolling
4021 m_scrollPaused
= FALSE
;
4022 if ( m_timerScroll
)
4024 // we were scrolling by line/page, restart timer
4025 m_timerScroll
->Start(m_interval
);
4027 Press(scrollbar
, TRUE
);
4029 else // we were dragging the thumb
4031 // restore its last location
4032 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4038 else // normal case, scrolling hasn't been paused
4040 // if we're scrolling the scrollbar because the arrow or the shaft was
4041 // pressed, check that the mouse stays on the same scrollbar element
4043 if ( event
.Moving() )
4045 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4047 else // event.Leaving()
4052 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4053 // is still ok - we only want to catch the case when the mouse leaves
4054 // the scrollbar here
4055 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4057 ht
= wxHT_SCROLLBAR_THUMB
;
4060 if ( ht
!= m_htLast
)
4062 // what were we doing? 2 possibilities: either an arrow/shaft was
4063 // pressed in which case we have a timer and so we just stop it or
4064 // we were dragging the thumb
4065 if ( m_timerScroll
)
4068 m_interval
= m_timerScroll
->GetInterval();
4069 m_timerScroll
->Stop();
4070 m_scrollPaused
= TRUE
;
4072 // unpress the arrow
4073 Press(scrollbar
, FALSE
);
4075 else // we were dragging the thumb
4077 // remember the current thumb position to be able to restore it
4078 // if the mouse returns to it later
4079 m_eventLastDrag
= event
;
4081 // and restore the original position (before dragging) of the
4083 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4090 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4093 // ----------------------------------------------------------------------------
4094 // wxWin32CheckboxInputHandler
4095 // ----------------------------------------------------------------------------
4097 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4098 const wxKeyEvent
& event
,
4103 wxControlAction action
;
4104 int keycode
= event
.GetKeyCode();
4108 action
= wxACTION_CHECKBOX_TOGGLE
;
4112 case WXK_NUMPAD_SUBTRACT
:
4113 action
= wxACTION_CHECKBOX_CHECK
;
4117 case WXK_NUMPAD_ADD
:
4118 case WXK_NUMPAD_EQUAL
:
4119 action
= wxACTION_CHECKBOX_CLEAR
;
4125 control
->PerformAction(action
);
4134 // ----------------------------------------------------------------------------
4135 // wxWin32TextCtrlInputHandler
4136 // ----------------------------------------------------------------------------
4138 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4139 const wxKeyEvent
& event
,
4142 // handle only MSW-specific text bindings here, the others are handled in
4146 int keycode
= event
.GetKeyCode();
4148 wxControlAction action
;
4149 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4151 action
= wxACTION_TEXT_CUT
;
4153 else if ( keycode
== WXK_INSERT
)
4155 if ( event
.ControlDown() )
4156 action
= wxACTION_TEXT_COPY
;
4157 else if ( event
.ShiftDown() )
4158 action
= wxACTION_TEXT_PASTE
;
4161 if ( action
!= wxACTION_NONE
)
4163 control
->PerformAction(action
);
4169 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4172 // ----------------------------------------------------------------------------
4173 // wxWin32StatusBarInputHandler
4174 // ----------------------------------------------------------------------------
4176 wxWin32StatusBarInputHandler::
4177 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4178 : wxStdInputHandler(handler
)
4183 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4184 const wxPoint
& pt
) const
4186 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4187 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4189 wxSize sizeSbar
= statbar
->GetSize();
4191 return (sizeSbar
.x
- pt
.x
) < (wxCoord
)STATUSBAR_GRIP_SIZE
&&
4192 (sizeSbar
.y
- pt
.y
) < (wxCoord
)STATUSBAR_GRIP_SIZE
;
4198 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4199 const wxMouseEvent
& event
)
4201 if ( event
.Button(1) )
4203 if ( event
.ButtonDown(1) )
4205 wxWindow
*statbar
= consumer
->GetInputWindow();
4207 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4209 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4213 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4214 wxHT_TOPLEVEL_BORDER_SE
);
4216 statbar
->SetCursor(m_cursorOld
);
4224 return wxStdInputHandler::HandleMouse(consumer
, event
);
4227 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4228 const wxMouseEvent
& event
)
4230 wxWindow
*statbar
= consumer
->GetInputWindow();
4232 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4233 if ( isOnGrip
!= m_isOnGrip
)
4235 m_isOnGrip
= isOnGrip
;
4238 m_cursorOld
= statbar
->GetCursor();
4239 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4243 statbar
->SetCursor(m_cursorOld
);
4247 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4250 // ----------------------------------------------------------------------------
4251 // wxWin32FrameInputHandler
4252 // ----------------------------------------------------------------------------
4254 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4255 const wxMouseEvent
& event
)
4257 if ( event
.LeftDClick() )
4259 wxTopLevelWindow
*tlw
=
4260 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4262 long hit
= tlw
->HitTest(event
.GetPosition());
4264 if ( hit
== wxHT_TOPLEVEL_TITLEBAR
)
4266 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4267 tlw
->IsMaximized() ?
4268 wxTOPLEVEL_BUTTON_RESTORE
:
4269 wxTOPLEVEL_BUTTON_MAXIMIZE
);
4274 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);