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"
41 #include "wx/toolbar.h"
44 // for COLOR_* constants
45 #include "wx/msw/private.h"
49 #include "wx/notebook.h"
50 #include "wx/spinbutt.h"
51 #include "wx/settings.h"
54 #include "wx/univ/scrtimer.h"
55 #include "wx/toplevel.h"
56 #include "wx/univ/renderer.h"
57 #include "wx/univ/inphand.h"
58 #include "wx/univ/colschem.h"
59 #include "wx/univ/theme.h"
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 static const int BORDER_THICKNESS
= 2;
67 // the offset between the label and focus rect around it
68 static const int FOCUS_RECT_OFFSET_X
= 1;
69 static const int FOCUS_RECT_OFFSET_Y
= 1;
71 static const int FRAME_BORDER_THICKNESS
= 3;
72 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
73 static const int FRAME_TITLEBAR_HEIGHT
= 18;
74 static const int FRAME_BUTTON_WIDTH
= 16;
75 static const int FRAME_BUTTON_HEIGHT
= 14;
77 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
78 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
79 static const size_t STATUSBAR_GRIP_SIZE
=
80 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
92 IndicatorState_Normal
,
93 IndicatorState_Pressed
, // this one is for check/radioboxes
94 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
95 IndicatorState_Disabled
,
96 IndicatorState_SelectedDisabled
, // only for the menus
102 IndicatorStatus_Checked
,
103 IndicatorStatus_Unchecked
,
107 // wxWin32Renderer: draw the GUI elements in Win32 style
108 // ----------------------------------------------------------------------------
110 class wxWin32Renderer
: public wxRenderer
114 enum wxArrowDirection
129 Arrow_InversedDisabled
,
133 enum wxFrameButtonType
136 FrameButton_Minimize
,
137 FrameButton_Maximize
,
144 wxWin32Renderer(const wxColourScheme
*scheme
);
146 // implement the base class pure virtuals
147 virtual void DrawBackground(wxDC
& dc
,
151 virtual void DrawLabel(wxDC
& dc
,
152 const wxString
& label
,
155 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
157 wxRect
*rectBounds
= NULL
);
158 virtual void DrawButtonLabel(wxDC
& dc
,
159 const wxString
& label
,
160 const wxBitmap
& image
,
163 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
165 wxRect
*rectBounds
= NULL
);
166 virtual void DrawBorder(wxDC
& dc
,
170 wxRect
*rectIn
= (wxRect
*)NULL
);
171 virtual void DrawHorizontalLine(wxDC
& dc
,
172 wxCoord y
, wxCoord x1
, wxCoord x2
);
173 virtual void DrawVerticalLine(wxDC
& dc
,
174 wxCoord x
, wxCoord y1
, wxCoord y2
);
175 virtual void DrawFrame(wxDC
& dc
,
176 const wxString
& label
,
179 int alignment
= wxALIGN_LEFT
,
180 int indexAccel
= -1);
181 virtual void DrawTextBorder(wxDC
& dc
,
185 wxRect
*rectIn
= (wxRect
*)NULL
);
186 virtual void DrawButtonBorder(wxDC
& dc
,
189 wxRect
*rectIn
= (wxRect
*)NULL
);
190 virtual void DrawArrow(wxDC
& dc
,
194 virtual void DrawScrollbarArrow(wxDC
& dc
,
198 { DrawArrow(dc
, dir
, rect
, flags
); }
199 virtual void DrawScrollbarThumb(wxDC
& dc
,
200 wxOrientation orient
,
203 virtual void DrawScrollbarShaft(wxDC
& dc
,
204 wxOrientation orient
,
207 virtual void DrawScrollCorner(wxDC
& dc
,
209 virtual void DrawItem(wxDC
& dc
,
210 const wxString
& label
,
213 virtual void DrawCheckItem(wxDC
& dc
,
214 const wxString
& label
,
215 const wxBitmap
& bitmap
,
218 virtual void DrawCheckButton(wxDC
& dc
,
219 const wxString
& label
,
220 const wxBitmap
& bitmap
,
223 wxAlignment align
= wxALIGN_LEFT
,
224 int indexAccel
= -1);
225 virtual void DrawRadioButton(wxDC
& dc
,
226 const wxString
& label
,
227 const wxBitmap
& bitmap
,
230 wxAlignment align
= wxALIGN_LEFT
,
231 int indexAccel
= -1);
232 virtual void DrawToolBarButton(wxDC
& dc
,
233 const wxString
& label
,
234 const wxBitmap
& bitmap
,
237 virtual void DrawTextLine(wxDC
& dc
,
238 const wxString
& text
,
243 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
244 virtual void DrawTab(wxDC
& dc
,
247 const wxString
& label
,
248 const wxBitmap
& bitmap
= wxNullBitmap
,
250 int indexAccel
= -1);
252 virtual void DrawSliderShaft(wxDC
& dc
,
254 wxOrientation orient
,
256 wxRect
*rectShaft
= NULL
);
257 virtual void DrawSliderThumb(wxDC
& dc
,
259 wxOrientation orient
,
261 virtual void DrawSliderTicks(wxDC
& dc
,
263 const wxSize
& sizeThumb
,
264 wxOrientation orient
,
270 virtual void DrawMenuBarItem(wxDC
& dc
,
272 const wxString
& label
,
274 int indexAccel
= -1);
275 virtual void DrawMenuItem(wxDC
& dc
,
277 const wxMenuGeometryInfo
& geometryInfo
,
278 const wxString
& label
,
279 const wxString
& accel
,
280 const wxBitmap
& bitmap
= wxNullBitmap
,
282 int indexAccel
= -1);
283 virtual void DrawMenuSeparator(wxDC
& dc
,
285 const wxMenuGeometryInfo
& geomInfo
);
287 virtual void DrawStatusField(wxDC
& dc
,
289 const wxString
& label
,
293 virtual void DrawFrameTitleBar(wxDC
& dc
,
295 const wxString
& title
,
298 int specialButton
= 0,
299 int specialButtonFlags
= 0);
300 virtual void DrawFrameBorder(wxDC
& dc
,
303 virtual void DrawFrameBackground(wxDC
& dc
,
306 virtual void DrawFrameTitle(wxDC
& dc
,
308 const wxString
& title
,
310 virtual void DrawFrameIcon(wxDC
& dc
,
314 virtual void DrawFrameButton(wxDC
& dc
,
315 wxCoord x
, wxCoord y
,
318 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
319 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
320 virtual wxSize
GetFrameMinSize(int flags
) const;
321 virtual wxSize
GetFrameIconSize() const;
322 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
324 virtual wxIcon
GetStdIcon(int which
) const;
326 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
328 wxBitmap
*bmpPressed
,
329 wxBitmap
*bmpDisabled
);
331 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
332 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
333 virtual bool AreScrollbarsInsideBorder() const;
335 virtual wxSize
GetScrollbarArrowSize() const
336 { return m_sizeScrollbarArrow
; }
337 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
338 wxScrollBar::Element elem
,
339 int thumbPos
= -1) const;
340 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
341 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
342 const wxPoint
& pt
) const;
343 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
345 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
346 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
347 { return fontHeight
+ 2; }
348 virtual wxSize
GetCheckBitmapSize() const
349 { return wxSize(13, 13); }
350 virtual wxSize
GetRadioBitmapSize() const
351 { return wxSize(12, 12); }
352 virtual wxCoord
GetCheckItemMargin() const
355 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
356 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
357 virtual wxSize
GetToolBarMargin() const
358 { return wxSize(6, 6); }
360 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
361 const wxRect
& rect
) const;
362 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
364 wxCoord
*extraSpaceBeyond
) const;
366 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
367 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
369 virtual wxCoord
GetSliderDim() const { return 20; }
370 virtual wxCoord
GetSliderTickLen() const { return 4; }
371 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
372 wxOrientation orient
) const;
373 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
374 wxOrientation orient
) const;
375 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
377 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
378 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
379 const wxMenu
& menu
) const;
381 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
384 // helper of DrawLabel() and DrawCheckOrRadioButton()
385 void DoDrawLabel(wxDC
& dc
,
386 const wxString
& label
,
389 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
391 wxRect
*rectBounds
= NULL
,
392 const wxPoint
& focusOffset
393 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
395 // common part of DrawLabel() and DrawItem()
396 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
398 // DrawLabel() and DrawButtonLabel() helper
399 void DrawLabelShadow(wxDC
& dc
,
400 const wxString
& label
,
405 // DrawButtonBorder() helper
406 void DoDrawBackground(wxDC
& dc
,
410 // DrawBorder() helpers: all of them shift and clip the DC after drawing
413 // just draw a rectangle with the given pen
414 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
416 // draw the lower left part of rectangle
417 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
419 // draw the rectange using the first brush for the left and top sides and
420 // the second one for the bottom and right ones
421 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
422 const wxPen
& pen1
, const wxPen
& pen2
);
424 // draw the normal 3D border
425 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
427 // draw the sunken 3D border
428 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
430 // draw the border used for scrollbar arrows
431 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
433 // public DrawArrow()s helper
434 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
435 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
437 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
438 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
439 wxArrowDirection arrowDir
,
440 wxArrowStyle arrowStyle
);
442 // DrawCheckButton/DrawRadioButton helper
443 void DrawCheckOrRadioButton(wxDC
& dc
,
444 const wxString
& label
,
445 const wxBitmap
& bitmap
,
450 wxCoord focusOffsetY
);
452 // draw a normal or transposed line (useful for using the same code fo both
453 // horizontal and vertical widgets)
454 void DrawLine(wxDC
& dc
,
455 wxCoord x1
, wxCoord y1
,
456 wxCoord x2
, wxCoord y2
,
457 bool transpose
= FALSE
)
460 dc
.DrawLine(y1
, x1
, y2
, x2
);
462 dc
.DrawLine(x1
, y1
, x2
, y2
);
465 // get the standard check/radio button bitmap
466 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
467 wxBitmap
GetCheckBitmap(int flags
)
468 { return GetIndicator(IndicatorType_Check
, flags
); }
469 wxBitmap
GetRadioBitmap(int flags
)
470 { return GetIndicator(IndicatorType_Radio
, flags
); }
473 const wxColourScheme
*m_scheme
;
475 // the sizing parameters (TODO make them changeable)
476 wxSize m_sizeScrollbarArrow
;
478 // GDI objects we use for drawing
479 wxColour m_colDarkGrey
,
487 wxFont m_titlebarFont
;
489 // the checked and unchecked bitmaps for DrawCheckItem()
490 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
492 // the bitmaps returned by GetIndicator()
493 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
495 [IndicatorStatus_Max
];
498 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
500 // first row is for the normal state, second - for the disabled
501 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
504 // ----------------------------------------------------------------------------
505 // wxWin32InputHandler and derived classes: process the keyboard and mouse
506 // messages according to Windows standards
507 // ----------------------------------------------------------------------------
509 class wxWin32InputHandler
: public wxInputHandler
512 wxWin32InputHandler(wxWin32Renderer
*renderer
);
514 virtual bool HandleKey(wxInputConsumer
*control
,
515 const wxKeyEvent
& event
,
517 virtual bool HandleMouse(wxInputConsumer
*control
,
518 const wxMouseEvent
& event
);
521 wxWin32Renderer
*m_renderer
;
524 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
527 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
528 wxInputHandler
*handler
);
530 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
531 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
533 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
534 const wxControlAction
& action
);
537 virtual bool IsAllowedButton(int button
) { return button
== 1; }
539 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
541 // we don't highlight anything
544 // the first and last event which caused the thumb to move
545 wxMouseEvent m_eventStartDrag
,
548 // have we paused the scrolling because the mouse moved?
551 // we remember the interval of the timer to be able to restart it
555 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
558 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
559 : wxStdCheckboxInputHandler(handler
) { }
561 virtual bool HandleKey(wxInputConsumer
*control
,
562 const wxKeyEvent
& event
,
566 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
569 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
570 : wxStdTextCtrlInputHandler(handler
) { }
572 virtual bool HandleKey(wxInputConsumer
*control
,
573 const wxKeyEvent
& event
,
577 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
580 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
582 virtual bool HandleMouse(wxInputConsumer
*consumer
,
583 const wxMouseEvent
& event
);
585 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
586 const wxMouseEvent
& event
);
589 // is the given point over the statusbar grip?
590 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
593 // the cursor we had replaced with the resize one
594 wxCursor m_cursorOld
;
596 // was the mouse over the grip last time we checked?
600 class wxWin32SystemMenuEvtHandler
;
602 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
605 wxWin32FrameInputHandler(wxInputHandler
*handler
)
606 : wxStdFrameInputHandler(handler
), m_menuHandler(NULL
) { }
608 virtual bool HandleMouse(wxInputConsumer
*control
,
609 const wxMouseEvent
& event
);
611 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
613 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
616 // was the mouse over the grip last time we checked?
617 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
620 // ----------------------------------------------------------------------------
621 // wxWin32ColourScheme: uses (default) Win32 colours
622 // ----------------------------------------------------------------------------
624 class wxWin32ColourScheme
: public wxColourScheme
627 virtual wxColour
Get(StdColour col
) const;
628 virtual wxColour
GetBackground(wxWindow
*win
) const;
631 // ----------------------------------------------------------------------------
633 // ----------------------------------------------------------------------------
635 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
637 class wxWin32Theme
: public wxTheme
641 virtual ~wxWin32Theme();
643 virtual wxRenderer
*GetRenderer();
644 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
645 virtual wxColourScheme
*GetColourScheme();
648 // get the default input handler
649 wxInputHandler
*GetDefaultInputHandler();
651 wxWin32Renderer
*m_renderer
;
653 // the names of the already created handlers and the handlers themselves
654 // (these arrays are synchronized)
655 wxSortedArrayString m_handlerNames
;
656 wxArrayHandlers m_handlers
;
658 wxWin32InputHandler
*m_handlerDefault
;
660 wxWin32ColourScheme
*m_scheme
;
662 WX_DECLARE_THEME(win32
)
665 // ----------------------------------------------------------------------------
667 // ----------------------------------------------------------------------------
669 // frame buttons bitmaps
671 static const char *frame_button_close_xpm
[] = {
686 static const char *frame_button_help_xpm
[] = {
701 static const char *frame_button_maximize_xpm
[] = {
716 static const char *frame_button_minimize_xpm
[] = {
731 static const char *frame_button_restore_xpm
[] = {
748 static const char *checked_menu_xpm
[] = {
749 /* columns rows colors chars-per-pixel */
765 static const char *selected_checked_menu_xpm
[] = {
766 /* columns rows colors chars-per-pixel */
782 static const char *disabled_checked_menu_xpm
[] = {
783 /* columns rows colors chars-per-pixel */
800 static const char *selected_disabled_checked_menu_xpm
[] = {
801 /* columns rows colors chars-per-pixel */
817 // checkbox and radiobox bitmaps below
819 static const char *checked_xpm
[] = {
820 /* columns rows colors chars-per-pixel */
843 static const char *pressed_checked_xpm
[] = {
844 /* columns rows colors chars-per-pixel */
866 static const char *pressed_disabled_checked_xpm
[] = {
867 /* columns rows colors chars-per-pixel */
889 static const char *checked_item_xpm
[] = {
890 /* columns rows colors chars-per-pixel */
911 static const char *unchecked_xpm
[] = {
912 /* columns rows colors chars-per-pixel */
935 static const char *pressed_unchecked_xpm
[] = {
936 /* columns rows colors chars-per-pixel */
958 static const char *unchecked_item_xpm
[] = {
959 /* columns rows colors chars-per-pixel */
979 static const char *checked_radio_xpm
[] = {
980 /* columns rows colors chars-per-pixel */
1003 static const char *pressed_checked_radio_xpm
[] = {
1004 /* columns rows colors chars-per-pixel */
1027 static const char *pressed_disabled_checked_radio_xpm
[] = {
1028 /* columns rows colors chars-per-pixel */
1051 static const char *unchecked_radio_xpm
[] = {
1052 /* columns rows colors chars-per-pixel */
1075 static const char *pressed_unchecked_radio_xpm
[] = {
1076 /* columns rows colors chars-per-pixel */
1099 static const char **
1100 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1105 { checked_xpm
, unchecked_xpm
},
1108 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1111 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1117 { checked_radio_xpm
, unchecked_radio_xpm
},
1120 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1123 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1129 { checked_menu_xpm
, NULL
},
1132 { selected_checked_menu_xpm
, NULL
},
1135 { disabled_checked_menu_xpm
, NULL
},
1137 // disabled selected state
1138 { selected_disabled_checked_menu_xpm
, NULL
},
1142 static const char **xpmChecked
[IndicatorStatus_Max
] =
1148 // ============================================================================
1150 // ============================================================================
1152 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1154 // ----------------------------------------------------------------------------
1156 // ----------------------------------------------------------------------------
1158 wxWin32Theme::wxWin32Theme()
1162 m_handlerDefault
= NULL
;
1165 wxWin32Theme::~wxWin32Theme()
1167 size_t count
= m_handlers
.GetCount();
1168 for ( size_t n
= 0; n
< count
; n
++ )
1170 if ( m_handlers
[n
] != m_handlerDefault
)
1171 delete m_handlers
[n
];
1174 delete m_handlerDefault
;
1180 wxRenderer
*wxWin32Theme::GetRenderer()
1184 m_renderer
= new wxWin32Renderer(GetColourScheme());
1190 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1192 if ( !m_handlerDefault
)
1194 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1197 return m_handlerDefault
;
1200 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1202 wxInputHandler
*handler
;
1203 int n
= m_handlerNames
.Index(control
);
1204 if ( n
== wxNOT_FOUND
)
1206 // create a new handler
1207 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1208 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1209 GetDefaultInputHandler());
1211 else if ( control
== wxINP_HANDLER_BUTTON
)
1212 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1213 #endif // wxUSE_BUTTON
1215 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1216 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1217 #endif // wxUSE_CHECKBOX
1219 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1220 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1221 #endif // wxUSE_COMBOBOX
1223 else if ( control
== wxINP_HANDLER_LISTBOX
)
1224 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1225 #endif // wxUSE_LISTBOX
1226 #if wxUSE_CHECKLISTBOX
1227 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1228 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1229 #endif // wxUSE_CHECKLISTBOX
1231 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1232 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1233 #endif // wxUSE_TEXTCTRL
1235 else if ( control
== wxINP_HANDLER_SLIDER
)
1236 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1237 #endif // wxUSE_SLIDER
1239 else if ( control
== wxINP_HANDLER_SPINBTN
)
1240 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1241 #endif // wxUSE_SPINBTN
1243 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1244 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1245 #endif // wxUSE_NOTEBOOK
1247 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1248 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1249 #endif // wxUSE_STATUSBAR
1251 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1252 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1253 #endif // wxUSE_TOOLBAR
1254 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1255 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1257 handler
= GetDefaultInputHandler();
1259 n
= m_handlerNames
.Add(control
);
1260 m_handlers
.Insert(handler
, n
);
1262 else // we already have it
1264 handler
= m_handlers
[n
];
1270 wxColourScheme
*wxWin32Theme::GetColourScheme()
1274 m_scheme
= new wxWin32ColourScheme
;
1279 // ============================================================================
1280 // wxWin32ColourScheme
1281 // ============================================================================
1283 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1286 if ( win
->UseBgCol() )
1288 // use the user specified colour
1289 col
= win
->GetBackgroundColour();
1292 if ( win
->IsContainerWindow() )
1294 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1297 if ( !text
->IsEnabled() ) // not IsEditable()
1299 //else: execute code below
1304 // doesn't depend on the state
1310 int flags
= win
->GetStateFlags();
1312 // the colour set by the user should be used for the normal state
1313 // and for the states for which we don't have any specific colours
1314 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1316 if ( wxDynamicCast(win
, wxScrollBar
) )
1317 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1327 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1331 // use the system colours under Windows
1332 #if defined(__WXMSW__)
1333 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1335 case CONTROL_PRESSED
:
1336 case CONTROL_CURRENT
:
1337 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1339 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1341 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1342 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1344 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1345 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1347 #if defined(COLOR_3DDKSHADOW)
1348 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1350 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1353 case CONTROL_TEXT_DISABLED
:
1354 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1356 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1358 case CONTROL_TEXT_DISABLED_SHADOW
:
1359 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1361 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1362 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1363 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1364 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1366 case DESKTOP
: return wxColour(0x808000);
1368 // use the standard Windows colours elsewhere
1369 case WINDOW
: return *wxWHITE
;
1371 case CONTROL_PRESSED
:
1372 case CONTROL_CURRENT
:
1373 case CONTROL
: return wxColour(0xc0c0c0);
1375 case CONTROL_TEXT
: return *wxBLACK
;
1377 case SCROLLBAR
: return wxColour(0xe0e0e0);
1378 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1380 case HIGHLIGHT
: return wxColour(0x800000);
1381 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1383 case SHADOW_DARK
: return *wxBLACK
;
1385 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1386 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1388 case SHADOW_IN
: return wxColour(0xc0c0c0);
1390 case CONTROL_TEXT_DISABLED_SHADOW
:
1391 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1393 case TITLEBAR
: return wxColour(0xaeaaae);
1394 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1395 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1396 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1398 case DESKTOP
: return wxColour(0x808000);
1401 case GAUGE
: return Get(HIGHLIGHT
);
1405 wxFAIL_MSG(_T("invalid standard colour"));
1410 // ============================================================================
1412 // ============================================================================
1414 // ----------------------------------------------------------------------------
1416 // ----------------------------------------------------------------------------
1418 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1422 m_sizeScrollbarArrow
= wxSize(16, 16);
1424 // init colours and pens
1425 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1427 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1428 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1430 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1432 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1433 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1435 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1436 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1438 // init the arrow bitmaps
1439 static const size_t ARROW_WIDTH
= 7;
1440 static const size_t ARROW_LENGTH
= 4;
1443 wxMemoryDC dcNormal
,
1446 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1448 bool isVertical
= n
> Arrow_Right
;
1461 // disabled arrow is larger because of the shadow
1462 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1463 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1465 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1466 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1468 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1469 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1473 dcNormal
.SetPen(m_penBlack
);
1474 dcDisabled
.SetPen(m_penDarkGrey
);
1476 // calculate the position of the point of the arrow
1480 x1
= (ARROW_WIDTH
- 1)/2;
1481 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1485 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1486 y1
= (ARROW_WIDTH
- 1)/2;
1497 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1499 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1500 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1507 if ( n
== Arrow_Up
)
1518 else // left or right arrow
1523 if ( n
== Arrow_Left
)
1536 // draw the shadow for the disabled one
1537 dcDisabled
.SetPen(m_penHighlight
);
1542 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1546 x1
= ARROW_LENGTH
- 1;
1547 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1550 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1551 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1556 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1560 x1
= ARROW_WIDTH
- 1;
1562 x2
= (ARROW_WIDTH
- 1)/2;
1564 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1565 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1570 // create the inversed bitmap but only for the right arrow as we only
1571 // use it for the menus
1572 if ( n
== Arrow_Right
)
1574 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1575 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1577 dcInverse
.Blit(0, 0, w
, h
,
1580 dcInverse
.SelectObject(wxNullBitmap
);
1582 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1583 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1585 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1586 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1588 dcInverse
.Blit(0, 0, w
, h
,
1591 dcInverse
.SelectObject(wxNullBitmap
);
1593 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1594 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1597 dcNormal
.SelectObject(wxNullBitmap
);
1598 dcDisabled
.SelectObject(wxNullBitmap
);
1600 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1601 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1602 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1603 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1605 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1608 // init the frame buttons bitmaps
1609 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1610 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1611 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1612 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1613 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1616 // ----------------------------------------------------------------------------
1618 // ----------------------------------------------------------------------------
1621 The raised border in Win32 looks like this:
1623 IIIIIIIIIIIIIIIIIIIIIIB
1625 I GB I = white (HILIGHT)
1626 I GB H = light grey (LIGHT)
1627 I GB G = dark grey (SHADOI)
1628 I GB B = black (DKSHADOI)
1629 I GB I = hIghlight (COLOR_3DHILIGHT)
1631 IGGGGGGGGGGGGGGGGGGGGGB
1632 BBBBBBBBBBBBBBBBBBBBBBB
1634 The sunken border looks like this:
1636 GGGGGGGGGGGGGGGGGGGGGGI
1637 GBBBBBBBBBBBBBBBBBBBBHI
1644 GHHHHHHHHHHHHHHHHHHHHHI
1645 IIIIIIIIIIIIIIIIIIIIIII
1647 The static border (used for the controls which don't get focus) is like
1650 GGGGGGGGGGGGGGGGGGGGGGW
1658 WWWWWWWWWWWWWWWWWWWWWWW
1660 The most complicated is the double border:
1662 HHHHHHHHHHHHHHHHHHHHHHB
1663 HWWWWWWWWWWWWWWWWWWWWGB
1664 HWHHHHHHHHHHHHHHHHHHHGB
1669 HWHHHHHHHHHHHHHHHHHHHGB
1670 HGGGGGGGGGGGGGGGGGGGGGB
1671 BBBBBBBBBBBBBBBBBBBBBBB
1673 And the simple border is, well, simple:
1675 BBBBBBBBBBBBBBBBBBBBBBB
1684 BBBBBBBBBBBBBBBBBBBBBBB
1687 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1691 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1692 dc
.DrawRectangle(*rect
);
1698 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1700 // draw the bottom and right sides
1702 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1703 rect
->GetRight() + 1, rect
->GetBottom());
1704 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1705 rect
->GetRight(), rect
->GetBottom());
1712 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1713 const wxPen
& pen1
, const wxPen
& pen2
)
1715 // draw the rectangle
1717 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1718 rect
->GetLeft(), rect
->GetBottom());
1719 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1720 rect
->GetRight(), rect
->GetTop());
1722 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1723 rect
->GetRight(), rect
->GetBottom());
1724 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1725 rect
->GetRight() + 1, rect
->GetBottom());
1731 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1733 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1734 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1737 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1739 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1740 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1743 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1747 DrawRect(dc
, rect
, m_penDarkGrey
);
1749 // the arrow is usually drawn inside border of width 2 and is offset by
1750 // another pixel in both directions when it's pressed - as the border
1751 // in this case is more narrow as well, we have to adjust rect like
1759 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1760 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1764 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1766 const wxRect
& rectTotal
,
1767 int WXUNUSED(flags
),
1772 wxRect rect
= rectTotal
;
1776 case wxBORDER_SUNKEN
:
1777 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1779 DrawSunkenBorder(dc
, &rect
);
1783 case wxBORDER_STATIC
:
1784 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1787 case wxBORDER_RAISED
:
1788 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1790 DrawRaisedBorder(dc
, &rect
);
1794 case wxBORDER_DOUBLE
:
1795 DrawArrowBorder(dc
, &rect
);
1796 DrawRect(dc
, &rect
, m_penLightGrey
);
1799 case wxBORDER_SIMPLE
:
1800 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1802 DrawRect(dc
, &rect
, m_penBlack
);
1807 wxFAIL_MSG(_T("unknown border type"));
1810 case wxBORDER_DEFAULT
:
1819 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1824 case wxBORDER_RAISED
:
1825 case wxBORDER_SUNKEN
:
1826 width
= BORDER_THICKNESS
;
1829 case wxBORDER_SIMPLE
:
1830 case wxBORDER_STATIC
:
1834 case wxBORDER_DOUBLE
:
1839 wxFAIL_MSG(_T("unknown border type"));
1842 case wxBORDER_DEFAULT
:
1852 rect
.height
= width
;
1857 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1862 // ----------------------------------------------------------------------------
1864 // ----------------------------------------------------------------------------
1866 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1872 // text controls are not special under windows
1873 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1876 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1877 const wxRect
& rectTotal
,
1881 wxRect rect
= rectTotal
;
1883 if ( flags
& wxCONTROL_PRESSED
)
1885 // button pressed: draw a double border around it
1886 DrawRect(dc
, &rect
, m_penBlack
);
1887 DrawRect(dc
, &rect
, m_penDarkGrey
);
1891 // button not pressed
1893 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1895 // button either default or focused (or both): add an extra border around it
1896 DrawRect(dc
, &rect
, m_penBlack
);
1899 // now draw a normal button
1900 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1901 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1910 // ----------------------------------------------------------------------------
1912 // ----------------------------------------------------------------------------
1914 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1915 wxCoord y
, wxCoord x1
, wxCoord x2
)
1917 dc
.SetPen(m_penDarkGrey
);
1918 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1919 dc
.SetPen(m_penHighlight
);
1921 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1924 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1925 wxCoord x
, wxCoord y1
, wxCoord y2
)
1927 dc
.SetPen(m_penDarkGrey
);
1928 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1929 dc
.SetPen(m_penHighlight
);
1931 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1934 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1935 const wxString
& label
,
1941 wxCoord height
= 0; // of the label
1942 wxRect rectFrame
= rect
;
1943 if ( !label
.empty() )
1945 // the text should touch the top border of the rect, so the frame
1946 // itself should be lower
1947 dc
.GetTextExtent(label
, NULL
, &height
);
1948 rectFrame
.y
+= height
/ 2;
1949 rectFrame
.height
-= height
/ 2;
1951 // we have to draw each part of the frame individually as we can't
1952 // erase the background beyond the label as it might contain some
1953 // pixmap already, so drawing everything and then overwriting part of
1954 // the frame with label doesn't work
1956 // TODO: the +5 and space insertion should be customizable
1959 rectText
.x
= rectFrame
.x
+ 5;
1960 rectText
.y
= rect
.y
;
1961 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1962 rectText
.height
= height
;
1965 label2
<< _T(' ') << label
<< _T(' ');
1966 if ( indexAccel
!= -1 )
1968 // adjust it as we prepended a space
1973 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1975 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1979 // just draw the complete frame
1980 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1981 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1985 // ----------------------------------------------------------------------------
1987 // ----------------------------------------------------------------------------
1989 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1991 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1992 // pixels each while we really need dots here... PS_ALTERNATE might
1993 // work, but it is for NT 5 only
1995 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1997 // draw the pixels manually: note that to behave in the same manner as
1998 // DrawRect(), we must exclude the bottom and right borders from the
2000 wxCoord x1
= rect
.GetLeft(),
2002 x2
= rect
.GetRight(),
2003 y2
= rect
.GetBottom();
2005 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2007 // this seems to be closer than what Windows does than wxINVERT although
2008 // I'm still not sure if it's correct
2009 dc
.SetLogicalFunction(wxAND_REVERSE
);
2012 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2013 dc
.DrawPoint(z
, rect
.GetTop());
2015 wxCoord shift
= z
== x2
? 0 : 1;
2016 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2017 dc
.DrawPoint(x2
, z
);
2019 shift
= z
== y2
? 0 : 1;
2020 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2021 dc
.DrawPoint(z
, y2
);
2023 shift
= z
== x1
? 0 : 1;
2024 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2025 dc
.DrawPoint(x1
, z
);
2027 dc
.SetLogicalFunction(wxCOPY
);
2031 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2032 const wxString
& label
,
2037 // draw shadow of the text
2038 dc
.SetTextForeground(m_colHighlight
);
2039 wxRect rectShadow
= rect
;
2042 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2044 // make the text grey
2045 dc
.SetTextForeground(m_colDarkGrey
);
2048 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2049 const wxString
& label
,
2056 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2059 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2060 const wxString
& label
,
2066 const wxPoint
& focusOffset
)
2068 // the underscores are not drawn for focused controls in wxMSW
2069 if ( flags
& wxCONTROL_FOCUSED
)
2074 if ( flags
& wxCONTROL_DISABLED
)
2076 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2077 // currently only can happen for a menu item and it seems that Windows
2078 // doesn't draw the shadow in this case, so we don't do it neither
2079 if ( flags
& wxCONTROL_SELECTED
)
2081 // just make the label text greyed out
2082 dc
.SetTextForeground(m_colDarkGrey
);
2084 else // draw normal disabled label
2086 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2091 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2093 if ( flags
& wxCONTROL_DISABLED
)
2095 // restore the fg colour
2096 dc
.SetTextForeground(*wxBLACK
);
2099 if ( flags
& wxCONTROL_FOCUSED
)
2101 if ( focusOffset
.x
|| focusOffset
.y
)
2103 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2106 DrawFocusRect(dc
, rectLabel
);
2110 *rectBounds
= rectLabel
;
2113 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2114 const wxString
& label
,
2115 const wxBitmap
& image
,
2122 // the underscores are not drawn for focused controls in wxMSW
2123 if ( flags
& wxCONTROL_PRESSED
)
2128 wxRect rectLabel
= rect
;
2129 if ( !label
.empty() )
2131 // shift the label if a button is pressed
2132 if ( flags
& wxCONTROL_PRESSED
)
2138 if ( flags
& wxCONTROL_DISABLED
)
2140 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2143 // leave enough space for the focus rectangle
2144 if ( flags
& wxCONTROL_FOCUSED
)
2146 rectLabel
.Inflate(-2);
2150 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2152 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2154 if ( flags
& wxCONTROL_PRESSED
)
2156 // the focus rectangle is never pressed, so undo the shift done
2164 DrawFocusRect(dc
, rectLabel
);
2168 // ----------------------------------------------------------------------------
2169 // (check)listbox items
2170 // ----------------------------------------------------------------------------
2172 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2173 const wxString
& label
,
2177 wxDCTextColourChanger
colChanger(dc
);
2179 if ( flags
& wxCONTROL_SELECTED
)
2181 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2183 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2184 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2185 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2186 dc
.DrawRectangle(rect
);
2189 wxRect rectText
= rect
;
2191 rectText
.width
-= 2;
2192 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2194 if ( flags
& wxCONTROL_FOCUSED
)
2196 DrawFocusRect(dc
, rect
);
2200 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2201 const wxString
& label
,
2202 const wxBitmap
& bitmap
,
2211 else // use default bitmap
2213 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2214 ? IndicatorStatus_Checked
2215 : IndicatorStatus_Unchecked
;
2217 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2219 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2222 bmp
= m_bmpCheckBitmaps
[i
];
2225 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2226 TRUE
/* use mask */);
2228 wxRect rectLabel
= rect
;
2229 int bmpWidth
= bmp
.GetWidth();
2230 rectLabel
.x
+= bmpWidth
;
2231 rectLabel
.width
-= bmpWidth
;
2233 DrawItem(dc
, label
, rectLabel
, flags
);
2236 // ----------------------------------------------------------------------------
2237 // check/radio buttons
2238 // ----------------------------------------------------------------------------
2240 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2242 IndicatorState indState
;
2243 if ( flags
& wxCONTROL_SELECTED
)
2244 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2245 : IndicatorState_Selected
;
2246 else if ( flags
& wxCONTROL_DISABLED
)
2247 indState
= IndicatorState_Disabled
;
2248 else if ( flags
& wxCONTROL_PRESSED
)
2249 indState
= IndicatorState_Pressed
;
2251 indState
= IndicatorState_Normal
;
2253 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2254 ? IndicatorStatus_Checked
2255 : IndicatorStatus_Unchecked
;
2257 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2260 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2263 // create and cache it
2264 bmp
= wxBitmap(xpm
);
2265 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2272 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2273 const wxString
& label
,
2274 const wxBitmap
& bitmap
,
2279 wxCoord focusOffsetY
)
2281 // calculate the position of the bitmap and of the label
2282 wxCoord heightBmp
= bitmap
.GetHeight();
2284 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2287 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2288 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2290 // align label vertically with the bitmap - looks nicer like this
2291 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2293 // calc horz position
2294 if ( align
== wxALIGN_RIGHT
)
2296 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2297 rectLabel
.x
= rect
.x
+ 3;
2298 rectLabel
.SetRight(xBmp
);
2300 else // normal (checkbox to the left of the text) case
2303 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2304 rectLabel
.SetRight(rect
.GetRight());
2307 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2310 dc
, label
, rectLabel
,
2312 wxALIGN_LEFT
| wxALIGN_TOP
,
2314 NULL
, // we don't need bounding rect
2315 // use custom vert focus rect offset
2316 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2320 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2321 const wxString
& label
,
2322 const wxBitmap
& bitmap
,
2332 bmp
= GetRadioBitmap(flags
);
2334 DrawCheckOrRadioButton(dc
, label
,
2336 rect
, flags
, align
, indexAccel
,
2337 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2340 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2341 const wxString
& label
,
2342 const wxBitmap
& bitmap
,
2352 bmp
= GetCheckBitmap(flags
);
2354 DrawCheckOrRadioButton(dc
, label
,
2356 rect
, flags
, align
, indexAccel
,
2357 0); // no focus rect offset for checkboxes
2360 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2361 const wxString
& label
,
2362 const wxBitmap
& bitmap
,
2363 const wxRect
& rectOrig
,
2366 if ( !label
.empty() || bitmap
.Ok() )
2368 wxRect rect
= rectOrig
;
2369 rect
.Deflate(BORDER_THICKNESS
);
2371 if ( flags
& wxCONTROL_PRESSED
)
2373 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2375 else if ( flags
& wxCONTROL_CURRENT
)
2377 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2380 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2388 // ----------------------------------------------------------------------------
2390 // ----------------------------------------------------------------------------
2392 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2393 const wxString
& text
,
2399 // nothing special to do here
2400 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2403 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2405 // we don't draw them
2408 // ----------------------------------------------------------------------------
2410 // ----------------------------------------------------------------------------
2412 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2413 const wxRect
& rectOrig
,
2415 const wxString
& label
,
2416 const wxBitmap
& bitmap
,
2420 wxRect rect
= rectOrig
;
2422 // the current tab is drawn indented (to the top for default case) and
2423 // bigger than the other ones
2424 const wxSize indent
= GetTabIndent();
2425 if ( flags
& wxCONTROL_SELECTED
)
2430 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2434 rect
.Inflate(indent
.x
, 0);
2436 rect
.height
+= indent
.y
;
2440 rect
.Inflate(indent
.x
, 0);
2441 rect
.height
+= indent
.y
;
2446 wxFAIL_MSG(_T("TODO"));
2451 // draw the text, image and the focus around them (if necessary)
2452 wxRect rectLabel
= rect
;
2453 rectLabel
.Deflate(1, 1);
2454 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2455 flags
, wxALIGN_CENTRE
, indexAccel
);
2457 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2458 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2461 x2
= rect
.GetRight(),
2462 y2
= rect
.GetBottom();
2464 // FIXME: all this code will break if the tab indent or the border width,
2465 // it is tied to the fact that both of them are equal to 2
2470 dc
.SetPen(m_penHighlight
);
2471 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2472 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2473 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2475 dc
.SetPen(m_penBlack
);
2476 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2477 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2479 dc
.SetPen(m_penDarkGrey
);
2480 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2482 if ( flags
& wxCONTROL_SELECTED
)
2484 dc
.SetPen(m_penLightGrey
);
2486 // overwrite the part of the border below this tab
2487 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2489 // and the shadow of the tab to the left of us
2490 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2495 dc
.SetPen(m_penHighlight
);
2496 // we need to continue one pixel further to overwrite the corner of
2497 // the border for the selected tab
2498 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2500 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2502 dc
.SetPen(m_penBlack
);
2503 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2504 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2505 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2507 dc
.SetPen(m_penDarkGrey
);
2508 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2509 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2511 if ( flags
& wxCONTROL_SELECTED
)
2513 dc
.SetPen(m_penLightGrey
);
2515 // overwrite the part of the (double!) border above this tab
2516 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2517 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2519 // and the shadow of the tab to the left of us
2520 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2526 wxFAIL_MSG(_T("TODO"));
2530 // ----------------------------------------------------------------------------
2532 // ----------------------------------------------------------------------------
2534 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2535 wxOrientation orient
) const
2539 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2540 if ( orient
== wxHORIZONTAL
)
2542 size
.y
= rect
.height
- 6;
2543 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2547 size
.x
= rect
.width
- 6;
2548 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2554 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2555 wxOrientation orient
) const
2557 static const wxCoord SLIDER_MARGIN
= 6;
2559 wxRect rect
= rectOrig
;
2561 if ( orient
== wxHORIZONTAL
)
2563 // make the rect of minimal width and centre it
2564 rect
.height
= 2*BORDER_THICKNESS
;
2565 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2569 // leave margins on the sides
2570 rect
.Deflate(SLIDER_MARGIN
, 0);
2574 // same as above but in other direction
2575 rect
.width
= 2*BORDER_THICKNESS
;
2576 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2580 rect
.Deflate(0, SLIDER_MARGIN
);
2586 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2587 const wxRect
& rectOrig
,
2588 wxOrientation orient
,
2592 if ( flags
& wxCONTROL_FOCUSED
)
2594 DrawFocusRect(dc
, rectOrig
);
2597 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2602 DrawSunkenBorder(dc
, &rect
);
2605 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2607 wxOrientation orient
,
2611 we are drawing a shape of this form
2616 H DB where H is hightlight colour
2629 The interior of this shape is filled with the hatched brush if the thumb
2633 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2635 bool transpose
= orient
== wxVERTICAL
;
2637 wxCoord x
, y
, x2
, y2
;
2642 x2
= rect
.GetBottom();
2643 y2
= rect
.GetRight();
2649 x2
= rect
.GetRight();
2650 y2
= rect
.GetBottom();
2653 // the size of the pointed part of the thumb
2654 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2656 wxCoord x3
= x
+ sizeArrow
,
2657 y3
= y2
- sizeArrow
;
2659 dc
.SetPen(m_penHighlight
);
2660 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2661 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2662 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2664 dc
.SetPen(m_penBlack
);
2665 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2666 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2668 dc
.SetPen(m_penDarkGrey
);
2669 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2670 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2672 if ( flags
& wxCONTROL_PRESSED
)
2674 // TODO: MSW fills the entire area inside, not just the rect
2675 wxRect rectInt
= rect
;
2677 rectInt
.SetRight(y3
);
2679 rectInt
.SetBottom(y3
);
2682 #if !defined(__WXMGL__)
2683 static const char *stipple_xpm
[] = {
2684 /* columns rows colors chars-per-pixel */
2693 // VS: MGL can only do 8x8 stipple brushes
2694 static const char *stipple_xpm
[] = {
2695 /* columns rows colors chars-per-pixel */
2710 dc
.SetBrush(wxBrush(stipple_xpm
));
2712 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2713 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2714 dc
.SetPen(*wxTRANSPARENT_PEN
);
2715 dc
.DrawRectangle(rectInt
);
2719 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2721 const wxSize
& sizeThumb
,
2722 wxOrientation orient
,
2734 // the variable names correspond to horizontal case, but they can be used
2735 // for both orientations
2736 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2737 if ( orient
== wxHORIZONTAL
)
2739 x1
= rect
.GetLeft();
2740 x2
= rect
.GetRight();
2742 // draw from bottom to top to leave one pixel space between the ticks
2743 // and the slider as Windows do
2744 y1
= rect
.GetBottom();
2749 widthThumb
= sizeThumb
.x
;
2754 x2
= rect
.GetBottom();
2756 y1
= rect
.GetRight();
2757 y2
= rect
.GetLeft();
2761 widthThumb
= sizeThumb
.y
;
2764 // the first tick should be positioned in such way that a thumb drawn in
2765 // the first position points down directly to it
2766 x1
+= widthThumb
/ 2;
2767 x2
-= widthThumb
/ 2;
2769 // this also means that we have slightly less space for the ticks in
2770 // between the first and the last
2773 dc
.SetPen(m_penBlack
);
2775 int range
= end
- start
;
2776 for ( int n
= 0; n
< range
; n
+= step
)
2778 wxCoord x
= x1
+ (len
*n
) / range
;
2780 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2783 // always draw the line at the end position
2784 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2787 // ----------------------------------------------------------------------------
2789 // ----------------------------------------------------------------------------
2791 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2792 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2795 virtual wxSize
GetSize() const { return m_size
; }
2797 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2798 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2800 wxCoord
GetItemHeight() const { return m_heightItem
; }
2803 // the total size of the menu
2806 // the offset of the start of the menu item label
2809 // the offset of the start of the accel label
2812 // the height of a normal (not separator) item
2813 wxCoord m_heightItem
;
2815 friend wxMenuGeometryInfo
*
2816 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2819 // FIXME: all constants are hardcoded but shouldn't be
2820 static const wxCoord MENU_LEFT_MARGIN
= 9;
2821 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2822 static const wxCoord MENU_VERT_MARGIN
= 3;
2824 // the margin around bitmap/check marks (on each side)
2825 static const wxCoord MENU_BMP_MARGIN
= 2;
2827 // the margin between the labels and accel strings
2828 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2830 // the separator height in pixels: in fact, strangely enough, the real height
2831 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2833 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2835 // the size of the standard checkmark bitmap
2836 static const wxCoord MENU_CHECK_SIZE
= 9;
2838 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2839 const wxRect
& rectOrig
,
2840 const wxString
& label
,
2844 wxRect rect
= rectOrig
;
2847 wxDCTextColourChanger
colChanger(dc
);
2849 if ( flags
& wxCONTROL_SELECTED
)
2851 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2853 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2854 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2855 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2856 dc
.DrawRectangle(rect
);
2859 // don't draw the focus rect around menu bar items
2860 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2861 wxALIGN_CENTRE
, indexAccel
);
2864 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2866 const wxMenuGeometryInfo
& gi
,
2867 const wxString
& label
,
2868 const wxString
& accel
,
2869 const wxBitmap
& bitmap
,
2873 const wxWin32MenuGeometryInfo
& geometryInfo
=
2874 (const wxWin32MenuGeometryInfo
&)gi
;
2879 rect
.width
= geometryInfo
.GetSize().x
;
2880 rect
.height
= geometryInfo
.GetItemHeight();
2882 // draw the selected item specially
2883 wxDCTextColourChanger
colChanger(dc
);
2884 if ( flags
& wxCONTROL_SELECTED
)
2886 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2888 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2889 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2890 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2891 dc
.DrawRectangle(rect
);
2894 // draw the bitmap: use the bitmap provided or the standard checkmark for
2895 // the checkable items
2896 wxBitmap bmp
= bitmap
;
2897 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2899 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2904 rect
.SetRight(geometryInfo
.GetLabelOffset());
2905 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2909 rect
.x
= geometryInfo
.GetLabelOffset();
2910 rect
.SetRight(geometryInfo
.GetAccelOffset());
2912 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2914 // draw the accel string
2915 rect
.x
= geometryInfo
.GetAccelOffset();
2916 rect
.SetRight(geometryInfo
.GetSize().x
);
2918 // NB: no accel index here
2919 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2921 // draw the submenu indicator
2922 if ( flags
& wxCONTROL_ISSUBMENU
)
2924 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2925 rect
.width
= MENU_RIGHT_MARGIN
;
2927 wxArrowStyle arrowStyle
;
2928 if ( flags
& wxCONTROL_DISABLED
)
2929 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2931 else if ( flags
& wxCONTROL_SELECTED
)
2932 arrowStyle
= Arrow_Inversed
;
2934 arrowStyle
= Arrow_Normal
;
2936 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2940 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2942 const wxMenuGeometryInfo
& geomInfo
)
2944 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2947 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2949 wxSize size
= sizeText
;
2951 // FIXME: menubar height is configurable under Windows
2958 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2959 const wxMenu
& menu
) const
2961 // prepare the dc: for now we draw all the items with the system font
2963 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2965 // the height of a normal item
2966 wxCoord heightText
= dc
.GetCharHeight();
2971 // the max length of label and accel strings: the menu width is the sum of
2972 // them, even if they're for different items (as the accels should be
2975 // the max length of the bitmap is never 0 as Windows always leaves enough
2976 // space for a check mark indicator
2977 wxCoord widthLabelMax
= 0,
2979 widthBmpMax
= MENU_LEFT_MARGIN
;
2981 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2983 node
= node
->GetNext() )
2985 // height of this item
2988 wxMenuItem
*item
= node
->GetData();
2989 if ( item
->IsSeparator() )
2991 h
= MENU_SEPARATOR_HEIGHT
;
2993 else // not separator
2998 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2999 if ( widthLabel
> widthLabelMax
)
3001 widthLabelMax
= widthLabel
;
3005 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3006 if ( widthAccel
> widthAccelMax
)
3008 widthAccelMax
= widthAccel
;
3011 const wxBitmap
& bmp
= item
->GetBitmap();
3014 wxCoord widthBmp
= bmp
.GetWidth();
3015 if ( widthBmp
> widthBmpMax
)
3016 widthBmpMax
= widthBmp
;
3018 //else if ( item->IsCheckable() ): no need to check for this as
3019 // MENU_LEFT_MARGIN is big enough to show the check mark
3022 h
+= 2*MENU_VERT_MARGIN
;
3024 // remember the item position and height
3025 item
->SetGeometry(height
, h
);
3030 // bundle the metrics into a struct and return it
3031 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3033 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3034 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3035 if ( widthAccelMax
> 0 )
3037 // if we actually have any accesl, add a margin
3038 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3041 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3043 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3044 gi
->m_size
.y
= height
;
3049 // ----------------------------------------------------------------------------
3051 // ----------------------------------------------------------------------------
3053 static const wxCoord STATBAR_BORDER_X
= 2;
3054 static const wxCoord STATBAR_BORDER_Y
= 2;
3056 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3058 if ( borderBetweenFields
)
3059 *borderBetweenFields
= 2;
3061 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3064 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3066 const wxString
& label
,
3071 if ( flags
& wxCONTROL_ISDEFAULT
)
3073 // draw the size grip: it is a normal rect except that in the lower
3074 // right corner we have several bands which may be used for dragging
3075 // the status bar corner
3077 // each band consists of 4 stripes: m_penHighlight, double
3078 // m_penDarkGrey and transparent one
3079 wxCoord x2
= rect
.GetRight(),
3080 y2
= rect
.GetBottom();
3082 // draw the upper left part of the rect normally
3083 dc
.SetPen(m_penDarkGrey
);
3084 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3085 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3087 // draw the grey stripes of the grip
3089 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3090 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3092 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3093 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3096 // draw the white stripes
3097 dc
.SetPen(m_penHighlight
);
3098 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3099 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3101 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3104 // draw the remaining rect boundaries
3105 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3106 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3107 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3112 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3116 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3119 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3121 wxDCClipper
clipper(dc
, rectIn
);
3122 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3125 // ----------------------------------------------------------------------------
3127 // ----------------------------------------------------------------------------
3129 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3131 wxBitmap
*bmpPressed
,
3132 wxBitmap
*bmpDisabled
)
3134 static const wxCoord widthCombo
= 16;
3135 static const wxCoord heightCombo
= 17;
3141 bmpNormal
->Create(widthCombo
, heightCombo
);
3142 dcMem
.SelectObject(*bmpNormal
);
3143 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3144 Arrow_Down
, Arrow_Normal
);
3149 bmpPressed
->Create(widthCombo
, heightCombo
);
3150 dcMem
.SelectObject(*bmpPressed
);
3151 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3152 Arrow_Down
, Arrow_Pressed
);
3157 bmpDisabled
->Create(widthCombo
, heightCombo
);
3158 dcMem
.SelectObject(*bmpDisabled
);
3159 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3160 Arrow_Down
, Arrow_Disabled
);
3164 // ----------------------------------------------------------------------------
3166 // ----------------------------------------------------------------------------
3168 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3169 const wxColour
& col
,
3172 wxBrush
brush(col
, wxSOLID
);
3174 dc
.SetPen(*wxTRANSPARENT_PEN
);
3175 dc
.DrawRectangle(rect
);
3178 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3179 const wxColour
& col
,
3183 // just fill it with the given or default bg colour
3184 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3185 DoDrawBackground(dc
, colBg
, rect
);
3188 // ----------------------------------------------------------------------------
3190 // ----------------------------------------------------------------------------
3192 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3197 // get the bitmap for this arrow
3198 wxArrowDirection arrowDir
;
3201 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3202 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3203 case wxUP
: arrowDir
= Arrow_Up
; break;
3204 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3207 wxFAIL_MSG(_T("unknown arrow direction"));
3211 wxArrowStyle arrowStyle
;
3212 if ( flags
& wxCONTROL_PRESSED
)
3214 // can't be pressed and disabled
3215 arrowStyle
= Arrow_Pressed
;
3219 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3222 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3225 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3227 wxArrowDirection arrowDir
,
3228 wxArrowStyle arrowStyle
)
3230 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3232 // under Windows the arrows always have the same size so just centre it in
3233 // the provided rectangle
3234 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3235 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3237 // Windows does it like this...
3238 if ( arrowDir
== Arrow_Left
)
3242 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3245 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3246 const wxRect
& rectAll
,
3247 wxArrowDirection arrowDir
,
3248 wxArrowStyle arrowStyle
)
3250 wxRect rect
= rectAll
;
3251 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3252 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3253 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3256 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3257 wxOrientation orient
,
3261 // we don't use the flags, the thumb never changes appearance
3262 wxRect rectThumb
= rect
;
3263 DrawArrowBorder(dc
, &rectThumb
);
3264 DrawBackground(dc
, wxNullColour
, rectThumb
);
3267 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3268 wxOrientation orient
,
3269 const wxRect
& rectBar
,
3272 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3273 ? wxColourScheme::SCROLLBAR_PRESSED
3274 : wxColourScheme::SCROLLBAR
;
3275 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3278 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3280 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3283 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3284 wxScrollBar::Element elem
,
3287 return StandardGetScrollbarRect(scrollbar
, elem
,
3288 thumbPos
, m_sizeScrollbarArrow
);
3291 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3293 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3296 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3297 const wxPoint
& pt
) const
3299 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3302 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3305 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3308 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3311 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3314 // ----------------------------------------------------------------------------
3315 // top level windows
3316 // ----------------------------------------------------------------------------
3318 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3320 wxRect client
= GetFrameClientArea(rect
, flags
);
3322 if ( client
.Inside(pt
) )
3323 return wxHT_TOPLEVEL_CLIENT_AREA
;
3325 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3327 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3329 if ( flags
& wxTOPLEVEL_ICON
)
3331 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3332 return wxHT_TOPLEVEL_ICON
;
3335 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3336 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3337 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3339 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3341 if ( btnRect
.Inside(pt
) )
3342 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3343 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3345 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3347 if ( btnRect
.Inside(pt
) )
3348 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3349 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3351 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3353 if ( btnRect
.Inside(pt
) )
3354 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3355 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3357 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3359 if ( btnRect
.Inside(pt
) )
3360 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3361 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3363 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3365 if ( btnRect
.Inside(pt
) )
3366 return wxHT_TOPLEVEL_BUTTON_HELP
;
3367 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3370 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3371 return wxHT_TOPLEVEL_TITLEBAR
;
3374 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3376 // we are certainly at one of borders, lets decide which one:
3379 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3380 if ( pt
.x
< client
.x
)
3381 border
|= wxHT_TOPLEVEL_BORDER_W
;
3382 else if ( pt
.x
>= client
.width
+ client
.x
)
3383 border
|= wxHT_TOPLEVEL_BORDER_E
;
3384 if ( pt
.y
< client
.y
)
3385 border
|= wxHT_TOPLEVEL_BORDER_N
;
3386 else if ( pt
.y
>= client
.height
+ client
.y
)
3387 border
|= wxHT_TOPLEVEL_BORDER_S
;
3391 return wxHT_NOWHERE
;
3394 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3396 const wxString
& title
,
3400 int specialButtonFlags
)
3402 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3404 DrawFrameBorder(dc
, rect
, flags
);
3406 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3408 DrawFrameBackground(dc
, rect
, flags
);
3409 if ( flags
& wxTOPLEVEL_ICON
)
3410 DrawFrameIcon(dc
, rect
, icon
, flags
);
3411 DrawFrameTitle(dc
, rect
, title
, flags
);
3413 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3415 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3416 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3418 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3420 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3421 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3422 specialButtonFlags
: 0);
3423 x
-= FRAME_BUTTON_WIDTH
+ 2;
3425 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3427 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3428 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3429 specialButtonFlags
: 0);
3430 x
-= FRAME_BUTTON_WIDTH
;
3432 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3434 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3435 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3436 specialButtonFlags
: 0);
3437 x
-= FRAME_BUTTON_WIDTH
;
3439 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3441 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3442 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3443 specialButtonFlags
: 0);
3444 x
-= FRAME_BUTTON_WIDTH
;
3446 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3448 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3449 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3450 specialButtonFlags
: 0);
3451 x
-= FRAME_BUTTON_WIDTH
;
3456 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3460 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3464 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3465 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3466 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3467 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3468 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3471 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3475 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3477 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3478 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3479 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3481 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3482 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3484 DrawBackground(dc
, col
, r
);
3487 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3489 const wxString
& title
,
3492 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3493 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3494 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3496 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3497 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3498 if ( flags
& wxTOPLEVEL_ICON
)
3500 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3501 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3509 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3510 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3511 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3512 r
.width
-= FRAME_BUTTON_WIDTH
;
3513 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3514 r
.width
-= FRAME_BUTTON_WIDTH
;
3515 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3516 r
.width
-= FRAME_BUTTON_WIDTH
;
3517 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3518 r
.width
-= FRAME_BUTTON_WIDTH
;
3520 dc
.SetFont(m_titlebarFont
);
3521 dc
.SetTextForeground(col
);
3524 dc
.GetTextExtent(title
, &textW
, NULL
);
3525 if ( textW
> r
.width
)
3527 // text is too big, let's shorten it and add "..." after it:
3528 size_t len
= title
.length();
3529 wxCoord WSoFar
, letterW
;
3531 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3532 if ( WSoFar
> r
.width
)
3534 // not enough space to draw anything
3540 for (size_t i
= 0; i
< len
; i
++)
3542 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3543 if ( letterW
+ WSoFar
> r
.width
)
3549 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3550 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3553 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3554 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3557 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3564 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3565 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3569 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3570 wxCoord x
, wxCoord y
,
3574 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3579 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3580 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3581 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3582 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3583 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3585 wxFAIL_MSG(wxT("incorrect button specification"));
3588 if ( flags
& wxCONTROL_PRESSED
)
3590 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3591 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3592 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3593 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3597 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3598 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3599 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3600 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3605 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3610 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3612 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3613 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3614 FRAME_BORDER_THICKNESS
;
3617 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3619 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3620 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3626 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3629 wxSize
s(clientSize
);
3631 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3633 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3634 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3635 FRAME_BORDER_THICKNESS
;
3639 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3640 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3645 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3649 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3651 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3652 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3653 FRAME_BORDER_THICKNESS
;
3658 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3660 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3662 if ( flags
& wxTOPLEVEL_ICON
)
3663 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3664 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3665 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3666 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3667 s
.x
+= FRAME_BUTTON_WIDTH
;
3668 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3669 s
.x
+= FRAME_BUTTON_WIDTH
;
3670 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3671 s
.x
+= FRAME_BUTTON_WIDTH
;
3672 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3673 s
.x
+= FRAME_BUTTON_WIDTH
;
3679 wxSize
wxWin32Renderer::GetFrameIconSize() const
3681 return wxSize(16, 16);
3685 // ----------------------------------------------------------------------------
3687 // ----------------------------------------------------------------------------
3689 static char *error_xpm
[]={
3696 "...........########.............",
3697 "........###aaaaaaaa###..........",
3698 ".......#aaaaaaaaaaaaaa#.........",
3699 ".....##aaaaaaaaaaaaaaaa##.......",
3700 "....#aaaaaaaaaaaaaaaaaaaa#......",
3701 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3702 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3703 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3704 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3705 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3706 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3707 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3708 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3709 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3710 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3711 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3712 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3713 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3714 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3715 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3716 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3717 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3718 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3719 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3720 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3721 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3722 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3723 "......b#aaaaaaaaaaaaaa#bbbbb....",
3724 ".......b###aaaaaaaa###bbbbb.....",
3725 ".........bb########bbbbbb.......",
3726 "..........bbbbbbbbbbbbbb........",
3727 ".............bbbbbbbb..........."};
3729 static char *info_xpm
[]={
3737 "...........########.............",
3738 "........###abbbbbba###..........",
3739 "......##abbbbbbbbbbbba##........",
3740 ".....#abbbbbbbbbbbbbbbba#.......",
3741 "....#bbbbbbbaccccabbbbbbbd......",
3742 "...#bbbbbbbbccccccbbbbbbbbd.....",
3743 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3744 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3745 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3746 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3747 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3748 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3749 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3750 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3751 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3752 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3753 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3754 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3755 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3756 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3757 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3758 ".....dabbbbbbbbbbbbbbbbad####...",
3759 "......ddabbbbbbbbbbbbadd####....",
3760 ".......#dddabbbbbbaddd#####.....",
3761 "........###dddabbbd#######......",
3762 "..........####dbbbd#####........",
3763 ".............#dbbbd##...........",
3764 "...............dbbd##...........",
3765 "................dbd##...........",
3766 ".................dd##...........",
3767 "..................###...........",
3768 "...................##..........."};
3770 static char *question_xpm
[]={
3778 "...........########.............",
3779 "........###abbbbbba###..........",
3780 "......##abbbbbbbbbbbba##........",
3781 ".....#abbbbbbbbbbbbbbbba#.......",
3782 "....#bbbbbbbbbbbbbbbbbbbbc......",
3783 "...#bbbbbbbaddddddabbbbbbbc.....",
3784 "..#bbbbbbbadabbddddabbbbbbbc....",
3785 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3786 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3787 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3788 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3789 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3790 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3791 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3792 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3793 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3794 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3795 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3796 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3797 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3798 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3799 ".....cabbbbbbbbbbbbbbbbac####...",
3800 "......ccabbbbbbbbbbbbacc####....",
3801 ".......#cccabbbbbbaccc#####.....",
3802 "........###cccabbbc#######......",
3803 "..........####cbbbc#####........",
3804 ".............#cbbbc##...........",
3805 "...............cbbc##...........",
3806 "................cbc##...........",
3807 ".................cc##...........",
3808 "..................###...........",
3809 "...................##..........."};
3811 static char *warning_xpm
[]={
3819 ".............###................",
3820 "............#aabc...............",
3821 "...........#aaaabcd.............",
3822 "...........#aaaaacdd............",
3823 "..........#aaaaaabcdd...........",
3824 "..........#aaaaaaacdd...........",
3825 ".........#aaaaaaaabcdd..........",
3826 ".........#aaaaaaaaacdd..........",
3827 "........#aaaaaaaaaabcdd.........",
3828 "........#aaabcccbaaacdd.........",
3829 ".......#aaaacccccaaabcdd........",
3830 ".......#aaaacccccaaaacdd........",
3831 "......#aaaaacccccaaaabcdd.......",
3832 "......#aaaaacccccaaaaacdd.......",
3833 ".....#aaaaaacccccaaaaabcdd......",
3834 ".....#aaaaaa#ccc#aaaaaacdd......",
3835 "....#aaaaaaabcccbaaaaaabcdd.....",
3836 "....#aaaaaaaacccaaaaaaaacdd.....",
3837 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3838 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3839 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3840 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3841 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3842 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3843 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3844 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3845 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3846 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3847 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3848 "..#ccccccccccccccccccccccccddddd",
3849 "....ddddddddddddddddddddddddddd.",
3850 ".....ddddddddddddddddddddddddd.."};
3852 wxIcon
wxWin32Renderer::GetStdIcon(int which
) const
3856 case wxICON_INFORMATION
:
3857 return wxIcon(info_xpm
);
3859 case wxICON_QUESTION
:
3860 return wxIcon(question_xpm
);
3862 case wxICON_EXCLAMATION
:
3863 return wxIcon(warning_xpm
);
3866 wxFAIL_MSG(wxT("requested non existent standard icon"));
3867 // still fall through
3870 return wxIcon(error_xpm
);
3875 // ----------------------------------------------------------------------------
3876 // text control geometry
3877 // ----------------------------------------------------------------------------
3879 static inline int GetTextBorderWidth()
3884 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3885 const wxRect
& rect
) const
3887 wxRect rectTotal
= rect
;
3889 wxCoord widthBorder
= GetTextBorderWidth();
3890 rectTotal
.Inflate(widthBorder
);
3892 // this is what Windows does
3898 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3900 wxCoord
*extraSpaceBeyond
) const
3902 wxRect rectText
= rect
;
3904 // undo GetTextTotalArea()
3905 if ( rectText
.height
> 0 )
3908 wxCoord widthBorder
= GetTextBorderWidth();
3909 rectText
.Inflate(-widthBorder
);
3911 if ( extraSpaceBeyond
)
3912 *extraSpaceBeyond
= 0;
3917 // ----------------------------------------------------------------------------
3919 // ----------------------------------------------------------------------------
3921 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3924 if ( wxDynamicCast(window
, wxScrollBar
) )
3926 // we only set the width of vert scrollbars and height of the
3928 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3929 size
->y
= m_sizeScrollbarArrow
.y
;
3931 size
->x
= m_sizeScrollbarArrow
.x
;
3933 // skip border width adjustments, they don't make sense for us
3936 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3939 if ( wxDynamicCast(window
, wxButton
) )
3941 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3943 // TODO: don't harcode all this
3944 size
->x
+= 3*window
->GetCharWidth();
3946 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3947 if ( size
->y
< heightBtn
- 8 )
3948 size
->y
= heightBtn
;
3953 // no border width adjustments for buttons
3956 #endif // wxUSE_BUTTON
3958 // take into account the border width
3959 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3960 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3961 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3964 // ============================================================================
3966 // ============================================================================
3968 // ----------------------------------------------------------------------------
3969 // wxWin32InputHandler
3970 // ----------------------------------------------------------------------------
3972 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3974 m_renderer
= renderer
;
3977 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3978 const wxKeyEvent
& event
,
3984 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3985 const wxMouseEvent
& event
)
3987 // clicking on the control gives it focus
3988 if ( event
.ButtonDown() )
3990 wxWindow
*win
= control
->GetInputWindow();
3992 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
3993 ( win
->AcceptsFocus() ) )
4004 // ----------------------------------------------------------------------------
4005 // wxWin32ScrollBarInputHandler
4006 // ----------------------------------------------------------------------------
4008 wxWin32ScrollBarInputHandler::
4009 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4010 wxInputHandler
*handler
)
4011 : wxStdScrollBarInputHandler(renderer
, handler
)
4013 m_scrollPaused
= FALSE
;
4017 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4018 const wxControlAction
& action
)
4020 // stop if went beyond the position of the original click (this can only
4021 // happen when we scroll by pages)
4023 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4025 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4026 != wxHT_SCROLLBAR_BAR_2
;
4028 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4030 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4031 != wxHT_SCROLLBAR_BAR_1
;
4036 StopScrolling(scrollbar
);
4038 scrollbar
->Refresh();
4043 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4046 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4047 const wxMouseEvent
& event
)
4049 // remember the current state
4050 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4052 // do process the message
4053 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4055 // analyse the changes
4056 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4058 // we just started dragging the thumb, remember its initial position to
4059 // be able to restore it if the drag is cancelled later
4060 m_eventStartDrag
= event
;
4066 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4067 const wxMouseEvent
& event
)
4069 // we don't highlight scrollbar elements, so there is no need to process
4070 // mouse move events normally - only do it while mouse is captured (i.e.
4071 // when we're dragging the thumb or pressing on something)
4072 if ( !m_winCapture
)
4075 if ( event
.Entering() )
4077 // we're not interested in this at all
4081 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4083 if ( m_scrollPaused
)
4085 // check if the mouse returned to its original location
4087 if ( event
.Leaving() )
4093 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4094 if ( ht
== m_htLast
)
4096 // yes it did, resume scrolling
4097 m_scrollPaused
= FALSE
;
4098 if ( m_timerScroll
)
4100 // we were scrolling by line/page, restart timer
4101 m_timerScroll
->Start(m_interval
);
4103 Press(scrollbar
, TRUE
);
4105 else // we were dragging the thumb
4107 // restore its last location
4108 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4114 else // normal case, scrolling hasn't been paused
4116 // if we're scrolling the scrollbar because the arrow or the shaft was
4117 // pressed, check that the mouse stays on the same scrollbar element
4119 if ( event
.Moving() )
4121 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4123 else // event.Leaving()
4128 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4129 // is still ok - we only want to catch the case when the mouse leaves
4130 // the scrollbar here
4131 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4133 ht
= wxHT_SCROLLBAR_THUMB
;
4136 if ( ht
!= m_htLast
)
4138 // what were we doing? 2 possibilities: either an arrow/shaft was
4139 // pressed in which case we have a timer and so we just stop it or
4140 // we were dragging the thumb
4141 if ( m_timerScroll
)
4144 m_interval
= m_timerScroll
->GetInterval();
4145 m_timerScroll
->Stop();
4146 m_scrollPaused
= TRUE
;
4148 // unpress the arrow
4149 Press(scrollbar
, FALSE
);
4151 else // we were dragging the thumb
4153 // remember the current thumb position to be able to restore it
4154 // if the mouse returns to it later
4155 m_eventLastDrag
= event
;
4157 // and restore the original position (before dragging) of the
4159 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4166 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4169 // ----------------------------------------------------------------------------
4170 // wxWin32CheckboxInputHandler
4171 // ----------------------------------------------------------------------------
4173 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4174 const wxKeyEvent
& event
,
4179 wxControlAction action
;
4180 int keycode
= event
.GetKeyCode();
4184 action
= wxACTION_CHECKBOX_TOGGLE
;
4188 case WXK_NUMPAD_SUBTRACT
:
4189 action
= wxACTION_CHECKBOX_CHECK
;
4193 case WXK_NUMPAD_ADD
:
4194 case WXK_NUMPAD_EQUAL
:
4195 action
= wxACTION_CHECKBOX_CLEAR
;
4201 control
->PerformAction(action
);
4210 // ----------------------------------------------------------------------------
4211 // wxWin32TextCtrlInputHandler
4212 // ----------------------------------------------------------------------------
4214 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4215 const wxKeyEvent
& event
,
4218 // handle only MSW-specific text bindings here, the others are handled in
4222 int keycode
= event
.GetKeyCode();
4224 wxControlAction action
;
4225 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4227 action
= wxACTION_TEXT_CUT
;
4229 else if ( keycode
== WXK_INSERT
)
4231 if ( event
.ControlDown() )
4232 action
= wxACTION_TEXT_COPY
;
4233 else if ( event
.ShiftDown() )
4234 action
= wxACTION_TEXT_PASTE
;
4237 if ( action
!= wxACTION_NONE
)
4239 control
->PerformAction(action
);
4245 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4248 // ----------------------------------------------------------------------------
4249 // wxWin32StatusBarInputHandler
4250 // ----------------------------------------------------------------------------
4252 wxWin32StatusBarInputHandler::
4253 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4254 : wxStdInputHandler(handler
)
4259 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4260 const wxPoint
& pt
) const
4262 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4263 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4266 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4268 wxCHECK_MSG( parentTLW
, FALSE
,
4269 _T("the status bar should be a child of a TLW") );
4271 // a maximized window can't be resized anyhow
4272 if ( !parentTLW
->IsMaximized() )
4274 // VZ: I think that the standard Windows behaviour is to only
4275 // show the resizing cursor when the mouse is on top of the
4276 // grip itself but apparently different Windows versions behave
4277 // differently (?) and it seems a better UI to allow resizing
4278 // the status bar even when the mouse is above the grip
4279 wxSize sizeSbar
= statbar
->GetSize();
4281 int diff
= sizeSbar
.x
- pt
.x
;
4282 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4289 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4290 const wxMouseEvent
& event
)
4292 if ( event
.Button(1) )
4294 if ( event
.ButtonDown(1) )
4296 wxWindow
*statbar
= consumer
->GetInputWindow();
4298 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4300 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4304 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4305 wxHT_TOPLEVEL_BORDER_SE
);
4307 statbar
->SetCursor(m_cursorOld
);
4315 return wxStdInputHandler::HandleMouse(consumer
, event
);
4318 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4319 const wxMouseEvent
& event
)
4321 wxWindow
*statbar
= consumer
->GetInputWindow();
4323 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4324 if ( isOnGrip
!= m_isOnGrip
)
4326 m_isOnGrip
= isOnGrip
;
4329 m_cursorOld
= statbar
->GetCursor();
4330 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4334 statbar
->SetCursor(m_cursorOld
);
4338 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4341 // ----------------------------------------------------------------------------
4342 // wxWin32FrameInputHandler
4343 // ----------------------------------------------------------------------------
4345 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4346 const wxMouseEvent
& event
)
4348 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4350 wxTopLevelWindow
*tlw
=
4351 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4353 long hit
= tlw
->HitTest(event
.GetPosition());
4355 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4357 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4358 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4359 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4362 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4364 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4365 (event
.RightDown() &&
4366 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4367 hit
== wxHT_TOPLEVEL_ICON
)) )
4369 PopupSystemMenu(tlw
, event
.GetPosition());
4375 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4378 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4379 const wxPoint
& pos
) const
4381 wxMenu
*menu
= new wxMenu
;
4383 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4384 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4385 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4386 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4387 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4388 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4389 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4390 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4391 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4392 menu
->AppendSeparator();
4393 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4395 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4397 if ( window
->IsMaximized() )
4399 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4400 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4401 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4402 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4405 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4408 window
->PopupMenu(menu
, pos
);
4412 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4415 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
,
4416 wxInputConsumer
*consumer
);
4420 DECLARE_EVENT_TABLE()
4421 void OnSystemMenu(wxCommandEvent
&event
);
4422 void OnCloseFrame(wxCommandEvent
&event
);
4423 void OnClose(wxCloseEvent
&event
);
4425 wxWin32FrameInputHandler
*m_inputHnd
;
4426 wxTopLevelWindow
*m_wnd
;
4427 wxAcceleratorTable m_oldAccelTable
;
4430 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4431 wxWin32FrameInputHandler
*handler
,
4432 wxInputConsumer
*consumer
)
4434 m_inputHnd
= handler
;
4435 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4436 m_wnd
->PushEventHandler(this);
4438 // VS: This code relies on using generic implementation of
4439 // wxAcceleratorTable in wxUniv!
4440 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4441 m_oldAccelTable
= table
;
4442 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4443 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4444 m_wnd
->SetAcceleratorTable(table
);
4447 void wxWin32SystemMenuEvtHandler::RemoveSelf()
4451 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4452 m_wnd
->RemoveEventHandler(this);
4456 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4457 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4458 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4459 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4462 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4464 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4465 !m_wnd
->IsMaximized()) ?
4466 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4467 FRAME_BORDER_THICKNESS
;
4468 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4469 pt
.x
= -pt
.x
+ border
;
4470 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4472 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4473 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4474 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4475 m_wnd
->SetAcceleratorTable(table
);
4478 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4480 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4481 wxTOPLEVEL_BUTTON_CLOSE
);
4484 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4491 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4494 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4496 if ( !activated
&& m_menuHandler
)
4498 m_menuHandler
->RemoveSelf();
4499 wxDELETE(m_menuHandler
);
4501 else if ( activated
)
4503 if ( m_menuHandler
)
4505 m_menuHandler
->RemoveSelf();
4506 delete m_menuHandler
;
4509 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this, consumer
);
4513 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);