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"
53 #include "wx/artprov.h"
54 #include "wx/toplevel.h"
56 #include "wx/univ/scrtimer.h"
57 #include "wx/univ/renderer.h"
58 #include "wx/univ/inphand.h"
59 #include "wx/univ/colschem.h"
60 #include "wx/univ/theme.h"
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 static const int BORDER_THICKNESS
= 2;
68 // the offset between the label and focus rect around it
69 static const int FOCUS_RECT_OFFSET_X
= 1;
70 static const int FOCUS_RECT_OFFSET_Y
= 1;
72 static const int FRAME_BORDER_THICKNESS
= 3;
73 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
74 static const int FRAME_TITLEBAR_HEIGHT
= 18;
75 static const int FRAME_BUTTON_WIDTH
= 16;
76 static const int FRAME_BUTTON_HEIGHT
= 14;
78 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
79 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
80 static const size_t STATUSBAR_GRIP_SIZE
=
81 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
93 IndicatorState_Normal
,
94 IndicatorState_Pressed
, // this one is for check/radioboxes
95 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
96 IndicatorState_Disabled
,
97 IndicatorState_SelectedDisabled
, // only for the menus
103 IndicatorStatus_Checked
,
104 IndicatorStatus_Unchecked
,
108 // wxWin32Renderer: draw the GUI elements in Win32 style
109 // ----------------------------------------------------------------------------
111 class wxWin32Renderer
: public wxRenderer
115 enum wxArrowDirection
130 Arrow_InversedDisabled
,
134 enum wxFrameButtonType
137 FrameButton_Minimize
,
138 FrameButton_Maximize
,
145 wxWin32Renderer(const wxColourScheme
*scheme
);
147 // implement the base class pure virtuals
148 virtual void DrawBackground(wxDC
& dc
,
152 virtual void DrawLabel(wxDC
& dc
,
153 const wxString
& label
,
156 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
158 wxRect
*rectBounds
= NULL
);
159 virtual void DrawButtonLabel(wxDC
& dc
,
160 const wxString
& label
,
161 const wxBitmap
& image
,
164 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
166 wxRect
*rectBounds
= NULL
);
167 virtual void DrawBorder(wxDC
& dc
,
171 wxRect
*rectIn
= (wxRect
*)NULL
);
172 virtual void DrawHorizontalLine(wxDC
& dc
,
173 wxCoord y
, wxCoord x1
, wxCoord x2
);
174 virtual void DrawVerticalLine(wxDC
& dc
,
175 wxCoord x
, wxCoord y1
, wxCoord y2
);
176 virtual void DrawFrame(wxDC
& dc
,
177 const wxString
& label
,
180 int alignment
= wxALIGN_LEFT
,
181 int indexAccel
= -1);
182 virtual void DrawTextBorder(wxDC
& dc
,
186 wxRect
*rectIn
= (wxRect
*)NULL
);
187 virtual void DrawButtonBorder(wxDC
& dc
,
190 wxRect
*rectIn
= (wxRect
*)NULL
);
191 virtual void DrawArrow(wxDC
& dc
,
195 virtual void DrawScrollbarArrow(wxDC
& dc
,
199 { DrawArrow(dc
, dir
, rect
, flags
); }
200 virtual void DrawScrollbarThumb(wxDC
& dc
,
201 wxOrientation orient
,
204 virtual void DrawScrollbarShaft(wxDC
& dc
,
205 wxOrientation orient
,
208 virtual void DrawScrollCorner(wxDC
& dc
,
210 virtual void DrawItem(wxDC
& dc
,
211 const wxString
& label
,
214 virtual void DrawCheckItem(wxDC
& dc
,
215 const wxString
& label
,
216 const wxBitmap
& bitmap
,
219 virtual void DrawCheckButton(wxDC
& dc
,
220 const wxString
& label
,
221 const wxBitmap
& bitmap
,
224 wxAlignment align
= wxALIGN_LEFT
,
225 int indexAccel
= -1);
226 virtual void DrawRadioButton(wxDC
& dc
,
227 const wxString
& label
,
228 const wxBitmap
& bitmap
,
231 wxAlignment align
= wxALIGN_LEFT
,
232 int indexAccel
= -1);
233 virtual void DrawToolBarButton(wxDC
& dc
,
234 const wxString
& label
,
235 const wxBitmap
& bitmap
,
238 virtual void DrawTextLine(wxDC
& dc
,
239 const wxString
& text
,
244 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
245 virtual void DrawTab(wxDC
& dc
,
248 const wxString
& label
,
249 const wxBitmap
& bitmap
= wxNullBitmap
,
251 int indexAccel
= -1);
253 virtual void DrawSliderShaft(wxDC
& dc
,
255 wxOrientation orient
,
257 wxRect
*rectShaft
= NULL
);
258 virtual void DrawSliderThumb(wxDC
& dc
,
260 wxOrientation orient
,
262 virtual void DrawSliderTicks(wxDC
& dc
,
264 const wxSize
& sizeThumb
,
265 wxOrientation orient
,
271 virtual void DrawMenuBarItem(wxDC
& dc
,
273 const wxString
& label
,
275 int indexAccel
= -1);
276 virtual void DrawMenuItem(wxDC
& dc
,
278 const wxMenuGeometryInfo
& geometryInfo
,
279 const wxString
& label
,
280 const wxString
& accel
,
281 const wxBitmap
& bitmap
= wxNullBitmap
,
283 int indexAccel
= -1);
284 virtual void DrawMenuSeparator(wxDC
& dc
,
286 const wxMenuGeometryInfo
& geomInfo
);
288 virtual void DrawStatusField(wxDC
& dc
,
290 const wxString
& label
,
294 virtual void DrawFrameTitleBar(wxDC
& dc
,
296 const wxString
& title
,
299 int specialButton
= 0,
300 int specialButtonFlags
= 0);
301 virtual void DrawFrameBorder(wxDC
& dc
,
304 virtual void DrawFrameBackground(wxDC
& dc
,
307 virtual void DrawFrameTitle(wxDC
& dc
,
309 const wxString
& title
,
311 virtual void DrawFrameIcon(wxDC
& dc
,
315 virtual void DrawFrameButton(wxDC
& dc
,
316 wxCoord x
, wxCoord y
,
319 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
320 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
321 virtual wxSize
GetFrameMinSize(int flags
) const;
322 virtual wxSize
GetFrameIconSize() const;
323 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
325 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
327 wxBitmap
*bmpPressed
,
328 wxBitmap
*bmpDisabled
);
330 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
331 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
332 virtual bool AreScrollbarsInsideBorder() const;
334 virtual wxSize
GetScrollbarArrowSize() const
335 { return m_sizeScrollbarArrow
; }
336 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
337 wxScrollBar::Element elem
,
338 int thumbPos
= -1) const;
339 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
340 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
341 const wxPoint
& pt
) const;
342 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
344 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
345 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
346 { return fontHeight
+ 2; }
347 virtual wxSize
GetCheckBitmapSize() const
348 { return wxSize(13, 13); }
349 virtual wxSize
GetRadioBitmapSize() const
350 { return wxSize(12, 12); }
351 virtual wxCoord
GetCheckItemMargin() const
354 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
355 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
356 virtual wxSize
GetToolBarMargin() const
357 { return wxSize(6, 6); }
359 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
360 const wxRect
& rect
) const;
361 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
363 wxCoord
*extraSpaceBeyond
) const;
365 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
366 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
368 virtual wxCoord
GetSliderDim() const { return 20; }
369 virtual wxCoord
GetSliderTickLen() const { return 4; }
370 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
371 wxOrientation orient
) const;
372 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
373 wxOrientation orient
) const;
374 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
376 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
377 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
378 const wxMenu
& menu
) const;
380 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
383 // helper of DrawLabel() and DrawCheckOrRadioButton()
384 void DoDrawLabel(wxDC
& dc
,
385 const wxString
& label
,
388 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
390 wxRect
*rectBounds
= NULL
,
391 const wxPoint
& focusOffset
392 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
394 // common part of DrawLabel() and DrawItem()
395 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
397 // DrawLabel() and DrawButtonLabel() helper
398 void DrawLabelShadow(wxDC
& dc
,
399 const wxString
& label
,
404 // DrawButtonBorder() helper
405 void DoDrawBackground(wxDC
& dc
,
409 // DrawBorder() helpers: all of them shift and clip the DC after drawing
412 // just draw a rectangle with the given pen
413 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
415 // draw the lower left part of rectangle
416 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
418 // draw the rectange using the first brush for the left and top sides and
419 // the second one for the bottom and right ones
420 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
421 const wxPen
& pen1
, const wxPen
& pen2
);
423 // draw the normal 3D border
424 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
426 // draw the sunken 3D border
427 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
429 // draw the border used for scrollbar arrows
430 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
432 // public DrawArrow()s helper
433 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
434 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
436 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
437 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
438 wxArrowDirection arrowDir
,
439 wxArrowStyle arrowStyle
);
441 // DrawCheckButton/DrawRadioButton helper
442 void DrawCheckOrRadioButton(wxDC
& dc
,
443 const wxString
& label
,
444 const wxBitmap
& bitmap
,
449 wxCoord focusOffsetY
);
451 // draw a normal or transposed line (useful for using the same code fo both
452 // horizontal and vertical widgets)
453 void DrawLine(wxDC
& dc
,
454 wxCoord x1
, wxCoord y1
,
455 wxCoord x2
, wxCoord y2
,
456 bool transpose
= FALSE
)
459 dc
.DrawLine(y1
, x1
, y2
, x2
);
461 dc
.DrawLine(x1
, y1
, x2
, y2
);
464 // get the standard check/radio button bitmap
465 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
466 wxBitmap
GetCheckBitmap(int flags
)
467 { return GetIndicator(IndicatorType_Check
, flags
); }
468 wxBitmap
GetRadioBitmap(int flags
)
469 { return GetIndicator(IndicatorType_Radio
, flags
); }
472 const wxColourScheme
*m_scheme
;
474 // the sizing parameters (TODO make them changeable)
475 wxSize m_sizeScrollbarArrow
;
477 // GDI objects we use for drawing
478 wxColour m_colDarkGrey
,
486 wxFont m_titlebarFont
;
488 // the checked and unchecked bitmaps for DrawCheckItem()
489 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
491 // the bitmaps returned by GetIndicator()
492 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
494 [IndicatorStatus_Max
];
497 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
499 // first row is for the normal state, second - for the disabled
500 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
503 // ----------------------------------------------------------------------------
504 // wxWin32InputHandler and derived classes: process the keyboard and mouse
505 // messages according to Windows standards
506 // ----------------------------------------------------------------------------
508 class wxWin32InputHandler
: public wxInputHandler
511 wxWin32InputHandler(wxWin32Renderer
*renderer
);
513 virtual bool HandleKey(wxInputConsumer
*control
,
514 const wxKeyEvent
& event
,
516 virtual bool HandleMouse(wxInputConsumer
*control
,
517 const wxMouseEvent
& event
);
520 wxWin32Renderer
*m_renderer
;
523 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
526 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
527 wxInputHandler
*handler
);
529 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
530 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
532 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
533 const wxControlAction
& action
);
536 virtual bool IsAllowedButton(int button
) { return button
== 1; }
538 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
540 // we don't highlight anything
543 // the first and last event which caused the thumb to move
544 wxMouseEvent m_eventStartDrag
,
547 // have we paused the scrolling because the mouse moved?
550 // we remember the interval of the timer to be able to restart it
554 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
557 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
558 : wxStdCheckboxInputHandler(handler
) { }
560 virtual bool HandleKey(wxInputConsumer
*control
,
561 const wxKeyEvent
& event
,
565 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
568 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
569 : wxStdTextCtrlInputHandler(handler
) { }
571 virtual bool HandleKey(wxInputConsumer
*control
,
572 const wxKeyEvent
& event
,
576 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
579 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
581 virtual bool HandleMouse(wxInputConsumer
*consumer
,
582 const wxMouseEvent
& event
);
584 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
585 const wxMouseEvent
& event
);
588 // is the given point over the statusbar grip?
589 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
592 // the cursor we had replaced with the resize one
593 wxCursor m_cursorOld
;
595 // was the mouse over the grip last time we checked?
599 class wxWin32SystemMenuEvtHandler
;
601 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
604 wxWin32FrameInputHandler(wxInputHandler
*handler
);
605 ~wxWin32FrameInputHandler();
607 virtual bool HandleMouse(wxInputConsumer
*control
,
608 const wxMouseEvent
& event
);
610 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
612 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
615 // was the mouse over the grip last time we checked?
616 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
619 // ----------------------------------------------------------------------------
620 // wxWin32ColourScheme: uses (default) Win32 colours
621 // ----------------------------------------------------------------------------
623 class wxWin32ColourScheme
: public wxColourScheme
626 virtual wxColour
Get(StdColour col
) const;
627 virtual wxColour
GetBackground(wxWindow
*win
) const;
630 // ----------------------------------------------------------------------------
631 // wxWin32ArtProvider
632 // ----------------------------------------------------------------------------
634 class wxWin32ArtProvider
: public wxArtProvider
637 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
638 const wxArtClient
& client
,
642 // ----------------------------------------------------------------------------
644 // ----------------------------------------------------------------------------
646 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
648 class wxWin32Theme
: public wxTheme
652 virtual ~wxWin32Theme();
654 virtual wxRenderer
*GetRenderer();
655 virtual wxArtProvider
*GetArtProvider();
656 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
657 virtual wxColourScheme
*GetColourScheme();
660 // get the default input handler
661 wxInputHandler
*GetDefaultInputHandler();
663 wxWin32Renderer
*m_renderer
;
665 wxWin32ArtProvider
*m_artProvider
;
667 // the names of the already created handlers and the handlers themselves
668 // (these arrays are synchronized)
669 wxSortedArrayString m_handlerNames
;
670 wxArrayHandlers m_handlers
;
672 wxWin32InputHandler
*m_handlerDefault
;
674 wxWin32ColourScheme
*m_scheme
;
676 WX_DECLARE_THEME(win32
)
679 // ----------------------------------------------------------------------------
681 // ----------------------------------------------------------------------------
683 // frame buttons bitmaps
685 static const char *frame_button_close_xpm
[] = {
700 static const char *frame_button_help_xpm
[] = {
715 static const char *frame_button_maximize_xpm
[] = {
730 static const char *frame_button_minimize_xpm
[] = {
745 static const char *frame_button_restore_xpm
[] = {
762 static const char *checked_menu_xpm
[] = {
763 /* columns rows colors chars-per-pixel */
779 static const char *selected_checked_menu_xpm
[] = {
780 /* columns rows colors chars-per-pixel */
796 static const char *disabled_checked_menu_xpm
[] = {
797 /* columns rows colors chars-per-pixel */
814 static const char *selected_disabled_checked_menu_xpm
[] = {
815 /* columns rows colors chars-per-pixel */
831 // checkbox and radiobox bitmaps below
833 static const char *checked_xpm
[] = {
834 /* columns rows colors chars-per-pixel */
857 static const char *pressed_checked_xpm
[] = {
858 /* columns rows colors chars-per-pixel */
880 static const char *pressed_disabled_checked_xpm
[] = {
881 /* columns rows colors chars-per-pixel */
903 static const char *checked_item_xpm
[] = {
904 /* columns rows colors chars-per-pixel */
925 static const char *unchecked_xpm
[] = {
926 /* columns rows colors chars-per-pixel */
949 static const char *pressed_unchecked_xpm
[] = {
950 /* columns rows colors chars-per-pixel */
972 static const char *unchecked_item_xpm
[] = {
973 /* columns rows colors chars-per-pixel */
993 static const char *checked_radio_xpm
[] = {
994 /* columns rows colors chars-per-pixel */
1017 static const char *pressed_checked_radio_xpm
[] = {
1018 /* columns rows colors chars-per-pixel */
1041 static const char *pressed_disabled_checked_radio_xpm
[] = {
1042 /* columns rows colors chars-per-pixel */
1065 static const char *unchecked_radio_xpm
[] = {
1066 /* columns rows colors chars-per-pixel */
1089 static const char *pressed_unchecked_radio_xpm
[] = {
1090 /* columns rows colors chars-per-pixel */
1113 static const char **
1114 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1119 { checked_xpm
, unchecked_xpm
},
1122 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1125 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1131 { checked_radio_xpm
, unchecked_radio_xpm
},
1134 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1137 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1143 { checked_menu_xpm
, NULL
},
1146 { selected_checked_menu_xpm
, NULL
},
1149 { disabled_checked_menu_xpm
, NULL
},
1151 // disabled selected state
1152 { selected_disabled_checked_menu_xpm
, NULL
},
1156 static const char **xpmChecked
[IndicatorStatus_Max
] =
1162 // ============================================================================
1164 // ============================================================================
1166 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1168 // ----------------------------------------------------------------------------
1170 // ----------------------------------------------------------------------------
1172 wxWin32Theme::wxWin32Theme()
1176 m_handlerDefault
= NULL
;
1179 wxWin32Theme::~wxWin32Theme()
1181 size_t count
= m_handlers
.GetCount();
1182 for ( size_t n
= 0; n
< count
; n
++ )
1184 if ( m_handlers
[n
] != m_handlerDefault
)
1185 delete m_handlers
[n
];
1188 delete m_handlerDefault
;
1194 wxRenderer
*wxWin32Theme::GetRenderer()
1198 m_renderer
= new wxWin32Renderer(GetColourScheme());
1204 wxArtProvider
*wxWin32Theme::GetArtProvider()
1206 if ( !m_artProvider
)
1208 m_artProvider
= new wxWin32ArtProvider
;
1211 return m_artProvider
;
1214 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1216 if ( !m_handlerDefault
)
1218 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1221 return m_handlerDefault
;
1224 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1226 wxInputHandler
*handler
;
1227 int n
= m_handlerNames
.Index(control
);
1228 if ( n
== wxNOT_FOUND
)
1230 // create a new handler
1231 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1232 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1233 GetDefaultInputHandler());
1235 else if ( control
== wxINP_HANDLER_BUTTON
)
1236 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1237 #endif // wxUSE_BUTTON
1239 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1240 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1241 #endif // wxUSE_CHECKBOX
1243 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1244 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1245 #endif // wxUSE_COMBOBOX
1247 else if ( control
== wxINP_HANDLER_LISTBOX
)
1248 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1249 #endif // wxUSE_LISTBOX
1250 #if wxUSE_CHECKLISTBOX
1251 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1252 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1253 #endif // wxUSE_CHECKLISTBOX
1255 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1256 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1257 #endif // wxUSE_TEXTCTRL
1259 else if ( control
== wxINP_HANDLER_SLIDER
)
1260 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1261 #endif // wxUSE_SLIDER
1263 else if ( control
== wxINP_HANDLER_SPINBTN
)
1264 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1265 #endif // wxUSE_SPINBTN
1267 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1268 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1269 #endif // wxUSE_NOTEBOOK
1271 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1272 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1273 #endif // wxUSE_STATUSBAR
1275 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1276 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1277 #endif // wxUSE_TOOLBAR
1278 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1279 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1281 handler
= GetDefaultInputHandler();
1283 n
= m_handlerNames
.Add(control
);
1284 m_handlers
.Insert(handler
, n
);
1286 else // we already have it
1288 handler
= m_handlers
[n
];
1294 wxColourScheme
*wxWin32Theme::GetColourScheme()
1298 m_scheme
= new wxWin32ColourScheme
;
1303 // ============================================================================
1304 // wxWin32ColourScheme
1305 // ============================================================================
1307 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1310 if ( win
->UseBgCol() )
1312 // use the user specified colour
1313 col
= win
->GetBackgroundColour();
1316 if ( win
->IsContainerWindow() )
1318 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1321 if ( !text
->IsEnabled() ) // not IsEditable()
1323 //else: execute code below
1328 // doesn't depend on the state
1334 int flags
= win
->GetStateFlags();
1336 // the colour set by the user should be used for the normal state
1337 // and for the states for which we don't have any specific colours
1338 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1340 if ( wxDynamicCast(win
, wxScrollBar
) )
1341 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1351 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1355 // use the system colours under Windows
1356 #if defined(__WXMSW__)
1357 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1359 case CONTROL_PRESSED
:
1360 case CONTROL_CURRENT
:
1361 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1363 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1365 #if defined(COLOR_3DLIGHT)
1366 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1368 case SCROLLBAR
: return wxColour(0xe0e0e0);
1370 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1372 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1373 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1375 #if defined(COLOR_3DDKSHADOW)
1376 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1378 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1381 case CONTROL_TEXT_DISABLED
:
1382 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1384 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1386 case CONTROL_TEXT_DISABLED_SHADOW
:
1387 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1389 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1390 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1391 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1392 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1394 case DESKTOP
: return wxColour(0x808000);
1396 // use the standard Windows colours elsewhere
1397 case WINDOW
: return *wxWHITE
;
1399 case CONTROL_PRESSED
:
1400 case CONTROL_CURRENT
:
1401 case CONTROL
: return wxColour(0xc0c0c0);
1403 case CONTROL_TEXT
: return *wxBLACK
;
1405 case SCROLLBAR
: return wxColour(0xe0e0e0);
1406 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1408 case HIGHLIGHT
: return wxColour(0x800000);
1409 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1411 case SHADOW_DARK
: return *wxBLACK
;
1413 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1414 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1416 case SHADOW_IN
: return wxColour(0xc0c0c0);
1418 case CONTROL_TEXT_DISABLED_SHADOW
:
1419 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1421 case TITLEBAR
: return wxColour(0xaeaaae);
1422 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1423 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1424 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1426 case DESKTOP
: return wxColour(0x808000);
1429 case GAUGE
: return Get(HIGHLIGHT
);
1433 wxFAIL_MSG(_T("invalid standard colour"));
1438 // ============================================================================
1440 // ============================================================================
1442 // ----------------------------------------------------------------------------
1444 // ----------------------------------------------------------------------------
1446 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1450 m_sizeScrollbarArrow
= wxSize(16, 16);
1452 // init colours and pens
1453 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1455 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1456 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1458 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1460 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1461 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1463 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1464 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1466 // init the arrow bitmaps
1467 static const size_t ARROW_WIDTH
= 7;
1468 static const size_t ARROW_LENGTH
= 4;
1471 wxMemoryDC dcNormal
,
1474 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1476 bool isVertical
= n
> Arrow_Right
;
1489 // disabled arrow is larger because of the shadow
1490 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1491 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1493 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1494 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1496 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1497 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1501 dcNormal
.SetPen(m_penBlack
);
1502 dcDisabled
.SetPen(m_penDarkGrey
);
1504 // calculate the position of the point of the arrow
1508 x1
= (ARROW_WIDTH
- 1)/2;
1509 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1513 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1514 y1
= (ARROW_WIDTH
- 1)/2;
1525 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1527 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1528 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1535 if ( n
== Arrow_Up
)
1546 else // left or right arrow
1551 if ( n
== Arrow_Left
)
1564 // draw the shadow for the disabled one
1565 dcDisabled
.SetPen(m_penHighlight
);
1570 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1574 x1
= ARROW_LENGTH
- 1;
1575 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1578 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1579 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1584 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1588 x1
= ARROW_WIDTH
- 1;
1590 x2
= (ARROW_WIDTH
- 1)/2;
1592 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1593 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1598 // create the inversed bitmap but only for the right arrow as we only
1599 // use it for the menus
1600 if ( n
== Arrow_Right
)
1602 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1603 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1605 dcInverse
.Blit(0, 0, w
, h
,
1608 dcInverse
.SelectObject(wxNullBitmap
);
1610 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1611 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1613 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1614 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1616 dcInverse
.Blit(0, 0, w
, h
,
1619 dcInverse
.SelectObject(wxNullBitmap
);
1621 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1622 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1625 dcNormal
.SelectObject(wxNullBitmap
);
1626 dcDisabled
.SelectObject(wxNullBitmap
);
1628 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1629 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1630 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1631 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1633 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1636 // init the frame buttons bitmaps
1637 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1638 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1639 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1640 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1641 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1644 // ----------------------------------------------------------------------------
1646 // ----------------------------------------------------------------------------
1649 The raised border in Win32 looks like this:
1651 IIIIIIIIIIIIIIIIIIIIIIB
1653 I GB I = white (HILIGHT)
1654 I GB H = light grey (LIGHT)
1655 I GB G = dark grey (SHADOI)
1656 I GB B = black (DKSHADOI)
1657 I GB I = hIghlight (COLOR_3DHILIGHT)
1659 IGGGGGGGGGGGGGGGGGGGGGB
1660 BBBBBBBBBBBBBBBBBBBBBBB
1662 The sunken border looks like this:
1664 GGGGGGGGGGGGGGGGGGGGGGI
1665 GBBBBBBBBBBBBBBBBBBBBHI
1672 GHHHHHHHHHHHHHHHHHHHHHI
1673 IIIIIIIIIIIIIIIIIIIIIII
1675 The static border (used for the controls which don't get focus) is like
1678 GGGGGGGGGGGGGGGGGGGGGGW
1686 WWWWWWWWWWWWWWWWWWWWWWW
1688 The most complicated is the double border:
1690 HHHHHHHHHHHHHHHHHHHHHHB
1691 HWWWWWWWWWWWWWWWWWWWWGB
1692 HWHHHHHHHHHHHHHHHHHHHGB
1697 HWHHHHHHHHHHHHHHHHHHHGB
1698 HGGGGGGGGGGGGGGGGGGGGGB
1699 BBBBBBBBBBBBBBBBBBBBBBB
1701 And the simple border is, well, simple:
1703 BBBBBBBBBBBBBBBBBBBBBBB
1712 BBBBBBBBBBBBBBBBBBBBBBB
1715 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1719 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1720 dc
.DrawRectangle(*rect
);
1726 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1728 // draw the bottom and right sides
1730 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1731 rect
->GetRight() + 1, rect
->GetBottom());
1732 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1733 rect
->GetRight(), rect
->GetBottom());
1740 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1741 const wxPen
& pen1
, const wxPen
& pen2
)
1743 // draw the rectangle
1745 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1746 rect
->GetLeft(), rect
->GetBottom());
1747 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1748 rect
->GetRight(), rect
->GetTop());
1750 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1751 rect
->GetRight(), rect
->GetBottom());
1752 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1753 rect
->GetRight() + 1, rect
->GetBottom());
1759 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1761 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1762 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1765 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1767 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1768 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1771 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1775 DrawRect(dc
, rect
, m_penDarkGrey
);
1777 // the arrow is usually drawn inside border of width 2 and is offset by
1778 // another pixel in both directions when it's pressed - as the border
1779 // in this case is more narrow as well, we have to adjust rect like
1787 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1788 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1792 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1794 const wxRect
& rectTotal
,
1795 int WXUNUSED(flags
),
1800 wxRect rect
= rectTotal
;
1804 case wxBORDER_SUNKEN
:
1805 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1807 DrawSunkenBorder(dc
, &rect
);
1811 case wxBORDER_STATIC
:
1812 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1815 case wxBORDER_RAISED
:
1816 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1818 DrawRaisedBorder(dc
, &rect
);
1822 case wxBORDER_DOUBLE
:
1823 DrawArrowBorder(dc
, &rect
);
1824 DrawRect(dc
, &rect
, m_penLightGrey
);
1827 case wxBORDER_SIMPLE
:
1828 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1830 DrawRect(dc
, &rect
, m_penBlack
);
1835 wxFAIL_MSG(_T("unknown border type"));
1838 case wxBORDER_DEFAULT
:
1847 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1852 case wxBORDER_RAISED
:
1853 case wxBORDER_SUNKEN
:
1854 width
= BORDER_THICKNESS
;
1857 case wxBORDER_SIMPLE
:
1858 case wxBORDER_STATIC
:
1862 case wxBORDER_DOUBLE
:
1868 // char *crash = NULL;
1870 wxFAIL_MSG(_T("unknown border type"));
1874 case wxBORDER_DEFAULT
:
1884 rect
.height
= width
;
1889 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1894 // ----------------------------------------------------------------------------
1896 // ----------------------------------------------------------------------------
1898 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1904 // text controls are not special under windows
1905 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1908 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1909 const wxRect
& rectTotal
,
1913 wxRect rect
= rectTotal
;
1915 if ( flags
& wxCONTROL_PRESSED
)
1917 // button pressed: draw a double border around it
1918 DrawRect(dc
, &rect
, m_penBlack
);
1919 DrawRect(dc
, &rect
, m_penDarkGrey
);
1923 // button not pressed
1925 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1927 // button either default or focused (or both): add an extra border around it
1928 DrawRect(dc
, &rect
, m_penBlack
);
1931 // now draw a normal button
1932 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1933 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1942 // ----------------------------------------------------------------------------
1944 // ----------------------------------------------------------------------------
1946 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1947 wxCoord y
, wxCoord x1
, wxCoord x2
)
1949 dc
.SetPen(m_penDarkGrey
);
1950 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1951 dc
.SetPen(m_penHighlight
);
1953 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1956 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1957 wxCoord x
, wxCoord y1
, wxCoord y2
)
1959 dc
.SetPen(m_penDarkGrey
);
1960 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1961 dc
.SetPen(m_penHighlight
);
1963 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1966 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1967 const wxString
& label
,
1973 wxCoord height
= 0; // of the label
1974 wxRect rectFrame
= rect
;
1975 if ( !label
.empty() )
1977 // the text should touch the top border of the rect, so the frame
1978 // itself should be lower
1979 dc
.GetTextExtent(label
, NULL
, &height
);
1980 rectFrame
.y
+= height
/ 2;
1981 rectFrame
.height
-= height
/ 2;
1983 // we have to draw each part of the frame individually as we can't
1984 // erase the background beyond the label as it might contain some
1985 // pixmap already, so drawing everything and then overwriting part of
1986 // the frame with label doesn't work
1988 // TODO: the +5 and space insertion should be customizable
1991 rectText
.x
= rectFrame
.x
+ 5;
1992 rectText
.y
= rect
.y
;
1993 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1994 rectText
.height
= height
;
1997 label2
<< _T(' ') << label
<< _T(' ');
1998 if ( indexAccel
!= -1 )
2000 // adjust it as we prepended a space
2005 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2007 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2011 // just draw the complete frame
2012 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2013 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2017 // ----------------------------------------------------------------------------
2019 // ----------------------------------------------------------------------------
2021 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2023 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2024 // pixels each while we really need dots here... PS_ALTERNATE might
2025 // work, but it is for NT 5 only
2027 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2029 // draw the pixels manually: note that to behave in the same manner as
2030 // DrawRect(), we must exclude the bottom and right borders from the
2032 wxCoord x1
= rect
.GetLeft(),
2034 x2
= rect
.GetRight(),
2035 y2
= rect
.GetBottom();
2037 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2039 // this seems to be closer than what Windows does than wxINVERT although
2040 // I'm still not sure if it's correct
2041 dc
.SetLogicalFunction(wxAND_REVERSE
);
2044 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2045 dc
.DrawPoint(z
, rect
.GetTop());
2047 wxCoord shift
= z
== x2
? 0 : 1;
2048 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2049 dc
.DrawPoint(x2
, z
);
2051 shift
= z
== y2
? 0 : 1;
2052 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2053 dc
.DrawPoint(z
, y2
);
2055 shift
= z
== x1
? 0 : 1;
2056 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2057 dc
.DrawPoint(x1
, z
);
2059 dc
.SetLogicalFunction(wxCOPY
);
2063 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2064 const wxString
& label
,
2069 // draw shadow of the text
2070 dc
.SetTextForeground(m_colHighlight
);
2071 wxRect rectShadow
= rect
;
2074 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2076 // make the text grey
2077 dc
.SetTextForeground(m_colDarkGrey
);
2080 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2081 const wxString
& label
,
2088 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2091 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2092 const wxString
& label
,
2098 const wxPoint
& focusOffset
)
2100 // the underscores are not drawn for focused controls in wxMSW
2101 if ( flags
& wxCONTROL_FOCUSED
)
2106 if ( flags
& wxCONTROL_DISABLED
)
2108 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2109 // currently only can happen for a menu item and it seems that Windows
2110 // doesn't draw the shadow in this case, so we don't do it neither
2111 if ( flags
& wxCONTROL_SELECTED
)
2113 // just make the label text greyed out
2114 dc
.SetTextForeground(m_colDarkGrey
);
2116 else // draw normal disabled label
2118 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2123 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2125 if ( flags
& wxCONTROL_DISABLED
)
2127 // restore the fg colour
2128 dc
.SetTextForeground(*wxBLACK
);
2131 if ( flags
& wxCONTROL_FOCUSED
)
2133 if ( focusOffset
.x
|| focusOffset
.y
)
2135 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2138 DrawFocusRect(dc
, rectLabel
);
2142 *rectBounds
= rectLabel
;
2145 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2146 const wxString
& label
,
2147 const wxBitmap
& image
,
2154 // the underscores are not drawn for focused controls in wxMSW
2155 if ( flags
& wxCONTROL_PRESSED
)
2160 wxRect rectLabel
= rect
;
2161 if ( !label
.empty() )
2163 // shift the label if a button is pressed
2164 if ( flags
& wxCONTROL_PRESSED
)
2170 if ( flags
& wxCONTROL_DISABLED
)
2172 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2175 // leave enough space for the focus rectangle
2176 if ( flags
& wxCONTROL_FOCUSED
)
2178 rectLabel
.Inflate(-2);
2182 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2184 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2186 if ( flags
& wxCONTROL_PRESSED
)
2188 // the focus rectangle is never pressed, so undo the shift done
2196 DrawFocusRect(dc
, rectLabel
);
2200 // ----------------------------------------------------------------------------
2201 // (check)listbox items
2202 // ----------------------------------------------------------------------------
2204 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2205 const wxString
& label
,
2209 wxDCTextColourChanger
colChanger(dc
);
2211 if ( flags
& wxCONTROL_SELECTED
)
2213 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2215 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2216 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2217 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2218 dc
.DrawRectangle(rect
);
2221 wxRect rectText
= rect
;
2223 rectText
.width
-= 2;
2224 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2226 if ( flags
& wxCONTROL_FOCUSED
)
2228 DrawFocusRect(dc
, rect
);
2232 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2233 const wxString
& label
,
2234 const wxBitmap
& bitmap
,
2243 else // use default bitmap
2245 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2246 ? IndicatorStatus_Checked
2247 : IndicatorStatus_Unchecked
;
2249 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2251 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2254 bmp
= m_bmpCheckBitmaps
[i
];
2257 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2258 TRUE
/* use mask */);
2260 wxRect rectLabel
= rect
;
2261 int bmpWidth
= bmp
.GetWidth();
2262 rectLabel
.x
+= bmpWidth
;
2263 rectLabel
.width
-= bmpWidth
;
2265 DrawItem(dc
, label
, rectLabel
, flags
);
2268 // ----------------------------------------------------------------------------
2269 // check/radio buttons
2270 // ----------------------------------------------------------------------------
2272 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2274 IndicatorState indState
;
2275 if ( flags
& wxCONTROL_SELECTED
)
2276 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2277 : IndicatorState_Selected
;
2278 else if ( flags
& wxCONTROL_DISABLED
)
2279 indState
= IndicatorState_Disabled
;
2280 else if ( flags
& wxCONTROL_PRESSED
)
2281 indState
= IndicatorState_Pressed
;
2283 indState
= IndicatorState_Normal
;
2285 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2286 ? IndicatorStatus_Checked
2287 : IndicatorStatus_Unchecked
;
2289 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2292 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2295 // create and cache it
2296 bmp
= wxBitmap(xpm
);
2297 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2304 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2305 const wxString
& label
,
2306 const wxBitmap
& bitmap
,
2311 wxCoord focusOffsetY
)
2313 // calculate the position of the bitmap and of the label
2314 wxCoord heightBmp
= bitmap
.GetHeight();
2316 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2319 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2320 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2322 // align label vertically with the bitmap - looks nicer like this
2323 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2325 // calc horz position
2326 if ( align
== wxALIGN_RIGHT
)
2328 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2329 rectLabel
.x
= rect
.x
+ 3;
2330 rectLabel
.SetRight(xBmp
);
2332 else // normal (checkbox to the left of the text) case
2335 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2336 rectLabel
.SetRight(rect
.GetRight());
2339 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2342 dc
, label
, rectLabel
,
2344 wxALIGN_LEFT
| wxALIGN_TOP
,
2346 NULL
, // we don't need bounding rect
2347 // use custom vert focus rect offset
2348 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2352 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2353 const wxString
& label
,
2354 const wxBitmap
& bitmap
,
2364 bmp
= GetRadioBitmap(flags
);
2366 DrawCheckOrRadioButton(dc
, label
,
2368 rect
, flags
, align
, indexAccel
,
2369 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2372 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2373 const wxString
& label
,
2374 const wxBitmap
& bitmap
,
2384 bmp
= GetCheckBitmap(flags
);
2386 DrawCheckOrRadioButton(dc
, label
,
2388 rect
, flags
, align
, indexAccel
,
2389 0); // no focus rect offset for checkboxes
2392 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2393 const wxString
& label
,
2394 const wxBitmap
& bitmap
,
2395 const wxRect
& rectOrig
,
2398 if ( !label
.empty() || bitmap
.Ok() )
2400 wxRect rect
= rectOrig
;
2401 rect
.Deflate(BORDER_THICKNESS
);
2403 if ( flags
& wxCONTROL_PRESSED
)
2405 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2407 else if ( flags
& wxCONTROL_CURRENT
)
2409 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2412 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2416 // leave a small gap aroudn the line, also account for the toolbar
2418 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2419 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2420 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2424 // ----------------------------------------------------------------------------
2426 // ----------------------------------------------------------------------------
2428 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2429 const wxString
& text
,
2435 // nothing special to do here
2436 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2439 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2441 // we don't draw them
2444 // ----------------------------------------------------------------------------
2446 // ----------------------------------------------------------------------------
2448 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2449 const wxRect
& rectOrig
,
2451 const wxString
& label
,
2452 const wxBitmap
& bitmap
,
2456 wxRect rect
= rectOrig
;
2458 // the current tab is drawn indented (to the top for default case) and
2459 // bigger than the other ones
2460 const wxSize indent
= GetTabIndent();
2461 if ( flags
& wxCONTROL_SELECTED
)
2466 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2470 rect
.Inflate(indent
.x
, 0);
2472 rect
.height
+= indent
.y
;
2476 rect
.Inflate(indent
.x
, 0);
2477 rect
.height
+= indent
.y
;
2482 wxFAIL_MSG(_T("TODO"));
2487 // draw the text, image and the focus around them (if necessary)
2488 wxRect rectLabel
= rect
;
2489 rectLabel
.Deflate(1, 1);
2490 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2491 flags
, wxALIGN_CENTRE
, indexAccel
);
2493 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2494 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2497 x2
= rect
.GetRight(),
2498 y2
= rect
.GetBottom();
2500 // FIXME: all this code will break if the tab indent or the border width,
2501 // it is tied to the fact that both of them are equal to 2
2506 dc
.SetPen(m_penHighlight
);
2507 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2508 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2509 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2511 dc
.SetPen(m_penBlack
);
2512 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2513 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2515 dc
.SetPen(m_penDarkGrey
);
2516 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2518 if ( flags
& wxCONTROL_SELECTED
)
2520 dc
.SetPen(m_penLightGrey
);
2522 // overwrite the part of the border below this tab
2523 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2525 // and the shadow of the tab to the left of us
2526 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2531 dc
.SetPen(m_penHighlight
);
2532 // we need to continue one pixel further to overwrite the corner of
2533 // the border for the selected tab
2534 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2536 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2538 dc
.SetPen(m_penBlack
);
2539 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2540 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2541 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2543 dc
.SetPen(m_penDarkGrey
);
2544 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2545 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2547 if ( flags
& wxCONTROL_SELECTED
)
2549 dc
.SetPen(m_penLightGrey
);
2551 // overwrite the part of the (double!) border above this tab
2552 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2553 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2555 // and the shadow of the tab to the left of us
2556 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2562 wxFAIL_MSG(_T("TODO"));
2566 // ----------------------------------------------------------------------------
2568 // ----------------------------------------------------------------------------
2570 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2571 wxOrientation orient
) const
2575 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2576 if ( orient
== wxHORIZONTAL
)
2578 size
.y
= rect
.height
- 6;
2579 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2583 size
.x
= rect
.width
- 6;
2584 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2590 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2591 wxOrientation orient
) const
2593 static const wxCoord SLIDER_MARGIN
= 6;
2595 wxRect rect
= rectOrig
;
2597 if ( orient
== wxHORIZONTAL
)
2599 // make the rect of minimal width and centre it
2600 rect
.height
= 2*BORDER_THICKNESS
;
2601 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2605 // leave margins on the sides
2606 rect
.Deflate(SLIDER_MARGIN
, 0);
2610 // same as above but in other direction
2611 rect
.width
= 2*BORDER_THICKNESS
;
2612 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2616 rect
.Deflate(0, SLIDER_MARGIN
);
2622 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2623 const wxRect
& rectOrig
,
2624 wxOrientation orient
,
2628 if ( flags
& wxCONTROL_FOCUSED
)
2630 DrawFocusRect(dc
, rectOrig
);
2633 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2638 DrawSunkenBorder(dc
, &rect
);
2641 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2643 wxOrientation orient
,
2647 we are drawing a shape of this form
2652 H DB where H is hightlight colour
2665 The interior of this shape is filled with the hatched brush if the thumb
2669 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2671 bool transpose
= orient
== wxVERTICAL
;
2673 wxCoord x
, y
, x2
, y2
;
2678 x2
= rect
.GetBottom();
2679 y2
= rect
.GetRight();
2685 x2
= rect
.GetRight();
2686 y2
= rect
.GetBottom();
2689 // the size of the pointed part of the thumb
2690 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2692 wxCoord x3
= x
+ sizeArrow
,
2693 y3
= y2
- sizeArrow
;
2695 dc
.SetPen(m_penHighlight
);
2696 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2697 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2698 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2700 dc
.SetPen(m_penBlack
);
2701 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2702 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2704 dc
.SetPen(m_penDarkGrey
);
2705 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2706 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2708 if ( flags
& wxCONTROL_PRESSED
)
2710 // TODO: MSW fills the entire area inside, not just the rect
2711 wxRect rectInt
= rect
;
2713 rectInt
.SetRight(y3
);
2715 rectInt
.SetBottom(y3
);
2718 #if !defined(__WXMGL__)
2719 static const char *stipple_xpm
[] = {
2720 /* columns rows colors chars-per-pixel */
2729 // VS: MGL can only do 8x8 stipple brushes
2730 static const char *stipple_xpm
[] = {
2731 /* columns rows colors chars-per-pixel */
2746 dc
.SetBrush(wxBrush(stipple_xpm
));
2748 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2749 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2750 dc
.SetPen(*wxTRANSPARENT_PEN
);
2751 dc
.DrawRectangle(rectInt
);
2755 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2757 const wxSize
& sizeThumb
,
2758 wxOrientation orient
,
2770 // the variable names correspond to horizontal case, but they can be used
2771 // for both orientations
2772 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2773 if ( orient
== wxHORIZONTAL
)
2775 x1
= rect
.GetLeft();
2776 x2
= rect
.GetRight();
2778 // draw from bottom to top to leave one pixel space between the ticks
2779 // and the slider as Windows do
2780 y1
= rect
.GetBottom();
2785 widthThumb
= sizeThumb
.x
;
2790 x2
= rect
.GetBottom();
2792 y1
= rect
.GetRight();
2793 y2
= rect
.GetLeft();
2797 widthThumb
= sizeThumb
.y
;
2800 // the first tick should be positioned in such way that a thumb drawn in
2801 // the first position points down directly to it
2802 x1
+= widthThumb
/ 2;
2803 x2
-= widthThumb
/ 2;
2805 // this also means that we have slightly less space for the ticks in
2806 // between the first and the last
2809 dc
.SetPen(m_penBlack
);
2811 int range
= end
- start
;
2812 for ( int n
= 0; n
< range
; n
+= step
)
2814 wxCoord x
= x1
+ (len
*n
) / range
;
2816 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2819 // always draw the line at the end position
2820 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2823 // ----------------------------------------------------------------------------
2825 // ----------------------------------------------------------------------------
2827 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2828 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2831 virtual wxSize
GetSize() const { return m_size
; }
2833 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2834 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2836 wxCoord
GetItemHeight() const { return m_heightItem
; }
2839 // the total size of the menu
2842 // the offset of the start of the menu item label
2845 // the offset of the start of the accel label
2848 // the height of a normal (not separator) item
2849 wxCoord m_heightItem
;
2851 friend wxMenuGeometryInfo
*
2852 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2855 // FIXME: all constants are hardcoded but shouldn't be
2856 static const wxCoord MENU_LEFT_MARGIN
= 9;
2857 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2858 static const wxCoord MENU_VERT_MARGIN
= 3;
2860 // the margin around bitmap/check marks (on each side)
2861 static const wxCoord MENU_BMP_MARGIN
= 2;
2863 // the margin between the labels and accel strings
2864 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2866 // the separator height in pixels: in fact, strangely enough, the real height
2867 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2869 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2871 // the size of the standard checkmark bitmap
2872 static const wxCoord MENU_CHECK_SIZE
= 9;
2874 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2875 const wxRect
& rectOrig
,
2876 const wxString
& label
,
2880 wxRect rect
= rectOrig
;
2883 wxDCTextColourChanger
colChanger(dc
);
2885 if ( flags
& wxCONTROL_SELECTED
)
2887 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2889 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2890 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2891 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2892 dc
.DrawRectangle(rect
);
2895 // don't draw the focus rect around menu bar items
2896 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2897 wxALIGN_CENTRE
, indexAccel
);
2900 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2902 const wxMenuGeometryInfo
& gi
,
2903 const wxString
& label
,
2904 const wxString
& accel
,
2905 const wxBitmap
& bitmap
,
2909 const wxWin32MenuGeometryInfo
& geometryInfo
=
2910 (const wxWin32MenuGeometryInfo
&)gi
;
2915 rect
.width
= geometryInfo
.GetSize().x
;
2916 rect
.height
= geometryInfo
.GetItemHeight();
2918 // draw the selected item specially
2919 wxDCTextColourChanger
colChanger(dc
);
2920 if ( flags
& wxCONTROL_SELECTED
)
2922 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2924 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2925 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2926 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2927 dc
.DrawRectangle(rect
);
2930 // draw the bitmap: use the bitmap provided or the standard checkmark for
2931 // the checkable items
2932 wxBitmap bmp
= bitmap
;
2933 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2935 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2940 rect
.SetRight(geometryInfo
.GetLabelOffset());
2941 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2945 rect
.x
= geometryInfo
.GetLabelOffset();
2946 rect
.SetRight(geometryInfo
.GetAccelOffset());
2948 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2950 // draw the accel string
2951 rect
.x
= geometryInfo
.GetAccelOffset();
2952 rect
.SetRight(geometryInfo
.GetSize().x
);
2954 // NB: no accel index here
2955 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2957 // draw the submenu indicator
2958 if ( flags
& wxCONTROL_ISSUBMENU
)
2960 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2961 rect
.width
= MENU_RIGHT_MARGIN
;
2963 wxArrowStyle arrowStyle
;
2964 if ( flags
& wxCONTROL_DISABLED
)
2965 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2967 else if ( flags
& wxCONTROL_SELECTED
)
2968 arrowStyle
= Arrow_Inversed
;
2970 arrowStyle
= Arrow_Normal
;
2972 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2976 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2978 const wxMenuGeometryInfo
& geomInfo
)
2980 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2983 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2985 wxSize size
= sizeText
;
2987 // FIXME: menubar height is configurable under Windows
2994 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2995 const wxMenu
& menu
) const
2997 // prepare the dc: for now we draw all the items with the system font
2999 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3001 // the height of a normal item
3002 wxCoord heightText
= dc
.GetCharHeight();
3007 // the max length of label and accel strings: the menu width is the sum of
3008 // them, even if they're for different items (as the accels should be
3011 // the max length of the bitmap is never 0 as Windows always leaves enough
3012 // space for a check mark indicator
3013 wxCoord widthLabelMax
= 0,
3015 widthBmpMax
= MENU_LEFT_MARGIN
;
3017 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
3019 node
= node
->GetNext() )
3021 // height of this item
3024 wxMenuItem
*item
= node
->GetData();
3025 if ( item
->IsSeparator() )
3027 h
= MENU_SEPARATOR_HEIGHT
;
3029 else // not separator
3034 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3035 if ( widthLabel
> widthLabelMax
)
3037 widthLabelMax
= widthLabel
;
3041 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3042 if ( widthAccel
> widthAccelMax
)
3044 widthAccelMax
= widthAccel
;
3047 const wxBitmap
& bmp
= item
->GetBitmap();
3050 wxCoord widthBmp
= bmp
.GetWidth();
3051 if ( widthBmp
> widthBmpMax
)
3052 widthBmpMax
= widthBmp
;
3054 //else if ( item->IsCheckable() ): no need to check for this as
3055 // MENU_LEFT_MARGIN is big enough to show the check mark
3058 h
+= 2*MENU_VERT_MARGIN
;
3060 // remember the item position and height
3061 item
->SetGeometry(height
, h
);
3066 // bundle the metrics into a struct and return it
3067 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3069 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3070 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3071 if ( widthAccelMax
> 0 )
3073 // if we actually have any accesl, add a margin
3074 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3077 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3079 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3080 gi
->m_size
.y
= height
;
3085 // ----------------------------------------------------------------------------
3087 // ----------------------------------------------------------------------------
3089 static const wxCoord STATBAR_BORDER_X
= 2;
3090 static const wxCoord STATBAR_BORDER_Y
= 2;
3092 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3094 if ( borderBetweenFields
)
3095 *borderBetweenFields
= 2;
3097 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3100 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3102 const wxString
& label
,
3107 if ( flags
& wxCONTROL_ISDEFAULT
)
3109 // draw the size grip: it is a normal rect except that in the lower
3110 // right corner we have several bands which may be used for dragging
3111 // the status bar corner
3113 // each band consists of 4 stripes: m_penHighlight, double
3114 // m_penDarkGrey and transparent one
3115 wxCoord x2
= rect
.GetRight(),
3116 y2
= rect
.GetBottom();
3118 // draw the upper left part of the rect normally
3119 dc
.SetPen(m_penDarkGrey
);
3120 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3121 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3123 // draw the grey stripes of the grip
3125 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3126 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3128 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3129 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3132 // draw the white stripes
3133 dc
.SetPen(m_penHighlight
);
3134 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3135 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3137 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3140 // draw the remaining rect boundaries
3141 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3142 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3143 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3148 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3152 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3155 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3157 wxDCClipper
clipper(dc
, rectIn
);
3158 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3161 // ----------------------------------------------------------------------------
3163 // ----------------------------------------------------------------------------
3165 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3167 wxBitmap
*bmpPressed
,
3168 wxBitmap
*bmpDisabled
)
3170 static const wxCoord widthCombo
= 16;
3171 static const wxCoord heightCombo
= 17;
3177 bmpNormal
->Create(widthCombo
, heightCombo
);
3178 dcMem
.SelectObject(*bmpNormal
);
3179 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3180 Arrow_Down
, Arrow_Normal
);
3185 bmpPressed
->Create(widthCombo
, heightCombo
);
3186 dcMem
.SelectObject(*bmpPressed
);
3187 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3188 Arrow_Down
, Arrow_Pressed
);
3193 bmpDisabled
->Create(widthCombo
, heightCombo
);
3194 dcMem
.SelectObject(*bmpDisabled
);
3195 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3196 Arrow_Down
, Arrow_Disabled
);
3200 // ----------------------------------------------------------------------------
3202 // ----------------------------------------------------------------------------
3204 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3205 const wxColour
& col
,
3208 wxBrush
brush(col
, wxSOLID
);
3210 dc
.SetPen(*wxTRANSPARENT_PEN
);
3211 dc
.DrawRectangle(rect
);
3214 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3215 const wxColour
& col
,
3219 // just fill it with the given or default bg colour
3220 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3221 DoDrawBackground(dc
, colBg
, rect
);
3224 // ----------------------------------------------------------------------------
3226 // ----------------------------------------------------------------------------
3228 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3233 // get the bitmap for this arrow
3234 wxArrowDirection arrowDir
;
3237 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3238 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3239 case wxUP
: arrowDir
= Arrow_Up
; break;
3240 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3243 wxFAIL_MSG(_T("unknown arrow direction"));
3247 wxArrowStyle arrowStyle
;
3248 if ( flags
& wxCONTROL_PRESSED
)
3250 // can't be pressed and disabled
3251 arrowStyle
= Arrow_Pressed
;
3255 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3258 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3261 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3263 wxArrowDirection arrowDir
,
3264 wxArrowStyle arrowStyle
)
3266 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3268 // under Windows the arrows always have the same size so just centre it in
3269 // the provided rectangle
3270 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3271 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3273 // Windows does it like this...
3274 if ( arrowDir
== Arrow_Left
)
3278 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3281 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3282 const wxRect
& rectAll
,
3283 wxArrowDirection arrowDir
,
3284 wxArrowStyle arrowStyle
)
3286 wxRect rect
= rectAll
;
3287 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3288 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3289 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3292 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3293 wxOrientation orient
,
3297 // we don't use the flags, the thumb never changes appearance
3298 wxRect rectThumb
= rect
;
3299 DrawArrowBorder(dc
, &rectThumb
);
3300 DrawBackground(dc
, wxNullColour
, rectThumb
);
3303 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3304 wxOrientation orient
,
3305 const wxRect
& rectBar
,
3308 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3309 ? wxColourScheme::SCROLLBAR_PRESSED
3310 : wxColourScheme::SCROLLBAR
;
3311 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3314 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3316 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3319 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3320 wxScrollBar::Element elem
,
3323 return StandardGetScrollbarRect(scrollbar
, elem
,
3324 thumbPos
, m_sizeScrollbarArrow
);
3327 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3329 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3332 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3333 const wxPoint
& pt
) const
3335 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3338 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3341 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3344 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3347 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3350 // ----------------------------------------------------------------------------
3351 // top level windows
3352 // ----------------------------------------------------------------------------
3354 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3356 wxRect client
= GetFrameClientArea(rect
, flags
);
3358 if ( client
.Inside(pt
) )
3359 return wxHT_TOPLEVEL_CLIENT_AREA
;
3361 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3363 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3365 if ( flags
& wxTOPLEVEL_ICON
)
3367 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3368 return wxHT_TOPLEVEL_ICON
;
3371 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3372 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3373 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3375 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3377 if ( btnRect
.Inside(pt
) )
3378 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3379 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3381 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3383 if ( btnRect
.Inside(pt
) )
3384 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3385 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3387 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3389 if ( btnRect
.Inside(pt
) )
3390 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3391 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3393 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3395 if ( btnRect
.Inside(pt
) )
3396 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3397 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3399 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3401 if ( btnRect
.Inside(pt
) )
3402 return wxHT_TOPLEVEL_BUTTON_HELP
;
3403 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3406 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3407 return wxHT_TOPLEVEL_TITLEBAR
;
3410 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3412 // we are certainly at one of borders, lets decide which one:
3415 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3416 if ( pt
.x
< client
.x
)
3417 border
|= wxHT_TOPLEVEL_BORDER_W
;
3418 else if ( pt
.x
>= client
.width
+ client
.x
)
3419 border
|= wxHT_TOPLEVEL_BORDER_E
;
3420 if ( pt
.y
< client
.y
)
3421 border
|= wxHT_TOPLEVEL_BORDER_N
;
3422 else if ( pt
.y
>= client
.height
+ client
.y
)
3423 border
|= wxHT_TOPLEVEL_BORDER_S
;
3427 return wxHT_NOWHERE
;
3430 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3432 const wxString
& title
,
3436 int specialButtonFlags
)
3438 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3440 DrawFrameBorder(dc
, rect
, flags
);
3442 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3444 DrawFrameBackground(dc
, rect
, flags
);
3445 if ( flags
& wxTOPLEVEL_ICON
)
3446 DrawFrameIcon(dc
, rect
, icon
, flags
);
3447 DrawFrameTitle(dc
, rect
, title
, flags
);
3449 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3451 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3452 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3454 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3456 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3457 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3458 specialButtonFlags
: 0);
3459 x
-= FRAME_BUTTON_WIDTH
+ 2;
3461 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3463 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3464 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3465 specialButtonFlags
: 0);
3466 x
-= FRAME_BUTTON_WIDTH
;
3468 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3470 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3471 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3472 specialButtonFlags
: 0);
3473 x
-= FRAME_BUTTON_WIDTH
;
3475 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3477 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3478 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3479 specialButtonFlags
: 0);
3480 x
-= FRAME_BUTTON_WIDTH
;
3482 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3484 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3485 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3486 specialButtonFlags
: 0);
3487 x
-= FRAME_BUTTON_WIDTH
;
3492 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3496 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3500 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3501 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3502 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3503 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3504 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3507 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3511 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3513 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3514 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3515 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3517 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3518 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3520 DrawBackground(dc
, col
, r
);
3523 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3525 const wxString
& title
,
3528 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3529 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3530 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3532 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3533 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3534 if ( flags
& wxTOPLEVEL_ICON
)
3536 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3537 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3545 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3546 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3547 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3548 r
.width
-= FRAME_BUTTON_WIDTH
;
3549 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3550 r
.width
-= FRAME_BUTTON_WIDTH
;
3551 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3552 r
.width
-= FRAME_BUTTON_WIDTH
;
3553 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3554 r
.width
-= FRAME_BUTTON_WIDTH
;
3556 dc
.SetFont(m_titlebarFont
);
3557 dc
.SetTextForeground(col
);
3560 dc
.GetTextExtent(title
, &textW
, NULL
);
3561 if ( textW
> r
.width
)
3563 // text is too big, let's shorten it and add "..." after it:
3564 size_t len
= title
.length();
3565 wxCoord WSoFar
, letterW
;
3567 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3568 if ( WSoFar
> r
.width
)
3570 // not enough space to draw anything
3576 for (size_t i
= 0; i
< len
; i
++)
3578 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3579 if ( letterW
+ WSoFar
> r
.width
)
3585 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3586 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3589 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3590 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3593 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3600 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3601 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3605 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3606 wxCoord x
, wxCoord y
,
3610 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3615 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3616 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3617 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3618 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3619 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3621 wxFAIL_MSG(wxT("incorrect button specification"));
3624 if ( flags
& wxCONTROL_PRESSED
)
3626 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3627 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3628 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3629 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3633 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3634 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3635 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3636 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3641 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3646 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3648 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3649 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3650 FRAME_BORDER_THICKNESS
;
3653 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3655 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3656 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3662 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3665 wxSize
s(clientSize
);
3667 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3669 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3670 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3671 FRAME_BORDER_THICKNESS
;
3675 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3676 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3681 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3685 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3687 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3688 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3689 FRAME_BORDER_THICKNESS
;
3694 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3696 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3698 if ( flags
& wxTOPLEVEL_ICON
)
3699 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3700 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3701 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3702 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3703 s
.x
+= FRAME_BUTTON_WIDTH
;
3704 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3705 s
.x
+= FRAME_BUTTON_WIDTH
;
3706 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3707 s
.x
+= FRAME_BUTTON_WIDTH
;
3708 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3709 s
.x
+= FRAME_BUTTON_WIDTH
;
3715 wxSize
wxWin32Renderer::GetFrameIconSize() const
3717 return wxSize(16, 16);
3721 // ----------------------------------------------------------------------------
3723 // ----------------------------------------------------------------------------
3725 static char *error_xpm
[]={
3732 "...........########.............",
3733 "........###aaaaaaaa###..........",
3734 ".......#aaaaaaaaaaaaaa#.........",
3735 ".....##aaaaaaaaaaaaaaaa##.......",
3736 "....#aaaaaaaaaaaaaaaaaaaa#......",
3737 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3738 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3739 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3740 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3741 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3742 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3743 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3744 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3745 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3746 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3747 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3748 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3749 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3750 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3751 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3752 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3753 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3754 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3755 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3756 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3757 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3758 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3759 "......b#aaaaaaaaaaaaaa#bbbbb....",
3760 ".......b###aaaaaaaa###bbbbb.....",
3761 ".........bb########bbbbbb.......",
3762 "..........bbbbbbbbbbbbbb........",
3763 ".............bbbbbbbb..........."};
3765 static char *info_xpm
[]={
3773 "...........########.............",
3774 "........###abbbbbba###..........",
3775 "......##abbbbbbbbbbbba##........",
3776 ".....#abbbbbbbbbbbbbbbba#.......",
3777 "....#bbbbbbbaccccabbbbbbbd......",
3778 "...#bbbbbbbbccccccbbbbbbbbd.....",
3779 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3780 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3781 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3782 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3783 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3784 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3785 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3786 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3787 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3788 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3789 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3790 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3791 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3792 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3793 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3794 ".....dabbbbbbbbbbbbbbbbad####...",
3795 "......ddabbbbbbbbbbbbadd####....",
3796 ".......#dddabbbbbbaddd#####.....",
3797 "........###dddabbbd#######......",
3798 "..........####dbbbd#####........",
3799 ".............#dbbbd##...........",
3800 "...............dbbd##...........",
3801 "................dbd##...........",
3802 ".................dd##...........",
3803 "..................###...........",
3804 "...................##..........."};
3806 static char *question_xpm
[]={
3814 "...........########.............",
3815 "........###abbbbbba###..........",
3816 "......##abbbbbbbbbbbba##........",
3817 ".....#abbbbbbbbbbbbbbbba#.......",
3818 "....#bbbbbbbbbbbbbbbbbbbbc......",
3819 "...#bbbbbbbaddddddabbbbbbbc.....",
3820 "..#bbbbbbbadabbddddabbbbbbbc....",
3821 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3822 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3823 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3824 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3825 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3826 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3827 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3828 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3829 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3830 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3831 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3832 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3833 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3834 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3835 ".....cabbbbbbbbbbbbbbbbac####...",
3836 "......ccabbbbbbbbbbbbacc####....",
3837 ".......#cccabbbbbbaccc#####.....",
3838 "........###cccabbbc#######......",
3839 "..........####cbbbc#####........",
3840 ".............#cbbbc##...........",
3841 "...............cbbc##...........",
3842 "................cbc##...........",
3843 ".................cc##...........",
3844 "..................###...........",
3845 "...................##..........."};
3847 static char *warning_xpm
[]={
3855 ".............###................",
3856 "............#aabc...............",
3857 "...........#aaaabcd.............",
3858 "...........#aaaaacdd............",
3859 "..........#aaaaaabcdd...........",
3860 "..........#aaaaaaacdd...........",
3861 ".........#aaaaaaaabcdd..........",
3862 ".........#aaaaaaaaacdd..........",
3863 "........#aaaaaaaaaabcdd.........",
3864 "........#aaabcccbaaacdd.........",
3865 ".......#aaaacccccaaabcdd........",
3866 ".......#aaaacccccaaaacdd........",
3867 "......#aaaaacccccaaaabcdd.......",
3868 "......#aaaaacccccaaaaacdd.......",
3869 ".....#aaaaaacccccaaaaabcdd......",
3870 ".....#aaaaaa#ccc#aaaaaacdd......",
3871 "....#aaaaaaabcccbaaaaaabcdd.....",
3872 "....#aaaaaaaacccaaaaaaaacdd.....",
3873 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3874 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3875 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3876 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3877 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3878 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3879 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3880 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3881 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3882 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3883 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3884 "..#ccccccccccccccccccccccccddddd",
3885 "....ddddddddddddddddddddddddddd.",
3886 ".....ddddddddddddddddddddddddd.."};
3888 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3889 const wxArtClient
& WXUNUSED(client
),
3890 const wxSize
& WXUNUSED(size
))
3892 if ( id
== wxART_INFORMATION
)
3893 return wxBitmap(info_xpm
);
3894 if ( id
== wxART_ERROR
)
3895 return wxBitmap(error_xpm
);
3896 if ( id
== wxART_WARNING
)
3897 return wxBitmap(warning_xpm
);
3898 if ( id
== wxART_QUESTION
)
3899 return wxBitmap(question_xpm
);
3900 return wxNullBitmap
;
3904 // ----------------------------------------------------------------------------
3905 // text control geometry
3906 // ----------------------------------------------------------------------------
3908 static inline int GetTextBorderWidth()
3913 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3914 const wxRect
& rect
) const
3916 wxRect rectTotal
= rect
;
3918 wxCoord widthBorder
= GetTextBorderWidth();
3919 rectTotal
.Inflate(widthBorder
);
3921 // this is what Windows does
3927 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3929 wxCoord
*extraSpaceBeyond
) const
3931 wxRect rectText
= rect
;
3933 // undo GetTextTotalArea()
3934 if ( rectText
.height
> 0 )
3937 wxCoord widthBorder
= GetTextBorderWidth();
3938 rectText
.Inflate(-widthBorder
);
3940 if ( extraSpaceBeyond
)
3941 *extraSpaceBeyond
= 0;
3946 // ----------------------------------------------------------------------------
3948 // ----------------------------------------------------------------------------
3950 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3953 if ( wxDynamicCast(window
, wxScrollBar
) )
3955 // we only set the width of vert scrollbars and height of the
3957 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3958 size
->y
= m_sizeScrollbarArrow
.y
;
3960 size
->x
= m_sizeScrollbarArrow
.x
;
3962 // skip border width adjustments, they don't make sense for us
3965 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3968 if ( wxDynamicCast(window
, wxButton
) )
3970 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3972 // TODO: don't harcode all this
3973 size
->x
+= 3*window
->GetCharWidth();
3975 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3976 if ( size
->y
< heightBtn
- 8 )
3977 size
->y
= heightBtn
;
3982 // no border width adjustments for buttons
3985 #endif // wxUSE_BUTTON
3987 // take into account the border width
3988 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3989 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3990 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3993 // ============================================================================
3995 // ============================================================================
3997 // ----------------------------------------------------------------------------
3998 // wxWin32InputHandler
3999 // ----------------------------------------------------------------------------
4001 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4003 m_renderer
= renderer
;
4006 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
4007 const wxKeyEvent
& event
,
4013 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4014 const wxMouseEvent
& event
)
4016 // clicking on the control gives it focus
4017 if ( event
.ButtonDown() )
4019 wxWindow
*win
= control
->GetInputWindow();
4021 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4022 ( win
->AcceptsFocus() ) )
4033 // ----------------------------------------------------------------------------
4034 // wxWin32ScrollBarInputHandler
4035 // ----------------------------------------------------------------------------
4037 wxWin32ScrollBarInputHandler::
4038 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4039 wxInputHandler
*handler
)
4040 : wxStdScrollBarInputHandler(renderer
, handler
)
4042 m_scrollPaused
= FALSE
;
4046 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4047 const wxControlAction
& action
)
4049 // stop if went beyond the position of the original click (this can only
4050 // happen when we scroll by pages)
4052 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4054 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4055 != wxHT_SCROLLBAR_BAR_2
;
4057 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4059 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4060 != wxHT_SCROLLBAR_BAR_1
;
4065 StopScrolling(scrollbar
);
4067 scrollbar
->Refresh();
4072 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4075 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4076 const wxMouseEvent
& event
)
4078 // remember the current state
4079 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4081 // do process the message
4082 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4084 // analyse the changes
4085 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4087 // we just started dragging the thumb, remember its initial position to
4088 // be able to restore it if the drag is cancelled later
4089 m_eventStartDrag
= event
;
4095 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4096 const wxMouseEvent
& event
)
4098 // we don't highlight scrollbar elements, so there is no need to process
4099 // mouse move events normally - only do it while mouse is captured (i.e.
4100 // when we're dragging the thumb or pressing on something)
4101 if ( !m_winCapture
)
4104 if ( event
.Entering() )
4106 // we're not interested in this at all
4110 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4112 if ( m_scrollPaused
)
4114 // check if the mouse returned to its original location
4116 if ( event
.Leaving() )
4122 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4123 if ( ht
== m_htLast
)
4125 // yes it did, resume scrolling
4126 m_scrollPaused
= FALSE
;
4127 if ( m_timerScroll
)
4129 // we were scrolling by line/page, restart timer
4130 m_timerScroll
->Start(m_interval
);
4132 Press(scrollbar
, TRUE
);
4134 else // we were dragging the thumb
4136 // restore its last location
4137 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4143 else // normal case, scrolling hasn't been paused
4145 // if we're scrolling the scrollbar because the arrow or the shaft was
4146 // pressed, check that the mouse stays on the same scrollbar element
4148 if ( event
.Moving() )
4150 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4152 else // event.Leaving()
4157 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4158 // is still ok - we only want to catch the case when the mouse leaves
4159 // the scrollbar here
4160 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4162 ht
= wxHT_SCROLLBAR_THUMB
;
4165 if ( ht
!= m_htLast
)
4167 // what were we doing? 2 possibilities: either an arrow/shaft was
4168 // pressed in which case we have a timer and so we just stop it or
4169 // we were dragging the thumb
4170 if ( m_timerScroll
)
4173 m_interval
= m_timerScroll
->GetInterval();
4174 m_timerScroll
->Stop();
4175 m_scrollPaused
= TRUE
;
4177 // unpress the arrow
4178 Press(scrollbar
, FALSE
);
4180 else // we were dragging the thumb
4182 // remember the current thumb position to be able to restore it
4183 // if the mouse returns to it later
4184 m_eventLastDrag
= event
;
4186 // and restore the original position (before dragging) of the
4188 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4195 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4198 // ----------------------------------------------------------------------------
4199 // wxWin32CheckboxInputHandler
4200 // ----------------------------------------------------------------------------
4202 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4203 const wxKeyEvent
& event
,
4208 wxControlAction action
;
4209 int keycode
= event
.GetKeyCode();
4213 action
= wxACTION_CHECKBOX_TOGGLE
;
4217 case WXK_NUMPAD_SUBTRACT
:
4218 action
= wxACTION_CHECKBOX_CHECK
;
4222 case WXK_NUMPAD_ADD
:
4223 case WXK_NUMPAD_EQUAL
:
4224 action
= wxACTION_CHECKBOX_CLEAR
;
4230 control
->PerformAction(action
);
4239 // ----------------------------------------------------------------------------
4240 // wxWin32TextCtrlInputHandler
4241 // ----------------------------------------------------------------------------
4243 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4244 const wxKeyEvent
& event
,
4247 // handle only MSW-specific text bindings here, the others are handled in
4251 int keycode
= event
.GetKeyCode();
4253 wxControlAction action
;
4254 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4256 action
= wxACTION_TEXT_CUT
;
4258 else if ( keycode
== WXK_INSERT
)
4260 if ( event
.ControlDown() )
4261 action
= wxACTION_TEXT_COPY
;
4262 else if ( event
.ShiftDown() )
4263 action
= wxACTION_TEXT_PASTE
;
4266 if ( action
!= wxACTION_NONE
)
4268 control
->PerformAction(action
);
4274 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4277 // ----------------------------------------------------------------------------
4278 // wxWin32StatusBarInputHandler
4279 // ----------------------------------------------------------------------------
4281 wxWin32StatusBarInputHandler::
4282 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4283 : wxStdInputHandler(handler
)
4288 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4289 const wxPoint
& pt
) const
4291 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4292 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4295 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4297 wxCHECK_MSG( parentTLW
, FALSE
,
4298 _T("the status bar should be a child of a TLW") );
4300 // a maximized window can't be resized anyhow
4301 if ( !parentTLW
->IsMaximized() )
4303 // VZ: I think that the standard Windows behaviour is to only
4304 // show the resizing cursor when the mouse is on top of the
4305 // grip itself but apparently different Windows versions behave
4306 // differently (?) and it seems a better UI to allow resizing
4307 // the status bar even when the mouse is above the grip
4308 wxSize sizeSbar
= statbar
->GetSize();
4310 int diff
= sizeSbar
.x
- pt
.x
;
4311 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4318 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4319 const wxMouseEvent
& event
)
4321 if ( event
.Button(1) )
4323 if ( event
.ButtonDown(1) )
4325 wxWindow
*statbar
= consumer
->GetInputWindow();
4327 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4329 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4333 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4334 wxHT_TOPLEVEL_BORDER_SE
);
4336 statbar
->SetCursor(m_cursorOld
);
4344 return wxStdInputHandler::HandleMouse(consumer
, event
);
4347 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4348 const wxMouseEvent
& event
)
4350 wxWindow
*statbar
= consumer
->GetInputWindow();
4352 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4353 if ( isOnGrip
!= m_isOnGrip
)
4355 m_isOnGrip
= isOnGrip
;
4358 m_cursorOld
= statbar
->GetCursor();
4359 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4363 statbar
->SetCursor(m_cursorOld
);
4367 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4370 // ----------------------------------------------------------------------------
4371 // wxWin32FrameInputHandler
4372 // ----------------------------------------------------------------------------
4374 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4377 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4379 void Attach(wxInputConsumer
*consumer
);
4383 DECLARE_EVENT_TABLE()
4384 void OnSystemMenu(wxCommandEvent
&event
);
4385 void OnCloseFrame(wxCommandEvent
&event
);
4386 void OnClose(wxCloseEvent
&event
);
4388 wxWin32FrameInputHandler
*m_inputHnd
;
4389 wxTopLevelWindow
*m_wnd
;
4390 wxAcceleratorTable m_oldAccelTable
;
4393 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4394 wxWin32FrameInputHandler
*handler
)
4396 m_inputHnd
= handler
;
4400 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4402 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4404 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4405 m_wnd
->PushEventHandler(this);
4407 // VS: This code relies on using generic implementation of
4408 // wxAcceleratorTable in wxUniv!
4409 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4410 m_oldAccelTable
= table
;
4411 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4412 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4413 m_wnd
->SetAcceleratorTable(table
);
4416 void wxWin32SystemMenuEvtHandler::Detach()
4420 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4421 m_wnd
->RemoveEventHandler(this);
4426 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4427 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4428 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4429 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4432 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4434 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4435 !m_wnd
->IsMaximized()) ?
4436 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4437 FRAME_BORDER_THICKNESS
;
4438 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4439 pt
.x
= -pt
.x
+ border
;
4440 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4442 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4443 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4444 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4445 m_wnd
->SetAcceleratorTable(table
);
4448 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4450 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4451 wxTOPLEVEL_BUTTON_CLOSE
);
4454 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4461 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4462 : wxStdFrameInputHandler(handler
)
4464 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4467 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4469 if ( m_menuHandler
)
4471 m_menuHandler
->Detach();
4472 delete m_menuHandler
;
4476 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4477 const wxMouseEvent
& event
)
4479 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4481 wxTopLevelWindow
*tlw
=
4482 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4484 long hit
= tlw
->HitTest(event
.GetPosition());
4486 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4488 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4489 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4490 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4493 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4495 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4496 (event
.RightDown() &&
4497 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4498 hit
== wxHT_TOPLEVEL_ICON
)) )
4500 PopupSystemMenu(tlw
, event
.GetPosition());
4506 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4509 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4510 const wxPoint
& pos
) const
4512 wxMenu
*menu
= new wxMenu
;
4514 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4515 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4516 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4517 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4518 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4519 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4520 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4521 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4522 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4523 menu
->AppendSeparator();
4524 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4526 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4528 if ( window
->IsMaximized() )
4530 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4531 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4532 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4533 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4536 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4539 window
->PopupMenu(menu
, pos
);
4543 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4546 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4548 // always detach if active frame changed:
4549 m_menuHandler
->Detach();
4553 m_menuHandler
->Attach(consumer
);
4557 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);