1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: univ/themes/win32.cpp
3 // Purpose: wxUniversal theme implementing Win32-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
31 #include "wx/window.h"
33 #include "wx/dcmemory.h"
35 #include "wx/button.h"
36 #include "wx/listbox.h"
37 #include "wx/checklst.h"
38 #include "wx/combobox.h"
39 #include "wx/scrolbar.h"
40 #include "wx/slider.h"
41 #include "wx/textctrl.h"
42 #include "wx/listbox.h"
43 #include "wx/toolbar.h"
44 #include "wx/statusbr.h"
47 // for COLOR_* constants
48 #include "wx/msw/private.h"
52 #include "wx/notebook.h"
53 #include "wx/spinbutt.h"
54 #include "wx/settings.h"
56 #include "wx/artprov.h"
57 #include "wx/toplevel.h"
60 #include "wx/univ/scrtimer.h"
61 #include "wx/univ/renderer.h"
62 #include "wx/univ/inphand.h"
63 #include "wx/univ/colschem.h"
64 #include "wx/univ/theme.h"
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 static const int BORDER_THICKNESS
= 2;
72 // the offset between the label and focus rect around it
73 static const int FOCUS_RECT_OFFSET_X
= 1;
74 static const int FOCUS_RECT_OFFSET_Y
= 1;
76 static const int FRAME_BORDER_THICKNESS
= 3;
77 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
78 static const int FRAME_TITLEBAR_HEIGHT
= 18;
79 static const int FRAME_BUTTON_WIDTH
= 16;
80 static const int FRAME_BUTTON_HEIGHT
= 14;
82 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
83 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
84 static const size_t STATUSBAR_GRIP_SIZE
=
85 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
87 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
88 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
89 static const wxCoord SLIDER_TICK_LENGTH
= 6;
101 IndicatorState_Normal
,
102 IndicatorState_Pressed
, // this one is for check/radioboxes
103 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
104 IndicatorState_Disabled
,
105 IndicatorState_SelectedDisabled
, // only for the menus
111 IndicatorStatus_Checked
,
112 IndicatorStatus_Unchecked
,
116 // wxWin32Renderer: draw the GUI elements in Win32 style
117 // ----------------------------------------------------------------------------
119 class wxWin32Renderer
: public wxRenderer
123 enum wxArrowDirection
138 Arrow_InversedDisabled
,
142 enum wxFrameButtonType
145 FrameButton_Minimize
,
146 FrameButton_Maximize
,
153 wxWin32Renderer(const wxColourScheme
*scheme
);
155 // implement the base class pure virtuals
156 virtual void DrawBackground(wxDC
& dc
,
160 wxWindow
*window
= NULL
);
161 virtual void DrawLabel(wxDC
& dc
,
162 const wxString
& label
,
165 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
167 wxRect
*rectBounds
= NULL
);
168 virtual void DrawButtonLabel(wxDC
& dc
,
169 const wxString
& label
,
170 const wxBitmap
& image
,
173 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
175 wxRect
*rectBounds
= NULL
);
176 virtual void DrawBorder(wxDC
& dc
,
180 wxRect
*rectIn
= (wxRect
*)NULL
);
181 virtual void DrawHorizontalLine(wxDC
& dc
,
182 wxCoord y
, wxCoord x1
, wxCoord x2
);
183 virtual void DrawVerticalLine(wxDC
& dc
,
184 wxCoord x
, wxCoord y1
, wxCoord y2
);
185 virtual void DrawFrame(wxDC
& dc
,
186 const wxString
& label
,
189 int alignment
= wxALIGN_LEFT
,
190 int indexAccel
= -1);
191 virtual void DrawTextBorder(wxDC
& dc
,
195 wxRect
*rectIn
= (wxRect
*)NULL
);
196 virtual void DrawButtonBorder(wxDC
& dc
,
199 wxRect
*rectIn
= (wxRect
*)NULL
);
200 virtual void DrawArrow(wxDC
& dc
,
204 virtual void DrawScrollbarArrow(wxDC
& dc
,
208 { DrawArrow(dc
, dir
, rect
, flags
); }
209 virtual void DrawScrollbarThumb(wxDC
& dc
,
210 wxOrientation orient
,
213 virtual void DrawScrollbarShaft(wxDC
& dc
,
214 wxOrientation orient
,
217 virtual void DrawScrollCorner(wxDC
& dc
,
219 virtual void DrawItem(wxDC
& dc
,
220 const wxString
& label
,
223 virtual void DrawCheckItem(wxDC
& dc
,
224 const wxString
& label
,
225 const wxBitmap
& bitmap
,
228 virtual void DrawCheckButton(wxDC
& dc
,
229 const wxString
& label
,
230 const wxBitmap
& bitmap
,
233 wxAlignment align
= wxALIGN_LEFT
,
234 int indexAccel
= -1);
235 virtual void DrawRadioButton(wxDC
& dc
,
236 const wxString
& label
,
237 const wxBitmap
& bitmap
,
240 wxAlignment align
= wxALIGN_LEFT
,
241 int indexAccel
= -1);
242 virtual void DrawToolBarButton(wxDC
& dc
,
243 const wxString
& label
,
244 const wxBitmap
& bitmap
,
248 virtual void DrawTextLine(wxDC
& dc
,
249 const wxString
& text
,
254 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
255 virtual void DrawTab(wxDC
& dc
,
258 const wxString
& label
,
259 const wxBitmap
& bitmap
= wxNullBitmap
,
261 int indexAccel
= -1);
263 virtual void DrawSliderShaft(wxDC
& dc
,
266 wxOrientation orient
,
269 wxRect
*rectShaft
= NULL
);
270 virtual void DrawSliderThumb(wxDC
& dc
,
272 wxOrientation orient
,
275 virtual void DrawSliderTicks(wxDC
& dc
,
278 wxOrientation orient
,
285 virtual void DrawMenuBarItem(wxDC
& dc
,
287 const wxString
& label
,
289 int indexAccel
= -1);
290 virtual void DrawMenuItem(wxDC
& dc
,
292 const wxMenuGeometryInfo
& geometryInfo
,
293 const wxString
& label
,
294 const wxString
& accel
,
295 const wxBitmap
& bitmap
= wxNullBitmap
,
297 int indexAccel
= -1);
298 virtual void DrawMenuSeparator(wxDC
& dc
,
300 const wxMenuGeometryInfo
& geomInfo
);
302 virtual void DrawStatusField(wxDC
& dc
,
304 const wxString
& label
,
305 int flags
= 0, int style
= 0);
308 virtual void DrawFrameTitleBar(wxDC
& dc
,
310 const wxString
& title
,
313 int specialButton
= 0,
314 int specialButtonFlags
= 0);
315 virtual void DrawFrameBorder(wxDC
& dc
,
318 virtual void DrawFrameBackground(wxDC
& dc
,
321 virtual void DrawFrameTitle(wxDC
& dc
,
323 const wxString
& title
,
325 virtual void DrawFrameIcon(wxDC
& dc
,
329 virtual void DrawFrameButton(wxDC
& dc
,
330 wxCoord x
, wxCoord y
,
333 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
334 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
335 virtual wxSize
GetFrameMinSize(int flags
) const;
336 virtual wxSize
GetFrameIconSize() const;
337 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
339 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
341 wxBitmap
*bmpPressed
,
342 wxBitmap
*bmpDisabled
);
344 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
345 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
346 virtual bool AreScrollbarsInsideBorder() const;
348 virtual wxSize
GetScrollbarArrowSize() const
349 { return m_sizeScrollbarArrow
; }
350 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
351 wxScrollBar
::Element elem
,
352 int thumbPos
= -1) const;
353 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
354 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
355 const wxPoint
& pt
) const;
356 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
358 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
359 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
360 { return fontHeight
+ 2; }
361 virtual wxSize
GetCheckBitmapSize() const
362 { return wxSize(13, 13); }
363 virtual wxSize
GetRadioBitmapSize() const
364 { return wxSize(12, 12); }
365 virtual wxCoord
GetCheckItemMargin() const
368 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
369 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
370 virtual wxSize
GetToolBarMargin() const
371 { return wxSize(4, 4); }
373 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
374 const wxRect
& rect
) const;
375 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
377 wxCoord
*extraSpaceBeyond
) const;
379 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
380 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
382 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
383 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
384 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
386 wxOrientation orient
,
387 long style
= 0) const;
388 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
390 wxOrientation orient
) const;
391 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
393 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
394 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
395 const wxMenu
& menu
) const;
397 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
400 // helper of DrawLabel() and DrawCheckOrRadioButton()
401 void DoDrawLabel(wxDC
& dc
,
402 const wxString
& label
,
405 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
407 wxRect
*rectBounds
= NULL
,
408 const wxPoint
& focusOffset
409 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
411 // common part of DrawLabel() and DrawItem()
412 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
414 // DrawLabel() and DrawButtonLabel() helper
415 void DrawLabelShadow(wxDC
& dc
,
416 const wxString
& label
,
421 // DrawButtonBorder() helper
422 void DoDrawBackground(wxDC
& dc
,
425 wxWindow
*window
= NULL
);
427 // DrawBorder() helpers: all of them shift and clip the DC after drawing
430 // just draw a rectangle with the given pen
431 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
433 // draw the lower left part of rectangle
434 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
436 // draw the rectange using the first brush for the left and top sides and
437 // the second one for the bottom and right ones
438 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
439 const wxPen
& pen1
, const wxPen
& pen2
);
441 // draw the normal 3D border
442 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
444 // draw the sunken 3D border
445 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
447 // draw the border used for scrollbar arrows
448 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
450 // public DrawArrow()s helper
451 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
452 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
454 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
455 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
456 wxArrowDirection arrowDir
,
457 wxArrowStyle arrowStyle
);
459 // DrawCheckButton/DrawRadioButton helper
460 void DrawCheckOrRadioButton(wxDC
& dc
,
461 const wxString
& label
,
462 const wxBitmap
& bitmap
,
467 wxCoord focusOffsetY
);
469 // draw a normal or transposed line (useful for using the same code fo both
470 // horizontal and vertical widgets)
471 void DrawLine(wxDC
& dc
,
472 wxCoord x1
, wxCoord y1
,
473 wxCoord x2
, wxCoord y2
,
474 bool transpose
= false)
477 dc
.DrawLine(y1
, x1
, y2
, x2
);
479 dc
.DrawLine(x1
, y1
, x2
, y2
);
482 // get the standard check/radio button bitmap
483 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
484 wxBitmap
GetCheckBitmap(int flags
)
485 { return GetIndicator(IndicatorType_Check
, flags
); }
486 wxBitmap
GetRadioBitmap(int flags
)
487 { return GetIndicator(IndicatorType_Radio
, flags
); }
490 const wxColourScheme
*m_scheme
;
492 // the sizing parameters (TODO make them changeable)
493 wxSize m_sizeScrollbarArrow
;
495 // GDI objects we use for drawing
496 wxColour m_colDarkGrey
,
504 wxFont m_titlebarFont
;
506 // the checked and unchecked bitmaps for DrawCheckItem()
507 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
509 // the bitmaps returned by GetIndicator()
510 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
512 [IndicatorStatus_Max
];
515 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
517 // first row is for the normal state, second - for the disabled
518 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
521 // ----------------------------------------------------------------------------
522 // wxWin32InputHandler and derived classes: process the keyboard and mouse
523 // messages according to Windows standards
524 // ----------------------------------------------------------------------------
526 class wxWin32InputHandler
: public wxInputHandler
529 wxWin32InputHandler(wxWin32Renderer
*renderer
);
531 virtual bool HandleKey(wxInputConsumer
*control
,
532 const wxKeyEvent
& event
,
534 virtual bool HandleMouse(wxInputConsumer
*control
,
535 const wxMouseEvent
& event
);
538 wxWin32Renderer
*m_renderer
;
541 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
544 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
545 wxInputHandler
*handler
);
547 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
548 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
550 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
551 const wxControlAction
& action
);
554 virtual bool IsAllowedButton(int button
) { return button
== 1; }
556 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
559 // we don't highlight anything
562 // the first and last event which caused the thumb to move
563 wxMouseEvent m_eventStartDrag
,
566 // have we paused the scrolling because the mouse moved?
569 // we remember the interval of the timer to be able to restart it
573 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
576 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
577 : wxStdCheckboxInputHandler(handler
) { }
579 virtual bool HandleKey(wxInputConsumer
*control
,
580 const wxKeyEvent
& event
,
584 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
587 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
588 : wxStdTextCtrlInputHandler(handler
) { }
590 virtual bool HandleKey(wxInputConsumer
*control
,
591 const wxKeyEvent
& event
,
595 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
598 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
600 virtual bool HandleMouse(wxInputConsumer
*consumer
,
601 const wxMouseEvent
& event
);
603 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
604 const wxMouseEvent
& event
);
607 // is the given point over the statusbar grip?
608 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
611 // the cursor we had replaced with the resize one
612 wxCursor m_cursorOld
;
614 // was the mouse over the grip last time we checked?
618 class wxWin32SystemMenuEvtHandler
;
620 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
623 wxWin32FrameInputHandler(wxInputHandler
*handler
);
624 ~wxWin32FrameInputHandler();
626 virtual bool HandleMouse(wxInputConsumer
*control
,
627 const wxMouseEvent
& event
);
629 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
631 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
634 // was the mouse over the grip last time we checked?
635 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
638 // ----------------------------------------------------------------------------
639 // wxWin32ColourScheme: uses (default) Win32 colours
640 // ----------------------------------------------------------------------------
642 class wxWin32ColourScheme
: public wxColourScheme
645 virtual wxColour
Get(StdColour col
) const;
646 virtual wxColour
GetBackground(wxWindow
*win
) const;
649 // ----------------------------------------------------------------------------
650 // wxWin32ArtProvider
651 // ----------------------------------------------------------------------------
653 class wxWin32ArtProvider
: public wxArtProvider
656 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
657 const wxArtClient
& client
,
661 // ----------------------------------------------------------------------------
663 // ----------------------------------------------------------------------------
665 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
667 class wxWin32Theme
: public wxTheme
671 virtual ~wxWin32Theme();
673 virtual wxRenderer
*GetRenderer();
674 virtual wxArtProvider
*GetArtProvider();
675 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
676 virtual wxColourScheme
*GetColourScheme();
679 // get the default input handler
680 wxInputHandler
*GetDefaultInputHandler();
682 wxWin32Renderer
*m_renderer
;
684 wxWin32ArtProvider
*m_artProvider
;
686 // the names of the already created handlers and the handlers themselves
687 // (these arrays are synchronized)
688 wxSortedArrayString m_handlerNames
;
689 wxArrayHandlers m_handlers
;
691 wxWin32InputHandler
*m_handlerDefault
;
693 wxWin32ColourScheme
*m_scheme
;
695 WX_DECLARE_THEME(win32
)
698 // ----------------------------------------------------------------------------
700 // ----------------------------------------------------------------------------
702 // frame buttons bitmaps
704 static const char *frame_button_close_xpm
[] = {
719 static const char *frame_button_help_xpm
[] = {
734 static const char *frame_button_maximize_xpm
[] = {
749 static const char *frame_button_minimize_xpm
[] = {
764 static const char *frame_button_restore_xpm
[] = {
781 static const char *checked_menu_xpm
[] = {
782 /* columns rows colors chars-per-pixel */
798 static const char *selected_checked_menu_xpm
[] = {
799 /* columns rows colors chars-per-pixel */
815 static const char *disabled_checked_menu_xpm
[] = {
816 /* columns rows colors chars-per-pixel */
833 static const char *selected_disabled_checked_menu_xpm
[] = {
834 /* columns rows colors chars-per-pixel */
850 // checkbox and radiobox bitmaps below
852 static const char *checked_xpm
[] = {
853 /* columns rows colors chars-per-pixel */
876 static const char *pressed_checked_xpm
[] = {
877 /* columns rows colors chars-per-pixel */
899 static const char *pressed_disabled_checked_xpm
[] = {
900 /* columns rows colors chars-per-pixel */
922 static const char *checked_item_xpm
[] = {
923 /* columns rows colors chars-per-pixel */
944 static const char *unchecked_xpm
[] = {
945 /* columns rows colors chars-per-pixel */
968 static const char *pressed_unchecked_xpm
[] = {
969 /* columns rows colors chars-per-pixel */
991 static const char *unchecked_item_xpm
[] = {
992 /* columns rows colors chars-per-pixel */
1012 static const char *checked_radio_xpm
[] = {
1013 /* columns rows colors chars-per-pixel */
1036 static const char *pressed_checked_radio_xpm
[] = {
1037 /* columns rows colors chars-per-pixel */
1060 static const char *pressed_disabled_checked_radio_xpm
[] = {
1061 /* columns rows colors chars-per-pixel */
1084 static const char *unchecked_radio_xpm
[] = {
1085 /* columns rows colors chars-per-pixel */
1108 static const char *pressed_unchecked_radio_xpm
[] = {
1109 /* columns rows colors chars-per-pixel */
1132 static const char **
1133 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1138 { checked_xpm
, unchecked_xpm
},
1141 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1144 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1150 { checked_radio_xpm
, unchecked_radio_xpm
},
1153 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1156 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1162 { checked_menu_xpm
, NULL
},
1165 { selected_checked_menu_xpm
, NULL
},
1168 { disabled_checked_menu_xpm
, NULL
},
1170 // disabled selected state
1171 { selected_disabled_checked_menu_xpm
, NULL
},
1175 static const char **xpmChecked
[IndicatorStatus_Max
] =
1181 // ============================================================================
1183 // ============================================================================
1185 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1187 // ----------------------------------------------------------------------------
1189 // ----------------------------------------------------------------------------
1191 wxWin32Theme
::wxWin32Theme()
1195 m_handlerDefault
= NULL
;
1196 m_artProvider
= NULL
;
1199 wxWin32Theme
::~wxWin32Theme()
1201 size_t count
= m_handlers
.GetCount();
1202 for ( size_t n
= 0; n
< count
; n
++ )
1204 if ( m_handlers
[n
] != m_handlerDefault
)
1205 delete m_handlers
[n
];
1208 delete m_handlerDefault
;
1212 wxArtProvider
::RemoveProvider(m_artProvider
);
1215 wxRenderer
*wxWin32Theme
::GetRenderer()
1219 m_renderer
= new wxWin32Renderer(GetColourScheme());
1225 wxArtProvider
*wxWin32Theme
::GetArtProvider()
1227 if ( !m_artProvider
)
1229 m_artProvider
= new wxWin32ArtProvider
;
1232 return m_artProvider
;
1235 wxInputHandler
*wxWin32Theme
::GetDefaultInputHandler()
1237 if ( !m_handlerDefault
)
1239 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1242 return m_handlerDefault
;
1245 wxInputHandler
*wxWin32Theme
::GetInputHandler(const wxString
& control
)
1247 wxInputHandler
*handler
;
1248 int n
= m_handlerNames
.Index(control
);
1249 if ( n
== wxNOT_FOUND
)
1251 // create a new handler
1252 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1253 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1254 GetDefaultInputHandler());
1256 else if ( control
== wxINP_HANDLER_BUTTON
)
1257 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1258 #endif // wxUSE_BUTTON
1260 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1261 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1262 #endif // wxUSE_CHECKBOX
1264 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1265 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1266 #endif // wxUSE_COMBOBOX
1268 else if ( control
== wxINP_HANDLER_LISTBOX
)
1269 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1270 #endif // wxUSE_LISTBOX
1271 #if wxUSE_CHECKLISTBOX
1272 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1273 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1274 #endif // wxUSE_CHECKLISTBOX
1276 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1277 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1278 #endif // wxUSE_TEXTCTRL
1280 else if ( control
== wxINP_HANDLER_SLIDER
)
1281 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1282 #endif // wxUSE_SLIDER
1284 else if ( control
== wxINP_HANDLER_SPINBTN
)
1285 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1286 #endif // wxUSE_SPINBTN
1288 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1289 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1290 #endif // wxUSE_NOTEBOOK
1292 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1293 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1294 #endif // wxUSE_STATUSBAR
1296 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1297 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1298 #endif // wxUSE_TOOLBAR
1299 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1300 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1302 handler
= GetDefaultInputHandler();
1304 n
= m_handlerNames
.Add(control
);
1305 m_handlers
.Insert(handler
, n
);
1307 else // we already have it
1309 handler
= m_handlers
[n
];
1315 wxColourScheme
*wxWin32Theme
::GetColourScheme()
1319 m_scheme
= new wxWin32ColourScheme
;
1324 // ============================================================================
1325 // wxWin32ColourScheme
1326 // ============================================================================
1328 wxColour wxWin32ColourScheme
::GetBackground(wxWindow
*win
) const
1331 if ( win
->UseBgCol() )
1333 // use the user specified colour
1334 col
= win
->GetBackgroundColour();
1337 if ( !win
->ShouldInheritColours() )
1339 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1341 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1349 if ( !win
->IsEnabled() ) // not IsEditable()
1355 // doesn't depend on the state
1362 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1366 int flags
= win
->GetStateFlags();
1368 // the colour set by the user should be used for the normal state
1369 // and for the states for which we don't have any specific colours
1370 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1372 if ( wxDynamicCast(win
, wxScrollBar
) )
1373 col
= Get(flags
& wxCONTROL_PRESSED ? SCROLLBAR_PRESSED
1383 wxColour wxWin32ColourScheme
::Get(wxWin32ColourScheme
::StdColour col
) const
1387 // use the system colours under Windows
1388 #if defined(__WXMSW__)
1389 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1391 case CONTROL_PRESSED
:
1392 case CONTROL_CURRENT
:
1393 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1395 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1397 #if defined(COLOR_3DLIGHT)
1398 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1400 case SCROLLBAR
: return wxColour(0xe0e0e0);
1402 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1404 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1405 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1407 #if defined(COLOR_3DDKSHADOW)
1408 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1410 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1413 case CONTROL_TEXT_DISABLED
:
1414 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1416 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1418 case CONTROL_TEXT_DISABLED_SHADOW
:
1419 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1421 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1422 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1423 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1424 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1426 case DESKTOP
: return wxColour(0x808000);
1428 // use the standard Windows colours elsewhere
1429 case WINDOW
: return *wxWHITE
;
1431 case CONTROL_PRESSED
:
1432 case CONTROL_CURRENT
:
1433 case CONTROL
: return wxColour(0xc0c0c0);
1435 case CONTROL_TEXT
: return *wxBLACK
;
1437 case SCROLLBAR
: return wxColour(0xe0e0e0);
1438 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1440 case HIGHLIGHT
: return wxColour(0x800000);
1441 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1443 case SHADOW_DARK
: return *wxBLACK
;
1445 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1446 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1448 case SHADOW_IN
: return wxColour(0xc0c0c0);
1450 case CONTROL_TEXT_DISABLED_SHADOW
:
1451 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1453 case TITLEBAR
: return wxColour(0xaeaaae);
1454 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1455 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1456 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1458 case DESKTOP
: return wxColour(0x808000);
1461 case GAUGE
: return Get(HIGHLIGHT
);
1465 wxFAIL_MSG(_T("invalid standard colour"));
1470 // ============================================================================
1472 // ============================================================================
1474 // ----------------------------------------------------------------------------
1476 // ----------------------------------------------------------------------------
1478 wxWin32Renderer
::wxWin32Renderer(const wxColourScheme
*scheme
)
1482 m_sizeScrollbarArrow
= wxSize(16, 16);
1484 // init colours and pens
1485 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1487 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1488 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1490 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1492 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1493 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1495 m_titlebarFont
= wxSystemSettings
::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1496 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1498 // init the arrow bitmaps
1499 static const size_t ARROW_WIDTH
= 7;
1500 static const size_t ARROW_LENGTH
= 4;
1503 wxMemoryDC dcNormal
,
1506 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1508 bool isVertical
= n
> Arrow_Right
;
1521 // disabled arrow is larger because of the shadow
1522 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1523 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1525 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1526 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1528 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1529 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1533 dcNormal
.SetPen(m_penBlack
);
1534 dcDisabled
.SetPen(m_penDarkGrey
);
1536 // calculate the position of the point of the arrow
1540 x1
= (ARROW_WIDTH
- 1)/2;
1541 y1
= n
== Arrow_Up ?
0 : ARROW_LENGTH
- 1;
1545 x1
= n
== Arrow_Left ?
0 : ARROW_LENGTH
- 1;
1546 y1
= (ARROW_WIDTH
- 1)/2;
1557 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1559 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1560 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1567 if ( n
== Arrow_Up
)
1578 else // left or right arrow
1583 if ( n
== Arrow_Left
)
1596 // draw the shadow for the disabled one
1597 dcDisabled
.SetPen(m_penHighlight
);
1602 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1606 x1
= ARROW_LENGTH
- 1;
1607 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1610 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1611 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1616 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1620 x1
= ARROW_WIDTH
- 1;
1622 x2
= (ARROW_WIDTH
- 1)/2;
1624 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1625 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1630 // create the inversed bitmap but only for the right arrow as we only
1631 // use it for the menus
1632 if ( n
== Arrow_Right
)
1634 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1635 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1637 dcInverse
.Blit(0, 0, w
, h
,
1640 dcInverse
.SelectObject(wxNullBitmap
);
1642 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1643 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1645 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1646 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1648 dcInverse
.Blit(0, 0, w
, h
,
1651 dcInverse
.SelectObject(wxNullBitmap
);
1653 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1654 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1657 dcNormal
.SelectObject(wxNullBitmap
);
1658 dcDisabled
.SelectObject(wxNullBitmap
);
1660 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1661 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1662 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1663 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1665 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1668 // init the frame buttons bitmaps
1669 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1670 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1671 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1672 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1673 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1676 // ----------------------------------------------------------------------------
1678 // ----------------------------------------------------------------------------
1681 The raised border in Win32 looks like this:
1683 IIIIIIIIIIIIIIIIIIIIIIB
1685 I GB I = white (HILIGHT)
1686 I GB H = light grey (LIGHT)
1687 I GB G = dark grey (SHADOI)
1688 I GB B = black (DKSHADOI)
1689 I GB I = hIghlight (COLOR_3DHILIGHT)
1691 IGGGGGGGGGGGGGGGGGGGGGB
1692 BBBBBBBBBBBBBBBBBBBBBBB
1694 The sunken border looks like this:
1696 GGGGGGGGGGGGGGGGGGGGGGI
1697 GBBBBBBBBBBBBBBBBBBBBHI
1704 GHHHHHHHHHHHHHHHHHHHHHI
1705 IIIIIIIIIIIIIIIIIIIIIII
1707 The static border (used for the controls which don't get focus) is like
1710 GGGGGGGGGGGGGGGGGGGGGGW
1718 WWWWWWWWWWWWWWWWWWWWWWW
1720 The most complicated is the double border:
1722 HHHHHHHHHHHHHHHHHHHHHHB
1723 HWWWWWWWWWWWWWWWWWWWWGB
1724 HWHHHHHHHHHHHHHHHHHHHGB
1729 HWHHHHHHHHHHHHHHHHHHHGB
1730 HGGGGGGGGGGGGGGGGGGGGGB
1731 BBBBBBBBBBBBBBBBBBBBBBB
1733 And the simple border is, well, simple:
1735 BBBBBBBBBBBBBBBBBBBBBBB
1744 BBBBBBBBBBBBBBBBBBBBBBB
1747 void wxWin32Renderer
::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1751 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1752 dc
.DrawRectangle(*rect
);
1758 void wxWin32Renderer
::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1760 // draw the bottom and right sides
1762 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1763 rect
->GetRight() + 1, rect
->GetBottom());
1764 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1765 rect
->GetRight(), rect
->GetBottom());
1771 void wxWin32Renderer
::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1772 const wxPen
& pen1
, const wxPen
& pen2
)
1774 // draw the rectangle
1776 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1777 rect
->GetLeft(), rect
->GetBottom());
1778 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1779 rect
->GetRight(), rect
->GetTop());
1781 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1782 rect
->GetRight(), rect
->GetBottom());
1783 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1784 rect
->GetRight() + 1, rect
->GetBottom());
1790 void wxWin32Renderer
::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1792 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1793 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1796 void wxWin32Renderer
::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1798 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1799 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1802 void wxWin32Renderer
::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1806 DrawRect(dc
, rect
, m_penDarkGrey
);
1808 // the arrow is usually drawn inside border of width 2 and is offset by
1809 // another pixel in both directions when it's pressed - as the border
1810 // in this case is more narrow as well, we have to adjust rect like
1818 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1819 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1823 void wxWin32Renderer
::DrawBorder(wxDC
& dc
,
1825 const wxRect
& rectTotal
,
1826 int WXUNUSED(flags
),
1831 wxRect rect
= rectTotal
;
1835 case wxBORDER_SUNKEN
:
1836 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1838 DrawSunkenBorder(dc
, &rect
);
1842 case wxBORDER_STATIC
:
1843 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1846 case wxBORDER_RAISED
:
1847 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1849 DrawRaisedBorder(dc
, &rect
);
1853 case wxBORDER_DOUBLE
:
1854 DrawArrowBorder(dc
, &rect
);
1855 DrawRect(dc
, &rect
, m_penLightGrey
);
1858 case wxBORDER_SIMPLE
:
1859 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1861 DrawRect(dc
, &rect
, m_penBlack
);
1866 wxFAIL_MSG(_T("unknown border type"));
1869 case wxBORDER_DEFAULT
:
1878 wxRect wxWin32Renderer
::GetBorderDimensions(wxBorder border
) const
1883 case wxBORDER_RAISED
:
1884 case wxBORDER_SUNKEN
:
1885 width
= BORDER_THICKNESS
;
1888 case wxBORDER_SIMPLE
:
1889 case wxBORDER_STATIC
:
1893 case wxBORDER_DOUBLE
:
1899 // char *crash = NULL;
1901 wxFAIL_MSG(_T("unknown border type"));
1905 case wxBORDER_DEFAULT
:
1915 rect
.height
= width
;
1920 bool wxWin32Renderer
::AreScrollbarsInsideBorder() const
1925 // ----------------------------------------------------------------------------
1927 // ----------------------------------------------------------------------------
1929 void wxWin32Renderer
::DrawTextBorder(wxDC
& dc
,
1935 // text controls are not special under windows
1936 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1939 void wxWin32Renderer
::DrawButtonBorder(wxDC
& dc
,
1940 const wxRect
& rectTotal
,
1944 wxRect rect
= rectTotal
;
1946 if ( flags
& wxCONTROL_PRESSED
)
1948 // button pressed: draw a double border around it
1949 DrawRect(dc
, &rect
, m_penBlack
);
1950 DrawRect(dc
, &rect
, m_penDarkGrey
);
1954 // button not pressed
1956 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1958 // button either default or focused (or both): add an extra border around it
1959 DrawRect(dc
, &rect
, m_penBlack
);
1962 // now draw a normal button
1963 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1964 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1973 // ----------------------------------------------------------------------------
1975 // ----------------------------------------------------------------------------
1977 void wxWin32Renderer
::DrawHorizontalLine(wxDC
& dc
,
1978 wxCoord y
, wxCoord x1
, wxCoord x2
)
1980 dc
.SetPen(m_penDarkGrey
);
1981 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1982 dc
.SetPen(m_penHighlight
);
1984 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1987 void wxWin32Renderer
::DrawVerticalLine(wxDC
& dc
,
1988 wxCoord x
, wxCoord y1
, wxCoord y2
)
1990 dc
.SetPen(m_penDarkGrey
);
1991 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1992 dc
.SetPen(m_penHighlight
);
1994 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1997 void wxWin32Renderer
::DrawFrame(wxDC
& dc
,
1998 const wxString
& label
,
2004 wxCoord height
= 0; // of the label
2005 wxRect rectFrame
= rect
;
2006 if ( !label
.empty() )
2008 // the text should touch the top border of the rect, so the frame
2009 // itself should be lower
2010 dc
.GetTextExtent(label
, NULL
, &height
);
2011 rectFrame
.y
+= height
/ 2;
2012 rectFrame
.height
-= height
/ 2;
2014 // we have to draw each part of the frame individually as we can't
2015 // erase the background beyond the label as it might contain some
2016 // pixmap already, so drawing everything and then overwriting part of
2017 // the frame with label doesn't work
2019 // TODO: the +5 and space insertion should be customizable
2022 rectText
.x
= rectFrame
.x
+ 5;
2023 rectText
.y
= rect
.y
;
2024 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2025 rectText
.height
= height
;
2028 label2
<< _T(' ') << label
<< _T(' ');
2029 if ( indexAccel
!= -1 )
2031 // adjust it as we prepended a space
2036 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2038 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2042 // just draw the complete frame
2043 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2044 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2048 // ----------------------------------------------------------------------------
2050 // ----------------------------------------------------------------------------
2052 void wxWin32Renderer
::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2054 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2055 // pixels each while we really need dots here... PS_ALTERNATE might
2056 // work, but it is for NT 5 only
2058 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2060 // draw the pixels manually: note that to behave in the same manner as
2061 // DrawRect(), we must exclude the bottom and right borders from the
2063 wxCoord x1
= rect
.GetLeft(),
2065 x2
= rect
.GetRight(),
2066 y2
= rect
.GetBottom();
2068 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2070 // this seems to be closer than what Windows does than wxINVERT although
2071 // I'm still not sure if it's correct
2072 dc
.SetLogicalFunction(wxAND_REVERSE
);
2075 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2076 dc
.DrawPoint(z
, rect
.GetTop());
2078 wxCoord shift
= z
== x2 ?
0 : 1;
2079 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2080 dc
.DrawPoint(x2
, z
);
2082 shift
= z
== y2 ?
0 : 1;
2083 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2084 dc
.DrawPoint(z
, y2
);
2086 shift
= z
== x1 ?
0 : 1;
2087 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2088 dc
.DrawPoint(x1
, z
);
2090 dc
.SetLogicalFunction(wxCOPY
);
2094 void wxWin32Renderer
::DrawLabelShadow(wxDC
& dc
,
2095 const wxString
& label
,
2100 // draw shadow of the text
2101 dc
.SetTextForeground(m_colHighlight
);
2102 wxRect rectShadow
= rect
;
2105 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2107 // make the text grey
2108 dc
.SetTextForeground(m_colDarkGrey
);
2111 void wxWin32Renderer
::DrawLabel(wxDC
& dc
,
2112 const wxString
& label
,
2119 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2122 void wxWin32Renderer
::DoDrawLabel(wxDC
& dc
,
2123 const wxString
& label
,
2129 const wxPoint
& focusOffset
)
2131 // the underscores are not drawn for focused controls in wxMSW
2132 if ( flags
& wxCONTROL_FOCUSED
)
2137 if ( flags
& wxCONTROL_DISABLED
)
2139 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2140 // currently only can happen for a menu item and it seems that Windows
2141 // doesn't draw the shadow in this case, so we don't do it neither
2142 if ( flags
& wxCONTROL_SELECTED
)
2144 // just make the label text greyed out
2145 dc
.SetTextForeground(m_colDarkGrey
);
2147 else // draw normal disabled label
2149 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2154 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2156 if ( flags
& wxCONTROL_DISABLED
)
2158 // restore the fg colour
2159 dc
.SetTextForeground(*wxBLACK
);
2162 if ( flags
& wxCONTROL_FOCUSED
)
2164 if ( focusOffset
.x
|| focusOffset
.y
)
2166 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2169 DrawFocusRect(dc
, rectLabel
);
2173 *rectBounds
= rectLabel
;
2176 void wxWin32Renderer
::DrawButtonLabel(wxDC
& dc
,
2177 const wxString
& label
,
2178 const wxBitmap
& image
,
2185 // the underscores are not drawn for focused controls in wxMSW
2186 if ( flags
& wxCONTROL_PRESSED
)
2191 wxRect rectLabel
= rect
;
2192 if ( !label
.empty() )
2194 // shift the label if a button is pressed
2195 if ( flags
& wxCONTROL_PRESSED
)
2201 if ( flags
& wxCONTROL_DISABLED
)
2203 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2206 // leave enough space for the focus rectangle
2207 if ( flags
& wxCONTROL_FOCUSED
)
2209 rectLabel
.Inflate(-2);
2213 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2215 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2217 if ( flags
& wxCONTROL_PRESSED
)
2219 // the focus rectangle is never pressed, so undo the shift done
2227 DrawFocusRect(dc
, rectLabel
);
2231 // ----------------------------------------------------------------------------
2232 // (check)listbox items
2233 // ----------------------------------------------------------------------------
2235 void wxWin32Renderer
::DrawItem(wxDC
& dc
,
2236 const wxString
& label
,
2240 wxDCTextColourChanger
colChanger(dc
);
2242 if ( flags
& wxCONTROL_SELECTED
)
2244 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2246 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2247 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2248 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2249 dc
.DrawRectangle(rect
);
2252 wxRect rectText
= rect
;
2254 rectText
.width
-= 2;
2255 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2257 if ( flags
& wxCONTROL_FOCUSED
)
2259 DrawFocusRect(dc
, rect
);
2263 void wxWin32Renderer
::DrawCheckItem(wxDC
& dc
,
2264 const wxString
& label
,
2265 const wxBitmap
& bitmap
,
2274 else // use default bitmap
2276 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2277 ? IndicatorStatus_Checked
2278 : IndicatorStatus_Unchecked
;
2280 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2282 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2285 bmp
= m_bmpCheckBitmaps
[i
];
2288 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2289 true /* use mask */);
2291 wxRect rectLabel
= rect
;
2292 int bmpWidth
= bmp
.GetWidth();
2293 rectLabel
.x
+= bmpWidth
;
2294 rectLabel
.width
-= bmpWidth
;
2296 DrawItem(dc
, label
, rectLabel
, flags
);
2299 // ----------------------------------------------------------------------------
2300 // check/radio buttons
2301 // ----------------------------------------------------------------------------
2303 wxBitmap wxWin32Renderer
::GetIndicator(IndicatorType indType
, int flags
)
2305 IndicatorState indState
;
2306 if ( flags
& wxCONTROL_SELECTED
)
2307 indState
= flags
& wxCONTROL_DISABLED ? IndicatorState_SelectedDisabled
2308 : IndicatorState_Selected
;
2309 else if ( flags
& wxCONTROL_DISABLED
)
2310 indState
= IndicatorState_Disabled
;
2311 else if ( flags
& wxCONTROL_PRESSED
)
2312 indState
= IndicatorState_Pressed
;
2314 indState
= IndicatorState_Normal
;
2316 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2317 ? IndicatorStatus_Checked
2318 : IndicatorStatus_Unchecked
;
2320 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2323 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2326 // create and cache it
2327 bmp
= wxBitmap(xpm
);
2328 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2335 void wxWin32Renderer
::DrawCheckOrRadioButton(wxDC
& dc
,
2336 const wxString
& label
,
2337 const wxBitmap
& bitmap
,
2342 wxCoord focusOffsetY
)
2344 // calculate the position of the bitmap and of the label
2345 wxCoord heightBmp
= bitmap
.GetHeight();
2347 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2350 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2351 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2353 // align label vertically with the bitmap - looks nicer like this
2354 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2356 // calc horz position
2357 if ( align
== wxALIGN_RIGHT
)
2359 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2360 rectLabel
.x
= rect
.x
+ 3;
2361 rectLabel
.SetRight(xBmp
);
2363 else // normal (checkbox to the left of the text) case
2366 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2367 rectLabel
.SetRight(rect
.GetRight());
2370 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2373 dc
, label
, rectLabel
,
2375 wxALIGN_LEFT
| wxALIGN_TOP
,
2377 NULL
, // we don't need bounding rect
2378 // use custom vert focus rect offset
2379 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2383 void wxWin32Renderer
::DrawRadioButton(wxDC
& dc
,
2384 const wxString
& label
,
2385 const wxBitmap
& bitmap
,
2395 bmp
= GetRadioBitmap(flags
);
2397 DrawCheckOrRadioButton(dc
, label
,
2399 rect
, flags
, align
, indexAccel
,
2400 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2403 void wxWin32Renderer
::DrawCheckButton(wxDC
& dc
,
2404 const wxString
& label
,
2405 const wxBitmap
& bitmap
,
2415 bmp
= GetCheckBitmap(flags
);
2417 DrawCheckOrRadioButton(dc
, label
,
2419 rect
, flags
, align
, indexAccel
,
2420 0); // no focus rect offset for checkboxes
2423 void wxWin32Renderer
::DrawToolBarButton(wxDC
& dc
,
2424 const wxString
& label
,
2425 const wxBitmap
& bitmap
,
2426 const wxRect
& rectOrig
,
2430 if (style
== wxTOOL_STYLE_BUTTON
)
2432 wxRect rect
= rectOrig
;
2433 rect
.Deflate(BORDER_THICKNESS
);
2435 if ( flags
& wxCONTROL_PRESSED
)
2437 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2439 else if ( flags
& wxCONTROL_CURRENT
)
2441 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2444 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2446 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2448 // leave a small gap aroudn the line, also account for the toolbar
2450 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2451 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2452 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2454 // don't draw wxTOOL_STYLE_CONTROL
2457 // ----------------------------------------------------------------------------
2459 // ----------------------------------------------------------------------------
2461 void wxWin32Renderer
::DrawTextLine(wxDC
& dc
,
2462 const wxString
& text
,
2468 // nothing special to do here
2469 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2473 wxWin32Renderer
::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2474 const wxRect
& WXUNUSED(rect
))
2476 // we don't draw them
2479 // ----------------------------------------------------------------------------
2481 // ----------------------------------------------------------------------------
2483 void wxWin32Renderer
::DrawTab(wxDC
& dc
,
2484 const wxRect
& rectOrig
,
2486 const wxString
& label
,
2487 const wxBitmap
& bitmap
,
2491 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2492 #define REVERSE_FOR_VERTICAL(X,Y) \
2493 SELECT_FOR_VERTICAL(X,Y) \
2495 SELECT_FOR_VERTICAL(Y,X)
2497 wxRect rect
= rectOrig
;
2499 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2501 // the current tab is drawn indented (to the top for default case) and
2502 // bigger than the other ones
2503 const wxSize indent
= GetTabIndent();
2504 if ( flags
& wxCONTROL_SELECTED
)
2506 rect
.Inflate( isVertical ?
0 : indent
.x
,
2507 isVertical ? indent
.y
: 0
2512 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2519 rect
.height
+= indent
.y
;
2526 rect
.width
+= indent
.x
;
2531 // draw the text, image and the focus around them (if necessary)
2532 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2533 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2535 rectLabel
.Deflate(1, 1);
2538 // draw it horizontally into memory and rotate for screen
2540 wxBitmap bitmapRotated
,
2541 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2542 rectLabel
.y
+ rectLabel
.height
);
2543 dcMem
.SelectObject(bitmapMem
);
2544 dcMem
.SetBackground(dc
.GetBackground());
2545 dcMem
.SetFont(dc
.GetFont());
2546 dcMem
.SetTextForeground(dc
.GetTextForeground());
2548 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
2549 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2550 flags
, wxALIGN_CENTRE
, indexAccel
);
2551 dcMem
.SelectObject(wxNullBitmap
);
2552 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2553 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2554 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2558 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2559 flags
, wxALIGN_CENTRE
, indexAccel
);
2562 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2563 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2564 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2565 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2566 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2567 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2569 // FIXME: all this code will break if the tab indent or the border width,
2570 // it is tied to the fact that both of them are equal to 2
2576 // left orientation looks like top but IsVertical makes x and y reversed
2578 // top is not vertical so use coordinates in written order
2579 dc
.SetPen(m_penHighlight
);
2580 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2581 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2582 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2583 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2584 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2585 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2587 dc
.SetPen(m_penBlack
);
2588 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2589 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2590 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2591 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2593 dc
.SetPen(m_penDarkGrey
);
2594 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2595 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2597 if ( flags
& wxCONTROL_SELECTED
)
2599 dc
.SetPen(m_penLightGrey
);
2601 // overwrite the part of the border below this tab
2602 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2603 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2605 // and the shadow of the tab to the left of us
2606 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2607 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2612 // right orientation looks like bottom but IsVertical makes x and y reversed
2614 // bottom is not vertical so use coordinates in written order
2615 dc
.SetPen(m_penHighlight
);
2616 // we need to continue one pixel further to overwrite the corner of
2617 // the border for the selected tab
2618 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED ?
1 : 0)),
2619 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2620 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2621 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2623 dc
.SetPen(m_penBlack
);
2624 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2625 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2626 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2627 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2628 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2629 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2631 dc
.SetPen(m_penDarkGrey
);
2632 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2633 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2634 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2635 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2637 if ( flags
& wxCONTROL_SELECTED
)
2639 dc
.SetPen(m_penLightGrey
);
2641 // overwrite the part of the (double!) border above this tab
2642 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2643 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2644 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2645 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2647 // and the shadow of the tab to the left of us
2648 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2649 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2654 #undef SELECT_FOR_VERTICAL
2655 #undef REVERSE_FOR_VERTICAL
2658 // ----------------------------------------------------------------------------
2660 // ----------------------------------------------------------------------------
2663 wxWin32Renderer
::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2665 wxOrientation orient
) const
2668 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2669 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2671 if (orient
== wxHORIZONTAL
)
2685 wxRect wxWin32Renderer
::GetSliderShaftRect(const wxRect
& rectOrig
,
2687 wxOrientation orient
,
2690 bool transpose
= (orient
== wxVERTICAL
);
2691 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2692 (((style
& wxSL_TOP
) != 0) & !transpose
|
2693 ((style
& wxSL_LEFT
) != 0) & transpose
|
2694 ((style
& wxSL_BOTH
) != 0));
2695 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2696 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2697 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2698 ((style
& wxSL_BOTH
) != 0));
2700 wxRect rect
= rectOrig
;
2702 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2704 if (orient
== wxHORIZONTAL
) {
2705 rect
.x
+= SLIDER_MARGIN
;
2708 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2712 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2716 rect
.y
+= sizeThumb
.y
/2;
2718 rect
.width
-= 2*SLIDER_MARGIN
;
2719 rect
.height
= 2*BORDER_THICKNESS
;
2723 rect
.y
+= SLIDER_MARGIN
;
2726 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2730 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2734 rect
.x
+= sizeThumb
.x
/2;
2736 rect
.width
= 2*BORDER_THICKNESS
;
2737 rect
.height
-= 2*SLIDER_MARGIN
;
2743 void wxWin32Renderer
::DrawSliderShaft(wxDC
& dc
,
2744 const wxRect
& rectOrig
,
2746 wxOrientation orient
,
2751 /* show shaft geometry
2769 if (flags
& wxCONTROL_FOCUSED
) {
2770 DrawFocusRect(dc
, rectOrig
);
2773 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2775 if (rectShaft
) *rectShaft
= rect
;
2777 DrawSunkenBorder(dc
, &rect
);
2780 void wxWin32Renderer
::DrawSliderThumb(wxDC
& dc
,
2782 wxOrientation orient
,
2786 /* show thumb geometry
2795 H D B where H is hightlight colour
2809 The interior of this shape is filled with the hatched brush if the thumb
2813 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2815 bool transpose
= (orient
== wxVERTICAL
);
2816 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2817 (((style
& wxSL_TOP
) != 0) & !transpose
|
2818 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2819 ((style
& wxSL_BOTH
) == 0);
2820 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2821 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2822 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2823 ((style
& wxSL_BOTH
) == 0);
2825 wxCoord sizeArrow
= (transpose ? rect
.height
: rect
.width
) / 2;
2826 wxCoord c
= ((transpose ? rect
.height
: rect
.width
) - 2*sizeArrow
);
2828 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2829 x1
= (transpose ? rect
.y
: rect
.x
);
2830 x2
= (transpose ? rect
.GetBottom() : rect
.GetRight());
2831 x3
= (x1
-1+c
) + sizeArrow
;
2832 y1
= (transpose ? rect
.x
: rect
.y
);
2833 y2
= (transpose ? rect
.GetRight() : rect
.GetBottom());
2834 y3
= (left ?
(y1
-1+c
) + sizeArrow
: y1
);
2835 y4
= (right ?
(y2
+1-c
) - sizeArrow
: y2
);
2837 dc
.SetPen(m_penBlack
);
2839 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2841 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2844 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2848 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2851 dc
.SetPen(m_penDarkGrey
);
2852 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2854 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2858 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2861 dc
.SetPen(m_penHighlight
);
2864 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2865 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2869 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2871 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2874 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2877 if (flags
& wxCONTROL_PRESSED
) {
2878 // TODO: MSW fills the entire area inside, not just the rect
2879 wxRect rectInt
= rect
;
2882 rectInt
.SetLeft(y3
);
2883 rectInt
.SetRight(y4
);
2888 rectInt
.SetBottom(y4
);
2892 #if !defined(__WXMGL__)
2893 static const char *stipple_xpm
[] = {
2894 /* columns rows colors chars-per-pixel */
2903 // VS: MGL can only do 8x8 stipple brushes
2904 static const char *stipple_xpm
[] = {
2905 /* columns rows colors chars-per-pixel */
2920 dc
.SetBrush(wxBrush(stipple_xpm
));
2922 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2923 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2924 dc
.SetPen(*wxTRANSPARENT_PEN
);
2925 dc
.DrawRectangle(rectInt
);
2929 void wxWin32Renderer
::DrawSliderTicks(wxDC
& dc
,
2932 wxOrientation orient
,
2936 int WXUNUSED(flags
),
2939 /* show ticks geometry
2954 if (end
== start
) return;
2956 bool transpose
= (orient
== wxVERTICAL
);
2957 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2958 (((style
& wxSL_TOP
) != 0) & !transpose
|
2959 ((style
& wxSL_LEFT
) != 0) & transpose
|
2960 ((style
& wxSL_BOTH
) != 0));
2961 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2962 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2963 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2964 ((style
& wxSL_BOTH
) != 0));
2966 // default thumb size
2967 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2968 wxCoord defaultLen
= (transpose ? sizeThumb
.x
: sizeThumb
.y
);
2970 // normal thumb size
2971 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2972 wxCoord widthThumb
= (transpose ? sizeThumb
.y
: sizeThumb
.x
);
2974 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2976 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2977 x1
= (transpose ? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2978 x2
= (transpose ? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2979 y1
= (transpose ? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2980 y2
= (transpose ? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2981 y3
= (transpose ? rect
.x
: rect
.y
);
2982 y4
= (transpose ? rect
.GetRight() : rect
.GetBottom());
2985 dc
.SetPen(m_penBlack
);
2987 int range
= end
- start
;
2988 for ( int n
= 0; n
< range
; n
+= step
) {
2989 wxCoord x
= x1
+ (len
*n
) / range
;
2991 if (left
& (y1
> y3
)) {
2992 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2994 if (right
& (y4
> y2
)) {
2995 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2998 // always draw the line at the end position
2999 if (left
& (y1
> y3
)) {
3000 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3002 if (right
& (y4
> y2
)) {
3003 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3007 // ----------------------------------------------------------------------------
3009 // ----------------------------------------------------------------------------
3011 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3012 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3015 virtual wxSize
GetSize() const { return m_size
; }
3017 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3018 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3020 wxCoord
GetItemHeight() const { return m_heightItem
; }
3023 // the total size of the menu
3026 // the offset of the start of the menu item label
3029 // the offset of the start of the accel label
3032 // the height of a normal (not separator) item
3033 wxCoord m_heightItem
;
3035 friend wxMenuGeometryInfo
*
3036 wxWin32Renderer
::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3039 // FIXME: all constants are hardcoded but shouldn't be
3040 static const wxCoord MENU_LEFT_MARGIN
= 9;
3041 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3042 static const wxCoord MENU_VERT_MARGIN
= 3;
3044 // the margin around bitmap/check marks (on each side)
3045 static const wxCoord MENU_BMP_MARGIN
= 2;
3047 // the margin between the labels and accel strings
3048 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3050 // the separator height in pixels: in fact, strangely enough, the real height
3051 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3053 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3055 // the size of the standard checkmark bitmap
3056 static const wxCoord MENU_CHECK_SIZE
= 9;
3058 void wxWin32Renderer
::DrawMenuBarItem(wxDC
& dc
,
3059 const wxRect
& rectOrig
,
3060 const wxString
& label
,
3064 wxRect rect
= rectOrig
;
3067 wxDCTextColourChanger
colChanger(dc
);
3069 if ( flags
& wxCONTROL_SELECTED
)
3071 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3073 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3074 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3075 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3076 dc
.DrawRectangle(rect
);
3079 // don't draw the focus rect around menu bar items
3080 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3081 wxALIGN_CENTRE
, indexAccel
);
3084 void wxWin32Renderer
::DrawMenuItem(wxDC
& dc
,
3086 const wxMenuGeometryInfo
& gi
,
3087 const wxString
& label
,
3088 const wxString
& accel
,
3089 const wxBitmap
& bitmap
,
3093 const wxWin32MenuGeometryInfo
& geometryInfo
=
3094 (const wxWin32MenuGeometryInfo
&)gi
;
3099 rect
.width
= geometryInfo
.GetSize().x
;
3100 rect
.height
= geometryInfo
.GetItemHeight();
3102 // draw the selected item specially
3103 wxDCTextColourChanger
colChanger(dc
);
3104 if ( flags
& wxCONTROL_SELECTED
)
3106 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3108 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3109 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3110 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3111 dc
.DrawRectangle(rect
);
3114 // draw the bitmap: use the bitmap provided or the standard checkmark for
3115 // the checkable items
3116 wxBitmap bmp
= bitmap
;
3117 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3119 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3124 rect
.SetRight(geometryInfo
.GetLabelOffset());
3125 wxControlRenderer
::DrawBitmap(dc
, bmp
, rect
);
3129 rect
.x
= geometryInfo
.GetLabelOffset();
3130 rect
.SetRight(geometryInfo
.GetAccelOffset());
3132 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3134 // draw the accel string
3135 rect
.x
= geometryInfo
.GetAccelOffset();
3136 rect
.SetRight(geometryInfo
.GetSize().x
);
3138 // NB: no accel index here
3139 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3141 // draw the submenu indicator
3142 if ( flags
& wxCONTROL_ISSUBMENU
)
3144 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3145 rect
.width
= MENU_RIGHT_MARGIN
;
3147 wxArrowStyle arrowStyle
;
3148 if ( flags
& wxCONTROL_DISABLED
)
3149 arrowStyle
= flags
& wxCONTROL_SELECTED ? Arrow_InversedDisabled
3151 else if ( flags
& wxCONTROL_SELECTED
)
3152 arrowStyle
= Arrow_Inversed
;
3154 arrowStyle
= Arrow_Normal
;
3156 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3160 void wxWin32Renderer
::DrawMenuSeparator(wxDC
& dc
,
3162 const wxMenuGeometryInfo
& geomInfo
)
3164 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3167 wxSize wxWin32Renderer
::GetMenuBarItemSize(const wxSize
& sizeText
) const
3169 wxSize size
= sizeText
;
3171 // FIXME: menubar height is configurable under Windows
3178 wxMenuGeometryInfo
*wxWin32Renderer
::GetMenuGeometry(wxWindow
*win
,
3179 const wxMenu
& menu
) const
3181 // prepare the dc: for now we draw all the items with the system font
3183 dc
.SetFont(wxSystemSettings
::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3185 // the height of a normal item
3186 wxCoord heightText
= dc
.GetCharHeight();
3191 // the max length of label and accel strings: the menu width is the sum of
3192 // them, even if they're for different items (as the accels should be
3195 // the max length of the bitmap is never 0 as Windows always leaves enough
3196 // space for a check mark indicator
3197 wxCoord widthLabelMax
= 0,
3199 widthBmpMax
= MENU_LEFT_MARGIN
;
3201 for ( wxMenuItemList
::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3203 node
= node
->GetNext() )
3205 // height of this item
3208 wxMenuItem
*item
= node
->GetData();
3209 if ( item
->IsSeparator() )
3211 h
= MENU_SEPARATOR_HEIGHT
;
3213 else // not separator
3218 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3219 if ( widthLabel
> widthLabelMax
)
3221 widthLabelMax
= widthLabel
;
3225 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3226 if ( widthAccel
> widthAccelMax
)
3228 widthAccelMax
= widthAccel
;
3231 const wxBitmap
& bmp
= item
->GetBitmap();
3234 wxCoord widthBmp
= bmp
.GetWidth();
3235 if ( widthBmp
> widthBmpMax
)
3236 widthBmpMax
= widthBmp
;
3238 //else if ( item->IsCheckable() ): no need to check for this as
3239 // MENU_LEFT_MARGIN is big enough to show the check mark
3242 h
+= 2*MENU_VERT_MARGIN
;
3244 // remember the item position and height
3245 item
->SetGeometry(height
, h
);
3250 // bundle the metrics into a struct and return it
3251 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3253 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3254 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3255 if ( widthAccelMax
> 0 )
3257 // if we actually have any accesl, add a margin
3258 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3261 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3263 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3264 gi
->m_size
.y
= height
;
3269 // ----------------------------------------------------------------------------
3271 // ----------------------------------------------------------------------------
3273 static const wxCoord STATBAR_BORDER_X
= 2;
3274 static const wxCoord STATBAR_BORDER_Y
= 2;
3276 wxSize wxWin32Renderer
::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3278 if ( borderBetweenFields
)
3279 *borderBetweenFields
= 2;
3281 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3284 void wxWin32Renderer
::DrawStatusField(wxDC
& dc
,
3286 const wxString
& label
,
3287 int flags
, int style
/*=0*/)
3291 if ( flags
& wxCONTROL_ISDEFAULT
)
3293 // draw the size grip: it is a normal rect except that in the lower
3294 // right corner we have several bands which may be used for dragging
3295 // the status bar corner
3297 // each band consists of 4 stripes: m_penHighlight, double
3298 // m_penDarkGrey and transparent one
3299 wxCoord x2
= rect
.GetRight(),
3300 y2
= rect
.GetBottom();
3302 // draw the upper left part of the rect normally
3303 if (style
!= wxSB_FLAT
)
3305 if (style
== wxSB_RAISED
)
3306 dc
.SetPen(m_penHighlight
);
3308 dc
.SetPen(m_penDarkGrey
);
3309 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3310 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3313 // draw the grey stripes of the grip
3315 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3316 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3318 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3319 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3322 // draw the white stripes
3323 dc
.SetPen(m_penHighlight
);
3324 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3325 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3327 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3330 // draw the remaining rect boundaries
3331 if (style
!= wxSB_FLAT
)
3333 if (style
== wxSB_RAISED
)
3334 dc
.SetPen(m_penDarkGrey
);
3336 dc
.SetPen(m_penHighlight
);
3337 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3338 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3339 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3345 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3349 if (style
== wxSB_RAISED
)
3350 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3351 else if (style
!= wxSB_FLAT
)
3352 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3355 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3357 wxDCClipper
clipper(dc
, rectIn
);
3358 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3361 // ----------------------------------------------------------------------------
3363 // ----------------------------------------------------------------------------
3365 void wxWin32Renderer
::GetComboBitmaps(wxBitmap
*bmpNormal
,
3366 wxBitmap
* WXUNUSED(bmpFocus
),
3367 wxBitmap
*bmpPressed
,
3368 wxBitmap
*bmpDisabled
)
3370 static const wxCoord widthCombo
= 16;
3371 static const wxCoord heightCombo
= 17;
3377 bmpNormal
->Create(widthCombo
, heightCombo
);
3378 dcMem
.SelectObject(*bmpNormal
);
3379 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3380 Arrow_Down
, Arrow_Normal
);
3385 bmpPressed
->Create(widthCombo
, heightCombo
);
3386 dcMem
.SelectObject(*bmpPressed
);
3387 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3388 Arrow_Down
, Arrow_Pressed
);
3393 bmpDisabled
->Create(widthCombo
, heightCombo
);
3394 dcMem
.SelectObject(*bmpDisabled
);
3395 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3396 Arrow_Down
, Arrow_Disabled
);
3400 // ----------------------------------------------------------------------------
3402 // ----------------------------------------------------------------------------
3404 void wxWin32Renderer
::DoDrawBackground(wxDC
& dc
,
3405 const wxColour
& col
,
3407 wxWindow
* WXUNUSED(window
))
3409 wxBrush
brush(col
, wxSOLID
);
3411 dc
.SetPen(*wxTRANSPARENT_PEN
);
3412 dc
.DrawRectangle(rect
);
3415 void wxWin32Renderer
::DrawBackground(wxDC
& dc
,
3416 const wxColour
& col
,
3418 int WXUNUSED(flags
),
3421 // just fill it with the given or default bg colour
3422 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3423 DoDrawBackground(dc
, colBg
, rect
, window
);
3426 // ----------------------------------------------------------------------------
3428 // ----------------------------------------------------------------------------
3430 void wxWin32Renderer
::DrawArrow(wxDC
& dc
,
3435 // get the bitmap for this arrow
3436 wxArrowDirection arrowDir
;
3439 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3440 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3441 case wxUP
: arrowDir
= Arrow_Up
; break;
3442 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3445 wxFAIL_MSG(_T("unknown arrow direction"));
3449 wxArrowStyle arrowStyle
;
3450 if ( flags
& wxCONTROL_PRESSED
)
3452 // can't be pressed and disabled
3453 arrowStyle
= Arrow_Pressed
;
3457 arrowStyle
= flags
& wxCONTROL_DISABLED ? Arrow_Disabled
: Arrow_Normal
;
3460 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3463 void wxWin32Renderer
::DrawArrow(wxDC
& dc
,
3465 wxArrowDirection arrowDir
,
3466 wxArrowStyle arrowStyle
)
3468 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3470 // under Windows the arrows always have the same size so just centre it in
3471 // the provided rectangle
3472 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3473 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3475 // Windows does it like this...
3476 if ( arrowDir
== Arrow_Left
)
3480 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3483 void wxWin32Renderer
::DrawArrowButton(wxDC
& dc
,
3484 const wxRect
& rectAll
,
3485 wxArrowDirection arrowDir
,
3486 wxArrowStyle arrowStyle
)
3488 wxRect rect
= rectAll
;
3489 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3490 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3491 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3494 void wxWin32Renderer
::DrawScrollbarThumb(wxDC
& dc
,
3495 wxOrientation
WXUNUSED(orient
),
3497 int WXUNUSED(flags
))
3499 // we don't use the flags, the thumb never changes appearance
3500 wxRect rectThumb
= rect
;
3501 DrawArrowBorder(dc
, &rectThumb
);
3502 DrawBackground(dc
, wxNullColour
, rectThumb
);
3505 void wxWin32Renderer
::DrawScrollbarShaft(wxDC
& dc
,
3506 wxOrientation
WXUNUSED(orient
),
3507 const wxRect
& rectBar
,
3510 wxColourScheme
::StdColour col
= flags
& wxCONTROL_PRESSED
3511 ? wxColourScheme
::SCROLLBAR_PRESSED
3512 : wxColourScheme
::SCROLLBAR
;
3513 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3516 void wxWin32Renderer
::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3518 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3521 wxRect wxWin32Renderer
::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3522 wxScrollBar
::Element elem
,
3525 return StandardGetScrollbarRect(scrollbar
, elem
,
3526 thumbPos
, m_sizeScrollbarArrow
);
3529 wxCoord wxWin32Renderer
::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3531 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3534 wxHitTest wxWin32Renderer
::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3535 const wxPoint
& pt
) const
3537 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3540 wxCoord wxWin32Renderer
::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3543 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3546 int wxWin32Renderer
::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3549 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3552 // ----------------------------------------------------------------------------
3553 // top level windows
3554 // ----------------------------------------------------------------------------
3556 int wxWin32Renderer
::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3558 wxRect client
= GetFrameClientArea(rect
, flags
);
3560 if ( client
.Inside(pt
) )
3561 return wxHT_TOPLEVEL_CLIENT_AREA
;
3563 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3565 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3567 if ( flags
& wxTOPLEVEL_ICON
)
3569 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3570 return wxHT_TOPLEVEL_ICON
;
3573 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3574 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3575 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3577 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3579 if ( btnRect
.Inside(pt
) )
3580 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3581 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3583 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3585 if ( btnRect
.Inside(pt
) )
3586 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3587 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3589 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3591 if ( btnRect
.Inside(pt
) )
3592 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3593 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3595 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3597 if ( btnRect
.Inside(pt
) )
3598 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3599 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3601 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3603 if ( btnRect
.Inside(pt
) )
3604 return wxHT_TOPLEVEL_BUTTON_HELP
;
3605 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3608 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3609 return wxHT_TOPLEVEL_TITLEBAR
;
3612 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3614 // we are certainly at one of borders, lets decide which one:
3617 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3618 if ( pt
.x
< client
.x
)
3619 border
|= wxHT_TOPLEVEL_BORDER_W
;
3620 else if ( pt
.x
>= client
.width
+ client
.x
)
3621 border
|= wxHT_TOPLEVEL_BORDER_E
;
3622 if ( pt
.y
< client
.y
)
3623 border
|= wxHT_TOPLEVEL_BORDER_N
;
3624 else if ( pt
.y
>= client
.height
+ client
.y
)
3625 border
|= wxHT_TOPLEVEL_BORDER_S
;
3629 return wxHT_NOWHERE
;
3632 void wxWin32Renderer
::DrawFrameTitleBar(wxDC
& dc
,
3634 const wxString
& title
,
3638 int specialButtonFlags
)
3640 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3642 DrawFrameBorder(dc
, rect
, flags
);
3644 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3646 DrawFrameBackground(dc
, rect
, flags
);
3647 if ( flags
& wxTOPLEVEL_ICON
)
3648 DrawFrameIcon(dc
, rect
, icon
, flags
);
3649 DrawFrameTitle(dc
, rect
, title
, flags
);
3651 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3653 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3654 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3656 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3658 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3659 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3660 specialButtonFlags
: 0);
3661 x
-= FRAME_BUTTON_WIDTH
+ 2;
3663 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3665 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3666 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3667 specialButtonFlags
: 0);
3668 x
-= FRAME_BUTTON_WIDTH
;
3670 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3672 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3673 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3674 specialButtonFlags
: 0);
3675 x
-= FRAME_BUTTON_WIDTH
;
3677 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3679 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3680 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3681 specialButtonFlags
: 0);
3682 x
-= FRAME_BUTTON_WIDTH
;
3684 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3686 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3687 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3688 specialButtonFlags
: 0);
3693 void wxWin32Renderer
::DrawFrameBorder(wxDC
& dc
,
3697 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3701 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3702 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3703 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3704 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3705 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3708 void wxWin32Renderer
::DrawFrameBackground(wxDC
& dc
,
3712 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3714 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3715 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3716 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3718 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3719 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3721 DrawBackground(dc
, col
, r
);
3724 void wxWin32Renderer
::DrawFrameTitle(wxDC
& dc
,
3726 const wxString
& title
,
3729 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3730 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3731 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3733 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3734 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3735 if ( flags
& wxTOPLEVEL_ICON
)
3737 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3738 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3746 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3747 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3748 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3749 r
.width
-= FRAME_BUTTON_WIDTH
;
3750 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3751 r
.width
-= FRAME_BUTTON_WIDTH
;
3752 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3753 r
.width
-= FRAME_BUTTON_WIDTH
;
3754 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3755 r
.width
-= FRAME_BUTTON_WIDTH
;
3757 dc
.SetFont(m_titlebarFont
);
3758 dc
.SetTextForeground(col
);
3761 dc
.GetTextExtent(title
, &textW
, NULL
);
3762 if ( textW
> r
.width
)
3764 // text is too big, let's shorten it and add "..." after it:
3765 size_t len
= title
.length();
3766 wxCoord WSoFar
, letterW
;
3768 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3769 if ( WSoFar
> r
.width
)
3771 // not enough space to draw anything
3777 for (size_t i
= 0; i
< len
; i
++)
3779 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3780 if ( letterW
+ WSoFar
> r
.width
)
3786 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3787 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3790 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3791 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3794 void wxWin32Renderer
::DrawFrameIcon(wxDC
& dc
,
3801 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3802 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3806 void wxWin32Renderer
::DrawFrameButton(wxDC
& dc
,
3807 wxCoord x
, wxCoord y
,
3811 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3816 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3817 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3818 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3819 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3820 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3822 wxFAIL_MSG(wxT("incorrect button specification"));
3825 if ( flags
& wxCONTROL_PRESSED
)
3827 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3828 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3829 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3830 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3834 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3835 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3836 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3837 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3842 wxRect wxWin32Renderer
::GetFrameClientArea(const wxRect
& rect
,
3847 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3849 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3850 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3851 FRAME_BORDER_THICKNESS
;
3854 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3856 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3857 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3863 wxSize wxWin32Renderer
::GetFrameTotalSize(const wxSize
& clientSize
,
3866 wxSize
s(clientSize
);
3868 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3870 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3871 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3872 FRAME_BORDER_THICKNESS
;
3876 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3877 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3882 wxSize wxWin32Renderer
::GetFrameMinSize(int flags
) const
3886 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3888 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3889 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3890 FRAME_BORDER_THICKNESS
;
3895 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3897 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3899 if ( flags
& wxTOPLEVEL_ICON
)
3900 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3901 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3902 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3903 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3904 s
.x
+= FRAME_BUTTON_WIDTH
;
3905 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3906 s
.x
+= FRAME_BUTTON_WIDTH
;
3907 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3908 s
.x
+= FRAME_BUTTON_WIDTH
;
3909 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3910 s
.x
+= FRAME_BUTTON_WIDTH
;
3916 wxSize wxWin32Renderer
::GetFrameIconSize() const
3918 return wxSize(16, 16);
3922 // ----------------------------------------------------------------------------
3924 // ----------------------------------------------------------------------------
3926 static char *error_xpm
[]={
3933 "...........########.............",
3934 "........###aaaaaaaa###..........",
3935 ".......#aaaaaaaaaaaaaa#.........",
3936 ".....##aaaaaaaaaaaaaaaa##.......",
3937 "....#aaaaaaaaaaaaaaaaaaaa#......",
3938 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3939 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3940 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3941 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3942 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3943 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3944 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3945 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3946 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3947 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3948 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3949 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3950 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3951 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3952 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3953 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3954 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3955 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3956 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3957 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3958 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3959 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3960 "......b#aaaaaaaaaaaaaa#bbbbb....",
3961 ".......b###aaaaaaaa###bbbbb.....",
3962 ".........bb########bbbbbb.......",
3963 "..........bbbbbbbbbbbbbb........",
3964 ".............bbbbbbbb..........."};
3966 static char *info_xpm
[]={
3974 "...........########.............",
3975 "........###abbbbbba###..........",
3976 "......##abbbbbbbbbbbba##........",
3977 ".....#abbbbbbbbbbbbbbbba#.......",
3978 "....#bbbbbbbaccccabbbbbbbd......",
3979 "...#bbbbbbbbccccccbbbbbbbbd.....",
3980 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3981 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3982 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3983 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3984 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3985 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3986 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3987 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3988 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3989 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3990 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3991 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3992 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3993 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3994 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3995 ".....dabbbbbbbbbbbbbbbbad####...",
3996 "......ddabbbbbbbbbbbbadd####....",
3997 ".......#dddabbbbbbaddd#####.....",
3998 "........###dddabbbd#######......",
3999 "..........####dbbbd#####........",
4000 ".............#dbbbd##...........",
4001 "...............dbbd##...........",
4002 "................dbd##...........",
4003 ".................dd##...........",
4004 "..................###...........",
4005 "...................##..........."};
4007 static char *question_xpm
[]={
4015 "...........########.............",
4016 "........###abbbbbba###..........",
4017 "......##abbbbbbbbbbbba##........",
4018 ".....#abbbbbbbbbbbbbbbba#.......",
4019 "....#bbbbbbbbbbbbbbbbbbbbc......",
4020 "...#bbbbbbbaddddddabbbbbbbc.....",
4021 "..#bbbbbbbadabbddddabbbbbbbc....",
4022 ".#abbbbbbbddbbbbddddbbbbbbbac...",
4023 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
4024 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
4025 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
4026 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
4027 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
4028 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
4029 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
4030 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
4031 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
4032 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
4033 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
4034 "...cbbbbbbbbbaddabbbbbbbbbc####.",
4035 "....cbbbbbbbbbbbbbbbbbbbbc####..",
4036 ".....cabbbbbbbbbbbbbbbbac####...",
4037 "......ccabbbbbbbbbbbbacc####....",
4038 ".......#cccabbbbbbaccc#####.....",
4039 "........###cccabbbc#######......",
4040 "..........####cbbbc#####........",
4041 ".............#cbbbc##...........",
4042 "...............cbbc##...........",
4043 "................cbc##...........",
4044 ".................cc##...........",
4045 "..................###...........",
4046 "...................##..........."};
4048 static char *warning_xpm
[]={
4056 ".............###................",
4057 "............#aabc...............",
4058 "...........#aaaabcd.............",
4059 "...........#aaaaacdd............",
4060 "..........#aaaaaabcdd...........",
4061 "..........#aaaaaaacdd...........",
4062 ".........#aaaaaaaabcdd..........",
4063 ".........#aaaaaaaaacdd..........",
4064 "........#aaaaaaaaaabcdd.........",
4065 "........#aaabcccbaaacdd.........",
4066 ".......#aaaacccccaaabcdd........",
4067 ".......#aaaacccccaaaacdd........",
4068 "......#aaaaacccccaaaabcdd.......",
4069 "......#aaaaacccccaaaaacdd.......",
4070 ".....#aaaaaacccccaaaaabcdd......",
4071 ".....#aaaaaa#ccc#aaaaaacdd......",
4072 "....#aaaaaaabcccbaaaaaabcdd.....",
4073 "....#aaaaaaaacccaaaaaaaacdd.....",
4074 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
4075 "...#aaaaaaaaabcbaaaaaaaaacdd....",
4076 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
4077 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
4078 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
4079 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
4080 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
4081 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
4082 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
4083 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
4084 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
4085 "..#ccccccccccccccccccccccccddddd",
4086 "....ddddddddddddddddddddddddddd.",
4087 ".....ddddddddddddddddddddddddd.."};
4089 wxBitmap wxWin32ArtProvider
::CreateBitmap(const wxArtID
& id
,
4090 const wxArtClient
& WXUNUSED(client
),
4091 const wxSize
& WXUNUSED(size
))
4093 if ( id
== wxART_INFORMATION
)
4094 return wxBitmap(info_xpm
);
4095 if ( id
== wxART_ERROR
)
4096 return wxBitmap(error_xpm
);
4097 if ( id
== wxART_WARNING
)
4098 return wxBitmap(warning_xpm
);
4099 if ( id
== wxART_QUESTION
)
4100 return wxBitmap(question_xpm
);
4101 return wxNullBitmap
;
4105 // ----------------------------------------------------------------------------
4106 // text control geometry
4107 // ----------------------------------------------------------------------------
4109 static inline int GetTextBorderWidth()
4115 wxWin32Renderer
::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4116 const wxRect
& rect
) const
4118 wxRect rectTotal
= rect
;
4120 wxCoord widthBorder
= GetTextBorderWidth();
4121 rectTotal
.Inflate(widthBorder
);
4123 // this is what Windows does
4130 wxWin32Renderer
::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4132 wxCoord
*extraSpaceBeyond
) const
4134 wxRect rectText
= rect
;
4136 // undo GetTextTotalArea()
4137 if ( rectText
.height
> 0 )
4140 wxCoord widthBorder
= GetTextBorderWidth();
4141 rectText
.Inflate(-widthBorder
);
4143 if ( extraSpaceBeyond
)
4144 *extraSpaceBeyond
= 0;
4149 // ----------------------------------------------------------------------------
4151 // ----------------------------------------------------------------------------
4153 void wxWin32Renderer
::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4156 if ( wxDynamicCast(window
, wxScrollBar
) )
4158 // we only set the width of vert scrollbars and height of the
4160 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4161 size
->y
= m_sizeScrollbarArrow
.y
;
4163 size
->x
= m_sizeScrollbarArrow
.x
;
4165 // skip border width adjustments, they don't make sense for us
4168 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4171 if ( wxDynamicCast(window
, wxButton
) )
4173 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4175 // TODO: don't harcode all this
4176 size
->x
+= 3*window
->GetCharWidth();
4178 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4179 if ( size
->y
< heightBtn
- 8 )
4180 size
->y
= heightBtn
;
4185 // for compatibility with other ports, the buttons default size is never
4186 // less than the standard one, but not when display not PDAs.
4187 if (wxSystemSettings
::GetScreenType() > wxSYS_SCREEN_PDA
)
4189 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4191 wxSize szDef
= wxButton
::GetDefaultSize();
4192 if ( size
->x
< szDef
.x
)
4197 // no border width adjustments for buttons
4200 #endif // wxUSE_BUTTON
4202 // take into account the border width
4203 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4204 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4205 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4208 // ============================================================================
4210 // ============================================================================
4212 // ----------------------------------------------------------------------------
4213 // wxWin32InputHandler
4214 // ----------------------------------------------------------------------------
4216 wxWin32InputHandler
::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4218 m_renderer
= renderer
;
4221 bool wxWin32InputHandler
::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4222 const wxKeyEvent
& WXUNUSED(event
),
4223 bool WXUNUSED(pressed
))
4228 bool wxWin32InputHandler
::HandleMouse(wxInputConsumer
*control
,
4229 const wxMouseEvent
& event
)
4231 // clicking on the control gives it focus
4232 if ( event
.ButtonDown() )
4234 wxWindow
*win
= control
->GetInputWindow();
4236 if (( wxWindow
::FindFocus() != control
->GetInputWindow() ) &&
4237 ( win
->AcceptsFocus() ) )
4248 // ----------------------------------------------------------------------------
4249 // wxWin32ScrollBarInputHandler
4250 // ----------------------------------------------------------------------------
4252 wxWin32ScrollBarInputHandler
::
4253 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4254 wxInputHandler
*handler
)
4255 : wxStdScrollBarInputHandler(renderer
, handler
)
4257 m_scrollPaused
= false;
4261 bool wxWin32ScrollBarInputHandler
::OnScrollTimer(wxScrollBar
*scrollbar
,
4262 const wxControlAction
& action
)
4264 // stop if went beyond the position of the original click (this can only
4265 // happen when we scroll by pages)
4267 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4269 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4270 != wxHT_SCROLLBAR_BAR_2
;
4272 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4274 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4275 != wxHT_SCROLLBAR_BAR_1
;
4280 StopScrolling(scrollbar
);
4282 scrollbar
->Refresh();
4287 return wxStdScrollBarInputHandler
::OnScrollTimer(scrollbar
, action
);
4290 bool wxWin32ScrollBarInputHandler
::HandleMouse(wxInputConsumer
*control
,
4291 const wxMouseEvent
& event
)
4293 // remember the current state
4294 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4296 // do process the message
4297 bool rc
= wxStdScrollBarInputHandler
::HandleMouse(control
, event
);
4299 // analyse the changes
4300 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4302 // we just started dragging the thumb, remember its initial position to
4303 // be able to restore it if the drag is cancelled later
4304 m_eventStartDrag
= event
;
4310 bool wxWin32ScrollBarInputHandler
::HandleMouseMove(wxInputConsumer
*control
,
4311 const wxMouseEvent
& event
)
4313 // we don't highlight scrollbar elements, so there is no need to process
4314 // mouse move events normally - only do it while mouse is captured (i.e.
4315 // when we're dragging the thumb or pressing on something)
4316 if ( !m_winCapture
)
4319 if ( event
.Entering() )
4321 // we're not interested in this at all
4325 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4327 if ( m_scrollPaused
)
4329 // check if the mouse returned to its original location
4331 if ( event
.Leaving() )
4337 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4338 if ( ht
== m_htLast
)
4340 // yes it did, resume scrolling
4341 m_scrollPaused
= false;
4342 if ( m_timerScroll
)
4344 // we were scrolling by line/page, restart timer
4345 m_timerScroll
->Start(m_interval
);
4347 Press(scrollbar
, true);
4349 else // we were dragging the thumb
4351 // restore its last location
4352 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4358 else // normal case, scrolling hasn't been paused
4360 // if we're scrolling the scrollbar because the arrow or the shaft was
4361 // pressed, check that the mouse stays on the same scrollbar element
4364 // Always let thumb jump back if we leave the scrollbar
4365 if ( event
.Moving() )
4367 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4369 else // event.Leaving()
4374 // Jump back only if we get far away from it
4375 wxPoint pos
= event
.GetPosition();
4376 if (scrollbar
->HasFlag( wxVERTICAL
))
4378 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4383 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4386 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4389 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4390 // is still ok - we only want to catch the case when the mouse leaves
4391 // the scrollbar here
4392 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4394 ht
= wxHT_SCROLLBAR_THUMB
;
4397 if ( ht
!= m_htLast
)
4399 // what were we doing? 2 possibilities: either an arrow/shaft was
4400 // pressed in which case we have a timer and so we just stop it or
4401 // we were dragging the thumb
4402 if ( m_timerScroll
)
4405 m_interval
= m_timerScroll
->GetInterval();
4406 m_timerScroll
->Stop();
4407 m_scrollPaused
= true;
4409 // unpress the arrow
4410 Press(scrollbar
, false);
4412 else // we were dragging the thumb
4414 // remember the current thumb position to be able to restore it
4415 // if the mouse returns to it later
4416 m_eventLastDrag
= event
;
4418 // and restore the original position (before dragging) of the
4420 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4427 return wxStdScrollBarInputHandler
::HandleMouseMove(control
, event
);
4430 // ----------------------------------------------------------------------------
4431 // wxWin32CheckboxInputHandler
4432 // ----------------------------------------------------------------------------
4434 bool wxWin32CheckboxInputHandler
::HandleKey(wxInputConsumer
*control
,
4435 const wxKeyEvent
& event
,
4440 wxControlAction action
;
4441 int keycode
= event
.GetKeyCode();
4445 action
= wxACTION_CHECKBOX_TOGGLE
;
4449 case WXK_NUMPAD_SUBTRACT
:
4450 action
= wxACTION_CHECKBOX_CHECK
;
4454 case WXK_NUMPAD_ADD
:
4455 case WXK_NUMPAD_EQUAL
:
4456 action
= wxACTION_CHECKBOX_CLEAR
;
4460 if ( !action
.IsEmpty() )
4462 control
->PerformAction(action
);
4471 // ----------------------------------------------------------------------------
4472 // wxWin32TextCtrlInputHandler
4473 // ----------------------------------------------------------------------------
4475 bool wxWin32TextCtrlInputHandler
::HandleKey(wxInputConsumer
*control
,
4476 const wxKeyEvent
& event
,
4479 // handle only MSW-specific text bindings here, the others are handled in
4483 int keycode
= event
.GetKeyCode();
4485 wxControlAction action
;
4486 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4488 action
= wxACTION_TEXT_CUT
;
4490 else if ( keycode
== WXK_INSERT
)
4492 if ( event
.ControlDown() )
4493 action
= wxACTION_TEXT_COPY
;
4494 else if ( event
.ShiftDown() )
4495 action
= wxACTION_TEXT_PASTE
;
4498 if ( action
!= wxACTION_NONE
)
4500 control
->PerformAction(action
);
4506 return wxStdTextCtrlInputHandler
::HandleKey(control
, event
, pressed
);
4509 // ----------------------------------------------------------------------------
4510 // wxWin32StatusBarInputHandler
4511 // ----------------------------------------------------------------------------
4513 wxWin32StatusBarInputHandler
::
4514 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4515 : wxStdInputHandler(handler
)
4520 bool wxWin32StatusBarInputHandler
::IsOnGrip(wxWindow
*statbar
,
4521 const wxPoint
& pt
) const
4523 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4524 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4527 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4529 wxCHECK_MSG( parentTLW
, false,
4530 _T("the status bar should be a child of a TLW") );
4532 // a maximized window can't be resized anyhow
4533 if ( !parentTLW
->IsMaximized() )
4535 // VZ: I think that the standard Windows behaviour is to only
4536 // show the resizing cursor when the mouse is on top of the
4537 // grip itself but apparently different Windows versions behave
4538 // differently (?) and it seems a better UI to allow resizing
4539 // the status bar even when the mouse is above the grip
4540 wxSize sizeSbar
= statbar
->GetSize();
4542 int diff
= sizeSbar
.x
- pt
.x
;
4543 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4550 bool wxWin32StatusBarInputHandler
::HandleMouse(wxInputConsumer
*consumer
,
4551 const wxMouseEvent
& event
)
4553 if ( event
.Button(1) )
4555 if ( event
.ButtonDown(1) )
4557 wxWindow
*statbar
= consumer
->GetInputWindow();
4559 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4561 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4565 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4566 wxHT_TOPLEVEL_BORDER_SE
);
4568 statbar
->SetCursor(m_cursorOld
);
4576 return wxStdInputHandler
::HandleMouse(consumer
, event
);
4579 bool wxWin32StatusBarInputHandler
::HandleMouseMove(wxInputConsumer
*consumer
,
4580 const wxMouseEvent
& event
)
4582 wxWindow
*statbar
= consumer
->GetInputWindow();
4584 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4585 if ( isOnGrip
!= m_isOnGrip
)
4587 m_isOnGrip
= isOnGrip
;
4590 m_cursorOld
= statbar
->GetCursor();
4591 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4595 statbar
->SetCursor(m_cursorOld
);
4599 return wxStdInputHandler
::HandleMouseMove(consumer
, event
);
4602 // ----------------------------------------------------------------------------
4603 // wxWin32FrameInputHandler
4604 // ----------------------------------------------------------------------------
4606 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4609 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4611 void Attach(wxInputConsumer
*consumer
);
4615 DECLARE_EVENT_TABLE()
4616 void OnSystemMenu(wxCommandEvent
&event
);
4617 void OnCloseFrame(wxCommandEvent
&event
);
4618 void OnClose(wxCloseEvent
&event
);
4620 wxWin32FrameInputHandler
*m_inputHnd
;
4621 wxTopLevelWindow
*m_wnd
;
4623 wxAcceleratorTable m_oldAccelTable
;
4627 wxWin32SystemMenuEvtHandler
::wxWin32SystemMenuEvtHandler(
4628 wxWin32FrameInputHandler
*handler
)
4630 m_inputHnd
= handler
;
4634 void wxWin32SystemMenuEvtHandler
::Attach(wxInputConsumer
*consumer
)
4636 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4638 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4639 m_wnd
->PushEventHandler(this);
4642 // VS: This code relies on using generic implementation of
4643 // wxAcceleratorTable in wxUniv!
4644 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4645 m_oldAccelTable
= table
;
4646 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4647 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4648 m_wnd
->SetAcceleratorTable(table
);
4652 void wxWin32SystemMenuEvtHandler
::Detach()
4657 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4659 m_wnd
->RemoveEventHandler(this);
4664 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4665 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler
::OnSystemMenu
)
4666 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler
::OnCloseFrame
)
4667 EVT_CLOSE(wxWin32SystemMenuEvtHandler
::OnClose
)
4670 void wxWin32SystemMenuEvtHandler
::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4672 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4673 !m_wnd
->IsMaximized()) ?
4674 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4675 FRAME_BORDER_THICKNESS
;
4676 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4677 pt
.x
= -pt
.x
+ border
;
4678 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4681 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4682 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4685 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4688 m_wnd
->SetAcceleratorTable(table
);
4692 void wxWin32SystemMenuEvtHandler
::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4694 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4695 wxTOPLEVEL_BUTTON_CLOSE
);
4698 void wxWin32SystemMenuEvtHandler
::OnClose(wxCloseEvent
&event
)
4705 wxWin32FrameInputHandler
::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4706 : wxStdFrameInputHandler(handler
)
4708 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4711 wxWin32FrameInputHandler
::~wxWin32FrameInputHandler()
4713 if ( m_menuHandler
)
4715 m_menuHandler
->Detach();
4716 delete m_menuHandler
;
4720 bool wxWin32FrameInputHandler
::HandleMouse(wxInputConsumer
*consumer
,
4721 const wxMouseEvent
& event
)
4723 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4725 wxTopLevelWindow
*tlw
=
4726 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4728 long hit
= tlw
->HitTest(event
.GetPosition());
4730 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4732 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4733 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4734 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4737 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4739 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4740 (event
.RightDown() &&
4741 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4742 hit
== wxHT_TOPLEVEL_ICON
)) )
4744 PopupSystemMenu(tlw
, event
.GetPosition());
4750 return wxStdFrameInputHandler
::HandleMouse(consumer
, event
);
4753 void wxWin32FrameInputHandler
::PopupSystemMenu(wxTopLevelWindow
*window
,
4754 const wxPoint
& pos
) const
4756 wxMenu
*menu
= new wxMenu
;
4758 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4759 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4760 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4761 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4762 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4763 if ( wxSystemSettings
::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4764 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4765 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4766 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4767 menu
->AppendSeparator();
4768 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4770 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4772 if ( window
->IsMaximized() )
4774 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4775 menu
->Enable(wxID_MOVE_FRAME
, false);
4776 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4777 menu
->Enable(wxID_RESIZE_FRAME
, false);
4780 menu
->Enable(wxID_RESTORE_FRAME
, false);
4783 window
->PopupMenu(menu
, pos
);
4787 bool wxWin32FrameInputHandler
::HandleActivation(wxInputConsumer
*consumer
,
4790 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4792 // always detach if active frame changed:
4793 m_menuHandler
->Detach();
4797 m_menuHandler
->Attach(consumer
);
4801 return wxStdFrameInputHandler
::HandleActivation(consumer
, activated
);