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 wxWindow
*window
= NULL
);
153 virtual void DrawLabel(wxDC
& dc
,
154 const wxString
& label
,
157 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
159 wxRect
*rectBounds
= NULL
);
160 virtual void DrawButtonLabel(wxDC
& dc
,
161 const wxString
& label
,
162 const wxBitmap
& image
,
165 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
167 wxRect
*rectBounds
= NULL
);
168 virtual void DrawBorder(wxDC
& dc
,
172 wxRect
*rectIn
= (wxRect
*)NULL
);
173 virtual void DrawHorizontalLine(wxDC
& dc
,
174 wxCoord y
, wxCoord x1
, wxCoord x2
);
175 virtual void DrawVerticalLine(wxDC
& dc
,
176 wxCoord x
, wxCoord y1
, wxCoord y2
);
177 virtual void DrawFrame(wxDC
& dc
,
178 const wxString
& label
,
181 int alignment
= wxALIGN_LEFT
,
182 int indexAccel
= -1);
183 virtual void DrawTextBorder(wxDC
& dc
,
187 wxRect
*rectIn
= (wxRect
*)NULL
);
188 virtual void DrawButtonBorder(wxDC
& dc
,
191 wxRect
*rectIn
= (wxRect
*)NULL
);
192 virtual void DrawArrow(wxDC
& dc
,
196 virtual void DrawScrollbarArrow(wxDC
& dc
,
200 { DrawArrow(dc
, dir
, rect
, flags
); }
201 virtual void DrawScrollbarThumb(wxDC
& dc
,
202 wxOrientation orient
,
205 virtual void DrawScrollbarShaft(wxDC
& dc
,
206 wxOrientation orient
,
209 virtual void DrawScrollCorner(wxDC
& dc
,
211 virtual void DrawItem(wxDC
& dc
,
212 const wxString
& label
,
215 virtual void DrawCheckItem(wxDC
& dc
,
216 const wxString
& label
,
217 const wxBitmap
& bitmap
,
220 virtual void DrawCheckButton(wxDC
& dc
,
221 const wxString
& label
,
222 const wxBitmap
& bitmap
,
225 wxAlignment align
= wxALIGN_LEFT
,
226 int indexAccel
= -1);
227 virtual void DrawRadioButton(wxDC
& dc
,
228 const wxString
& label
,
229 const wxBitmap
& bitmap
,
232 wxAlignment align
= wxALIGN_LEFT
,
233 int indexAccel
= -1);
234 virtual void DrawToolBarButton(wxDC
& dc
,
235 const wxString
& label
,
236 const wxBitmap
& bitmap
,
239 virtual void DrawTextLine(wxDC
& dc
,
240 const wxString
& text
,
245 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
246 virtual void DrawTab(wxDC
& dc
,
249 const wxString
& label
,
250 const wxBitmap
& bitmap
= wxNullBitmap
,
252 int indexAccel
= -1);
254 virtual void DrawSliderShaft(wxDC
& dc
,
256 wxOrientation orient
,
258 wxRect
*rectShaft
= NULL
);
259 virtual void DrawSliderThumb(wxDC
& dc
,
261 wxOrientation orient
,
263 virtual void DrawSliderTicks(wxDC
& dc
,
265 const wxSize
& sizeThumb
,
266 wxOrientation orient
,
272 virtual void DrawMenuBarItem(wxDC
& dc
,
274 const wxString
& label
,
276 int indexAccel
= -1);
277 virtual void DrawMenuItem(wxDC
& dc
,
279 const wxMenuGeometryInfo
& geometryInfo
,
280 const wxString
& label
,
281 const wxString
& accel
,
282 const wxBitmap
& bitmap
= wxNullBitmap
,
284 int indexAccel
= -1);
285 virtual void DrawMenuSeparator(wxDC
& dc
,
287 const wxMenuGeometryInfo
& geomInfo
);
289 virtual void DrawStatusField(wxDC
& dc
,
291 const wxString
& label
,
295 virtual void DrawFrameTitleBar(wxDC
& dc
,
297 const wxString
& title
,
300 int specialButton
= 0,
301 int specialButtonFlags
= 0);
302 virtual void DrawFrameBorder(wxDC
& dc
,
305 virtual void DrawFrameBackground(wxDC
& dc
,
308 virtual void DrawFrameTitle(wxDC
& dc
,
310 const wxString
& title
,
312 virtual void DrawFrameIcon(wxDC
& dc
,
316 virtual void DrawFrameButton(wxDC
& dc
,
317 wxCoord x
, wxCoord y
,
320 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
321 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
322 virtual wxSize
GetFrameMinSize(int flags
) const;
323 virtual wxSize
GetFrameIconSize() const;
324 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
326 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
328 wxBitmap
*bmpPressed
,
329 wxBitmap
*bmpDisabled
);
331 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
332 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
333 virtual bool AreScrollbarsInsideBorder() const;
335 virtual wxSize
GetScrollbarArrowSize() const
336 { return m_sizeScrollbarArrow
; }
337 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
338 wxScrollBar::Element elem
,
339 int thumbPos
= -1) const;
340 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
341 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
342 const wxPoint
& pt
) const;
343 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
345 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
346 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
347 { return fontHeight
+ 2; }
348 virtual wxSize
GetCheckBitmapSize() const
349 { return wxSize(13, 13); }
350 virtual wxSize
GetRadioBitmapSize() const
351 { return wxSize(12, 12); }
352 virtual wxCoord
GetCheckItemMargin() const
355 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
356 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
357 virtual wxSize
GetToolBarMargin() const
358 { return wxSize(4, 4); }
360 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
361 const wxRect
& rect
) const;
362 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
364 wxCoord
*extraSpaceBeyond
) const;
366 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
367 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
369 virtual wxCoord
GetSliderDim() const { return 20; }
370 virtual wxCoord
GetSliderTickLen() const { return 4; }
371 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
372 wxOrientation orient
) const;
373 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
374 wxOrientation orient
) const;
375 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
377 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
378 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
379 const wxMenu
& menu
) const;
381 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
384 // helper of DrawLabel() and DrawCheckOrRadioButton()
385 void DoDrawLabel(wxDC
& dc
,
386 const wxString
& label
,
389 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
391 wxRect
*rectBounds
= NULL
,
392 const wxPoint
& focusOffset
393 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
395 // common part of DrawLabel() and DrawItem()
396 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
398 // DrawLabel() and DrawButtonLabel() helper
399 void DrawLabelShadow(wxDC
& dc
,
400 const wxString
& label
,
405 // DrawButtonBorder() helper
406 void DoDrawBackground(wxDC
& dc
,
409 wxWindow
*window
= NULL
);
411 // DrawBorder() helpers: all of them shift and clip the DC after drawing
414 // just draw a rectangle with the given pen
415 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
417 // draw the lower left part of rectangle
418 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
420 // draw the rectange using the first brush for the left and top sides and
421 // the second one for the bottom and right ones
422 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
423 const wxPen
& pen1
, const wxPen
& pen2
);
425 // draw the normal 3D border
426 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
428 // draw the sunken 3D border
429 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
431 // draw the border used for scrollbar arrows
432 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
434 // public DrawArrow()s helper
435 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
436 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
438 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
439 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
440 wxArrowDirection arrowDir
,
441 wxArrowStyle arrowStyle
);
443 // DrawCheckButton/DrawRadioButton helper
444 void DrawCheckOrRadioButton(wxDC
& dc
,
445 const wxString
& label
,
446 const wxBitmap
& bitmap
,
451 wxCoord focusOffsetY
);
453 // draw a normal or transposed line (useful for using the same code fo both
454 // horizontal and vertical widgets)
455 void DrawLine(wxDC
& dc
,
456 wxCoord x1
, wxCoord y1
,
457 wxCoord x2
, wxCoord y2
,
458 bool transpose
= FALSE
)
461 dc
.DrawLine(y1
, x1
, y2
, x2
);
463 dc
.DrawLine(x1
, y1
, x2
, y2
);
466 // get the standard check/radio button bitmap
467 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
468 wxBitmap
GetCheckBitmap(int flags
)
469 { return GetIndicator(IndicatorType_Check
, flags
); }
470 wxBitmap
GetRadioBitmap(int flags
)
471 { return GetIndicator(IndicatorType_Radio
, flags
); }
474 const wxColourScheme
*m_scheme
;
476 // the sizing parameters (TODO make them changeable)
477 wxSize m_sizeScrollbarArrow
;
479 // GDI objects we use for drawing
480 wxColour m_colDarkGrey
,
488 wxFont m_titlebarFont
;
490 // the checked and unchecked bitmaps for DrawCheckItem()
491 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
493 // the bitmaps returned by GetIndicator()
494 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
496 [IndicatorStatus_Max
];
499 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
501 // first row is for the normal state, second - for the disabled
502 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
505 // ----------------------------------------------------------------------------
506 // wxWin32InputHandler and derived classes: process the keyboard and mouse
507 // messages according to Windows standards
508 // ----------------------------------------------------------------------------
510 class wxWin32InputHandler
: public wxInputHandler
513 wxWin32InputHandler(wxWin32Renderer
*renderer
);
515 virtual bool HandleKey(wxInputConsumer
*control
,
516 const wxKeyEvent
& event
,
518 virtual bool HandleMouse(wxInputConsumer
*control
,
519 const wxMouseEvent
& event
);
522 wxWin32Renderer
*m_renderer
;
525 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
528 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
529 wxInputHandler
*handler
);
531 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
532 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
534 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
535 const wxControlAction
& action
);
538 virtual bool IsAllowedButton(int button
) { return button
== 1; }
540 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
542 // we don't highlight anything
545 // the first and last event which caused the thumb to move
546 wxMouseEvent m_eventStartDrag
,
549 // have we paused the scrolling because the mouse moved?
552 // we remember the interval of the timer to be able to restart it
556 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
559 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
560 : wxStdCheckboxInputHandler(handler
) { }
562 virtual bool HandleKey(wxInputConsumer
*control
,
563 const wxKeyEvent
& event
,
567 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
570 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
571 : wxStdTextCtrlInputHandler(handler
) { }
573 virtual bool HandleKey(wxInputConsumer
*control
,
574 const wxKeyEvent
& event
,
578 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
581 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
583 virtual bool HandleMouse(wxInputConsumer
*consumer
,
584 const wxMouseEvent
& event
);
586 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
587 const wxMouseEvent
& event
);
590 // is the given point over the statusbar grip?
591 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
594 // the cursor we had replaced with the resize one
595 wxCursor m_cursorOld
;
597 // was the mouse over the grip last time we checked?
601 class wxWin32SystemMenuEvtHandler
;
603 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
606 wxWin32FrameInputHandler(wxInputHandler
*handler
);
607 ~wxWin32FrameInputHandler();
609 virtual bool HandleMouse(wxInputConsumer
*control
,
610 const wxMouseEvent
& event
);
612 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
614 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
617 // was the mouse over the grip last time we checked?
618 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
621 // ----------------------------------------------------------------------------
622 // wxWin32ColourScheme: uses (default) Win32 colours
623 // ----------------------------------------------------------------------------
625 class wxWin32ColourScheme
: public wxColourScheme
628 virtual wxColour
Get(StdColour col
) const;
629 virtual wxColour
GetBackground(wxWindow
*win
) const;
632 // ----------------------------------------------------------------------------
633 // wxWin32ArtProvider
634 // ----------------------------------------------------------------------------
636 class wxWin32ArtProvider
: public wxArtProvider
639 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
640 const wxArtClient
& client
,
644 // ----------------------------------------------------------------------------
646 // ----------------------------------------------------------------------------
648 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
650 class wxWin32Theme
: public wxTheme
654 virtual ~wxWin32Theme();
656 virtual wxRenderer
*GetRenderer();
657 virtual wxArtProvider
*GetArtProvider();
658 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
659 virtual wxColourScheme
*GetColourScheme();
662 // get the default input handler
663 wxInputHandler
*GetDefaultInputHandler();
665 wxWin32Renderer
*m_renderer
;
667 wxWin32ArtProvider
*m_artProvider
;
669 // the names of the already created handlers and the handlers themselves
670 // (these arrays are synchronized)
671 wxSortedArrayString m_handlerNames
;
672 wxArrayHandlers m_handlers
;
674 wxWin32InputHandler
*m_handlerDefault
;
676 wxWin32ColourScheme
*m_scheme
;
678 WX_DECLARE_THEME(win32
)
681 // ----------------------------------------------------------------------------
683 // ----------------------------------------------------------------------------
685 // frame buttons bitmaps
687 static const char *frame_button_close_xpm
[] = {
702 static const char *frame_button_help_xpm
[] = {
717 static const char *frame_button_maximize_xpm
[] = {
732 static const char *frame_button_minimize_xpm
[] = {
747 static const char *frame_button_restore_xpm
[] = {
764 static const char *checked_menu_xpm
[] = {
765 /* columns rows colors chars-per-pixel */
781 static const char *selected_checked_menu_xpm
[] = {
782 /* columns rows colors chars-per-pixel */
798 static const char *disabled_checked_menu_xpm
[] = {
799 /* columns rows colors chars-per-pixel */
816 static const char *selected_disabled_checked_menu_xpm
[] = {
817 /* columns rows colors chars-per-pixel */
833 // checkbox and radiobox bitmaps below
835 static const char *checked_xpm
[] = {
836 /* columns rows colors chars-per-pixel */
859 static const char *pressed_checked_xpm
[] = {
860 /* columns rows colors chars-per-pixel */
882 static const char *pressed_disabled_checked_xpm
[] = {
883 /* columns rows colors chars-per-pixel */
905 static const char *checked_item_xpm
[] = {
906 /* columns rows colors chars-per-pixel */
927 static const char *unchecked_xpm
[] = {
928 /* columns rows colors chars-per-pixel */
951 static const char *pressed_unchecked_xpm
[] = {
952 /* columns rows colors chars-per-pixel */
974 static const char *unchecked_item_xpm
[] = {
975 /* columns rows colors chars-per-pixel */
995 static const char *checked_radio_xpm
[] = {
996 /* columns rows colors chars-per-pixel */
1019 static const char *pressed_checked_radio_xpm
[] = {
1020 /* columns rows colors chars-per-pixel */
1043 static const char *pressed_disabled_checked_radio_xpm
[] = {
1044 /* columns rows colors chars-per-pixel */
1067 static const char *unchecked_radio_xpm
[] = {
1068 /* columns rows colors chars-per-pixel */
1091 static const char *pressed_unchecked_radio_xpm
[] = {
1092 /* columns rows colors chars-per-pixel */
1115 static const char **
1116 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1121 { checked_xpm
, unchecked_xpm
},
1124 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1127 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1133 { checked_radio_xpm
, unchecked_radio_xpm
},
1136 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1139 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1145 { checked_menu_xpm
, NULL
},
1148 { selected_checked_menu_xpm
, NULL
},
1151 { disabled_checked_menu_xpm
, NULL
},
1153 // disabled selected state
1154 { selected_disabled_checked_menu_xpm
, NULL
},
1158 static const char **xpmChecked
[IndicatorStatus_Max
] =
1164 // ============================================================================
1166 // ============================================================================
1168 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1170 // ----------------------------------------------------------------------------
1172 // ----------------------------------------------------------------------------
1174 wxWin32Theme::wxWin32Theme()
1178 m_handlerDefault
= NULL
;
1181 wxWin32Theme::~wxWin32Theme()
1183 size_t count
= m_handlers
.GetCount();
1184 for ( size_t n
= 0; n
< count
; n
++ )
1186 if ( m_handlers
[n
] != m_handlerDefault
)
1187 delete m_handlers
[n
];
1190 delete m_handlerDefault
;
1196 wxRenderer
*wxWin32Theme::GetRenderer()
1200 m_renderer
= new wxWin32Renderer(GetColourScheme());
1206 wxArtProvider
*wxWin32Theme::GetArtProvider()
1208 if ( !m_artProvider
)
1210 m_artProvider
= new wxWin32ArtProvider
;
1213 return m_artProvider
;
1216 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1218 if ( !m_handlerDefault
)
1220 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1223 return m_handlerDefault
;
1226 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1228 wxInputHandler
*handler
;
1229 int n
= m_handlerNames
.Index(control
);
1230 if ( n
== wxNOT_FOUND
)
1232 // create a new handler
1233 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1234 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1235 GetDefaultInputHandler());
1237 else if ( control
== wxINP_HANDLER_BUTTON
)
1238 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1239 #endif // wxUSE_BUTTON
1241 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1242 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1243 #endif // wxUSE_CHECKBOX
1245 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1246 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1247 #endif // wxUSE_COMBOBOX
1249 else if ( control
== wxINP_HANDLER_LISTBOX
)
1250 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1251 #endif // wxUSE_LISTBOX
1252 #if wxUSE_CHECKLISTBOX
1253 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1254 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1255 #endif // wxUSE_CHECKLISTBOX
1257 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1258 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1259 #endif // wxUSE_TEXTCTRL
1261 else if ( control
== wxINP_HANDLER_SLIDER
)
1262 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1263 #endif // wxUSE_SLIDER
1265 else if ( control
== wxINP_HANDLER_SPINBTN
)
1266 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1267 #endif // wxUSE_SPINBTN
1269 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1270 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1271 #endif // wxUSE_NOTEBOOK
1273 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1274 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1275 #endif // wxUSE_STATUSBAR
1277 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1278 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1279 #endif // wxUSE_TOOLBAR
1280 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1281 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1283 handler
= GetDefaultInputHandler();
1285 n
= m_handlerNames
.Add(control
);
1286 m_handlers
.Insert(handler
, n
);
1288 else // we already have it
1290 handler
= m_handlers
[n
];
1296 wxColourScheme
*wxWin32Theme::GetColourScheme()
1300 m_scheme
= new wxWin32ColourScheme
;
1305 // ============================================================================
1306 // wxWin32ColourScheme
1307 // ============================================================================
1309 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1312 if ( win
->UseBgCol() )
1314 // use the user specified colour
1315 col
= win
->GetBackgroundColour();
1318 if ( win
->IsContainerWindow() )
1320 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1323 if ( !text
->IsEnabled() ) // not IsEditable()
1325 //else: execute code below
1330 // doesn't depend on the state
1336 int flags
= win
->GetStateFlags();
1338 // the colour set by the user should be used for the normal state
1339 // and for the states for which we don't have any specific colours
1340 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1342 if ( wxDynamicCast(win
, wxScrollBar
) )
1343 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1353 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1357 // use the system colours under Windows
1358 #if defined(__WXMSW__)
1359 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1361 case CONTROL_PRESSED
:
1362 case CONTROL_CURRENT
:
1363 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1365 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1367 #if defined(COLOR_3DLIGHT)
1368 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1370 case SCROLLBAR
: return wxColour(0xe0e0e0);
1372 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1374 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1375 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1377 #if defined(COLOR_3DDKSHADOW)
1378 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1380 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1383 case CONTROL_TEXT_DISABLED
:
1384 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1386 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1388 case CONTROL_TEXT_DISABLED_SHADOW
:
1389 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1391 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1392 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1393 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1394 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1396 case DESKTOP
: return wxColour(0x808000);
1398 // use the standard Windows colours elsewhere
1399 case WINDOW
: return *wxWHITE
;
1401 case CONTROL_PRESSED
:
1402 case CONTROL_CURRENT
:
1403 case CONTROL
: return wxColour(0xc0c0c0);
1405 case CONTROL_TEXT
: return *wxBLACK
;
1407 case SCROLLBAR
: return wxColour(0xe0e0e0);
1408 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1410 case HIGHLIGHT
: return wxColour(0x800000);
1411 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1413 case SHADOW_DARK
: return *wxBLACK
;
1415 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1416 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1418 case SHADOW_IN
: return wxColour(0xc0c0c0);
1420 case CONTROL_TEXT_DISABLED_SHADOW
:
1421 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1423 case TITLEBAR
: return wxColour(0xaeaaae);
1424 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1425 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1426 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1428 case DESKTOP
: return wxColour(0x808000);
1431 case GAUGE
: return Get(HIGHLIGHT
);
1435 wxFAIL_MSG(_T("invalid standard colour"));
1440 // ============================================================================
1442 // ============================================================================
1444 // ----------------------------------------------------------------------------
1446 // ----------------------------------------------------------------------------
1448 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1452 m_sizeScrollbarArrow
= wxSize(16, 16);
1454 // init colours and pens
1455 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1457 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1458 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1460 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1462 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1463 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1465 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1466 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1468 // init the arrow bitmaps
1469 static const size_t ARROW_WIDTH
= 7;
1470 static const size_t ARROW_LENGTH
= 4;
1473 wxMemoryDC dcNormal
,
1476 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1478 bool isVertical
= n
> Arrow_Right
;
1491 // disabled arrow is larger because of the shadow
1492 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1493 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1495 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1496 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1498 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1499 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1503 dcNormal
.SetPen(m_penBlack
);
1504 dcDisabled
.SetPen(m_penDarkGrey
);
1506 // calculate the position of the point of the arrow
1510 x1
= (ARROW_WIDTH
- 1)/2;
1511 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1515 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1516 y1
= (ARROW_WIDTH
- 1)/2;
1527 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1529 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1530 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1537 if ( n
== Arrow_Up
)
1548 else // left or right arrow
1553 if ( n
== Arrow_Left
)
1566 // draw the shadow for the disabled one
1567 dcDisabled
.SetPen(m_penHighlight
);
1572 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1576 x1
= ARROW_LENGTH
- 1;
1577 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1580 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1581 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1586 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1590 x1
= ARROW_WIDTH
- 1;
1592 x2
= (ARROW_WIDTH
- 1)/2;
1594 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1595 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1600 // create the inversed bitmap but only for the right arrow as we only
1601 // use it for the menus
1602 if ( n
== Arrow_Right
)
1604 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1605 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1607 dcInverse
.Blit(0, 0, w
, h
,
1610 dcInverse
.SelectObject(wxNullBitmap
);
1612 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1613 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1615 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1616 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1618 dcInverse
.Blit(0, 0, w
, h
,
1621 dcInverse
.SelectObject(wxNullBitmap
);
1623 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1624 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1627 dcNormal
.SelectObject(wxNullBitmap
);
1628 dcDisabled
.SelectObject(wxNullBitmap
);
1630 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1631 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1632 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1633 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1635 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1638 // init the frame buttons bitmaps
1639 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1640 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1641 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1642 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1643 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1646 // ----------------------------------------------------------------------------
1648 // ----------------------------------------------------------------------------
1651 The raised border in Win32 looks like this:
1653 IIIIIIIIIIIIIIIIIIIIIIB
1655 I GB I = white (HILIGHT)
1656 I GB H = light grey (LIGHT)
1657 I GB G = dark grey (SHADOI)
1658 I GB B = black (DKSHADOI)
1659 I GB I = hIghlight (COLOR_3DHILIGHT)
1661 IGGGGGGGGGGGGGGGGGGGGGB
1662 BBBBBBBBBBBBBBBBBBBBBBB
1664 The sunken border looks like this:
1666 GGGGGGGGGGGGGGGGGGGGGGI
1667 GBBBBBBBBBBBBBBBBBBBBHI
1674 GHHHHHHHHHHHHHHHHHHHHHI
1675 IIIIIIIIIIIIIIIIIIIIIII
1677 The static border (used for the controls which don't get focus) is like
1680 GGGGGGGGGGGGGGGGGGGGGGW
1688 WWWWWWWWWWWWWWWWWWWWWWW
1690 The most complicated is the double border:
1692 HHHHHHHHHHHHHHHHHHHHHHB
1693 HWWWWWWWWWWWWWWWWWWWWGB
1694 HWHHHHHHHHHHHHHHHHHHHGB
1699 HWHHHHHHHHHHHHHHHHHHHGB
1700 HGGGGGGGGGGGGGGGGGGGGGB
1701 BBBBBBBBBBBBBBBBBBBBBBB
1703 And the simple border is, well, simple:
1705 BBBBBBBBBBBBBBBBBBBBBBB
1714 BBBBBBBBBBBBBBBBBBBBBBB
1717 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1721 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1722 dc
.DrawRectangle(*rect
);
1728 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1730 // draw the bottom and right sides
1732 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1733 rect
->GetRight() + 1, rect
->GetBottom());
1734 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1735 rect
->GetRight(), rect
->GetBottom());
1742 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1743 const wxPen
& pen1
, const wxPen
& pen2
)
1745 // draw the rectangle
1747 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1748 rect
->GetLeft(), rect
->GetBottom());
1749 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1750 rect
->GetRight(), rect
->GetTop());
1752 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1753 rect
->GetRight(), rect
->GetBottom());
1754 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1755 rect
->GetRight() + 1, rect
->GetBottom());
1761 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1763 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1764 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1767 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1769 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1770 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1773 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1777 DrawRect(dc
, rect
, m_penDarkGrey
);
1779 // the arrow is usually drawn inside border of width 2 and is offset by
1780 // another pixel in both directions when it's pressed - as the border
1781 // in this case is more narrow as well, we have to adjust rect like
1789 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1790 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1794 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1796 const wxRect
& rectTotal
,
1797 int WXUNUSED(flags
),
1802 wxRect rect
= rectTotal
;
1806 case wxBORDER_SUNKEN
:
1807 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1809 DrawSunkenBorder(dc
, &rect
);
1813 case wxBORDER_STATIC
:
1814 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1817 case wxBORDER_RAISED
:
1818 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1820 DrawRaisedBorder(dc
, &rect
);
1824 case wxBORDER_DOUBLE
:
1825 DrawArrowBorder(dc
, &rect
);
1826 DrawRect(dc
, &rect
, m_penLightGrey
);
1829 case wxBORDER_SIMPLE
:
1830 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1832 DrawRect(dc
, &rect
, m_penBlack
);
1837 wxFAIL_MSG(_T("unknown border type"));
1840 case wxBORDER_DEFAULT
:
1849 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1854 case wxBORDER_RAISED
:
1855 case wxBORDER_SUNKEN
:
1856 width
= BORDER_THICKNESS
;
1859 case wxBORDER_SIMPLE
:
1860 case wxBORDER_STATIC
:
1864 case wxBORDER_DOUBLE
:
1870 // char *crash = NULL;
1872 wxFAIL_MSG(_T("unknown border type"));
1876 case wxBORDER_DEFAULT
:
1886 rect
.height
= width
;
1891 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1896 // ----------------------------------------------------------------------------
1898 // ----------------------------------------------------------------------------
1900 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1906 // text controls are not special under windows
1907 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1910 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1911 const wxRect
& rectTotal
,
1915 wxRect rect
= rectTotal
;
1917 if ( flags
& wxCONTROL_PRESSED
)
1919 // button pressed: draw a double border around it
1920 DrawRect(dc
, &rect
, m_penBlack
);
1921 DrawRect(dc
, &rect
, m_penDarkGrey
);
1925 // button not pressed
1927 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1929 // button either default or focused (or both): add an extra border around it
1930 DrawRect(dc
, &rect
, m_penBlack
);
1933 // now draw a normal button
1934 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1935 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1944 // ----------------------------------------------------------------------------
1946 // ----------------------------------------------------------------------------
1948 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1949 wxCoord y
, wxCoord x1
, wxCoord x2
)
1951 dc
.SetPen(m_penDarkGrey
);
1952 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1953 dc
.SetPen(m_penHighlight
);
1955 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1958 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1959 wxCoord x
, wxCoord y1
, wxCoord y2
)
1961 dc
.SetPen(m_penDarkGrey
);
1962 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1963 dc
.SetPen(m_penHighlight
);
1965 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1968 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1969 const wxString
& label
,
1975 wxCoord height
= 0; // of the label
1976 wxRect rectFrame
= rect
;
1977 if ( !label
.empty() )
1979 // the text should touch the top border of the rect, so the frame
1980 // itself should be lower
1981 dc
.GetTextExtent(label
, NULL
, &height
);
1982 rectFrame
.y
+= height
/ 2;
1983 rectFrame
.height
-= height
/ 2;
1985 // we have to draw each part of the frame individually as we can't
1986 // erase the background beyond the label as it might contain some
1987 // pixmap already, so drawing everything and then overwriting part of
1988 // the frame with label doesn't work
1990 // TODO: the +5 and space insertion should be customizable
1993 rectText
.x
= rectFrame
.x
+ 5;
1994 rectText
.y
= rect
.y
;
1995 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1996 rectText
.height
= height
;
1999 label2
<< _T(' ') << label
<< _T(' ');
2000 if ( indexAccel
!= -1 )
2002 // adjust it as we prepended a space
2007 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2009 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2013 // just draw the complete frame
2014 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2015 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2019 // ----------------------------------------------------------------------------
2021 // ----------------------------------------------------------------------------
2023 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2025 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2026 // pixels each while we really need dots here... PS_ALTERNATE might
2027 // work, but it is for NT 5 only
2029 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2031 // draw the pixels manually: note that to behave in the same manner as
2032 // DrawRect(), we must exclude the bottom and right borders from the
2034 wxCoord x1
= rect
.GetLeft(),
2036 x2
= rect
.GetRight(),
2037 y2
= rect
.GetBottom();
2039 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2041 // this seems to be closer than what Windows does than wxINVERT although
2042 // I'm still not sure if it's correct
2043 dc
.SetLogicalFunction(wxAND_REVERSE
);
2046 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2047 dc
.DrawPoint(z
, rect
.GetTop());
2049 wxCoord shift
= z
== x2
? 0 : 1;
2050 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2051 dc
.DrawPoint(x2
, z
);
2053 shift
= z
== y2
? 0 : 1;
2054 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2055 dc
.DrawPoint(z
, y2
);
2057 shift
= z
== x1
? 0 : 1;
2058 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2059 dc
.DrawPoint(x1
, z
);
2061 dc
.SetLogicalFunction(wxCOPY
);
2065 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2066 const wxString
& label
,
2071 // draw shadow of the text
2072 dc
.SetTextForeground(m_colHighlight
);
2073 wxRect rectShadow
= rect
;
2076 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2078 // make the text grey
2079 dc
.SetTextForeground(m_colDarkGrey
);
2082 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2083 const wxString
& label
,
2090 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2093 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2094 const wxString
& label
,
2100 const wxPoint
& focusOffset
)
2102 // the underscores are not drawn for focused controls in wxMSW
2103 if ( flags
& wxCONTROL_FOCUSED
)
2108 if ( flags
& wxCONTROL_DISABLED
)
2110 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2111 // currently only can happen for a menu item and it seems that Windows
2112 // doesn't draw the shadow in this case, so we don't do it neither
2113 if ( flags
& wxCONTROL_SELECTED
)
2115 // just make the label text greyed out
2116 dc
.SetTextForeground(m_colDarkGrey
);
2118 else // draw normal disabled label
2120 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2125 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2127 if ( flags
& wxCONTROL_DISABLED
)
2129 // restore the fg colour
2130 dc
.SetTextForeground(*wxBLACK
);
2133 if ( flags
& wxCONTROL_FOCUSED
)
2135 if ( focusOffset
.x
|| focusOffset
.y
)
2137 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2140 DrawFocusRect(dc
, rectLabel
);
2144 *rectBounds
= rectLabel
;
2147 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2148 const wxString
& label
,
2149 const wxBitmap
& image
,
2156 // the underscores are not drawn for focused controls in wxMSW
2157 if ( flags
& wxCONTROL_PRESSED
)
2162 wxRect rectLabel
= rect
;
2163 if ( !label
.empty() )
2165 // shift the label if a button is pressed
2166 if ( flags
& wxCONTROL_PRESSED
)
2172 if ( flags
& wxCONTROL_DISABLED
)
2174 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2177 // leave enough space for the focus rectangle
2178 if ( flags
& wxCONTROL_FOCUSED
)
2180 rectLabel
.Inflate(-2);
2184 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2186 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2188 if ( flags
& wxCONTROL_PRESSED
)
2190 // the focus rectangle is never pressed, so undo the shift done
2198 DrawFocusRect(dc
, rectLabel
);
2202 // ----------------------------------------------------------------------------
2203 // (check)listbox items
2204 // ----------------------------------------------------------------------------
2206 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2207 const wxString
& label
,
2211 wxDCTextColourChanger
colChanger(dc
);
2213 if ( flags
& wxCONTROL_SELECTED
)
2215 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2217 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2218 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2219 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2220 dc
.DrawRectangle(rect
);
2223 wxRect rectText
= rect
;
2225 rectText
.width
-= 2;
2226 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2228 if ( flags
& wxCONTROL_FOCUSED
)
2230 DrawFocusRect(dc
, rect
);
2234 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2235 const wxString
& label
,
2236 const wxBitmap
& bitmap
,
2245 else // use default bitmap
2247 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2248 ? IndicatorStatus_Checked
2249 : IndicatorStatus_Unchecked
;
2251 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2253 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2256 bmp
= m_bmpCheckBitmaps
[i
];
2259 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2260 TRUE
/* use mask */);
2262 wxRect rectLabel
= rect
;
2263 int bmpWidth
= bmp
.GetWidth();
2264 rectLabel
.x
+= bmpWidth
;
2265 rectLabel
.width
-= bmpWidth
;
2267 DrawItem(dc
, label
, rectLabel
, flags
);
2270 // ----------------------------------------------------------------------------
2271 // check/radio buttons
2272 // ----------------------------------------------------------------------------
2274 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2276 IndicatorState indState
;
2277 if ( flags
& wxCONTROL_SELECTED
)
2278 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2279 : IndicatorState_Selected
;
2280 else if ( flags
& wxCONTROL_DISABLED
)
2281 indState
= IndicatorState_Disabled
;
2282 else if ( flags
& wxCONTROL_PRESSED
)
2283 indState
= IndicatorState_Pressed
;
2285 indState
= IndicatorState_Normal
;
2287 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2288 ? IndicatorStatus_Checked
2289 : IndicatorStatus_Unchecked
;
2291 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2294 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2297 // create and cache it
2298 bmp
= wxBitmap(xpm
);
2299 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2306 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2307 const wxString
& label
,
2308 const wxBitmap
& bitmap
,
2313 wxCoord focusOffsetY
)
2315 // calculate the position of the bitmap and of the label
2316 wxCoord heightBmp
= bitmap
.GetHeight();
2318 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2321 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2322 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2324 // align label vertically with the bitmap - looks nicer like this
2325 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2327 // calc horz position
2328 if ( align
== wxALIGN_RIGHT
)
2330 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2331 rectLabel
.x
= rect
.x
+ 3;
2332 rectLabel
.SetRight(xBmp
);
2334 else // normal (checkbox to the left of the text) case
2337 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2338 rectLabel
.SetRight(rect
.GetRight());
2341 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2344 dc
, label
, rectLabel
,
2346 wxALIGN_LEFT
| wxALIGN_TOP
,
2348 NULL
, // we don't need bounding rect
2349 // use custom vert focus rect offset
2350 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2354 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2355 const wxString
& label
,
2356 const wxBitmap
& bitmap
,
2366 bmp
= GetRadioBitmap(flags
);
2368 DrawCheckOrRadioButton(dc
, label
,
2370 rect
, flags
, align
, indexAccel
,
2371 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2374 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2375 const wxString
& label
,
2376 const wxBitmap
& bitmap
,
2386 bmp
= GetCheckBitmap(flags
);
2388 DrawCheckOrRadioButton(dc
, label
,
2390 rect
, flags
, align
, indexAccel
,
2391 0); // no focus rect offset for checkboxes
2394 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2395 const wxString
& label
,
2396 const wxBitmap
& bitmap
,
2397 const wxRect
& rectOrig
,
2400 if ( !label
.empty() || bitmap
.Ok() )
2402 wxRect rect
= rectOrig
;
2403 rect
.Deflate(BORDER_THICKNESS
);
2405 if ( flags
& wxCONTROL_PRESSED
)
2407 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2409 else if ( flags
& wxCONTROL_CURRENT
)
2411 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2414 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2418 // leave a small gap aroudn the line, also account for the toolbar
2420 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2421 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2422 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2426 // ----------------------------------------------------------------------------
2428 // ----------------------------------------------------------------------------
2430 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2431 const wxString
& text
,
2437 // nothing special to do here
2438 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2441 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2443 // we don't draw them
2446 // ----------------------------------------------------------------------------
2448 // ----------------------------------------------------------------------------
2450 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2451 const wxRect
& rectOrig
,
2453 const wxString
& label
,
2454 const wxBitmap
& bitmap
,
2458 wxRect rect
= rectOrig
;
2460 // the current tab is drawn indented (to the top for default case) and
2461 // bigger than the other ones
2462 const wxSize indent
= GetTabIndent();
2463 if ( flags
& wxCONTROL_SELECTED
)
2468 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2472 rect
.Inflate(indent
.x
, 0);
2474 rect
.height
+= indent
.y
;
2478 rect
.Inflate(indent
.x
, 0);
2479 rect
.height
+= indent
.y
;
2484 wxFAIL_MSG(_T("TODO"));
2489 // draw the text, image and the focus around them (if necessary)
2490 wxRect rectLabel
= rect
;
2491 rectLabel
.Deflate(1, 1);
2492 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2493 flags
, wxALIGN_CENTRE
, indexAccel
);
2495 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2496 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2499 x2
= rect
.GetRight(),
2500 y2
= rect
.GetBottom();
2502 // FIXME: all this code will break if the tab indent or the border width,
2503 // it is tied to the fact that both of them are equal to 2
2508 dc
.SetPen(m_penHighlight
);
2509 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2510 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2511 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2513 dc
.SetPen(m_penBlack
);
2514 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2515 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2517 dc
.SetPen(m_penDarkGrey
);
2518 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2520 if ( flags
& wxCONTROL_SELECTED
)
2522 dc
.SetPen(m_penLightGrey
);
2524 // overwrite the part of the border below this tab
2525 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2527 // and the shadow of the tab to the left of us
2528 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2533 dc
.SetPen(m_penHighlight
);
2534 // we need to continue one pixel further to overwrite the corner of
2535 // the border for the selected tab
2536 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2538 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2540 dc
.SetPen(m_penBlack
);
2541 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2542 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2543 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2545 dc
.SetPen(m_penDarkGrey
);
2546 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2547 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2549 if ( flags
& wxCONTROL_SELECTED
)
2551 dc
.SetPen(m_penLightGrey
);
2553 // overwrite the part of the (double!) border above this tab
2554 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2555 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2557 // and the shadow of the tab to the left of us
2558 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2564 wxFAIL_MSG(_T("TODO"));
2568 // ----------------------------------------------------------------------------
2570 // ----------------------------------------------------------------------------
2572 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2573 wxOrientation orient
) const
2577 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2578 if ( orient
== wxHORIZONTAL
)
2580 size
.y
= rect
.height
- 6;
2581 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2585 size
.x
= rect
.width
- 6;
2586 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2592 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2593 wxOrientation orient
) const
2595 static const wxCoord SLIDER_MARGIN
= 6;
2597 wxRect rect
= rectOrig
;
2599 if ( orient
== wxHORIZONTAL
)
2601 // make the rect of minimal width and centre it
2602 rect
.height
= 2*BORDER_THICKNESS
;
2603 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2607 // leave margins on the sides
2608 rect
.Deflate(SLIDER_MARGIN
, 0);
2612 // same as above but in other direction
2613 rect
.width
= 2*BORDER_THICKNESS
;
2614 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2618 rect
.Deflate(0, SLIDER_MARGIN
);
2624 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2625 const wxRect
& rectOrig
,
2626 wxOrientation orient
,
2630 if ( flags
& wxCONTROL_FOCUSED
)
2632 DrawFocusRect(dc
, rectOrig
);
2635 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2640 DrawSunkenBorder(dc
, &rect
);
2643 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2645 wxOrientation orient
,
2649 we are drawing a shape of this form
2654 H DB where H is hightlight colour
2667 The interior of this shape is filled with the hatched brush if the thumb
2671 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2673 bool transpose
= orient
== wxVERTICAL
;
2675 wxCoord x
, y
, x2
, y2
;
2680 x2
= rect
.GetBottom();
2681 y2
= rect
.GetRight();
2687 x2
= rect
.GetRight();
2688 y2
= rect
.GetBottom();
2691 // the size of the pointed part of the thumb
2692 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2694 wxCoord x3
= x
+ sizeArrow
,
2695 y3
= y2
- sizeArrow
;
2697 dc
.SetPen(m_penHighlight
);
2698 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2699 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2700 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2702 dc
.SetPen(m_penBlack
);
2703 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2704 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2706 dc
.SetPen(m_penDarkGrey
);
2707 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2708 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2710 if ( flags
& wxCONTROL_PRESSED
)
2712 // TODO: MSW fills the entire area inside, not just the rect
2713 wxRect rectInt
= rect
;
2715 rectInt
.SetRight(y3
);
2717 rectInt
.SetBottom(y3
);
2720 #if !defined(__WXMGL__)
2721 static const char *stipple_xpm
[] = {
2722 /* columns rows colors chars-per-pixel */
2731 // VS: MGL can only do 8x8 stipple brushes
2732 static const char *stipple_xpm
[] = {
2733 /* columns rows colors chars-per-pixel */
2748 dc
.SetBrush(wxBrush(stipple_xpm
));
2750 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2751 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2752 dc
.SetPen(*wxTRANSPARENT_PEN
);
2753 dc
.DrawRectangle(rectInt
);
2757 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2759 const wxSize
& sizeThumb
,
2760 wxOrientation orient
,
2772 // the variable names correspond to horizontal case, but they can be used
2773 // for both orientations
2774 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2775 if ( orient
== wxHORIZONTAL
)
2777 x1
= rect
.GetLeft();
2778 x2
= rect
.GetRight();
2780 // draw from bottom to top to leave one pixel space between the ticks
2781 // and the slider as Windows do
2782 y1
= rect
.GetBottom();
2787 widthThumb
= sizeThumb
.x
;
2792 x2
= rect
.GetBottom();
2794 y1
= rect
.GetRight();
2795 y2
= rect
.GetLeft();
2799 widthThumb
= sizeThumb
.y
;
2802 // the first tick should be positioned in such way that a thumb drawn in
2803 // the first position points down directly to it
2804 x1
+= widthThumb
/ 2;
2805 x2
-= widthThumb
/ 2;
2807 // this also means that we have slightly less space for the ticks in
2808 // between the first and the last
2811 dc
.SetPen(m_penBlack
);
2813 int range
= end
- start
;
2814 for ( int n
= 0; n
< range
; n
+= step
)
2816 wxCoord x
= x1
+ (len
*n
) / range
;
2818 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2821 // always draw the line at the end position
2822 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2825 // ----------------------------------------------------------------------------
2827 // ----------------------------------------------------------------------------
2829 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2830 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2833 virtual wxSize
GetSize() const { return m_size
; }
2835 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2836 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2838 wxCoord
GetItemHeight() const { return m_heightItem
; }
2841 // the total size of the menu
2844 // the offset of the start of the menu item label
2847 // the offset of the start of the accel label
2850 // the height of a normal (not separator) item
2851 wxCoord m_heightItem
;
2853 friend wxMenuGeometryInfo
*
2854 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2857 // FIXME: all constants are hardcoded but shouldn't be
2858 static const wxCoord MENU_LEFT_MARGIN
= 9;
2859 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2860 static const wxCoord MENU_VERT_MARGIN
= 3;
2862 // the margin around bitmap/check marks (on each side)
2863 static const wxCoord MENU_BMP_MARGIN
= 2;
2865 // the margin between the labels and accel strings
2866 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2868 // the separator height in pixels: in fact, strangely enough, the real height
2869 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2871 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2873 // the size of the standard checkmark bitmap
2874 static const wxCoord MENU_CHECK_SIZE
= 9;
2876 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2877 const wxRect
& rectOrig
,
2878 const wxString
& label
,
2882 wxRect rect
= rectOrig
;
2885 wxDCTextColourChanger
colChanger(dc
);
2887 if ( flags
& wxCONTROL_SELECTED
)
2889 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2891 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2892 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2893 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2894 dc
.DrawRectangle(rect
);
2897 // don't draw the focus rect around menu bar items
2898 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2899 wxALIGN_CENTRE
, indexAccel
);
2902 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2904 const wxMenuGeometryInfo
& gi
,
2905 const wxString
& label
,
2906 const wxString
& accel
,
2907 const wxBitmap
& bitmap
,
2911 const wxWin32MenuGeometryInfo
& geometryInfo
=
2912 (const wxWin32MenuGeometryInfo
&)gi
;
2917 rect
.width
= geometryInfo
.GetSize().x
;
2918 rect
.height
= geometryInfo
.GetItemHeight();
2920 // draw the selected item specially
2921 wxDCTextColourChanger
colChanger(dc
);
2922 if ( flags
& wxCONTROL_SELECTED
)
2924 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2926 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2927 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2928 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2929 dc
.DrawRectangle(rect
);
2932 // draw the bitmap: use the bitmap provided or the standard checkmark for
2933 // the checkable items
2934 wxBitmap bmp
= bitmap
;
2935 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2937 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2942 rect
.SetRight(geometryInfo
.GetLabelOffset());
2943 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2947 rect
.x
= geometryInfo
.GetLabelOffset();
2948 rect
.SetRight(geometryInfo
.GetAccelOffset());
2950 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2952 // draw the accel string
2953 rect
.x
= geometryInfo
.GetAccelOffset();
2954 rect
.SetRight(geometryInfo
.GetSize().x
);
2956 // NB: no accel index here
2957 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2959 // draw the submenu indicator
2960 if ( flags
& wxCONTROL_ISSUBMENU
)
2962 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2963 rect
.width
= MENU_RIGHT_MARGIN
;
2965 wxArrowStyle arrowStyle
;
2966 if ( flags
& wxCONTROL_DISABLED
)
2967 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2969 else if ( flags
& wxCONTROL_SELECTED
)
2970 arrowStyle
= Arrow_Inversed
;
2972 arrowStyle
= Arrow_Normal
;
2974 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2978 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2980 const wxMenuGeometryInfo
& geomInfo
)
2982 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2985 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2987 wxSize size
= sizeText
;
2989 // FIXME: menubar height is configurable under Windows
2996 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2997 const wxMenu
& menu
) const
2999 // prepare the dc: for now we draw all the items with the system font
3001 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3003 // the height of a normal item
3004 wxCoord heightText
= dc
.GetCharHeight();
3009 // the max length of label and accel strings: the menu width is the sum of
3010 // them, even if they're for different items (as the accels should be
3013 // the max length of the bitmap is never 0 as Windows always leaves enough
3014 // space for a check mark indicator
3015 wxCoord widthLabelMax
= 0,
3017 widthBmpMax
= MENU_LEFT_MARGIN
;
3019 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
3021 node
= node
->GetNext() )
3023 // height of this item
3026 wxMenuItem
*item
= node
->GetData();
3027 if ( item
->IsSeparator() )
3029 h
= MENU_SEPARATOR_HEIGHT
;
3031 else // not separator
3036 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3037 if ( widthLabel
> widthLabelMax
)
3039 widthLabelMax
= widthLabel
;
3043 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3044 if ( widthAccel
> widthAccelMax
)
3046 widthAccelMax
= widthAccel
;
3049 const wxBitmap
& bmp
= item
->GetBitmap();
3052 wxCoord widthBmp
= bmp
.GetWidth();
3053 if ( widthBmp
> widthBmpMax
)
3054 widthBmpMax
= widthBmp
;
3056 //else if ( item->IsCheckable() ): no need to check for this as
3057 // MENU_LEFT_MARGIN is big enough to show the check mark
3060 h
+= 2*MENU_VERT_MARGIN
;
3062 // remember the item position and height
3063 item
->SetGeometry(height
, h
);
3068 // bundle the metrics into a struct and return it
3069 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3071 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3072 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3073 if ( widthAccelMax
> 0 )
3075 // if we actually have any accesl, add a margin
3076 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3079 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3081 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3082 gi
->m_size
.y
= height
;
3087 // ----------------------------------------------------------------------------
3089 // ----------------------------------------------------------------------------
3091 static const wxCoord STATBAR_BORDER_X
= 2;
3092 static const wxCoord STATBAR_BORDER_Y
= 2;
3094 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3096 if ( borderBetweenFields
)
3097 *borderBetweenFields
= 2;
3099 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3102 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3104 const wxString
& label
,
3109 if ( flags
& wxCONTROL_ISDEFAULT
)
3111 // draw the size grip: it is a normal rect except that in the lower
3112 // right corner we have several bands which may be used for dragging
3113 // the status bar corner
3115 // each band consists of 4 stripes: m_penHighlight, double
3116 // m_penDarkGrey and transparent one
3117 wxCoord x2
= rect
.GetRight(),
3118 y2
= rect
.GetBottom();
3120 // draw the upper left part of the rect normally
3121 dc
.SetPen(m_penDarkGrey
);
3122 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3123 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3125 // draw the grey stripes of the grip
3127 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3128 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3130 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3131 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3134 // draw the white stripes
3135 dc
.SetPen(m_penHighlight
);
3136 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3137 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3139 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3142 // draw the remaining rect boundaries
3143 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3144 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3145 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3150 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3154 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3157 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3159 wxDCClipper
clipper(dc
, rectIn
);
3160 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3163 // ----------------------------------------------------------------------------
3165 // ----------------------------------------------------------------------------
3167 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3169 wxBitmap
*bmpPressed
,
3170 wxBitmap
*bmpDisabled
)
3172 static const wxCoord widthCombo
= 16;
3173 static const wxCoord heightCombo
= 17;
3179 bmpNormal
->Create(widthCombo
, heightCombo
);
3180 dcMem
.SelectObject(*bmpNormal
);
3181 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3182 Arrow_Down
, Arrow_Normal
);
3187 bmpPressed
->Create(widthCombo
, heightCombo
);
3188 dcMem
.SelectObject(*bmpPressed
);
3189 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3190 Arrow_Down
, Arrow_Pressed
);
3195 bmpDisabled
->Create(widthCombo
, heightCombo
);
3196 dcMem
.SelectObject(*bmpDisabled
);
3197 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3198 Arrow_Down
, Arrow_Disabled
);
3202 // ----------------------------------------------------------------------------
3204 // ----------------------------------------------------------------------------
3206 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3207 const wxColour
& col
,
3211 wxBrush
brush(col
, wxSOLID
);
3213 dc
.SetPen(*wxTRANSPARENT_PEN
);
3214 dc
.DrawRectangle(rect
);
3217 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3218 const wxColour
& col
,
3223 // just fill it with the given or default bg colour
3224 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3225 DoDrawBackground(dc
, colBg
, rect
, window
);
3228 // ----------------------------------------------------------------------------
3230 // ----------------------------------------------------------------------------
3232 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3237 // get the bitmap for this arrow
3238 wxArrowDirection arrowDir
;
3241 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3242 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3243 case wxUP
: arrowDir
= Arrow_Up
; break;
3244 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3247 wxFAIL_MSG(_T("unknown arrow direction"));
3251 wxArrowStyle arrowStyle
;
3252 if ( flags
& wxCONTROL_PRESSED
)
3254 // can't be pressed and disabled
3255 arrowStyle
= Arrow_Pressed
;
3259 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3262 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3265 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3267 wxArrowDirection arrowDir
,
3268 wxArrowStyle arrowStyle
)
3270 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3272 // under Windows the arrows always have the same size so just centre it in
3273 // the provided rectangle
3274 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3275 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3277 // Windows does it like this...
3278 if ( arrowDir
== Arrow_Left
)
3282 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3285 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3286 const wxRect
& rectAll
,
3287 wxArrowDirection arrowDir
,
3288 wxArrowStyle arrowStyle
)
3290 wxRect rect
= rectAll
;
3291 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3292 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3293 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3296 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3297 wxOrientation orient
,
3301 // we don't use the flags, the thumb never changes appearance
3302 wxRect rectThumb
= rect
;
3303 DrawArrowBorder(dc
, &rectThumb
);
3304 DrawBackground(dc
, wxNullColour
, rectThumb
);
3307 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3308 wxOrientation orient
,
3309 const wxRect
& rectBar
,
3312 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3313 ? wxColourScheme::SCROLLBAR_PRESSED
3314 : wxColourScheme::SCROLLBAR
;
3315 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3318 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3320 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3323 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3324 wxScrollBar::Element elem
,
3327 return StandardGetScrollbarRect(scrollbar
, elem
,
3328 thumbPos
, m_sizeScrollbarArrow
);
3331 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3333 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3336 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3337 const wxPoint
& pt
) const
3339 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3342 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3345 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3348 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3351 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3354 // ----------------------------------------------------------------------------
3355 // top level windows
3356 // ----------------------------------------------------------------------------
3358 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3360 wxRect client
= GetFrameClientArea(rect
, flags
);
3362 if ( client
.Inside(pt
) )
3363 return wxHT_TOPLEVEL_CLIENT_AREA
;
3365 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3367 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3369 if ( flags
& wxTOPLEVEL_ICON
)
3371 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3372 return wxHT_TOPLEVEL_ICON
;
3375 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3376 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3377 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3379 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3381 if ( btnRect
.Inside(pt
) )
3382 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3383 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3385 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3387 if ( btnRect
.Inside(pt
) )
3388 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3389 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3391 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3393 if ( btnRect
.Inside(pt
) )
3394 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3395 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3397 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3399 if ( btnRect
.Inside(pt
) )
3400 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3401 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3403 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3405 if ( btnRect
.Inside(pt
) )
3406 return wxHT_TOPLEVEL_BUTTON_HELP
;
3407 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3410 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3411 return wxHT_TOPLEVEL_TITLEBAR
;
3414 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3416 // we are certainly at one of borders, lets decide which one:
3419 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3420 if ( pt
.x
< client
.x
)
3421 border
|= wxHT_TOPLEVEL_BORDER_W
;
3422 else if ( pt
.x
>= client
.width
+ client
.x
)
3423 border
|= wxHT_TOPLEVEL_BORDER_E
;
3424 if ( pt
.y
< client
.y
)
3425 border
|= wxHT_TOPLEVEL_BORDER_N
;
3426 else if ( pt
.y
>= client
.height
+ client
.y
)
3427 border
|= wxHT_TOPLEVEL_BORDER_S
;
3431 return wxHT_NOWHERE
;
3434 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3436 const wxString
& title
,
3440 int specialButtonFlags
)
3442 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3444 DrawFrameBorder(dc
, rect
, flags
);
3446 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3448 DrawFrameBackground(dc
, rect
, flags
);
3449 if ( flags
& wxTOPLEVEL_ICON
)
3450 DrawFrameIcon(dc
, rect
, icon
, flags
);
3451 DrawFrameTitle(dc
, rect
, title
, flags
);
3453 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3455 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3456 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3458 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3460 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3461 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3462 specialButtonFlags
: 0);
3463 x
-= FRAME_BUTTON_WIDTH
+ 2;
3465 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3467 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3468 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3469 specialButtonFlags
: 0);
3470 x
-= FRAME_BUTTON_WIDTH
;
3472 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3474 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3475 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3476 specialButtonFlags
: 0);
3477 x
-= FRAME_BUTTON_WIDTH
;
3479 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3481 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3482 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3483 specialButtonFlags
: 0);
3484 x
-= FRAME_BUTTON_WIDTH
;
3486 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3488 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3489 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3490 specialButtonFlags
: 0);
3491 x
-= FRAME_BUTTON_WIDTH
;
3496 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3500 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3504 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3505 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3506 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3507 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3508 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3511 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3515 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3517 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3518 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3519 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3521 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3522 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3524 DrawBackground(dc
, col
, r
);
3527 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3529 const wxString
& title
,
3532 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3533 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3534 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3536 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3537 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3538 if ( flags
& wxTOPLEVEL_ICON
)
3540 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3541 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3549 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3550 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3551 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3552 r
.width
-= FRAME_BUTTON_WIDTH
;
3553 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3554 r
.width
-= FRAME_BUTTON_WIDTH
;
3555 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3556 r
.width
-= FRAME_BUTTON_WIDTH
;
3557 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3558 r
.width
-= FRAME_BUTTON_WIDTH
;
3560 dc
.SetFont(m_titlebarFont
);
3561 dc
.SetTextForeground(col
);
3564 dc
.GetTextExtent(title
, &textW
, NULL
);
3565 if ( textW
> r
.width
)
3567 // text is too big, let's shorten it and add "..." after it:
3568 size_t len
= title
.length();
3569 wxCoord WSoFar
, letterW
;
3571 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3572 if ( WSoFar
> r
.width
)
3574 // not enough space to draw anything
3580 for (size_t i
= 0; i
< len
; i
++)
3582 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3583 if ( letterW
+ WSoFar
> r
.width
)
3589 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3590 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3593 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3594 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3597 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3604 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3605 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3609 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3610 wxCoord x
, wxCoord y
,
3614 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3619 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3620 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3621 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3622 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3623 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3625 wxFAIL_MSG(wxT("incorrect button specification"));
3628 if ( flags
& wxCONTROL_PRESSED
)
3630 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3631 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3632 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3633 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3637 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3638 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3639 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3640 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3645 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3650 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3652 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3653 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3654 FRAME_BORDER_THICKNESS
;
3657 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3659 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3660 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3666 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3669 wxSize
s(clientSize
);
3671 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3673 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3674 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3675 FRAME_BORDER_THICKNESS
;
3679 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3680 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3685 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3689 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3691 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3692 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3693 FRAME_BORDER_THICKNESS
;
3698 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3700 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3702 if ( flags
& wxTOPLEVEL_ICON
)
3703 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3704 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3705 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3706 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3707 s
.x
+= FRAME_BUTTON_WIDTH
;
3708 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3709 s
.x
+= FRAME_BUTTON_WIDTH
;
3710 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3711 s
.x
+= FRAME_BUTTON_WIDTH
;
3712 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3713 s
.x
+= FRAME_BUTTON_WIDTH
;
3719 wxSize
wxWin32Renderer::GetFrameIconSize() const
3721 return wxSize(16, 16);
3725 // ----------------------------------------------------------------------------
3727 // ----------------------------------------------------------------------------
3729 static char *error_xpm
[]={
3736 "...........########.............",
3737 "........###aaaaaaaa###..........",
3738 ".......#aaaaaaaaaaaaaa#.........",
3739 ".....##aaaaaaaaaaaaaaaa##.......",
3740 "....#aaaaaaaaaaaaaaaaaaaa#......",
3741 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3742 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3743 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3744 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3745 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3746 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3747 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3748 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3749 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3750 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3751 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3752 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3753 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3754 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3755 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3756 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3757 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3758 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3759 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3760 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3761 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3762 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3763 "......b#aaaaaaaaaaaaaa#bbbbb....",
3764 ".......b###aaaaaaaa###bbbbb.....",
3765 ".........bb########bbbbbb.......",
3766 "..........bbbbbbbbbbbbbb........",
3767 ".............bbbbbbbb..........."};
3769 static char *info_xpm
[]={
3777 "...........########.............",
3778 "........###abbbbbba###..........",
3779 "......##abbbbbbbbbbbba##........",
3780 ".....#abbbbbbbbbbbbbbbba#.......",
3781 "....#bbbbbbbaccccabbbbbbbd......",
3782 "...#bbbbbbbbccccccbbbbbbbbd.....",
3783 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3784 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3785 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3786 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3787 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3788 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3789 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3790 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3791 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3792 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3793 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3794 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3795 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3796 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3797 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3798 ".....dabbbbbbbbbbbbbbbbad####...",
3799 "......ddabbbbbbbbbbbbadd####....",
3800 ".......#dddabbbbbbaddd#####.....",
3801 "........###dddabbbd#######......",
3802 "..........####dbbbd#####........",
3803 ".............#dbbbd##...........",
3804 "...............dbbd##...........",
3805 "................dbd##...........",
3806 ".................dd##...........",
3807 "..................###...........",
3808 "...................##..........."};
3810 static char *question_xpm
[]={
3818 "...........########.............",
3819 "........###abbbbbba###..........",
3820 "......##abbbbbbbbbbbba##........",
3821 ".....#abbbbbbbbbbbbbbbba#.......",
3822 "....#bbbbbbbbbbbbbbbbbbbbc......",
3823 "...#bbbbbbbaddddddabbbbbbbc.....",
3824 "..#bbbbbbbadabbddddabbbbbbbc....",
3825 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3826 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3827 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3828 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3829 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3830 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3831 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3832 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3833 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3834 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3835 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3836 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3837 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3838 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3839 ".....cabbbbbbbbbbbbbbbbac####...",
3840 "......ccabbbbbbbbbbbbacc####....",
3841 ".......#cccabbbbbbaccc#####.....",
3842 "........###cccabbbc#######......",
3843 "..........####cbbbc#####........",
3844 ".............#cbbbc##...........",
3845 "...............cbbc##...........",
3846 "................cbc##...........",
3847 ".................cc##...........",
3848 "..................###...........",
3849 "...................##..........."};
3851 static char *warning_xpm
[]={
3859 ".............###................",
3860 "............#aabc...............",
3861 "...........#aaaabcd.............",
3862 "...........#aaaaacdd............",
3863 "..........#aaaaaabcdd...........",
3864 "..........#aaaaaaacdd...........",
3865 ".........#aaaaaaaabcdd..........",
3866 ".........#aaaaaaaaacdd..........",
3867 "........#aaaaaaaaaabcdd.........",
3868 "........#aaabcccbaaacdd.........",
3869 ".......#aaaacccccaaabcdd........",
3870 ".......#aaaacccccaaaacdd........",
3871 "......#aaaaacccccaaaabcdd.......",
3872 "......#aaaaacccccaaaaacdd.......",
3873 ".....#aaaaaacccccaaaaabcdd......",
3874 ".....#aaaaaa#ccc#aaaaaacdd......",
3875 "....#aaaaaaabcccbaaaaaabcdd.....",
3876 "....#aaaaaaaacccaaaaaaaacdd.....",
3877 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3878 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3879 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3880 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3881 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3882 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3883 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3884 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3885 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3886 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3887 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3888 "..#ccccccccccccccccccccccccddddd",
3889 "....ddddddddddddddddddddddddddd.",
3890 ".....ddddddddddddddddddddddddd.."};
3892 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3893 const wxArtClient
& WXUNUSED(client
),
3894 const wxSize
& WXUNUSED(size
))
3896 if ( id
== wxART_INFORMATION
)
3897 return wxBitmap(info_xpm
);
3898 if ( id
== wxART_ERROR
)
3899 return wxBitmap(error_xpm
);
3900 if ( id
== wxART_WARNING
)
3901 return wxBitmap(warning_xpm
);
3902 if ( id
== wxART_QUESTION
)
3903 return wxBitmap(question_xpm
);
3904 return wxNullBitmap
;
3908 // ----------------------------------------------------------------------------
3909 // text control geometry
3910 // ----------------------------------------------------------------------------
3912 static inline int GetTextBorderWidth()
3917 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3918 const wxRect
& rect
) const
3920 wxRect rectTotal
= rect
;
3922 wxCoord widthBorder
= GetTextBorderWidth();
3923 rectTotal
.Inflate(widthBorder
);
3925 // this is what Windows does
3931 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3933 wxCoord
*extraSpaceBeyond
) const
3935 wxRect rectText
= rect
;
3937 // undo GetTextTotalArea()
3938 if ( rectText
.height
> 0 )
3941 wxCoord widthBorder
= GetTextBorderWidth();
3942 rectText
.Inflate(-widthBorder
);
3944 if ( extraSpaceBeyond
)
3945 *extraSpaceBeyond
= 0;
3950 // ----------------------------------------------------------------------------
3952 // ----------------------------------------------------------------------------
3954 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3957 if ( wxDynamicCast(window
, wxScrollBar
) )
3959 // we only set the width of vert scrollbars and height of the
3961 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3962 size
->y
= m_sizeScrollbarArrow
.y
;
3964 size
->x
= m_sizeScrollbarArrow
.x
;
3966 // skip border width adjustments, they don't make sense for us
3969 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3972 if ( wxDynamicCast(window
, wxButton
) )
3974 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3976 // TODO: don't harcode all this
3977 size
->x
+= 3*window
->GetCharWidth();
3979 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3980 if ( size
->y
< heightBtn
- 8 )
3981 size
->y
= heightBtn
;
3986 // no border width adjustments for buttons
3989 #endif // wxUSE_BUTTON
3991 // take into account the border width
3992 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3993 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3994 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3997 // ============================================================================
3999 // ============================================================================
4001 // ----------------------------------------------------------------------------
4002 // wxWin32InputHandler
4003 // ----------------------------------------------------------------------------
4005 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4007 m_renderer
= renderer
;
4010 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
4011 const wxKeyEvent
& event
,
4017 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4018 const wxMouseEvent
& event
)
4020 // clicking on the control gives it focus
4021 if ( event
.ButtonDown() )
4023 wxWindow
*win
= control
->GetInputWindow();
4025 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4026 ( win
->AcceptsFocus() ) )
4037 // ----------------------------------------------------------------------------
4038 // wxWin32ScrollBarInputHandler
4039 // ----------------------------------------------------------------------------
4041 wxWin32ScrollBarInputHandler::
4042 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4043 wxInputHandler
*handler
)
4044 : wxStdScrollBarInputHandler(renderer
, handler
)
4046 m_scrollPaused
= FALSE
;
4050 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4051 const wxControlAction
& action
)
4053 // stop if went beyond the position of the original click (this can only
4054 // happen when we scroll by pages)
4056 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4058 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4059 != wxHT_SCROLLBAR_BAR_2
;
4061 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4063 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4064 != wxHT_SCROLLBAR_BAR_1
;
4069 StopScrolling(scrollbar
);
4071 scrollbar
->Refresh();
4076 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4079 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4080 const wxMouseEvent
& event
)
4082 // remember the current state
4083 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4085 // do process the message
4086 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4088 // analyse the changes
4089 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4091 // we just started dragging the thumb, remember its initial position to
4092 // be able to restore it if the drag is cancelled later
4093 m_eventStartDrag
= event
;
4099 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4100 const wxMouseEvent
& event
)
4102 // we don't highlight scrollbar elements, so there is no need to process
4103 // mouse move events normally - only do it while mouse is captured (i.e.
4104 // when we're dragging the thumb or pressing on something)
4105 if ( !m_winCapture
)
4108 if ( event
.Entering() )
4110 // we're not interested in this at all
4114 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4116 if ( m_scrollPaused
)
4118 // check if the mouse returned to its original location
4120 if ( event
.Leaving() )
4126 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4127 if ( ht
== m_htLast
)
4129 // yes it did, resume scrolling
4130 m_scrollPaused
= FALSE
;
4131 if ( m_timerScroll
)
4133 // we were scrolling by line/page, restart timer
4134 m_timerScroll
->Start(m_interval
);
4136 Press(scrollbar
, TRUE
);
4138 else // we were dragging the thumb
4140 // restore its last location
4141 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4147 else // normal case, scrolling hasn't been paused
4149 // if we're scrolling the scrollbar because the arrow or the shaft was
4150 // pressed, check that the mouse stays on the same scrollbar element
4153 // Always let thumb jump back if we leave the scrollbar
4154 if ( event
.Moving() )
4156 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4158 else // event.Leaving()
4163 // Jump back only if we get far away from it
4164 wxPoint pos
= event
.GetPosition();
4165 if (scrollbar
->HasFlag( wxVERTICAL
))
4167 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4172 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4175 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4178 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4179 // is still ok - we only want to catch the case when the mouse leaves
4180 // the scrollbar here
4181 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4183 ht
= wxHT_SCROLLBAR_THUMB
;
4186 if ( ht
!= m_htLast
)
4188 // what were we doing? 2 possibilities: either an arrow/shaft was
4189 // pressed in which case we have a timer and so we just stop it or
4190 // we were dragging the thumb
4191 if ( m_timerScroll
)
4194 m_interval
= m_timerScroll
->GetInterval();
4195 m_timerScroll
->Stop();
4196 m_scrollPaused
= TRUE
;
4198 // unpress the arrow
4199 Press(scrollbar
, FALSE
);
4201 else // we were dragging the thumb
4203 // remember the current thumb position to be able to restore it
4204 // if the mouse returns to it later
4205 m_eventLastDrag
= event
;
4207 // and restore the original position (before dragging) of the
4209 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4216 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4219 // ----------------------------------------------------------------------------
4220 // wxWin32CheckboxInputHandler
4221 // ----------------------------------------------------------------------------
4223 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4224 const wxKeyEvent
& event
,
4229 wxControlAction action
;
4230 int keycode
= event
.GetKeyCode();
4234 action
= wxACTION_CHECKBOX_TOGGLE
;
4238 case WXK_NUMPAD_SUBTRACT
:
4239 action
= wxACTION_CHECKBOX_CHECK
;
4243 case WXK_NUMPAD_ADD
:
4244 case WXK_NUMPAD_EQUAL
:
4245 action
= wxACTION_CHECKBOX_CLEAR
;
4251 control
->PerformAction(action
);
4260 // ----------------------------------------------------------------------------
4261 // wxWin32TextCtrlInputHandler
4262 // ----------------------------------------------------------------------------
4264 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4265 const wxKeyEvent
& event
,
4268 // handle only MSW-specific text bindings here, the others are handled in
4272 int keycode
= event
.GetKeyCode();
4274 wxControlAction action
;
4275 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4277 action
= wxACTION_TEXT_CUT
;
4279 else if ( keycode
== WXK_INSERT
)
4281 if ( event
.ControlDown() )
4282 action
= wxACTION_TEXT_COPY
;
4283 else if ( event
.ShiftDown() )
4284 action
= wxACTION_TEXT_PASTE
;
4287 if ( action
!= wxACTION_NONE
)
4289 control
->PerformAction(action
);
4295 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4298 // ----------------------------------------------------------------------------
4299 // wxWin32StatusBarInputHandler
4300 // ----------------------------------------------------------------------------
4302 wxWin32StatusBarInputHandler::
4303 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4304 : wxStdInputHandler(handler
)
4309 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4310 const wxPoint
& pt
) const
4312 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4313 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4316 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4318 wxCHECK_MSG( parentTLW
, FALSE
,
4319 _T("the status bar should be a child of a TLW") );
4321 // a maximized window can't be resized anyhow
4322 if ( !parentTLW
->IsMaximized() )
4324 // VZ: I think that the standard Windows behaviour is to only
4325 // show the resizing cursor when the mouse is on top of the
4326 // grip itself but apparently different Windows versions behave
4327 // differently (?) and it seems a better UI to allow resizing
4328 // the status bar even when the mouse is above the grip
4329 wxSize sizeSbar
= statbar
->GetSize();
4331 int diff
= sizeSbar
.x
- pt
.x
;
4332 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4339 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4340 const wxMouseEvent
& event
)
4342 if ( event
.Button(1) )
4344 if ( event
.ButtonDown(1) )
4346 wxWindow
*statbar
= consumer
->GetInputWindow();
4348 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4350 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4354 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4355 wxHT_TOPLEVEL_BORDER_SE
);
4357 statbar
->SetCursor(m_cursorOld
);
4365 return wxStdInputHandler::HandleMouse(consumer
, event
);
4368 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4369 const wxMouseEvent
& event
)
4371 wxWindow
*statbar
= consumer
->GetInputWindow();
4373 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4374 if ( isOnGrip
!= m_isOnGrip
)
4376 m_isOnGrip
= isOnGrip
;
4379 m_cursorOld
= statbar
->GetCursor();
4380 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4384 statbar
->SetCursor(m_cursorOld
);
4388 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4391 // ----------------------------------------------------------------------------
4392 // wxWin32FrameInputHandler
4393 // ----------------------------------------------------------------------------
4395 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4398 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4400 void Attach(wxInputConsumer
*consumer
);
4404 DECLARE_EVENT_TABLE()
4405 void OnSystemMenu(wxCommandEvent
&event
);
4406 void OnCloseFrame(wxCommandEvent
&event
);
4407 void OnClose(wxCloseEvent
&event
);
4409 wxWin32FrameInputHandler
*m_inputHnd
;
4410 wxTopLevelWindow
*m_wnd
;
4411 wxAcceleratorTable m_oldAccelTable
;
4414 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4415 wxWin32FrameInputHandler
*handler
)
4417 m_inputHnd
= handler
;
4421 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4423 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4425 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4426 m_wnd
->PushEventHandler(this);
4428 // VS: This code relies on using generic implementation of
4429 // wxAcceleratorTable in wxUniv!
4430 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4431 m_oldAccelTable
= table
;
4432 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4433 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4434 m_wnd
->SetAcceleratorTable(table
);
4437 void wxWin32SystemMenuEvtHandler::Detach()
4441 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4442 m_wnd
->RemoveEventHandler(this);
4447 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4448 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4449 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4450 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4453 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4455 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4456 !m_wnd
->IsMaximized()) ?
4457 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4458 FRAME_BORDER_THICKNESS
;
4459 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4460 pt
.x
= -pt
.x
+ border
;
4461 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4463 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4464 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4465 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4466 m_wnd
->SetAcceleratorTable(table
);
4469 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4471 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4472 wxTOPLEVEL_BUTTON_CLOSE
);
4475 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4482 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4483 : wxStdFrameInputHandler(handler
)
4485 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4488 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4490 if ( m_menuHandler
)
4492 m_menuHandler
->Detach();
4493 delete m_menuHandler
;
4497 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4498 const wxMouseEvent
& event
)
4500 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4502 wxTopLevelWindow
*tlw
=
4503 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4505 long hit
= tlw
->HitTest(event
.GetPosition());
4507 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4509 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4510 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4511 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4514 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4516 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4517 (event
.RightDown() &&
4518 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4519 hit
== wxHT_TOPLEVEL_ICON
)) )
4521 PopupSystemMenu(tlw
, event
.GetPosition());
4527 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4530 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4531 const wxPoint
& pos
) const
4533 wxMenu
*menu
= new wxMenu
;
4535 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4536 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4537 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4538 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4539 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4540 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4541 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4542 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4543 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4544 menu
->AppendSeparator();
4545 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4547 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4549 if ( window
->IsMaximized() )
4551 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4552 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4553 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4554 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4557 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4560 window
->PopupMenu(menu
, pos
);
4564 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4567 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4569 // always detach if active frame changed:
4570 m_menuHandler
->Detach();
4574 m_menuHandler
->Attach(consumer
);
4578 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);