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
:
1867 wxFAIL_MSG(_T("unknown border type"));
1870 case wxBORDER_DEFAULT
:
1880 rect
.height
= width
;
1885 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1890 // ----------------------------------------------------------------------------
1892 // ----------------------------------------------------------------------------
1894 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1900 // text controls are not special under windows
1901 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1904 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1905 const wxRect
& rectTotal
,
1909 wxRect rect
= rectTotal
;
1911 if ( flags
& wxCONTROL_PRESSED
)
1913 // button pressed: draw a double border around it
1914 DrawRect(dc
, &rect
, m_penBlack
);
1915 DrawRect(dc
, &rect
, m_penDarkGrey
);
1919 // button not pressed
1921 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1923 // button either default or focused (or both): add an extra border around it
1924 DrawRect(dc
, &rect
, m_penBlack
);
1927 // now draw a normal button
1928 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1929 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1938 // ----------------------------------------------------------------------------
1940 // ----------------------------------------------------------------------------
1942 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1943 wxCoord y
, wxCoord x1
, wxCoord x2
)
1945 dc
.SetPen(m_penDarkGrey
);
1946 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1947 dc
.SetPen(m_penHighlight
);
1949 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1952 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1953 wxCoord x
, wxCoord y1
, wxCoord y2
)
1955 dc
.SetPen(m_penDarkGrey
);
1956 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1957 dc
.SetPen(m_penHighlight
);
1959 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1962 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1963 const wxString
& label
,
1969 wxCoord height
= 0; // of the label
1970 wxRect rectFrame
= rect
;
1971 if ( !label
.empty() )
1973 // the text should touch the top border of the rect, so the frame
1974 // itself should be lower
1975 dc
.GetTextExtent(label
, NULL
, &height
);
1976 rectFrame
.y
+= height
/ 2;
1977 rectFrame
.height
-= height
/ 2;
1979 // we have to draw each part of the frame individually as we can't
1980 // erase the background beyond the label as it might contain some
1981 // pixmap already, so drawing everything and then overwriting part of
1982 // the frame with label doesn't work
1984 // TODO: the +5 and space insertion should be customizable
1987 rectText
.x
= rectFrame
.x
+ 5;
1988 rectText
.y
= rect
.y
;
1989 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1990 rectText
.height
= height
;
1993 label2
<< _T(' ') << label
<< _T(' ');
1994 if ( indexAccel
!= -1 )
1996 // adjust it as we prepended a space
2001 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2003 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2007 // just draw the complete frame
2008 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2009 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2013 // ----------------------------------------------------------------------------
2015 // ----------------------------------------------------------------------------
2017 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2019 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2020 // pixels each while we really need dots here... PS_ALTERNATE might
2021 // work, but it is for NT 5 only
2023 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2025 // draw the pixels manually: note that to behave in the same manner as
2026 // DrawRect(), we must exclude the bottom and right borders from the
2028 wxCoord x1
= rect
.GetLeft(),
2030 x2
= rect
.GetRight(),
2031 y2
= rect
.GetBottom();
2033 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2035 // this seems to be closer than what Windows does than wxINVERT although
2036 // I'm still not sure if it's correct
2037 dc
.SetLogicalFunction(wxAND_REVERSE
);
2040 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2041 dc
.DrawPoint(z
, rect
.GetTop());
2043 wxCoord shift
= z
== x2
? 0 : 1;
2044 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2045 dc
.DrawPoint(x2
, z
);
2047 shift
= z
== y2
? 0 : 1;
2048 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2049 dc
.DrawPoint(z
, y2
);
2051 shift
= z
== x1
? 0 : 1;
2052 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2053 dc
.DrawPoint(x1
, z
);
2055 dc
.SetLogicalFunction(wxCOPY
);
2059 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2060 const wxString
& label
,
2065 // draw shadow of the text
2066 dc
.SetTextForeground(m_colHighlight
);
2067 wxRect rectShadow
= rect
;
2070 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2072 // make the text grey
2073 dc
.SetTextForeground(m_colDarkGrey
);
2076 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2077 const wxString
& label
,
2084 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2087 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2088 const wxString
& label
,
2094 const wxPoint
& focusOffset
)
2096 // the underscores are not drawn for focused controls in wxMSW
2097 if ( flags
& wxCONTROL_FOCUSED
)
2102 if ( flags
& wxCONTROL_DISABLED
)
2104 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2105 // currently only can happen for a menu item and it seems that Windows
2106 // doesn't draw the shadow in this case, so we don't do it neither
2107 if ( flags
& wxCONTROL_SELECTED
)
2109 // just make the label text greyed out
2110 dc
.SetTextForeground(m_colDarkGrey
);
2112 else // draw normal disabled label
2114 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2119 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2121 if ( flags
& wxCONTROL_DISABLED
)
2123 // restore the fg colour
2124 dc
.SetTextForeground(*wxBLACK
);
2127 if ( flags
& wxCONTROL_FOCUSED
)
2129 if ( focusOffset
.x
|| focusOffset
.y
)
2131 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2134 DrawFocusRect(dc
, rectLabel
);
2138 *rectBounds
= rectLabel
;
2141 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2142 const wxString
& label
,
2143 const wxBitmap
& image
,
2150 // the underscores are not drawn for focused controls in wxMSW
2151 if ( flags
& wxCONTROL_PRESSED
)
2156 wxRect rectLabel
= rect
;
2157 if ( !label
.empty() )
2159 // shift the label if a button is pressed
2160 if ( flags
& wxCONTROL_PRESSED
)
2166 if ( flags
& wxCONTROL_DISABLED
)
2168 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2171 // leave enough space for the focus rectangle
2172 if ( flags
& wxCONTROL_FOCUSED
)
2174 rectLabel
.Inflate(-2);
2178 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2180 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2182 if ( flags
& wxCONTROL_PRESSED
)
2184 // the focus rectangle is never pressed, so undo the shift done
2192 DrawFocusRect(dc
, rectLabel
);
2196 // ----------------------------------------------------------------------------
2197 // (check)listbox items
2198 // ----------------------------------------------------------------------------
2200 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2201 const wxString
& label
,
2205 wxDCTextColourChanger
colChanger(dc
);
2207 if ( flags
& wxCONTROL_SELECTED
)
2209 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2211 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2212 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2213 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2214 dc
.DrawRectangle(rect
);
2217 wxRect rectText
= rect
;
2219 rectText
.width
-= 2;
2220 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2222 if ( flags
& wxCONTROL_FOCUSED
)
2224 DrawFocusRect(dc
, rect
);
2228 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2229 const wxString
& label
,
2230 const wxBitmap
& bitmap
,
2239 else // use default bitmap
2241 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2242 ? IndicatorStatus_Checked
2243 : IndicatorStatus_Unchecked
;
2245 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2247 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2250 bmp
= m_bmpCheckBitmaps
[i
];
2253 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2254 TRUE
/* use mask */);
2256 wxRect rectLabel
= rect
;
2257 int bmpWidth
= bmp
.GetWidth();
2258 rectLabel
.x
+= bmpWidth
;
2259 rectLabel
.width
-= bmpWidth
;
2261 DrawItem(dc
, label
, rectLabel
, flags
);
2264 // ----------------------------------------------------------------------------
2265 // check/radio buttons
2266 // ----------------------------------------------------------------------------
2268 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2270 IndicatorState indState
;
2271 if ( flags
& wxCONTROL_SELECTED
)
2272 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2273 : IndicatorState_Selected
;
2274 else if ( flags
& wxCONTROL_DISABLED
)
2275 indState
= IndicatorState_Disabled
;
2276 else if ( flags
& wxCONTROL_PRESSED
)
2277 indState
= IndicatorState_Pressed
;
2279 indState
= IndicatorState_Normal
;
2281 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2282 ? IndicatorStatus_Checked
2283 : IndicatorStatus_Unchecked
;
2285 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2288 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2291 // create and cache it
2292 bmp
= wxBitmap(xpm
);
2293 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2300 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2301 const wxString
& label
,
2302 const wxBitmap
& bitmap
,
2307 wxCoord focusOffsetY
)
2309 // calculate the position of the bitmap and of the label
2310 wxCoord heightBmp
= bitmap
.GetHeight();
2312 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2315 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2316 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2318 // align label vertically with the bitmap - looks nicer like this
2319 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2321 // calc horz position
2322 if ( align
== wxALIGN_RIGHT
)
2324 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2325 rectLabel
.x
= rect
.x
+ 3;
2326 rectLabel
.SetRight(xBmp
);
2328 else // normal (checkbox to the left of the text) case
2331 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2332 rectLabel
.SetRight(rect
.GetRight());
2335 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2338 dc
, label
, rectLabel
,
2340 wxALIGN_LEFT
| wxALIGN_TOP
,
2342 NULL
, // we don't need bounding rect
2343 // use custom vert focus rect offset
2344 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2348 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2349 const wxString
& label
,
2350 const wxBitmap
& bitmap
,
2360 bmp
= GetRadioBitmap(flags
);
2362 DrawCheckOrRadioButton(dc
, label
,
2364 rect
, flags
, align
, indexAccel
,
2365 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2368 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2369 const wxString
& label
,
2370 const wxBitmap
& bitmap
,
2380 bmp
= GetCheckBitmap(flags
);
2382 DrawCheckOrRadioButton(dc
, label
,
2384 rect
, flags
, align
, indexAccel
,
2385 0); // no focus rect offset for checkboxes
2388 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2389 const wxString
& label
,
2390 const wxBitmap
& bitmap
,
2391 const wxRect
& rectOrig
,
2394 if ( !label
.empty() || bitmap
.Ok() )
2396 wxRect rect
= rectOrig
;
2397 rect
.Deflate(BORDER_THICKNESS
);
2399 if ( flags
& wxCONTROL_PRESSED
)
2401 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2403 else if ( flags
& wxCONTROL_CURRENT
)
2405 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2408 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2412 // leave a small gap aroudn the line, also account for the toolbar
2414 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2415 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2416 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2420 // ----------------------------------------------------------------------------
2422 // ----------------------------------------------------------------------------
2424 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2425 const wxString
& text
,
2431 // nothing special to do here
2432 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2435 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2437 // we don't draw them
2440 // ----------------------------------------------------------------------------
2442 // ----------------------------------------------------------------------------
2444 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2445 const wxRect
& rectOrig
,
2447 const wxString
& label
,
2448 const wxBitmap
& bitmap
,
2452 wxRect rect
= rectOrig
;
2454 // the current tab is drawn indented (to the top for default case) and
2455 // bigger than the other ones
2456 const wxSize indent
= GetTabIndent();
2457 if ( flags
& wxCONTROL_SELECTED
)
2462 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2466 rect
.Inflate(indent
.x
, 0);
2468 rect
.height
+= indent
.y
;
2472 rect
.Inflate(indent
.x
, 0);
2473 rect
.height
+= indent
.y
;
2478 wxFAIL_MSG(_T("TODO"));
2483 // draw the text, image and the focus around them (if necessary)
2484 wxRect rectLabel
= rect
;
2485 rectLabel
.Deflate(1, 1);
2486 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2487 flags
, wxALIGN_CENTRE
, indexAccel
);
2489 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2490 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2493 x2
= rect
.GetRight(),
2494 y2
= rect
.GetBottom();
2496 // FIXME: all this code will break if the tab indent or the border width,
2497 // it is tied to the fact that both of them are equal to 2
2502 dc
.SetPen(m_penHighlight
);
2503 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2504 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2505 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2507 dc
.SetPen(m_penBlack
);
2508 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2509 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2511 dc
.SetPen(m_penDarkGrey
);
2512 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2514 if ( flags
& wxCONTROL_SELECTED
)
2516 dc
.SetPen(m_penLightGrey
);
2518 // overwrite the part of the border below this tab
2519 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2521 // and the shadow of the tab to the left of us
2522 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2527 dc
.SetPen(m_penHighlight
);
2528 // we need to continue one pixel further to overwrite the corner of
2529 // the border for the selected tab
2530 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2532 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2534 dc
.SetPen(m_penBlack
);
2535 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2536 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2537 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2539 dc
.SetPen(m_penDarkGrey
);
2540 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2541 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2543 if ( flags
& wxCONTROL_SELECTED
)
2545 dc
.SetPen(m_penLightGrey
);
2547 // overwrite the part of the (double!) border above this tab
2548 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2549 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2551 // and the shadow of the tab to the left of us
2552 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2558 wxFAIL_MSG(_T("TODO"));
2562 // ----------------------------------------------------------------------------
2564 // ----------------------------------------------------------------------------
2566 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2567 wxOrientation orient
) const
2571 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2572 if ( orient
== wxHORIZONTAL
)
2574 size
.y
= rect
.height
- 6;
2575 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2579 size
.x
= rect
.width
- 6;
2580 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2586 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2587 wxOrientation orient
) const
2589 static const wxCoord SLIDER_MARGIN
= 6;
2591 wxRect rect
= rectOrig
;
2593 if ( orient
== wxHORIZONTAL
)
2595 // make the rect of minimal width and centre it
2596 rect
.height
= 2*BORDER_THICKNESS
;
2597 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2601 // leave margins on the sides
2602 rect
.Deflate(SLIDER_MARGIN
, 0);
2606 // same as above but in other direction
2607 rect
.width
= 2*BORDER_THICKNESS
;
2608 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2612 rect
.Deflate(0, SLIDER_MARGIN
);
2618 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2619 const wxRect
& rectOrig
,
2620 wxOrientation orient
,
2624 if ( flags
& wxCONTROL_FOCUSED
)
2626 DrawFocusRect(dc
, rectOrig
);
2629 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2634 DrawSunkenBorder(dc
, &rect
);
2637 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2639 wxOrientation orient
,
2643 we are drawing a shape of this form
2648 H DB where H is hightlight colour
2661 The interior of this shape is filled with the hatched brush if the thumb
2665 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2667 bool transpose
= orient
== wxVERTICAL
;
2669 wxCoord x
, y
, x2
, y2
;
2674 x2
= rect
.GetBottom();
2675 y2
= rect
.GetRight();
2681 x2
= rect
.GetRight();
2682 y2
= rect
.GetBottom();
2685 // the size of the pointed part of the thumb
2686 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2688 wxCoord x3
= x
+ sizeArrow
,
2689 y3
= y2
- sizeArrow
;
2691 dc
.SetPen(m_penHighlight
);
2692 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2693 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2694 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2696 dc
.SetPen(m_penBlack
);
2697 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2698 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2700 dc
.SetPen(m_penDarkGrey
);
2701 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2702 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2704 if ( flags
& wxCONTROL_PRESSED
)
2706 // TODO: MSW fills the entire area inside, not just the rect
2707 wxRect rectInt
= rect
;
2709 rectInt
.SetRight(y3
);
2711 rectInt
.SetBottom(y3
);
2714 #if !defined(__WXMGL__)
2715 static const char *stipple_xpm
[] = {
2716 /* columns rows colors chars-per-pixel */
2725 // VS: MGL can only do 8x8 stipple brushes
2726 static const char *stipple_xpm
[] = {
2727 /* columns rows colors chars-per-pixel */
2742 dc
.SetBrush(wxBrush(stipple_xpm
));
2744 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2745 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2746 dc
.SetPen(*wxTRANSPARENT_PEN
);
2747 dc
.DrawRectangle(rectInt
);
2751 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2753 const wxSize
& sizeThumb
,
2754 wxOrientation orient
,
2766 // the variable names correspond to horizontal case, but they can be used
2767 // for both orientations
2768 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2769 if ( orient
== wxHORIZONTAL
)
2771 x1
= rect
.GetLeft();
2772 x2
= rect
.GetRight();
2774 // draw from bottom to top to leave one pixel space between the ticks
2775 // and the slider as Windows do
2776 y1
= rect
.GetBottom();
2781 widthThumb
= sizeThumb
.x
;
2786 x2
= rect
.GetBottom();
2788 y1
= rect
.GetRight();
2789 y2
= rect
.GetLeft();
2793 widthThumb
= sizeThumb
.y
;
2796 // the first tick should be positioned in such way that a thumb drawn in
2797 // the first position points down directly to it
2798 x1
+= widthThumb
/ 2;
2799 x2
-= widthThumb
/ 2;
2801 // this also means that we have slightly less space for the ticks in
2802 // between the first and the last
2805 dc
.SetPen(m_penBlack
);
2807 int range
= end
- start
;
2808 for ( int n
= 0; n
< range
; n
+= step
)
2810 wxCoord x
= x1
+ (len
*n
) / range
;
2812 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2815 // always draw the line at the end position
2816 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2819 // ----------------------------------------------------------------------------
2821 // ----------------------------------------------------------------------------
2823 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2824 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2827 virtual wxSize
GetSize() const { return m_size
; }
2829 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2830 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2832 wxCoord
GetItemHeight() const { return m_heightItem
; }
2835 // the total size of the menu
2838 // the offset of the start of the menu item label
2841 // the offset of the start of the accel label
2844 // the height of a normal (not separator) item
2845 wxCoord m_heightItem
;
2847 friend wxMenuGeometryInfo
*
2848 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2851 // FIXME: all constants are hardcoded but shouldn't be
2852 static const wxCoord MENU_LEFT_MARGIN
= 9;
2853 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2854 static const wxCoord MENU_VERT_MARGIN
= 3;
2856 // the margin around bitmap/check marks (on each side)
2857 static const wxCoord MENU_BMP_MARGIN
= 2;
2859 // the margin between the labels and accel strings
2860 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2862 // the separator height in pixels: in fact, strangely enough, the real height
2863 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2865 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2867 // the size of the standard checkmark bitmap
2868 static const wxCoord MENU_CHECK_SIZE
= 9;
2870 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2871 const wxRect
& rectOrig
,
2872 const wxString
& label
,
2876 wxRect rect
= rectOrig
;
2879 wxDCTextColourChanger
colChanger(dc
);
2881 if ( flags
& wxCONTROL_SELECTED
)
2883 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2885 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2886 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2887 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2888 dc
.DrawRectangle(rect
);
2891 // don't draw the focus rect around menu bar items
2892 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2893 wxALIGN_CENTRE
, indexAccel
);
2896 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2898 const wxMenuGeometryInfo
& gi
,
2899 const wxString
& label
,
2900 const wxString
& accel
,
2901 const wxBitmap
& bitmap
,
2905 const wxWin32MenuGeometryInfo
& geometryInfo
=
2906 (const wxWin32MenuGeometryInfo
&)gi
;
2911 rect
.width
= geometryInfo
.GetSize().x
;
2912 rect
.height
= geometryInfo
.GetItemHeight();
2914 // draw the selected item specially
2915 wxDCTextColourChanger
colChanger(dc
);
2916 if ( flags
& wxCONTROL_SELECTED
)
2918 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2920 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2921 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2922 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2923 dc
.DrawRectangle(rect
);
2926 // draw the bitmap: use the bitmap provided or the standard checkmark for
2927 // the checkable items
2928 wxBitmap bmp
= bitmap
;
2929 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2931 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2936 rect
.SetRight(geometryInfo
.GetLabelOffset());
2937 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2941 rect
.x
= geometryInfo
.GetLabelOffset();
2942 rect
.SetRight(geometryInfo
.GetAccelOffset());
2944 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2946 // draw the accel string
2947 rect
.x
= geometryInfo
.GetAccelOffset();
2948 rect
.SetRight(geometryInfo
.GetSize().x
);
2950 // NB: no accel index here
2951 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2953 // draw the submenu indicator
2954 if ( flags
& wxCONTROL_ISSUBMENU
)
2956 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2957 rect
.width
= MENU_RIGHT_MARGIN
;
2959 wxArrowStyle arrowStyle
;
2960 if ( flags
& wxCONTROL_DISABLED
)
2961 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2963 else if ( flags
& wxCONTROL_SELECTED
)
2964 arrowStyle
= Arrow_Inversed
;
2966 arrowStyle
= Arrow_Normal
;
2968 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2972 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2974 const wxMenuGeometryInfo
& geomInfo
)
2976 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2979 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2981 wxSize size
= sizeText
;
2983 // FIXME: menubar height is configurable under Windows
2990 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2991 const wxMenu
& menu
) const
2993 // prepare the dc: for now we draw all the items with the system font
2995 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2997 // the height of a normal item
2998 wxCoord heightText
= dc
.GetCharHeight();
3003 // the max length of label and accel strings: the menu width is the sum of
3004 // them, even if they're for different items (as the accels should be
3007 // the max length of the bitmap is never 0 as Windows always leaves enough
3008 // space for a check mark indicator
3009 wxCoord widthLabelMax
= 0,
3011 widthBmpMax
= MENU_LEFT_MARGIN
;
3013 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
3015 node
= node
->GetNext() )
3017 // height of this item
3020 wxMenuItem
*item
= node
->GetData();
3021 if ( item
->IsSeparator() )
3023 h
= MENU_SEPARATOR_HEIGHT
;
3025 else // not separator
3030 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3031 if ( widthLabel
> widthLabelMax
)
3033 widthLabelMax
= widthLabel
;
3037 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3038 if ( widthAccel
> widthAccelMax
)
3040 widthAccelMax
= widthAccel
;
3043 const wxBitmap
& bmp
= item
->GetBitmap();
3046 wxCoord widthBmp
= bmp
.GetWidth();
3047 if ( widthBmp
> widthBmpMax
)
3048 widthBmpMax
= widthBmp
;
3050 //else if ( item->IsCheckable() ): no need to check for this as
3051 // MENU_LEFT_MARGIN is big enough to show the check mark
3054 h
+= 2*MENU_VERT_MARGIN
;
3056 // remember the item position and height
3057 item
->SetGeometry(height
, h
);
3062 // bundle the metrics into a struct and return it
3063 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3065 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3066 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3067 if ( widthAccelMax
> 0 )
3069 // if we actually have any accesl, add a margin
3070 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3073 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3075 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3076 gi
->m_size
.y
= height
;
3081 // ----------------------------------------------------------------------------
3083 // ----------------------------------------------------------------------------
3085 static const wxCoord STATBAR_BORDER_X
= 2;
3086 static const wxCoord STATBAR_BORDER_Y
= 2;
3088 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3090 if ( borderBetweenFields
)
3091 *borderBetweenFields
= 2;
3093 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3096 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3098 const wxString
& label
,
3103 if ( flags
& wxCONTROL_ISDEFAULT
)
3105 // draw the size grip: it is a normal rect except that in the lower
3106 // right corner we have several bands which may be used for dragging
3107 // the status bar corner
3109 // each band consists of 4 stripes: m_penHighlight, double
3110 // m_penDarkGrey and transparent one
3111 wxCoord x2
= rect
.GetRight(),
3112 y2
= rect
.GetBottom();
3114 // draw the upper left part of the rect normally
3115 dc
.SetPen(m_penDarkGrey
);
3116 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3117 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3119 // draw the grey stripes of the grip
3121 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3122 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3124 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3125 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3128 // draw the white stripes
3129 dc
.SetPen(m_penHighlight
);
3130 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3131 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3133 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3136 // draw the remaining rect boundaries
3137 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3138 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3139 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3144 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3148 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3151 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3153 wxDCClipper
clipper(dc
, rectIn
);
3154 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3157 // ----------------------------------------------------------------------------
3159 // ----------------------------------------------------------------------------
3161 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3163 wxBitmap
*bmpPressed
,
3164 wxBitmap
*bmpDisabled
)
3166 static const wxCoord widthCombo
= 16;
3167 static const wxCoord heightCombo
= 17;
3173 bmpNormal
->Create(widthCombo
, heightCombo
);
3174 dcMem
.SelectObject(*bmpNormal
);
3175 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3176 Arrow_Down
, Arrow_Normal
);
3181 bmpPressed
->Create(widthCombo
, heightCombo
);
3182 dcMem
.SelectObject(*bmpPressed
);
3183 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3184 Arrow_Down
, Arrow_Pressed
);
3189 bmpDisabled
->Create(widthCombo
, heightCombo
);
3190 dcMem
.SelectObject(*bmpDisabled
);
3191 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3192 Arrow_Down
, Arrow_Disabled
);
3196 // ----------------------------------------------------------------------------
3198 // ----------------------------------------------------------------------------
3200 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3201 const wxColour
& col
,
3204 wxBrush
brush(col
, wxSOLID
);
3206 dc
.SetPen(*wxTRANSPARENT_PEN
);
3207 dc
.DrawRectangle(rect
);
3210 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3211 const wxColour
& col
,
3215 // just fill it with the given or default bg colour
3216 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3217 DoDrawBackground(dc
, colBg
, rect
);
3220 // ----------------------------------------------------------------------------
3222 // ----------------------------------------------------------------------------
3224 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3229 // get the bitmap for this arrow
3230 wxArrowDirection arrowDir
;
3233 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3234 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3235 case wxUP
: arrowDir
= Arrow_Up
; break;
3236 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3239 wxFAIL_MSG(_T("unknown arrow direction"));
3243 wxArrowStyle arrowStyle
;
3244 if ( flags
& wxCONTROL_PRESSED
)
3246 // can't be pressed and disabled
3247 arrowStyle
= Arrow_Pressed
;
3251 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3254 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3257 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3259 wxArrowDirection arrowDir
,
3260 wxArrowStyle arrowStyle
)
3262 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3264 // under Windows the arrows always have the same size so just centre it in
3265 // the provided rectangle
3266 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3267 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3269 // Windows does it like this...
3270 if ( arrowDir
== Arrow_Left
)
3274 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3277 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3278 const wxRect
& rectAll
,
3279 wxArrowDirection arrowDir
,
3280 wxArrowStyle arrowStyle
)
3282 wxRect rect
= rectAll
;
3283 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3284 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3285 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3288 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3289 wxOrientation orient
,
3293 // we don't use the flags, the thumb never changes appearance
3294 wxRect rectThumb
= rect
;
3295 DrawArrowBorder(dc
, &rectThumb
);
3296 DrawBackground(dc
, wxNullColour
, rectThumb
);
3299 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3300 wxOrientation orient
,
3301 const wxRect
& rectBar
,
3304 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3305 ? wxColourScheme::SCROLLBAR_PRESSED
3306 : wxColourScheme::SCROLLBAR
;
3307 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3310 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3312 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3315 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3316 wxScrollBar::Element elem
,
3319 return StandardGetScrollbarRect(scrollbar
, elem
,
3320 thumbPos
, m_sizeScrollbarArrow
);
3323 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3325 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3328 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3329 const wxPoint
& pt
) const
3331 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3334 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3337 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3340 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3343 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3346 // ----------------------------------------------------------------------------
3347 // top level windows
3348 // ----------------------------------------------------------------------------
3350 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3352 wxRect client
= GetFrameClientArea(rect
, flags
);
3354 if ( client
.Inside(pt
) )
3355 return wxHT_TOPLEVEL_CLIENT_AREA
;
3357 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3359 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3361 if ( flags
& wxTOPLEVEL_ICON
)
3363 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3364 return wxHT_TOPLEVEL_ICON
;
3367 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3368 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3369 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3371 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3373 if ( btnRect
.Inside(pt
) )
3374 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3375 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3377 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3379 if ( btnRect
.Inside(pt
) )
3380 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3381 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3383 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3385 if ( btnRect
.Inside(pt
) )
3386 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3387 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3389 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3391 if ( btnRect
.Inside(pt
) )
3392 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3393 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3395 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3397 if ( btnRect
.Inside(pt
) )
3398 return wxHT_TOPLEVEL_BUTTON_HELP
;
3399 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3402 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3403 return wxHT_TOPLEVEL_TITLEBAR
;
3406 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3408 // we are certainly at one of borders, lets decide which one:
3411 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3412 if ( pt
.x
< client
.x
)
3413 border
|= wxHT_TOPLEVEL_BORDER_W
;
3414 else if ( pt
.x
>= client
.width
+ client
.x
)
3415 border
|= wxHT_TOPLEVEL_BORDER_E
;
3416 if ( pt
.y
< client
.y
)
3417 border
|= wxHT_TOPLEVEL_BORDER_N
;
3418 else if ( pt
.y
>= client
.height
+ client
.y
)
3419 border
|= wxHT_TOPLEVEL_BORDER_S
;
3423 return wxHT_NOWHERE
;
3426 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3428 const wxString
& title
,
3432 int specialButtonFlags
)
3434 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3436 DrawFrameBorder(dc
, rect
, flags
);
3438 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3440 DrawFrameBackground(dc
, rect
, flags
);
3441 if ( flags
& wxTOPLEVEL_ICON
)
3442 DrawFrameIcon(dc
, rect
, icon
, flags
);
3443 DrawFrameTitle(dc
, rect
, title
, flags
);
3445 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3447 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3448 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3450 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3452 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3453 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3454 specialButtonFlags
: 0);
3455 x
-= FRAME_BUTTON_WIDTH
+ 2;
3457 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3459 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3460 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3461 specialButtonFlags
: 0);
3462 x
-= FRAME_BUTTON_WIDTH
;
3464 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3466 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3467 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3468 specialButtonFlags
: 0);
3469 x
-= FRAME_BUTTON_WIDTH
;
3471 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3473 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3474 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3475 specialButtonFlags
: 0);
3476 x
-= FRAME_BUTTON_WIDTH
;
3478 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3480 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3481 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3482 specialButtonFlags
: 0);
3483 x
-= FRAME_BUTTON_WIDTH
;
3488 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3492 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3496 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3497 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3498 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3499 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3500 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3503 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3507 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3509 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3510 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3511 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3513 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3514 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3516 DrawBackground(dc
, col
, r
);
3519 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3521 const wxString
& title
,
3524 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3525 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3526 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3528 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3529 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3530 if ( flags
& wxTOPLEVEL_ICON
)
3532 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3533 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3541 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3542 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3543 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3544 r
.width
-= FRAME_BUTTON_WIDTH
;
3545 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3546 r
.width
-= FRAME_BUTTON_WIDTH
;
3547 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3548 r
.width
-= FRAME_BUTTON_WIDTH
;
3549 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3550 r
.width
-= FRAME_BUTTON_WIDTH
;
3552 dc
.SetFont(m_titlebarFont
);
3553 dc
.SetTextForeground(col
);
3556 dc
.GetTextExtent(title
, &textW
, NULL
);
3557 if ( textW
> r
.width
)
3559 // text is too big, let's shorten it and add "..." after it:
3560 size_t len
= title
.length();
3561 wxCoord WSoFar
, letterW
;
3563 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3564 if ( WSoFar
> r
.width
)
3566 // not enough space to draw anything
3572 for (size_t i
= 0; i
< len
; i
++)
3574 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3575 if ( letterW
+ WSoFar
> r
.width
)
3581 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3582 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3585 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3586 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3589 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3596 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3597 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3601 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3602 wxCoord x
, wxCoord y
,
3606 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3611 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3612 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3613 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3614 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3615 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3617 wxFAIL_MSG(wxT("incorrect button specification"));
3620 if ( flags
& wxCONTROL_PRESSED
)
3622 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3623 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3624 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3625 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3629 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3630 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3631 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3632 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3637 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3642 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3644 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3645 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3646 FRAME_BORDER_THICKNESS
;
3649 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3651 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3652 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3658 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3661 wxSize
s(clientSize
);
3663 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3665 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3666 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3667 FRAME_BORDER_THICKNESS
;
3671 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3672 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3677 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3681 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3683 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3684 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3685 FRAME_BORDER_THICKNESS
;
3690 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3692 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3694 if ( flags
& wxTOPLEVEL_ICON
)
3695 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3696 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3697 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3698 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3699 s
.x
+= FRAME_BUTTON_WIDTH
;
3700 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3701 s
.x
+= FRAME_BUTTON_WIDTH
;
3702 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3703 s
.x
+= FRAME_BUTTON_WIDTH
;
3704 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3705 s
.x
+= FRAME_BUTTON_WIDTH
;
3711 wxSize
wxWin32Renderer::GetFrameIconSize() const
3713 return wxSize(16, 16);
3717 // ----------------------------------------------------------------------------
3719 // ----------------------------------------------------------------------------
3721 static char *error_xpm
[]={
3728 "...........########.............",
3729 "........###aaaaaaaa###..........",
3730 ".......#aaaaaaaaaaaaaa#.........",
3731 ".....##aaaaaaaaaaaaaaaa##.......",
3732 "....#aaaaaaaaaaaaaaaaaaaa#......",
3733 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3734 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3735 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3736 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3737 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3738 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3739 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3740 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3741 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3742 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3743 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3744 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3745 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3746 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3747 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3748 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3749 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3750 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3751 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3752 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3753 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3754 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3755 "......b#aaaaaaaaaaaaaa#bbbbb....",
3756 ".......b###aaaaaaaa###bbbbb.....",
3757 ".........bb########bbbbbb.......",
3758 "..........bbbbbbbbbbbbbb........",
3759 ".............bbbbbbbb..........."};
3761 static char *info_xpm
[]={
3769 "...........########.............",
3770 "........###abbbbbba###..........",
3771 "......##abbbbbbbbbbbba##........",
3772 ".....#abbbbbbbbbbbbbbbba#.......",
3773 "....#bbbbbbbaccccabbbbbbbd......",
3774 "...#bbbbbbbbccccccbbbbbbbbd.....",
3775 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3776 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3777 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3778 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3779 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3780 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3781 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3782 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3783 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3784 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3785 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3786 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3787 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3788 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3789 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3790 ".....dabbbbbbbbbbbbbbbbad####...",
3791 "......ddabbbbbbbbbbbbadd####....",
3792 ".......#dddabbbbbbaddd#####.....",
3793 "........###dddabbbd#######......",
3794 "..........####dbbbd#####........",
3795 ".............#dbbbd##...........",
3796 "...............dbbd##...........",
3797 "................dbd##...........",
3798 ".................dd##...........",
3799 "..................###...........",
3800 "...................##..........."};
3802 static char *question_xpm
[]={
3810 "...........########.............",
3811 "........###abbbbbba###..........",
3812 "......##abbbbbbbbbbbba##........",
3813 ".....#abbbbbbbbbbbbbbbba#.......",
3814 "....#bbbbbbbbbbbbbbbbbbbbc......",
3815 "...#bbbbbbbaddddddabbbbbbbc.....",
3816 "..#bbbbbbbadabbddddabbbbbbbc....",
3817 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3818 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3819 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3820 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3821 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3822 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3823 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3824 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3825 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3826 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3827 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3828 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3829 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3830 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3831 ".....cabbbbbbbbbbbbbbbbac####...",
3832 "......ccabbbbbbbbbbbbacc####....",
3833 ".......#cccabbbbbbaccc#####.....",
3834 "........###cccabbbc#######......",
3835 "..........####cbbbc#####........",
3836 ".............#cbbbc##...........",
3837 "...............cbbc##...........",
3838 "................cbc##...........",
3839 ".................cc##...........",
3840 "..................###...........",
3841 "...................##..........."};
3843 static char *warning_xpm
[]={
3851 ".............###................",
3852 "............#aabc...............",
3853 "...........#aaaabcd.............",
3854 "...........#aaaaacdd............",
3855 "..........#aaaaaabcdd...........",
3856 "..........#aaaaaaacdd...........",
3857 ".........#aaaaaaaabcdd..........",
3858 ".........#aaaaaaaaacdd..........",
3859 "........#aaaaaaaaaabcdd.........",
3860 "........#aaabcccbaaacdd.........",
3861 ".......#aaaacccccaaabcdd........",
3862 ".......#aaaacccccaaaacdd........",
3863 "......#aaaaacccccaaaabcdd.......",
3864 "......#aaaaacccccaaaaacdd.......",
3865 ".....#aaaaaacccccaaaaabcdd......",
3866 ".....#aaaaaa#ccc#aaaaaacdd......",
3867 "....#aaaaaaabcccbaaaaaabcdd.....",
3868 "....#aaaaaaaacccaaaaaaaacdd.....",
3869 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3870 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3871 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3872 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3873 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3874 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3875 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3876 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3877 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3878 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3879 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3880 "..#ccccccccccccccccccccccccddddd",
3881 "....ddddddddddddddddddddddddddd.",
3882 ".....ddddddddddddddddddddddddd.."};
3884 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3885 const wxArtClient
& WXUNUSED(client
),
3886 const wxSize
& WXUNUSED(size
))
3888 if ( id
== wxART_INFORMATION
)
3889 return wxBitmap(info_xpm
);
3890 if ( id
== wxART_ERROR
)
3891 return wxBitmap(error_xpm
);
3892 if ( id
== wxART_WARNING
)
3893 return wxBitmap(warning_xpm
);
3894 if ( id
== wxART_QUESTION
)
3895 return wxBitmap(question_xpm
);
3896 return wxNullBitmap
;
3900 // ----------------------------------------------------------------------------
3901 // text control geometry
3902 // ----------------------------------------------------------------------------
3904 static inline int GetTextBorderWidth()
3909 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3910 const wxRect
& rect
) const
3912 wxRect rectTotal
= rect
;
3914 wxCoord widthBorder
= GetTextBorderWidth();
3915 rectTotal
.Inflate(widthBorder
);
3917 // this is what Windows does
3923 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3925 wxCoord
*extraSpaceBeyond
) const
3927 wxRect rectText
= rect
;
3929 // undo GetTextTotalArea()
3930 if ( rectText
.height
> 0 )
3933 wxCoord widthBorder
= GetTextBorderWidth();
3934 rectText
.Inflate(-widthBorder
);
3936 if ( extraSpaceBeyond
)
3937 *extraSpaceBeyond
= 0;
3942 // ----------------------------------------------------------------------------
3944 // ----------------------------------------------------------------------------
3946 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3949 if ( wxDynamicCast(window
, wxScrollBar
) )
3951 // we only set the width of vert scrollbars and height of the
3953 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3954 size
->y
= m_sizeScrollbarArrow
.y
;
3956 size
->x
= m_sizeScrollbarArrow
.x
;
3958 // skip border width adjustments, they don't make sense for us
3961 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3964 if ( wxDynamicCast(window
, wxButton
) )
3966 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3968 // TODO: don't harcode all this
3969 size
->x
+= 3*window
->GetCharWidth();
3971 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3972 if ( size
->y
< heightBtn
- 8 )
3973 size
->y
= heightBtn
;
3978 // no border width adjustments for buttons
3981 #endif // wxUSE_BUTTON
3983 // take into account the border width
3984 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3985 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3986 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3989 // ============================================================================
3991 // ============================================================================
3993 // ----------------------------------------------------------------------------
3994 // wxWin32InputHandler
3995 // ----------------------------------------------------------------------------
3997 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3999 m_renderer
= renderer
;
4002 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
4003 const wxKeyEvent
& event
,
4009 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4010 const wxMouseEvent
& event
)
4012 // clicking on the control gives it focus
4013 if ( event
.ButtonDown() )
4015 wxWindow
*win
= control
->GetInputWindow();
4017 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4018 ( win
->AcceptsFocus() ) )
4029 // ----------------------------------------------------------------------------
4030 // wxWin32ScrollBarInputHandler
4031 // ----------------------------------------------------------------------------
4033 wxWin32ScrollBarInputHandler::
4034 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4035 wxInputHandler
*handler
)
4036 : wxStdScrollBarInputHandler(renderer
, handler
)
4038 m_scrollPaused
= FALSE
;
4042 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4043 const wxControlAction
& action
)
4045 // stop if went beyond the position of the original click (this can only
4046 // happen when we scroll by pages)
4048 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4050 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4051 != wxHT_SCROLLBAR_BAR_2
;
4053 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4055 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4056 != wxHT_SCROLLBAR_BAR_1
;
4061 StopScrolling(scrollbar
);
4063 scrollbar
->Refresh();
4068 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4071 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4072 const wxMouseEvent
& event
)
4074 // remember the current state
4075 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4077 // do process the message
4078 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4080 // analyse the changes
4081 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4083 // we just started dragging the thumb, remember its initial position to
4084 // be able to restore it if the drag is cancelled later
4085 m_eventStartDrag
= event
;
4091 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4092 const wxMouseEvent
& event
)
4094 // we don't highlight scrollbar elements, so there is no need to process
4095 // mouse move events normally - only do it while mouse is captured (i.e.
4096 // when we're dragging the thumb or pressing on something)
4097 if ( !m_winCapture
)
4100 if ( event
.Entering() )
4102 // we're not interested in this at all
4106 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4108 if ( m_scrollPaused
)
4110 // check if the mouse returned to its original location
4112 if ( event
.Leaving() )
4118 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4119 if ( ht
== m_htLast
)
4121 // yes it did, resume scrolling
4122 m_scrollPaused
= FALSE
;
4123 if ( m_timerScroll
)
4125 // we were scrolling by line/page, restart timer
4126 m_timerScroll
->Start(m_interval
);
4128 Press(scrollbar
, TRUE
);
4130 else // we were dragging the thumb
4132 // restore its last location
4133 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4139 else // normal case, scrolling hasn't been paused
4141 // if we're scrolling the scrollbar because the arrow or the shaft was
4142 // pressed, check that the mouse stays on the same scrollbar element
4144 if ( event
.Moving() )
4146 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4148 else // event.Leaving()
4153 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4154 // is still ok - we only want to catch the case when the mouse leaves
4155 // the scrollbar here
4156 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4158 ht
= wxHT_SCROLLBAR_THUMB
;
4161 if ( ht
!= m_htLast
)
4163 // what were we doing? 2 possibilities: either an arrow/shaft was
4164 // pressed in which case we have a timer and so we just stop it or
4165 // we were dragging the thumb
4166 if ( m_timerScroll
)
4169 m_interval
= m_timerScroll
->GetInterval();
4170 m_timerScroll
->Stop();
4171 m_scrollPaused
= TRUE
;
4173 // unpress the arrow
4174 Press(scrollbar
, FALSE
);
4176 else // we were dragging the thumb
4178 // remember the current thumb position to be able to restore it
4179 // if the mouse returns to it later
4180 m_eventLastDrag
= event
;
4182 // and restore the original position (before dragging) of the
4184 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4191 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4194 // ----------------------------------------------------------------------------
4195 // wxWin32CheckboxInputHandler
4196 // ----------------------------------------------------------------------------
4198 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4199 const wxKeyEvent
& event
,
4204 wxControlAction action
;
4205 int keycode
= event
.GetKeyCode();
4209 action
= wxACTION_CHECKBOX_TOGGLE
;
4213 case WXK_NUMPAD_SUBTRACT
:
4214 action
= wxACTION_CHECKBOX_CHECK
;
4218 case WXK_NUMPAD_ADD
:
4219 case WXK_NUMPAD_EQUAL
:
4220 action
= wxACTION_CHECKBOX_CLEAR
;
4226 control
->PerformAction(action
);
4235 // ----------------------------------------------------------------------------
4236 // wxWin32TextCtrlInputHandler
4237 // ----------------------------------------------------------------------------
4239 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4240 const wxKeyEvent
& event
,
4243 // handle only MSW-specific text bindings here, the others are handled in
4247 int keycode
= event
.GetKeyCode();
4249 wxControlAction action
;
4250 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4252 action
= wxACTION_TEXT_CUT
;
4254 else if ( keycode
== WXK_INSERT
)
4256 if ( event
.ControlDown() )
4257 action
= wxACTION_TEXT_COPY
;
4258 else if ( event
.ShiftDown() )
4259 action
= wxACTION_TEXT_PASTE
;
4262 if ( action
!= wxACTION_NONE
)
4264 control
->PerformAction(action
);
4270 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4273 // ----------------------------------------------------------------------------
4274 // wxWin32StatusBarInputHandler
4275 // ----------------------------------------------------------------------------
4277 wxWin32StatusBarInputHandler::
4278 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4279 : wxStdInputHandler(handler
)
4284 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4285 const wxPoint
& pt
) const
4287 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4288 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4291 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4293 wxCHECK_MSG( parentTLW
, FALSE
,
4294 _T("the status bar should be a child of a TLW") );
4296 // a maximized window can't be resized anyhow
4297 if ( !parentTLW
->IsMaximized() )
4299 // VZ: I think that the standard Windows behaviour is to only
4300 // show the resizing cursor when the mouse is on top of the
4301 // grip itself but apparently different Windows versions behave
4302 // differently (?) and it seems a better UI to allow resizing
4303 // the status bar even when the mouse is above the grip
4304 wxSize sizeSbar
= statbar
->GetSize();
4306 int diff
= sizeSbar
.x
- pt
.x
;
4307 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4314 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4315 const wxMouseEvent
& event
)
4317 if ( event
.Button(1) )
4319 if ( event
.ButtonDown(1) )
4321 wxWindow
*statbar
= consumer
->GetInputWindow();
4323 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4325 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4329 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4330 wxHT_TOPLEVEL_BORDER_SE
);
4332 statbar
->SetCursor(m_cursorOld
);
4340 return wxStdInputHandler::HandleMouse(consumer
, event
);
4343 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4344 const wxMouseEvent
& event
)
4346 wxWindow
*statbar
= consumer
->GetInputWindow();
4348 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4349 if ( isOnGrip
!= m_isOnGrip
)
4351 m_isOnGrip
= isOnGrip
;
4354 m_cursorOld
= statbar
->GetCursor();
4355 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4359 statbar
->SetCursor(m_cursorOld
);
4363 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4366 // ----------------------------------------------------------------------------
4367 // wxWin32FrameInputHandler
4368 // ----------------------------------------------------------------------------
4370 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4373 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4375 void Attach(wxInputConsumer
*consumer
);
4379 DECLARE_EVENT_TABLE()
4380 void OnSystemMenu(wxCommandEvent
&event
);
4381 void OnCloseFrame(wxCommandEvent
&event
);
4382 void OnClose(wxCloseEvent
&event
);
4384 wxWin32FrameInputHandler
*m_inputHnd
;
4385 wxTopLevelWindow
*m_wnd
;
4386 wxAcceleratorTable m_oldAccelTable
;
4389 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4390 wxWin32FrameInputHandler
*handler
)
4392 m_inputHnd
= handler
;
4396 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4398 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4400 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4401 m_wnd
->PushEventHandler(this);
4403 // VS: This code relies on using generic implementation of
4404 // wxAcceleratorTable in wxUniv!
4405 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4406 m_oldAccelTable
= table
;
4407 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4408 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4409 m_wnd
->SetAcceleratorTable(table
);
4412 void wxWin32SystemMenuEvtHandler::Detach()
4416 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4417 m_wnd
->RemoveEventHandler(this);
4422 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4423 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4424 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4425 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4428 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4430 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4431 !m_wnd
->IsMaximized()) ?
4432 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4433 FRAME_BORDER_THICKNESS
;
4434 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4435 pt
.x
= -pt
.x
+ border
;
4436 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4438 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4439 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4440 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4441 m_wnd
->SetAcceleratorTable(table
);
4444 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4446 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4447 wxTOPLEVEL_BUTTON_CLOSE
);
4450 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4457 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4458 : wxStdFrameInputHandler(handler
)
4460 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4463 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4465 if ( m_menuHandler
)
4467 m_menuHandler
->Detach();
4468 delete m_menuHandler
;
4472 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4473 const wxMouseEvent
& event
)
4475 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4477 wxTopLevelWindow
*tlw
=
4478 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4480 long hit
= tlw
->HitTest(event
.GetPosition());
4482 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4484 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4485 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4486 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4489 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4491 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4492 (event
.RightDown() &&
4493 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4494 hit
== wxHT_TOPLEVEL_ICON
)) )
4496 PopupSystemMenu(tlw
, event
.GetPosition());
4502 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4505 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4506 const wxPoint
& pos
) const
4508 wxMenu
*menu
= new wxMenu
;
4510 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4511 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4512 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4513 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4514 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4515 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4516 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4517 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4518 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4519 menu
->AppendSeparator();
4520 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4522 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4524 if ( window
->IsMaximized() )
4526 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4527 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4528 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4529 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4532 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4535 window
->PopupMenu(menu
, pos
);
4539 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4542 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4544 // always detach if active frame changed:
4545 m_menuHandler
->Detach();
4549 m_menuHandler
->Attach(consumer
);
4553 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);