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
;
478 // the checked and unchecked bitmaps for DrawCheckItem()
479 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
481 // the bitmaps returned by GetIndicator()
482 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
484 [IndicatorStatus_Max
];
487 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
489 // first row is for the normal state, second - for the disabled
490 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
493 // ----------------------------------------------------------------------------
494 // wxWin32InputHandler and derived classes: process the keyboard and mouse
495 // messages according to Windows standards
496 // ----------------------------------------------------------------------------
498 class wxWin32InputHandler
: public wxInputHandler
501 wxWin32InputHandler(wxWin32Renderer
*renderer
);
503 virtual bool HandleKey(wxInputConsumer
*control
,
504 const wxKeyEvent
& event
,
506 virtual bool HandleMouse(wxInputConsumer
*control
,
507 const wxMouseEvent
& event
);
510 wxWin32Renderer
*m_renderer
;
513 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
516 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
517 wxInputHandler
*handler
);
519 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
520 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
522 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
523 const wxControlAction
& action
);
526 virtual bool IsAllowedButton(int button
) { return button
== 1; }
528 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
530 // we don't highlight anything
533 // the first and last event which caused the thumb to move
534 wxMouseEvent m_eventStartDrag
,
537 // have we paused the scrolling because the mouse moved?
540 // we remember the interval of the timer to be able to restart it
544 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
547 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
548 : wxStdCheckboxInputHandler(handler
) { }
550 virtual bool HandleKey(wxInputConsumer
*control
,
551 const wxKeyEvent
& event
,
555 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
558 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
559 : wxStdTextCtrlInputHandler(handler
) { }
561 virtual bool HandleKey(wxInputConsumer
*control
,
562 const wxKeyEvent
& event
,
566 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
569 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
571 virtual bool HandleMouse(wxInputConsumer
*consumer
,
572 const wxMouseEvent
& event
);
574 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
575 const wxMouseEvent
& event
);
578 // is the given point over the statusbar grip?
579 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
582 // the cursor we had replaced with the resize one
583 wxCursor m_cursorOld
;
585 // was the mouse over the grip last time we checked?
589 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
592 wxWin32FrameInputHandler(wxInputHandler
*handler
)
593 : wxStdFrameInputHandler(handler
) { }
595 virtual bool HandleMouse(wxInputConsumer
*control
,
596 const wxMouseEvent
& event
);
599 // ----------------------------------------------------------------------------
600 // wxWin32ColourScheme: uses (default) Win32 colours
601 // ----------------------------------------------------------------------------
603 class wxWin32ColourScheme
: public wxColourScheme
606 virtual wxColour
Get(StdColour col
) const;
607 virtual wxColour
GetBackground(wxWindow
*win
) const;
610 // ----------------------------------------------------------------------------
612 // ----------------------------------------------------------------------------
614 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
616 class wxWin32Theme
: public wxTheme
620 virtual ~wxWin32Theme();
622 virtual wxRenderer
*GetRenderer();
623 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
624 virtual wxColourScheme
*GetColourScheme();
627 // get the default input handler
628 wxInputHandler
*GetDefaultInputHandler();
630 wxWin32Renderer
*m_renderer
;
632 // the names of the already created handlers and the handlers themselves
633 // (these arrays are synchronized)
634 wxSortedArrayString m_handlerNames
;
635 wxArrayHandlers m_handlers
;
637 wxWin32InputHandler
*m_handlerDefault
;
639 wxWin32ColourScheme
*m_scheme
;
641 WX_DECLARE_THEME(win32
)
644 // ----------------------------------------------------------------------------
646 // ----------------------------------------------------------------------------
648 // frame buttons bitmaps
650 static const char *frame_button_close_xpm
[] = {
665 static const char *frame_button_help_xpm
[] = {
680 static const char *frame_button_maximize_xpm
[] = {
695 static const char *frame_button_minimize_xpm
[] = {
710 static const char *frame_button_restore_xpm
[] = {
727 static const char *checked_menu_xpm
[] = {
728 /* columns rows colors chars-per-pixel */
744 static const char *selected_checked_menu_xpm
[] = {
745 /* columns rows colors chars-per-pixel */
761 static const char *disabled_checked_menu_xpm
[] = {
762 /* columns rows colors chars-per-pixel */
779 static const char *selected_disabled_checked_menu_xpm
[] = {
780 /* columns rows colors chars-per-pixel */
796 // checkbox and radiobox bitmaps below
798 static const char *checked_xpm
[] = {
799 /* columns rows colors chars-per-pixel */
822 static const char *pressed_checked_xpm
[] = {
823 /* columns rows colors chars-per-pixel */
845 static const char *pressed_disabled_checked_xpm
[] = {
846 /* columns rows colors chars-per-pixel */
868 static const char *checked_item_xpm
[] = {
869 /* columns rows colors chars-per-pixel */
890 static const char *unchecked_xpm
[] = {
891 /* columns rows colors chars-per-pixel */
914 static const char *pressed_unchecked_xpm
[] = {
915 /* columns rows colors chars-per-pixel */
937 static const char *unchecked_item_xpm
[] = {
938 /* columns rows colors chars-per-pixel */
958 static const char *checked_radio_xpm
[] = {
959 /* columns rows colors chars-per-pixel */
982 static const char *pressed_checked_radio_xpm
[] = {
983 /* columns rows colors chars-per-pixel */
1006 static const char *pressed_disabled_checked_radio_xpm
[] = {
1007 /* columns rows colors chars-per-pixel */
1030 static const char *unchecked_radio_xpm
[] = {
1031 /* columns rows colors chars-per-pixel */
1054 static const char *pressed_unchecked_radio_xpm
[] = {
1055 /* columns rows colors chars-per-pixel */
1078 static const char **
1079 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1084 { checked_xpm
, unchecked_xpm
},
1087 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1090 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1096 { checked_radio_xpm
, unchecked_radio_xpm
},
1099 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1102 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1108 { checked_menu_xpm
, NULL
},
1111 { selected_checked_menu_xpm
, NULL
},
1114 { disabled_checked_menu_xpm
, NULL
},
1116 // disabled selected state
1117 { selected_disabled_checked_menu_xpm
, NULL
},
1121 static const char **xpmChecked
[IndicatorStatus_Max
] =
1127 // ============================================================================
1129 // ============================================================================
1131 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1133 // ----------------------------------------------------------------------------
1135 // ----------------------------------------------------------------------------
1137 wxWin32Theme::wxWin32Theme()
1141 m_handlerDefault
= NULL
;
1144 wxWin32Theme::~wxWin32Theme()
1146 size_t count
= m_handlers
.GetCount();
1147 for ( size_t n
= 0; n
< count
; n
++ )
1149 if ( m_handlers
[n
] != m_handlerDefault
)
1150 delete m_handlers
[n
];
1153 delete m_handlerDefault
;
1159 wxRenderer
*wxWin32Theme::GetRenderer()
1163 m_renderer
= new wxWin32Renderer(GetColourScheme());
1169 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1171 if ( !m_handlerDefault
)
1173 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1176 return m_handlerDefault
;
1179 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1181 wxInputHandler
*handler
;
1182 int n
= m_handlerNames
.Index(control
);
1183 if ( n
== wxNOT_FOUND
)
1185 // create a new handler
1186 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1187 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1188 GetDefaultInputHandler());
1190 else if ( control
== wxINP_HANDLER_BUTTON
)
1191 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1192 #endif // wxUSE_BUTTON
1194 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1195 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1196 #endif // wxUSE_CHECKBOX
1198 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1199 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1200 #endif // wxUSE_COMBOBOX
1202 else if ( control
== wxINP_HANDLER_LISTBOX
)
1203 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1204 #endif // wxUSE_LISTBOX
1205 #if wxUSE_CHECKLISTBOX
1206 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1207 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1208 #endif // wxUSE_CHECKLISTBOX
1210 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1211 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1212 #endif // wxUSE_TEXTCTRL
1214 else if ( control
== wxINP_HANDLER_SLIDER
)
1215 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1216 #endif // wxUSE_SLIDER
1218 else if ( control
== wxINP_HANDLER_SPINBTN
)
1219 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1220 #endif // wxUSE_SPINBTN
1222 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1223 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1224 #endif // wxUSE_NOTEBOOK
1226 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1227 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1228 #endif // wxUSE_STATUSBAR
1229 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1230 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1232 handler
= GetDefaultInputHandler();
1234 n
= m_handlerNames
.Add(control
);
1235 m_handlers
.Insert(handler
, n
);
1237 else // we already have it
1239 handler
= m_handlers
[n
];
1245 wxColourScheme
*wxWin32Theme::GetColourScheme()
1249 m_scheme
= new wxWin32ColourScheme
;
1254 // ============================================================================
1255 // wxWin32ColourScheme
1256 // ============================================================================
1258 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1261 if ( win
->UseBgCol() )
1263 // use the user specified colour
1264 col
= win
->GetBackgroundColour();
1267 if ( win
->IsContainerWindow() )
1269 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1272 if ( !text
->IsEnabled() ) // not IsEditable()
1274 //else: execute code below
1279 // doesn't depend on the state
1285 int flags
= win
->GetStateFlags();
1287 // the colour set by the user should be used for the normal state
1288 // and for the states for which we don't have any specific colours
1289 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1291 if ( wxDynamicCast(win
, wxScrollBar
) )
1292 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1302 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1306 // use the system colours under Windows
1307 #if defined(__WXMSW__)
1308 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1310 case CONTROL_PRESSED
:
1311 case CONTROL_CURRENT
:
1312 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1314 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1316 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1317 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1319 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1320 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1322 #if defined(COLOR_3DDKSHADOW)
1323 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1325 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1328 case CONTROL_TEXT_DISABLED
:
1329 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1331 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1333 case CONTROL_TEXT_DISABLED_SHADOW
:
1334 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1336 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1337 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1338 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1339 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1341 case DESKTOP
: return wxColour(0x808000);
1343 // use the standard Windows colours elsewhere
1344 case WINDOW
: return *wxWHITE
;
1346 case CONTROL_PRESSED
:
1347 case CONTROL_CURRENT
:
1348 case CONTROL
: return wxColour(0xc0c0c0);
1350 case CONTROL_TEXT
: return *wxBLACK
;
1352 case SCROLLBAR
: return wxColour(0xe0e0e0);
1353 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1355 case HIGHLIGHT
: return wxColour(0x800000);
1356 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1358 case SHADOW_DARK
: return *wxBLACK
;
1360 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1361 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1363 case SHADOW_IN
: return wxColour(0xc0c0c0);
1365 case CONTROL_TEXT_DISABLED_SHADOW
:
1366 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1368 case TITLEBAR
: return wxColour(0xaeaaae);
1369 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1370 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1371 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1373 case DESKTOP
: return wxColour(0x808000);
1376 case GAUGE
: return Get(HIGHLIGHT
);
1380 wxFAIL_MSG(_T("invalid standard colour"));
1385 // ============================================================================
1387 // ============================================================================
1389 // ----------------------------------------------------------------------------
1391 // ----------------------------------------------------------------------------
1393 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1397 m_sizeScrollbarArrow
= wxSize(16, 16);
1399 // init colours and pens
1400 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1402 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1403 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1405 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1407 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1408 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1410 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1411 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1413 // init the arrow bitmaps
1414 static const size_t ARROW_WIDTH
= 7;
1415 static const size_t ARROW_LENGTH
= 4;
1418 wxMemoryDC dcNormal
,
1421 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1423 bool isVertical
= n
> Arrow_Right
;
1436 // disabled arrow is larger because of the shadow
1437 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1438 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1440 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1441 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1443 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1444 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1448 dcNormal
.SetPen(m_penBlack
);
1449 dcDisabled
.SetPen(m_penDarkGrey
);
1451 // calculate the position of the point of the arrow
1455 x1
= (ARROW_WIDTH
- 1)/2;
1456 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1460 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1461 y1
= (ARROW_WIDTH
- 1)/2;
1472 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1474 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1475 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1482 if ( n
== Arrow_Up
)
1493 else // left or right arrow
1498 if ( n
== Arrow_Left
)
1511 // draw the shadow for the disabled one
1512 dcDisabled
.SetPen(m_penHighlight
);
1517 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1521 x1
= ARROW_LENGTH
- 1;
1522 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1525 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1526 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1531 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1535 x1
= ARROW_WIDTH
- 1;
1537 x2
= (ARROW_WIDTH
- 1)/2;
1539 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1540 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1545 // create the inversed bitmap but only for the right arrow as we only
1546 // use it for the menus
1547 if ( n
== Arrow_Right
)
1549 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1550 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1552 dcInverse
.Blit(0, 0, w
, h
,
1555 dcInverse
.SelectObject(wxNullBitmap
);
1557 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1558 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1560 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1561 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1563 dcInverse
.Blit(0, 0, w
, h
,
1566 dcInverse
.SelectObject(wxNullBitmap
);
1568 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1569 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1572 dcNormal
.SelectObject(wxNullBitmap
);
1573 dcDisabled
.SelectObject(wxNullBitmap
);
1575 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1576 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1577 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1578 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1580 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1583 // init the frame buttons bitmaps
1584 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1585 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1586 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1587 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1588 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1591 // ----------------------------------------------------------------------------
1593 // ----------------------------------------------------------------------------
1596 The raised border in Win32 looks like this:
1598 IIIIIIIIIIIIIIIIIIIIIIB
1600 I GB I = white (HILIGHT)
1601 I GB H = light grey (LIGHT)
1602 I GB G = dark grey (SHADOI)
1603 I GB B = black (DKSHADOI)
1604 I GB I = hIghlight (COLOR_3DHILIGHT)
1606 IGGGGGGGGGGGGGGGGGGGGGB
1607 BBBBBBBBBBBBBBBBBBBBBBB
1609 The sunken border looks like this:
1611 GGGGGGGGGGGGGGGGGGGGGGI
1612 GBBBBBBBBBBBBBBBBBBBBHI
1619 GHHHHHHHHHHHHHHHHHHHHHI
1620 IIIIIIIIIIIIIIIIIIIIIII
1622 The static border (used for the controls which don't get focus) is like
1625 GGGGGGGGGGGGGGGGGGGGGGW
1633 WWWWWWWWWWWWWWWWWWWWWWW
1635 The most complicated is the double border:
1637 HHHHHHHHHHHHHHHHHHHHHHB
1638 HWWWWWWWWWWWWWWWWWWWWGB
1639 HWHHHHHHHHHHHHHHHHHHHGB
1644 HWHHHHHHHHHHHHHHHHHHHGB
1645 HGGGGGGGGGGGGGGGGGGGGGB
1646 BBBBBBBBBBBBBBBBBBBBBBB
1648 And the simple border is, well, simple:
1650 BBBBBBBBBBBBBBBBBBBBBBB
1659 BBBBBBBBBBBBBBBBBBBBBBB
1662 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1666 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1667 dc
.DrawRectangle(*rect
);
1673 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1675 // draw the bottom and right sides
1677 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1678 rect
->GetRight() + 1, rect
->GetBottom());
1679 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1680 rect
->GetRight(), rect
->GetBottom());
1687 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1688 const wxPen
& pen1
, const wxPen
& pen2
)
1690 // draw the rectangle
1692 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1693 rect
->GetLeft(), rect
->GetBottom());
1694 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1695 rect
->GetRight(), rect
->GetTop());
1697 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1698 rect
->GetRight(), rect
->GetBottom());
1699 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1700 rect
->GetRight() + 1, rect
->GetBottom());
1706 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1708 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1709 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1712 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1714 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1715 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1718 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1722 DrawRect(dc
, rect
, m_penDarkGrey
);
1724 // the arrow is usually drawn inside border of width 2 and is offset by
1725 // another pixel in both directions when it's pressed - as the border
1726 // in this case is more narrow as well, we have to adjust rect like
1734 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1735 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1739 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1741 const wxRect
& rectTotal
,
1742 int WXUNUSED(flags
),
1747 wxRect rect
= rectTotal
;
1751 case wxBORDER_SUNKEN
:
1752 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1754 DrawSunkenBorder(dc
, &rect
);
1758 case wxBORDER_STATIC
:
1759 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1762 case wxBORDER_RAISED
:
1763 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1765 DrawRaisedBorder(dc
, &rect
);
1769 case wxBORDER_DOUBLE
:
1770 DrawArrowBorder(dc
, &rect
);
1771 DrawRect(dc
, &rect
, m_penLightGrey
);
1774 case wxBORDER_SIMPLE
:
1775 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1777 DrawRect(dc
, &rect
, m_penBlack
);
1782 wxFAIL_MSG(_T("unknown border type"));
1785 case wxBORDER_DEFAULT
:
1794 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1799 case wxBORDER_RAISED
:
1800 case wxBORDER_SUNKEN
:
1801 width
= BORDER_THICKNESS
;
1804 case wxBORDER_SIMPLE
:
1805 case wxBORDER_STATIC
:
1809 case wxBORDER_DOUBLE
:
1814 wxFAIL_MSG(_T("unknown border type"));
1817 case wxBORDER_DEFAULT
:
1827 rect
.height
= width
;
1832 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1837 // ----------------------------------------------------------------------------
1839 // ----------------------------------------------------------------------------
1841 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1847 // text controls are not special under windows
1848 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1851 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1852 const wxRect
& rectTotal
,
1856 wxRect rect
= rectTotal
;
1858 if ( flags
& wxCONTROL_PRESSED
)
1860 // button pressed: draw a double border around it
1861 DrawRect(dc
, &rect
, m_penBlack
);
1862 DrawRect(dc
, &rect
, m_penDarkGrey
);
1866 // button not pressed
1868 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1870 // button either default or focused (or both): add an extra border around it
1871 DrawRect(dc
, &rect
, m_penBlack
);
1874 // now draw a normal button
1875 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1876 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1885 // ----------------------------------------------------------------------------
1887 // ----------------------------------------------------------------------------
1889 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1890 wxCoord y
, wxCoord x1
, wxCoord x2
)
1892 dc
.SetPen(m_penDarkGrey
);
1893 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1894 dc
.SetPen(m_penHighlight
);
1896 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1899 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1900 wxCoord x
, wxCoord y1
, wxCoord y2
)
1902 dc
.SetPen(m_penDarkGrey
);
1903 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1904 dc
.SetPen(m_penHighlight
);
1906 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1909 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1910 const wxString
& label
,
1916 wxCoord height
= 0; // of the label
1917 wxRect rectFrame
= rect
;
1918 if ( !label
.empty() )
1920 // the text should touch the top border of the rect, so the frame
1921 // itself should be lower
1922 dc
.GetTextExtent(label
, NULL
, &height
);
1923 rectFrame
.y
+= height
/ 2;
1924 rectFrame
.height
-= height
/ 2;
1926 // we have to draw each part of the frame individually as we can't
1927 // erase the background beyond the label as it might contain some
1928 // pixmap already, so drawing everything and then overwriting part of
1929 // the frame with label doesn't work
1931 // TODO: the +5 and space insertion should be customizable
1934 rectText
.x
= rectFrame
.x
+ 5;
1935 rectText
.y
= rect
.y
;
1936 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1937 rectText
.height
= height
;
1940 label2
<< _T(' ') << label
<< _T(' ');
1941 if ( indexAccel
!= -1 )
1943 // adjust it as we prepended a space
1948 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1950 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1954 // just draw the complete frame
1955 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1956 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1960 // ----------------------------------------------------------------------------
1962 // ----------------------------------------------------------------------------
1964 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1966 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1967 // pixels each while we really need dots here... PS_ALTERNATE might
1968 // work, but it is for NT 5 only
1970 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1972 // draw the pixels manually: note that to behave in the same manner as
1973 // DrawRect(), we must exclude the bottom and right borders from the
1975 wxCoord x1
= rect
.GetLeft(),
1977 x2
= rect
.GetRight(),
1978 y2
= rect
.GetBottom();
1980 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1982 // this seems to be closer than what Windows does than wxINVERT although
1983 // I'm still not sure if it's correct
1984 dc
.SetLogicalFunction(wxAND_REVERSE
);
1987 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1988 dc
.DrawPoint(z
, rect
.GetTop());
1990 wxCoord shift
= z
== x2
? 0 : 1;
1991 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1992 dc
.DrawPoint(x2
, z
);
1994 shift
= z
== y2
? 0 : 1;
1995 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1996 dc
.DrawPoint(z
, y2
);
1998 shift
= z
== x1
? 0 : 1;
1999 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2000 dc
.DrawPoint(x1
, z
);
2002 dc
.SetLogicalFunction(wxCOPY
);
2006 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2007 const wxString
& label
,
2012 // draw shadow of the text
2013 dc
.SetTextForeground(m_colHighlight
);
2014 wxRect rectShadow
= rect
;
2017 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2019 // make the text grey
2020 dc
.SetTextForeground(m_colDarkGrey
);
2023 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2024 const wxString
& label
,
2031 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2034 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2035 const wxString
& label
,
2041 const wxPoint
& focusOffset
)
2043 // the underscores are not drawn for focused controls in wxMSW
2044 if ( flags
& wxCONTROL_FOCUSED
)
2049 if ( flags
& wxCONTROL_DISABLED
)
2051 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2052 // currently only can happen for a menu item and it seems that Windows
2053 // doesn't draw the shadow in this case, so we don't do it neither
2054 if ( flags
& wxCONTROL_SELECTED
)
2056 // just make the label text greyed out
2057 dc
.SetTextForeground(m_colDarkGrey
);
2059 else // draw normal disabled label
2061 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2066 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2068 if ( flags
& wxCONTROL_DISABLED
)
2070 // restore the fg colour
2071 dc
.SetTextForeground(*wxBLACK
);
2074 if ( flags
& wxCONTROL_FOCUSED
)
2076 if ( focusOffset
.x
|| focusOffset
.y
)
2078 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2081 DrawFocusRect(dc
, rectLabel
);
2085 *rectBounds
= rectLabel
;
2088 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2089 const wxString
& label
,
2090 const wxBitmap
& image
,
2097 // the underscores are not drawn for focused controls in wxMSW
2098 if ( flags
& wxCONTROL_PRESSED
)
2103 wxRect rectLabel
= rect
;
2104 if ( !label
.empty() )
2106 // shift the label if a button is pressed
2107 if ( flags
& wxCONTROL_PRESSED
)
2113 if ( flags
& wxCONTROL_DISABLED
)
2115 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2118 // leave enough space for the focus rectangle
2119 if ( flags
& wxCONTROL_FOCUSED
)
2121 rectLabel
.Inflate(-2);
2125 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2127 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2129 if ( flags
& wxCONTROL_PRESSED
)
2131 // the focus rectangle is never pressed, so undo the shift done
2139 DrawFocusRect(dc
, rectLabel
);
2143 // ----------------------------------------------------------------------------
2144 // (check)listbox items
2145 // ----------------------------------------------------------------------------
2147 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2148 const wxString
& label
,
2152 wxDCTextColourChanger
colChanger(dc
);
2154 if ( flags
& wxCONTROL_SELECTED
)
2156 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2158 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2159 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2160 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2161 dc
.DrawRectangle(rect
);
2164 wxRect rectText
= rect
;
2166 rectText
.width
-= 2;
2167 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2169 if ( flags
& wxCONTROL_FOCUSED
)
2171 DrawFocusRect(dc
, rect
);
2175 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2176 const wxString
& label
,
2177 const wxBitmap
& bitmap
,
2186 else // use default bitmap
2188 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2189 ? IndicatorStatus_Checked
2190 : IndicatorStatus_Unchecked
;
2192 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2194 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2197 bmp
= m_bmpCheckBitmaps
[i
];
2200 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2201 TRUE
/* use mask */);
2203 wxRect rectLabel
= rect
;
2204 int bmpWidth
= bmp
.GetWidth();
2205 rectLabel
.x
+= bmpWidth
;
2206 rectLabel
.width
-= bmpWidth
;
2208 DrawItem(dc
, label
, rectLabel
, flags
);
2211 // ----------------------------------------------------------------------------
2212 // check/radio buttons
2213 // ----------------------------------------------------------------------------
2215 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2217 IndicatorState indState
;
2218 if ( flags
& wxCONTROL_SELECTED
)
2219 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2220 : IndicatorState_Selected
;
2221 else if ( flags
& wxCONTROL_DISABLED
)
2222 indState
= IndicatorState_Disabled
;
2223 else if ( flags
& wxCONTROL_PRESSED
)
2224 indState
= IndicatorState_Pressed
;
2226 indState
= IndicatorState_Normal
;
2228 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2229 ? IndicatorStatus_Checked
2230 : IndicatorStatus_Unchecked
;
2232 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2235 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2238 // create and cache it
2239 bmp
= wxBitmap(xpm
);
2240 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2247 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2248 const wxString
& label
,
2249 const wxBitmap
& bitmap
,
2254 wxCoord focusOffsetY
)
2256 // calculate the position of the bitmap and of the label
2257 wxCoord heightBmp
= bitmap
.GetHeight();
2259 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2262 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2263 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2265 // align label vertically with the bitmap - looks nicer like this
2266 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2268 // calc horz position
2269 if ( align
== wxALIGN_RIGHT
)
2271 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2272 rectLabel
.x
= rect
.x
+ 3;
2273 rectLabel
.SetRight(xBmp
);
2275 else // normal (checkbox to the left of the text) case
2278 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2279 rectLabel
.SetRight(rect
.GetRight());
2282 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2285 dc
, label
, rectLabel
,
2287 wxALIGN_LEFT
| wxALIGN_TOP
,
2289 NULL
, // we don't need bounding rect
2290 // use custom vert focus rect offset
2291 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2295 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2296 const wxString
& label
,
2297 const wxBitmap
& bitmap
,
2307 bmp
= GetRadioBitmap(flags
);
2309 DrawCheckOrRadioButton(dc
, label
,
2311 rect
, flags
, align
, indexAccel
,
2312 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2315 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2316 const wxString
& label
,
2317 const wxBitmap
& bitmap
,
2327 bmp
= GetCheckBitmap(flags
);
2329 DrawCheckOrRadioButton(dc
, label
,
2331 rect
, flags
, align
, indexAccel
,
2332 0); // no focus rect offset for checkboxes
2335 // ----------------------------------------------------------------------------
2337 // ----------------------------------------------------------------------------
2339 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2340 const wxString
& text
,
2346 // nothing special to do here
2347 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2350 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2352 // we don't draw them
2355 // ----------------------------------------------------------------------------
2357 // ----------------------------------------------------------------------------
2359 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2360 const wxRect
& rectOrig
,
2362 const wxString
& label
,
2363 const wxBitmap
& bitmap
,
2367 wxRect rect
= rectOrig
;
2369 // the current tab is drawn indented (to the top for default case) and
2370 // bigger than the other ones
2371 const wxSize indent
= GetTabIndent();
2372 if ( flags
& wxCONTROL_SELECTED
)
2377 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2381 rect
.Inflate(indent
.x
, 0);
2383 rect
.height
+= indent
.y
;
2387 rect
.Inflate(indent
.x
, 0);
2388 rect
.height
+= indent
.y
;
2393 wxFAIL_MSG(_T("TODO"));
2398 // draw the text, image and the focus around them (if necessary)
2399 wxRect rectLabel
= rect
;
2400 rectLabel
.Deflate(1, 1);
2401 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2402 flags
, wxALIGN_CENTRE
, indexAccel
);
2404 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2405 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2408 x2
= rect
.GetRight(),
2409 y2
= rect
.GetBottom();
2411 // FIXME: all this code will break if the tab indent or the border width,
2412 // it is tied to the fact that both of them are equal to 2
2417 dc
.SetPen(m_penHighlight
);
2418 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2419 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2420 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2422 dc
.SetPen(m_penBlack
);
2423 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2424 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2426 dc
.SetPen(m_penDarkGrey
);
2427 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2429 if ( flags
& wxCONTROL_SELECTED
)
2431 dc
.SetPen(m_penLightGrey
);
2433 // overwrite the part of the border below this tab
2434 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2436 // and the shadow of the tab to the left of us
2437 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2442 dc
.SetPen(m_penHighlight
);
2443 // we need to continue one pixel further to overwrite the corner of
2444 // the border for the selected tab
2445 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2447 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2449 dc
.SetPen(m_penBlack
);
2450 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2451 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2452 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2454 dc
.SetPen(m_penDarkGrey
);
2455 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2456 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2458 if ( flags
& wxCONTROL_SELECTED
)
2460 dc
.SetPen(m_penLightGrey
);
2462 // overwrite the part of the (double!) border above this tab
2463 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2464 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2466 // and the shadow of the tab to the left of us
2467 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2473 wxFAIL_MSG(_T("TODO"));
2477 // ----------------------------------------------------------------------------
2479 // ----------------------------------------------------------------------------
2481 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2482 wxOrientation orient
) const
2486 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2487 if ( orient
== wxHORIZONTAL
)
2489 size
.y
= rect
.height
- 6;
2490 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2494 size
.x
= rect
.width
- 6;
2495 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2501 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2502 wxOrientation orient
) const
2504 static const wxCoord SLIDER_MARGIN
= 6;
2506 wxRect rect
= rectOrig
;
2508 if ( orient
== wxHORIZONTAL
)
2510 // make the rect of minimal width and centre it
2511 rect
.height
= 2*BORDER_THICKNESS
;
2512 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2516 // leave margins on the sides
2517 rect
.Deflate(SLIDER_MARGIN
, 0);
2521 // same as above but in other direction
2522 rect
.width
= 2*BORDER_THICKNESS
;
2523 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2527 rect
.Deflate(0, SLIDER_MARGIN
);
2533 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2534 const wxRect
& rectOrig
,
2535 wxOrientation orient
,
2539 if ( flags
& wxCONTROL_FOCUSED
)
2541 DrawFocusRect(dc
, rectOrig
);
2544 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2549 DrawSunkenBorder(dc
, &rect
);
2552 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2554 wxOrientation orient
,
2558 we are drawing a shape of this form
2563 H DB where H is hightlight colour
2576 The interior of this shape is filled with the hatched brush if the thumb
2580 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2582 bool transpose
= orient
== wxVERTICAL
;
2584 wxCoord x
, y
, x2
, y2
;
2589 x2
= rect
.GetBottom();
2590 y2
= rect
.GetRight();
2596 x2
= rect
.GetRight();
2597 y2
= rect
.GetBottom();
2600 // the size of the pointed part of the thumb
2601 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2603 wxCoord x3
= x
+ sizeArrow
,
2604 y3
= y2
- sizeArrow
;
2606 dc
.SetPen(m_penHighlight
);
2607 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2608 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2609 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2611 dc
.SetPen(m_penBlack
);
2612 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2613 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2615 dc
.SetPen(m_penDarkGrey
);
2616 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2617 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2619 if ( flags
& wxCONTROL_PRESSED
)
2621 // TODO: MSW fills the entire area inside, not just the rect
2622 wxRect rectInt
= rect
;
2624 rectInt
.SetRight(y3
);
2626 rectInt
.SetBottom(y3
);
2629 #if !defined(__WXMGL__)
2630 static const char *stipple_xpm
[] = {
2631 /* columns rows colors chars-per-pixel */
2640 // VS: MGL can only do 8x8 stipple brushes
2641 static const char *stipple_xpm
[] = {
2642 /* columns rows colors chars-per-pixel */
2657 dc
.SetBrush(wxBrush(stipple_xpm
));
2659 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2660 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2661 dc
.SetPen(*wxTRANSPARENT_PEN
);
2662 dc
.DrawRectangle(rectInt
);
2666 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2668 const wxSize
& sizeThumb
,
2669 wxOrientation orient
,
2681 // the variable names correspond to horizontal case, but they can be used
2682 // for both orientations
2683 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2684 if ( orient
== wxHORIZONTAL
)
2686 x1
= rect
.GetLeft();
2687 x2
= rect
.GetRight();
2689 // draw from bottom to top to leave one pixel space between the ticks
2690 // and the slider as Windows do
2691 y1
= rect
.GetBottom();
2696 widthThumb
= sizeThumb
.x
;
2701 x2
= rect
.GetBottom();
2703 y1
= rect
.GetRight();
2704 y2
= rect
.GetLeft();
2708 widthThumb
= sizeThumb
.y
;
2711 // the first tick should be positioned in such way that a thumb drawn in
2712 // the first position points down directly to it
2713 x1
+= widthThumb
/ 2;
2714 x2
-= widthThumb
/ 2;
2716 // this also means that we have slightly less space for the ticks in
2717 // between the first and the last
2720 dc
.SetPen(m_penBlack
);
2722 int range
= end
- start
;
2723 for ( int n
= 0; n
< range
; n
+= step
)
2725 wxCoord x
= x1
+ (len
*n
) / range
;
2727 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2730 // always draw the line at the end position
2731 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2734 // ----------------------------------------------------------------------------
2736 // ----------------------------------------------------------------------------
2738 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2739 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2742 virtual wxSize
GetSize() const { return m_size
; }
2744 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2745 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2747 wxCoord
GetItemHeight() const { return m_heightItem
; }
2750 // the total size of the menu
2753 // the offset of the start of the menu item label
2756 // the offset of the start of the accel label
2759 // the height of a normal (not separator) item
2760 wxCoord m_heightItem
;
2762 friend wxMenuGeometryInfo
*
2763 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2766 // FIXME: all constants are hardcoded but shouldn't be
2767 static const wxCoord MENU_LEFT_MARGIN
= 9;
2768 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2769 static const wxCoord MENU_VERT_MARGIN
= 3;
2771 // the margin around bitmap/check marks (on each side)
2772 static const wxCoord MENU_BMP_MARGIN
= 2;
2774 // the margin between the labels and accel strings
2775 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2777 // the separator height in pixels: in fact, strangely enough, the real height
2778 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2780 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2782 // the size of the standard checkmark bitmap
2783 static const wxCoord MENU_CHECK_SIZE
= 9;
2785 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2786 const wxRect
& rectOrig
,
2787 const wxString
& label
,
2791 wxRect rect
= rectOrig
;
2794 wxDCTextColourChanger
colChanger(dc
);
2796 if ( flags
& wxCONTROL_SELECTED
)
2798 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2800 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2801 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2802 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2803 dc
.DrawRectangle(rect
);
2806 // don't draw the focus rect around menu bar items
2807 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2808 wxALIGN_CENTRE
, indexAccel
);
2811 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2813 const wxMenuGeometryInfo
& gi
,
2814 const wxString
& label
,
2815 const wxString
& accel
,
2816 const wxBitmap
& bitmap
,
2820 const wxWin32MenuGeometryInfo
& geometryInfo
=
2821 (const wxWin32MenuGeometryInfo
&)gi
;
2826 rect
.width
= geometryInfo
.GetSize().x
;
2827 rect
.height
= geometryInfo
.GetItemHeight();
2829 // draw the selected item specially
2830 wxDCTextColourChanger
colChanger(dc
);
2831 if ( flags
& wxCONTROL_SELECTED
)
2833 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2835 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2836 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2837 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2838 dc
.DrawRectangle(rect
);
2841 // draw the bitmap: use the bitmap provided or the standard checkmark for
2842 // the checkable items
2843 wxBitmap bmp
= bitmap
;
2844 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2846 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2851 rect
.SetRight(geometryInfo
.GetLabelOffset());
2852 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2856 rect
.x
= geometryInfo
.GetLabelOffset();
2857 rect
.SetRight(geometryInfo
.GetAccelOffset());
2859 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2861 // draw the accel string
2862 rect
.x
= geometryInfo
.GetAccelOffset();
2863 rect
.SetRight(geometryInfo
.GetSize().x
);
2865 // NB: no accel index here
2866 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2868 // draw the submenu indicator
2869 if ( flags
& wxCONTROL_ISSUBMENU
)
2871 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2872 rect
.width
= MENU_RIGHT_MARGIN
;
2874 wxArrowStyle arrowStyle
;
2875 if ( flags
& wxCONTROL_DISABLED
)
2876 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2878 else if ( flags
& wxCONTROL_SELECTED
)
2879 arrowStyle
= Arrow_Inversed
;
2881 arrowStyle
= Arrow_Normal
;
2883 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2887 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2889 const wxMenuGeometryInfo
& geomInfo
)
2891 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2894 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2896 wxSize size
= sizeText
;
2898 // FIXME: menubar height is configurable under Windows
2905 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2906 const wxMenu
& menu
) const
2908 // prepare the dc: for now we draw all the items with the system font
2910 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2912 // the height of a normal item
2913 wxCoord heightText
= dc
.GetCharHeight();
2918 // the max length of label and accel strings: the menu width is the sum of
2919 // them, even if they're for different items (as the accels should be
2922 // the max length of the bitmap is never 0 as Windows always leaves enough
2923 // space for a check mark indicator
2924 wxCoord widthLabelMax
= 0,
2926 widthBmpMax
= MENU_LEFT_MARGIN
;
2928 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2930 node
= node
->GetNext() )
2932 // height of this item
2935 wxMenuItem
*item
= node
->GetData();
2936 if ( item
->IsSeparator() )
2938 h
= MENU_SEPARATOR_HEIGHT
;
2940 else // not separator
2945 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2946 if ( widthLabel
> widthLabelMax
)
2948 widthLabelMax
= widthLabel
;
2952 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2953 if ( widthAccel
> widthAccelMax
)
2955 widthAccelMax
= widthAccel
;
2958 const wxBitmap
& bmp
= item
->GetBitmap();
2961 wxCoord widthBmp
= bmp
.GetWidth();
2962 if ( widthBmp
> widthBmpMax
)
2963 widthBmpMax
= widthBmp
;
2965 //else if ( item->IsCheckable() ): no need to check for this as
2966 // MENU_LEFT_MARGIN is big enough to show the check mark
2969 h
+= 2*MENU_VERT_MARGIN
;
2971 // remember the item position and height
2972 item
->SetGeometry(height
, h
);
2977 // bundle the metrics into a struct and return it
2978 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2980 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2981 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2982 if ( widthAccelMax
> 0 )
2984 // if we actually have any accesl, add a margin
2985 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2988 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2990 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2991 gi
->m_size
.y
= height
;
2996 // ----------------------------------------------------------------------------
2998 // ----------------------------------------------------------------------------
3000 static const wxCoord STATBAR_BORDER_X
= 2;
3001 static const wxCoord STATBAR_BORDER_Y
= 2;
3003 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3005 if ( borderBetweenFields
)
3006 *borderBetweenFields
= 2;
3008 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3011 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3013 const wxString
& label
,
3018 if ( flags
& wxCONTROL_ISDEFAULT
)
3020 // draw the size grip: it is a normal rect except that in the lower
3021 // right corner we have several bands which may be used for dragging
3022 // the status bar corner
3024 // each band consists of 4 stripes: m_penHighlight, double
3025 // m_penDarkGrey and transparent one
3026 wxCoord x2
= rect
.GetRight(),
3027 y2
= rect
.GetBottom();
3029 // draw the upper left part of the rect normally
3030 dc
.SetPen(m_penDarkGrey
);
3031 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3032 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3034 // draw the grey stripes of the grip
3036 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3037 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3039 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3040 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3043 // draw the white stripes
3044 dc
.SetPen(m_penHighlight
);
3045 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3046 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3048 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3051 // draw the remaining rect boundaries
3052 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3053 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3054 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3059 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3063 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3066 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3068 wxDCClipper
clipper(dc
, rectIn
);
3069 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3072 // ----------------------------------------------------------------------------
3074 // ----------------------------------------------------------------------------
3076 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3078 wxBitmap
*bmpPressed
,
3079 wxBitmap
*bmpDisabled
)
3081 static const wxCoord widthCombo
= 16;
3082 static const wxCoord heightCombo
= 17;
3088 bmpNormal
->Create(widthCombo
, heightCombo
);
3089 dcMem
.SelectObject(*bmpNormal
);
3090 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3091 Arrow_Down
, Arrow_Normal
);
3096 bmpPressed
->Create(widthCombo
, heightCombo
);
3097 dcMem
.SelectObject(*bmpPressed
);
3098 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3099 Arrow_Down
, Arrow_Pressed
);
3104 bmpDisabled
->Create(widthCombo
, heightCombo
);
3105 dcMem
.SelectObject(*bmpDisabled
);
3106 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3107 Arrow_Down
, Arrow_Disabled
);
3111 // ----------------------------------------------------------------------------
3113 // ----------------------------------------------------------------------------
3115 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3116 const wxColour
& col
,
3119 wxBrush
brush(col
, wxSOLID
);
3121 dc
.SetPen(*wxTRANSPARENT_PEN
);
3122 dc
.DrawRectangle(rect
);
3125 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3126 const wxColour
& col
,
3130 // just fill it with the given or default bg colour
3131 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3132 DoDrawBackground(dc
, colBg
, rect
);
3135 // ----------------------------------------------------------------------------
3137 // ----------------------------------------------------------------------------
3139 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3144 // get the bitmap for this arrow
3145 wxArrowDirection arrowDir
;
3148 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3149 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3150 case wxUP
: arrowDir
= Arrow_Up
; break;
3151 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3154 wxFAIL_MSG(_T("unknown arrow direction"));
3158 wxArrowStyle arrowStyle
;
3159 if ( flags
& wxCONTROL_PRESSED
)
3161 // can't be pressed and disabled
3162 arrowStyle
= Arrow_Pressed
;
3166 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3169 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3172 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3174 wxArrowDirection arrowDir
,
3175 wxArrowStyle arrowStyle
)
3177 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3179 // under Windows the arrows always have the same size so just centre it in
3180 // the provided rectangle
3181 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3182 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3184 // Windows does it like this...
3185 if ( arrowDir
== Arrow_Left
)
3189 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3192 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3193 const wxRect
& rectAll
,
3194 wxArrowDirection arrowDir
,
3195 wxArrowStyle arrowStyle
)
3197 wxRect rect
= rectAll
;
3198 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3199 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3200 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3203 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3204 wxOrientation orient
,
3208 // we don't use the flags, the thumb never changes appearance
3209 wxRect rectThumb
= rect
;
3210 DrawArrowBorder(dc
, &rectThumb
);
3211 DrawBackground(dc
, wxNullColour
, rectThumb
);
3214 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3215 wxOrientation orient
,
3216 const wxRect
& rectBar
,
3219 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3220 ? wxColourScheme::SCROLLBAR_PRESSED
3221 : wxColourScheme::SCROLLBAR
;
3222 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3225 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3227 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3230 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3231 wxScrollBar::Element elem
,
3234 return StandardGetScrollbarRect(scrollbar
, elem
,
3235 thumbPos
, m_sizeScrollbarArrow
);
3238 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3240 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3243 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3244 const wxPoint
& pt
) const
3246 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3249 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3252 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3255 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3258 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3261 // ----------------------------------------------------------------------------
3262 // top level windows
3263 // ----------------------------------------------------------------------------
3265 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3267 wxRect client
= GetFrameClientArea(rect
, flags
);
3269 if ( client
.Inside(pt
) )
3270 return wxHT_TOPLEVEL_CLIENT_AREA
;
3272 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3274 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3276 if ( flags
& wxTOPLEVEL_ICON
)
3278 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3279 return wxHT_TOPLEVEL_ICON
;
3282 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3283 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3284 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3286 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3288 if ( btnRect
.Inside(pt
) )
3289 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3290 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3292 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3294 if ( btnRect
.Inside(pt
) )
3295 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3296 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3298 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3300 if ( btnRect
.Inside(pt
) )
3301 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3302 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3304 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3306 if ( btnRect
.Inside(pt
) )
3307 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3308 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3310 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3312 if ( btnRect
.Inside(pt
) )
3313 return wxHT_TOPLEVEL_BUTTON_HELP
;
3314 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3317 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3318 return wxHT_TOPLEVEL_TITLEBAR
;
3321 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3323 // we are certainly at one of borders, lets decide which one:
3326 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3327 if ( pt
.x
< client
.x
)
3328 border
|= wxHT_TOPLEVEL_BORDER_W
;
3329 else if ( pt
.x
>= client
.width
+ client
.x
)
3330 border
|= wxHT_TOPLEVEL_BORDER_E
;
3331 if ( pt
.y
< client
.y
)
3332 border
|= wxHT_TOPLEVEL_BORDER_N
;
3333 else if ( pt
.y
>= client
.height
+ client
.y
)
3334 border
|= wxHT_TOPLEVEL_BORDER_S
;
3338 return wxHT_NOWHERE
;
3341 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3343 const wxString
& title
,
3347 int specialButtonFlags
)
3349 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3351 DrawFrameBorder(dc
, rect
, flags
);
3353 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3355 DrawFrameBackground(dc
, rect
, flags
);
3356 if ( flags
& wxTOPLEVEL_ICON
)
3357 DrawFrameIcon(dc
, rect
, icon
, flags
);
3358 DrawFrameTitle(dc
, rect
, title
, flags
);
3360 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3362 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3363 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3365 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3367 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3368 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3369 specialButtonFlags
: 0);
3370 x
-= FRAME_BUTTON_WIDTH
+ 2;
3372 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3374 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3375 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3376 specialButtonFlags
: 0);
3377 x
-= FRAME_BUTTON_WIDTH
;
3379 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3381 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3382 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3383 specialButtonFlags
: 0);
3384 x
-= FRAME_BUTTON_WIDTH
;
3386 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3388 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3389 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3390 specialButtonFlags
: 0);
3391 x
-= FRAME_BUTTON_WIDTH
;
3393 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3395 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3396 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3397 specialButtonFlags
: 0);
3398 x
-= FRAME_BUTTON_WIDTH
;
3403 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3407 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3411 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3412 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3413 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3414 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3415 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3418 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3422 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3424 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3425 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3426 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3428 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3429 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3431 DrawBackground(dc
, col
, r
);
3434 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3436 const wxString
& title
,
3439 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3440 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3441 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3443 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3444 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3445 if ( flags
& wxTOPLEVEL_ICON
)
3447 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3448 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3456 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3457 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3458 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3459 r
.width
-= FRAME_BUTTON_WIDTH
;
3460 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3461 r
.width
-= FRAME_BUTTON_WIDTH
;
3462 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3463 r
.width
-= FRAME_BUTTON_WIDTH
;
3464 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3465 r
.width
-= FRAME_BUTTON_WIDTH
;
3467 dc
.SetFont(m_titlebarFont
);
3468 dc
.SetTextForeground(col
);
3471 dc
.GetTextExtent(title
, &textW
, NULL
);
3472 if ( textW
> r
.width
)
3474 // text is too big, let's shorten it and add "..." after it:
3475 size_t len
= title
.length();
3476 wxCoord WSoFar
, letterW
;
3478 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3479 if ( WSoFar
> r
.width
)
3481 // not enough space to draw anything
3487 for (size_t i
= 0; i
< len
; i
++)
3489 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3490 if ( letterW
+ WSoFar
> r
.width
)
3496 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3497 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3500 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3501 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3504 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3511 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3512 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3516 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3517 wxCoord x
, wxCoord y
,
3521 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3526 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3527 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3528 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3529 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3530 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3532 wxFAIL_MSG(wxT("incorrect button specification"));
3535 if ( flags
& wxCONTROL_PRESSED
)
3537 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3538 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3539 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3540 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3544 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3545 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3546 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3547 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3552 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3557 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3559 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3560 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3561 FRAME_BORDER_THICKNESS
;
3564 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3566 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3567 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3573 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3576 wxSize
s(clientSize
);
3578 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3580 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3581 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3582 FRAME_BORDER_THICKNESS
;
3586 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3587 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3592 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3596 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3598 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3599 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3600 FRAME_BORDER_THICKNESS
;
3605 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3607 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3609 if ( flags
& wxTOPLEVEL_ICON
)
3610 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3611 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3612 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3613 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3614 s
.x
+= FRAME_BUTTON_WIDTH
;
3615 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3616 s
.x
+= FRAME_BUTTON_WIDTH
;
3617 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3618 s
.x
+= FRAME_BUTTON_WIDTH
;
3619 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3620 s
.x
+= FRAME_BUTTON_WIDTH
;
3626 wxSize
wxWin32Renderer::GetFrameIconSize() const
3628 return wxSize(16, 16);
3632 // ----------------------------------------------------------------------------
3634 // ----------------------------------------------------------------------------
3636 static char *error_xpm
[]={
3643 "...........########.............",
3644 "........###aaaaaaaa###..........",
3645 ".......#aaaaaaaaaaaaaa#.........",
3646 ".....##aaaaaaaaaaaaaaaa##.......",
3647 "....#aaaaaaaaaaaaaaaaaaaa#......",
3648 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3649 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3650 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3651 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3652 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3653 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3654 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3655 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3656 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3657 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3658 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3659 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3660 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3661 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3662 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3663 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3664 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3665 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3666 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3667 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3668 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3669 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3670 "......b#aaaaaaaaaaaaaa#bbbbb....",
3671 ".......b###aaaaaaaa###bbbbb.....",
3672 ".........bb########bbbbbb.......",
3673 "..........bbbbbbbbbbbbbb........",
3674 ".............bbbbbbbb..........."};
3676 static char *info_xpm
[]={
3684 "...........########.............",
3685 "........###abbbbbba###..........",
3686 "......##abbbbbbbbbbbba##........",
3687 ".....#abbbbbbbbbbbbbbbba#.......",
3688 "....#bbbbbbbaccccabbbbbbbd......",
3689 "...#bbbbbbbbccccccbbbbbbbbd.....",
3690 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3691 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3692 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3693 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3694 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3695 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3696 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3697 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3698 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3699 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3700 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3701 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3702 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3703 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3704 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3705 ".....dabbbbbbbbbbbbbbbbad####...",
3706 "......ddabbbbbbbbbbbbadd####....",
3707 ".......#dddabbbbbbaddd#####.....",
3708 "........###dddabbbd#######......",
3709 "..........####dbbbd#####........",
3710 ".............#dbbbd##...........",
3711 "...............dbbd##...........",
3712 "................dbd##...........",
3713 ".................dd##...........",
3714 "..................###...........",
3715 "...................##..........."};
3717 static char *question_xpm
[]={
3725 "...........########.............",
3726 "........###abbbbbba###..........",
3727 "......##abbbbbbbbbbbba##........",
3728 ".....#abbbbbbbbbbbbbbbba#.......",
3729 "....#bbbbbbbbbbbbbbbbbbbbc......",
3730 "...#bbbbbbbaddddddabbbbbbbc.....",
3731 "..#bbbbbbbadabbddddabbbbbbbc....",
3732 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3733 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3734 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3735 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3736 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3737 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3738 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3739 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3740 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3741 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3742 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3743 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3744 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3745 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3746 ".....cabbbbbbbbbbbbbbbbac####...",
3747 "......ccabbbbbbbbbbbbacc####....",
3748 ".......#cccabbbbbbaccc#####.....",
3749 "........###cccabbbc#######......",
3750 "..........####cbbbc#####........",
3751 ".............#cbbbc##...........",
3752 "...............cbbc##...........",
3753 "................cbc##...........",
3754 ".................cc##...........",
3755 "..................###...........",
3756 "...................##..........."};
3758 static char *warning_xpm
[]={
3766 ".............###................",
3767 "............#aabc...............",
3768 "...........#aaaabcd.............",
3769 "...........#aaaaacdd............",
3770 "..........#aaaaaabcdd...........",
3771 "..........#aaaaaaacdd...........",
3772 ".........#aaaaaaaabcdd..........",
3773 ".........#aaaaaaaaacdd..........",
3774 "........#aaaaaaaaaabcdd.........",
3775 "........#aaabcccbaaacdd.........",
3776 ".......#aaaacccccaaabcdd........",
3777 ".......#aaaacccccaaaacdd........",
3778 "......#aaaaacccccaaaabcdd.......",
3779 "......#aaaaacccccaaaaacdd.......",
3780 ".....#aaaaaacccccaaaaabcdd......",
3781 ".....#aaaaaa#ccc#aaaaaacdd......",
3782 "....#aaaaaaabcccbaaaaaabcdd.....",
3783 "....#aaaaaaaacccaaaaaaaacdd.....",
3784 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3785 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3786 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3787 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3788 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3789 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3790 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3791 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3792 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3793 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3794 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3795 "..#ccccccccccccccccccccccccddddd",
3796 "....ddddddddddddddddddddddddddd.",
3797 ".....ddddddddddddddddddddddddd.."};
3799 wxIcon
wxWin32Renderer::GetStdIcon(int which
) const
3803 case wxICON_INFORMATION
:
3804 return wxIcon(info_xpm
);
3806 case wxICON_QUESTION
:
3807 return wxIcon(question_xpm
);
3809 case wxICON_EXCLAMATION
:
3810 return wxIcon(warning_xpm
);
3813 wxFAIL_MSG(wxT("requested non existent standard icon"));
3814 // still fall through
3817 return wxIcon(error_xpm
);
3822 // ----------------------------------------------------------------------------
3823 // text control geometry
3824 // ----------------------------------------------------------------------------
3826 static inline int GetTextBorderWidth()
3831 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3834 wxRect rectTotal
= rect
;
3836 wxCoord widthBorder
= GetTextBorderWidth();
3837 rectTotal
.Inflate(widthBorder
);
3839 // this is what Windows does
3845 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3847 wxCoord
*extraSpaceBeyond
)
3849 wxRect rectText
= rect
;
3851 // undo GetTextTotalArea()
3852 if ( rectText
.height
> 0 )
3855 wxCoord widthBorder
= GetTextBorderWidth();
3856 rectText
.Inflate(-widthBorder
);
3858 if ( extraSpaceBeyond
)
3859 *extraSpaceBeyond
= 0;
3864 // ----------------------------------------------------------------------------
3866 // ----------------------------------------------------------------------------
3868 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3871 if ( wxDynamicCast(window
, wxScrollBar
) )
3873 // we only set the width of vert scrollbars and height of the
3875 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3876 size
->y
= m_sizeScrollbarArrow
.y
;
3878 size
->x
= m_sizeScrollbarArrow
.x
;
3880 // skip border width adjustments, they don't make sense for us
3883 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3886 if ( wxDynamicCast(window
, wxButton
) )
3888 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3890 // TODO: don't harcode all this
3891 size
->x
+= 3*window
->GetCharWidth();
3893 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3894 if ( size
->y
< heightBtn
- 8 )
3895 size
->y
= heightBtn
;
3900 // no border width adjustments for buttons
3903 #endif // wxUSE_BUTTON
3905 // take into account the border width
3906 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3907 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3908 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3911 // ============================================================================
3913 // ============================================================================
3915 // ----------------------------------------------------------------------------
3916 // wxWin32InputHandler
3917 // ----------------------------------------------------------------------------
3919 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3921 m_renderer
= renderer
;
3924 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3925 const wxKeyEvent
& event
,
3931 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3932 const wxMouseEvent
& event
)
3934 // clicking on the control gives it focus
3935 if ( event
.ButtonDown() )
3937 wxWindow
*win
= control
->GetInputWindow();
3939 if ( wxWindow::FindFocus() != control
->GetInputWindow() )
3950 // ----------------------------------------------------------------------------
3951 // wxWin32ScrollBarInputHandler
3952 // ----------------------------------------------------------------------------
3954 wxWin32ScrollBarInputHandler::
3955 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3956 wxInputHandler
*handler
)
3957 : wxStdScrollBarInputHandler(renderer
, handler
)
3959 m_scrollPaused
= FALSE
;
3963 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3964 const wxControlAction
& action
)
3966 // stop if went beyond the position of the original click (this can only
3967 // happen when we scroll by pages)
3969 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3971 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3972 != wxHT_SCROLLBAR_BAR_2
;
3974 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3976 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3977 != wxHT_SCROLLBAR_BAR_1
;
3982 StopScrolling(scrollbar
);
3984 scrollbar
->Refresh();
3989 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3992 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3993 const wxMouseEvent
& event
)
3995 // remember the current state
3996 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3998 // do process the message
3999 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4001 // analyse the changes
4002 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4004 // we just started dragging the thumb, remember its initial position to
4005 // be able to restore it if the drag is cancelled later
4006 m_eventStartDrag
= event
;
4012 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4013 const wxMouseEvent
& event
)
4015 // we don't highlight scrollbar elements, so there is no need to process
4016 // mouse move events normally - only do it while mouse is captured (i.e.
4017 // when we're dragging the thumb or pressing on something)
4018 if ( !m_winCapture
)
4021 if ( event
.Entering() )
4023 // we're not interested in this at all
4027 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4029 if ( m_scrollPaused
)
4031 // check if the mouse returned to its original location
4033 if ( event
.Leaving() )
4039 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4040 if ( ht
== m_htLast
)
4042 // yes it did, resume scrolling
4043 m_scrollPaused
= FALSE
;
4044 if ( m_timerScroll
)
4046 // we were scrolling by line/page, restart timer
4047 m_timerScroll
->Start(m_interval
);
4049 Press(scrollbar
, TRUE
);
4051 else // we were dragging the thumb
4053 // restore its last location
4054 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4060 else // normal case, scrolling hasn't been paused
4062 // if we're scrolling the scrollbar because the arrow or the shaft was
4063 // pressed, check that the mouse stays on the same scrollbar element
4065 if ( event
.Moving() )
4067 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4069 else // event.Leaving()
4074 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4075 // is still ok - we only want to catch the case when the mouse leaves
4076 // the scrollbar here
4077 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4079 ht
= wxHT_SCROLLBAR_THUMB
;
4082 if ( ht
!= m_htLast
)
4084 // what were we doing? 2 possibilities: either an arrow/shaft was
4085 // pressed in which case we have a timer and so we just stop it or
4086 // we were dragging the thumb
4087 if ( m_timerScroll
)
4090 m_interval
= m_timerScroll
->GetInterval();
4091 m_timerScroll
->Stop();
4092 m_scrollPaused
= TRUE
;
4094 // unpress the arrow
4095 Press(scrollbar
, FALSE
);
4097 else // we were dragging the thumb
4099 // remember the current thumb position to be able to restore it
4100 // if the mouse returns to it later
4101 m_eventLastDrag
= event
;
4103 // and restore the original position (before dragging) of the
4105 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4112 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4115 // ----------------------------------------------------------------------------
4116 // wxWin32CheckboxInputHandler
4117 // ----------------------------------------------------------------------------
4119 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4120 const wxKeyEvent
& event
,
4125 wxControlAction action
;
4126 int keycode
= event
.GetKeyCode();
4130 action
= wxACTION_CHECKBOX_TOGGLE
;
4134 case WXK_NUMPAD_SUBTRACT
:
4135 action
= wxACTION_CHECKBOX_CHECK
;
4139 case WXK_NUMPAD_ADD
:
4140 case WXK_NUMPAD_EQUAL
:
4141 action
= wxACTION_CHECKBOX_CLEAR
;
4147 control
->PerformAction(action
);
4156 // ----------------------------------------------------------------------------
4157 // wxWin32TextCtrlInputHandler
4158 // ----------------------------------------------------------------------------
4160 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4161 const wxKeyEvent
& event
,
4164 // handle only MSW-specific text bindings here, the others are handled in
4168 int keycode
= event
.GetKeyCode();
4170 wxControlAction action
;
4171 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4173 action
= wxACTION_TEXT_CUT
;
4175 else if ( keycode
== WXK_INSERT
)
4177 if ( event
.ControlDown() )
4178 action
= wxACTION_TEXT_COPY
;
4179 else if ( event
.ShiftDown() )
4180 action
= wxACTION_TEXT_PASTE
;
4183 if ( action
!= wxACTION_NONE
)
4185 control
->PerformAction(action
);
4191 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4194 // ----------------------------------------------------------------------------
4195 // wxWin32StatusBarInputHandler
4196 // ----------------------------------------------------------------------------
4198 wxWin32StatusBarInputHandler::
4199 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4200 : wxStdInputHandler(handler
)
4205 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4206 const wxPoint
& pt
) const
4208 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4209 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4212 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4214 wxCHECK_MSG( parentTLW
, FALSE
,
4215 _T("the status bar should be a child of a TLW") );
4217 // a maximized window can't be resized anyhow
4218 if ( !parentTLW
->IsMaximized() )
4220 // VZ: I think that the standard Windows behaviour is to only
4221 // show the resizing cursor when the mouse is on top of the
4222 // grip itself but apparently different Windows versions behave
4223 // differently (?) and it seems a better UI to allow resizing
4224 // the status bar even when the mouse is above the grip
4225 wxSize sizeSbar
= statbar
->GetSize();
4227 int diff
= sizeSbar
.x
- pt
.x
;
4228 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4235 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4236 const wxMouseEvent
& event
)
4238 if ( event
.Button(1) )
4240 if ( event
.ButtonDown(1) )
4242 wxWindow
*statbar
= consumer
->GetInputWindow();
4244 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4246 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4250 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4251 wxHT_TOPLEVEL_BORDER_SE
);
4253 statbar
->SetCursor(m_cursorOld
);
4261 return wxStdInputHandler::HandleMouse(consumer
, event
);
4264 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4265 const wxMouseEvent
& event
)
4267 wxWindow
*statbar
= consumer
->GetInputWindow();
4269 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4270 if ( isOnGrip
!= m_isOnGrip
)
4272 m_isOnGrip
= isOnGrip
;
4275 m_cursorOld
= statbar
->GetCursor();
4276 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4280 statbar
->SetCursor(m_cursorOld
);
4284 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4287 // ----------------------------------------------------------------------------
4288 // wxWin32FrameInputHandler
4289 // ----------------------------------------------------------------------------
4291 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4292 const wxMouseEvent
& event
)
4294 if ( event
.LeftDClick() )
4296 wxTopLevelWindow
*tlw
=
4297 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4299 long hit
= tlw
->HitTest(event
.GetPosition());
4301 if ( hit
== wxHT_TOPLEVEL_TITLEBAR
)
4303 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4304 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4305 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4310 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);