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
,
113 IndicatorStatus_Undeterminated
,
117 // wxWin32Renderer: draw the GUI elements in Win32 style
118 // ----------------------------------------------------------------------------
120 class wxWin32Renderer
: public wxRenderer
124 enum wxArrowDirection
139 Arrow_InversedDisabled
,
143 enum wxFrameButtonType
146 FrameButton_Minimize
,
147 FrameButton_Maximize
,
154 wxWin32Renderer(const wxColourScheme
*scheme
);
156 // implement the base class pure virtuals
157 virtual void DrawBackground(wxDC
& dc
,
161 wxWindow
*window
= NULL
);
162 virtual void DrawLabel(wxDC
& dc
,
163 const wxString
& label
,
166 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
168 wxRect
*rectBounds
= NULL
);
169 virtual void DrawButtonLabel(wxDC
& dc
,
170 const wxString
& label
,
171 const wxBitmap
& image
,
174 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
176 wxRect
*rectBounds
= NULL
);
177 virtual void DrawBorder(wxDC
& dc
,
181 wxRect
*rectIn
= (wxRect
*)NULL
);
182 virtual void DrawHorizontalLine(wxDC
& dc
,
183 wxCoord y
, wxCoord x1
, wxCoord x2
);
184 virtual void DrawVerticalLine(wxDC
& dc
,
185 wxCoord x
, wxCoord y1
, wxCoord y2
);
186 virtual void DrawFrame(wxDC
& dc
,
187 const wxString
& label
,
190 int alignment
= wxALIGN_LEFT
,
191 int indexAccel
= -1);
192 virtual void DrawTextBorder(wxDC
& dc
,
196 wxRect
*rectIn
= (wxRect
*)NULL
);
197 virtual void DrawButtonBorder(wxDC
& dc
,
200 wxRect
*rectIn
= (wxRect
*)NULL
);
201 virtual void DrawArrow(wxDC
& dc
,
205 virtual void DrawScrollbarArrow(wxDC
& dc
,
209 { DrawArrow(dc
, dir
, rect
, flags
); }
210 virtual void DrawScrollbarThumb(wxDC
& dc
,
211 wxOrientation orient
,
214 virtual void DrawScrollbarShaft(wxDC
& dc
,
215 wxOrientation orient
,
218 virtual void DrawScrollCorner(wxDC
& dc
,
220 virtual void DrawItem(wxDC
& dc
,
221 const wxString
& label
,
224 virtual void DrawCheckItem(wxDC
& dc
,
225 const wxString
& label
,
226 const wxBitmap
& bitmap
,
229 virtual void DrawCheckButton(wxDC
& dc
,
230 const wxString
& label
,
231 const wxBitmap
& bitmap
,
234 wxAlignment align
= wxALIGN_LEFT
,
235 int indexAccel
= -1);
236 virtual void DrawRadioButton(wxDC
& dc
,
237 const wxString
& label
,
238 const wxBitmap
& bitmap
,
241 wxAlignment align
= wxALIGN_LEFT
,
242 int indexAccel
= -1);
243 virtual void DrawToolBarButton(wxDC
& dc
,
244 const wxString
& label
,
245 const wxBitmap
& bitmap
,
249 virtual void DrawTextLine(wxDC
& dc
,
250 const wxString
& text
,
255 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
256 virtual void DrawTab(wxDC
& dc
,
259 const wxString
& label
,
260 const wxBitmap
& bitmap
= wxNullBitmap
,
262 int indexAccel
= -1);
264 virtual void DrawSliderShaft(wxDC
& dc
,
267 wxOrientation orient
,
270 wxRect
*rectShaft
= NULL
);
271 virtual void DrawSliderThumb(wxDC
& dc
,
273 wxOrientation orient
,
276 virtual void DrawSliderTicks(wxDC
& dc
,
279 wxOrientation orient
,
286 virtual void DrawMenuBarItem(wxDC
& dc
,
288 const wxString
& label
,
290 int indexAccel
= -1);
291 virtual void DrawMenuItem(wxDC
& dc
,
293 const wxMenuGeometryInfo
& geometryInfo
,
294 const wxString
& label
,
295 const wxString
& accel
,
296 const wxBitmap
& bitmap
= wxNullBitmap
,
298 int indexAccel
= -1);
299 virtual void DrawMenuSeparator(wxDC
& dc
,
301 const wxMenuGeometryInfo
& geomInfo
);
303 virtual void DrawStatusField(wxDC
& dc
,
305 const wxString
& label
,
306 int flags
= 0, int style
= 0);
309 virtual void DrawFrameTitleBar(wxDC
& dc
,
311 const wxString
& title
,
314 int specialButton
= 0,
315 int specialButtonFlags
= 0);
316 virtual void DrawFrameBorder(wxDC
& dc
,
319 virtual void DrawFrameBackground(wxDC
& dc
,
322 virtual void DrawFrameTitle(wxDC
& dc
,
324 const wxString
& title
,
326 virtual void DrawFrameIcon(wxDC
& dc
,
330 virtual void DrawFrameButton(wxDC
& dc
,
331 wxCoord x
, wxCoord y
,
334 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
335 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
336 virtual wxSize
GetFrameMinSize(int flags
) const;
337 virtual wxSize
GetFrameIconSize() const;
338 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
340 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
342 wxBitmap
*bmpPressed
,
343 wxBitmap
*bmpDisabled
);
345 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
346 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
347 virtual bool AreScrollbarsInsideBorder() const;
349 virtual wxSize
GetScrollbarArrowSize() const
350 { return m_sizeScrollbarArrow
; }
351 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
352 wxScrollBar::Element elem
,
353 int thumbPos
= -1) const;
354 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
355 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
356 const wxPoint
& pt
) const;
357 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
359 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
360 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
361 { return fontHeight
+ 2; }
362 virtual wxSize
GetCheckBitmapSize() const
363 { return wxSize(13, 13); }
364 virtual wxSize
GetRadioBitmapSize() const
365 { return wxSize(12, 12); }
366 virtual wxCoord
GetCheckItemMargin() const
369 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
370 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
371 virtual wxSize
GetToolBarMargin() const
372 { return wxSize(4, 4); }
374 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
375 const wxRect
& rect
) const;
376 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
378 wxCoord
*extraSpaceBeyond
) const;
380 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
381 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
383 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
384 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
385 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
387 wxOrientation orient
,
388 long style
= 0) const;
389 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
391 wxOrientation orient
) const;
392 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
394 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
395 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
396 const wxMenu
& menu
) const;
398 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
401 // helper of DrawLabel() and DrawCheckOrRadioButton()
402 void DoDrawLabel(wxDC
& dc
,
403 const wxString
& label
,
406 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
408 wxRect
*rectBounds
= NULL
,
409 const wxPoint
& focusOffset
410 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
412 // common part of DrawLabel() and DrawItem()
413 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
415 // DrawLabel() and DrawButtonLabel() helper
416 void DrawLabelShadow(wxDC
& dc
,
417 const wxString
& label
,
422 // DrawButtonBorder() helper
423 void DoDrawBackground(wxDC
& dc
,
426 wxWindow
*window
= NULL
);
428 // DrawBorder() helpers: all of them shift and clip the DC after drawing
431 // just draw a rectangle with the given pen
432 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
434 // draw the lower left part of rectangle
435 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
437 // draw the rectange using the first brush for the left and top sides and
438 // the second one for the bottom and right ones
439 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
440 const wxPen
& pen1
, const wxPen
& pen2
);
442 // draw the normal 3D border
443 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
445 // draw the sunken 3D border
446 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
448 // draw the border used for scrollbar arrows
449 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
451 // public DrawArrow()s helper
452 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
453 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
455 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
456 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
457 wxArrowDirection arrowDir
,
458 wxArrowStyle arrowStyle
);
460 // DrawCheckButton/DrawRadioButton helper
461 void DrawCheckOrRadioButton(wxDC
& dc
,
462 const wxString
& label
,
463 const wxBitmap
& bitmap
,
468 wxCoord focusOffsetY
);
470 // draw a normal or transposed line (useful for using the same code fo both
471 // horizontal and vertical widgets)
472 void DrawLine(wxDC
& dc
,
473 wxCoord x1
, wxCoord y1
,
474 wxCoord x2
, wxCoord y2
,
475 bool transpose
= false)
478 dc
.DrawLine(y1
, x1
, y2
, x2
);
480 dc
.DrawLine(x1
, y1
, x2
, y2
);
483 // get the standard check/radio button bitmap
484 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
485 wxBitmap
GetCheckBitmap(int flags
)
486 { return GetIndicator(IndicatorType_Check
, flags
); }
487 wxBitmap
GetRadioBitmap(int flags
)
488 { return GetIndicator(IndicatorType_Radio
, flags
); }
491 const wxColourScheme
*m_scheme
;
493 // the sizing parameters (TODO make them changeable)
494 wxSize m_sizeScrollbarArrow
;
496 // GDI objects we use for drawing
497 wxColour m_colDarkGrey
,
505 wxFont m_titlebarFont
;
507 // the checked and unchecked bitmaps for DrawCheckItem()
508 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
510 // the bitmaps returned by GetIndicator()
511 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
513 [IndicatorStatus_Max
];
516 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
518 // first row is for the normal state, second - for the disabled
519 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
522 // ----------------------------------------------------------------------------
523 // wxWin32InputHandler and derived classes: process the keyboard and mouse
524 // messages according to Windows standards
525 // ----------------------------------------------------------------------------
527 class wxWin32InputHandler
: public wxInputHandler
530 wxWin32InputHandler(wxWin32Renderer
*renderer
);
532 virtual bool HandleKey(wxInputConsumer
*control
,
533 const wxKeyEvent
& event
,
535 virtual bool HandleMouse(wxInputConsumer
*control
,
536 const wxMouseEvent
& event
);
539 wxWin32Renderer
*m_renderer
;
542 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
545 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
546 wxInputHandler
*handler
);
548 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
549 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
551 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
552 const wxControlAction
& action
);
555 virtual bool IsAllowedButton(int button
) { return button
== 1; }
557 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
560 // we don't highlight anything
563 // the first and last event which caused the thumb to move
564 wxMouseEvent m_eventStartDrag
,
567 // have we paused the scrolling because the mouse moved?
570 // we remember the interval of the timer to be able to restart it
574 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
577 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
578 : wxStdCheckboxInputHandler(handler
) { }
580 virtual bool HandleKey(wxInputConsumer
*control
,
581 const wxKeyEvent
& event
,
585 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
588 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
589 : wxStdTextCtrlInputHandler(handler
) { }
591 virtual bool HandleKey(wxInputConsumer
*control
,
592 const wxKeyEvent
& event
,
596 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
599 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
601 virtual bool HandleMouse(wxInputConsumer
*consumer
,
602 const wxMouseEvent
& event
);
604 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
605 const wxMouseEvent
& event
);
608 // is the given point over the statusbar grip?
609 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
612 // the cursor we had replaced with the resize one
613 wxCursor m_cursorOld
;
615 // was the mouse over the grip last time we checked?
619 class wxWin32SystemMenuEvtHandler
;
621 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
624 wxWin32FrameInputHandler(wxInputHandler
*handler
);
625 ~wxWin32FrameInputHandler();
627 virtual bool HandleMouse(wxInputConsumer
*control
,
628 const wxMouseEvent
& event
);
630 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
632 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
635 // was the mouse over the grip last time we checked?
636 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
639 // ----------------------------------------------------------------------------
640 // wxWin32ColourScheme: uses (default) Win32 colours
641 // ----------------------------------------------------------------------------
643 class wxWin32ColourScheme
: public wxColourScheme
646 virtual wxColour
Get(StdColour col
) const;
647 virtual wxColour
GetBackground(wxWindow
*win
) const;
650 // ----------------------------------------------------------------------------
651 // wxWin32ArtProvider
652 // ----------------------------------------------------------------------------
654 class wxWin32ArtProvider
: public wxArtProvider
657 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
658 const wxArtClient
& client
,
662 // ----------------------------------------------------------------------------
664 // ----------------------------------------------------------------------------
666 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
668 class wxWin32Theme
: public wxTheme
672 virtual ~wxWin32Theme();
674 virtual wxRenderer
*GetRenderer();
675 virtual wxArtProvider
*GetArtProvider();
676 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
677 virtual wxColourScheme
*GetColourScheme();
680 // get the default input handler
681 wxInputHandler
*GetDefaultInputHandler();
683 wxWin32Renderer
*m_renderer
;
685 wxWin32ArtProvider
*m_artProvider
;
687 // the names of the already created handlers and the handlers themselves
688 // (these arrays are synchronized)
689 wxSortedArrayString m_handlerNames
;
690 wxArrayHandlers m_handlers
;
692 wxWin32InputHandler
*m_handlerDefault
;
694 wxWin32ColourScheme
*m_scheme
;
696 WX_DECLARE_THEME(win32
)
699 // ----------------------------------------------------------------------------
701 // ----------------------------------------------------------------------------
703 // frame buttons bitmaps
705 static const char *frame_button_close_xpm
[] = {
720 static const char *frame_button_help_xpm
[] = {
735 static const char *frame_button_maximize_xpm
[] = {
750 static const char *frame_button_minimize_xpm
[] = {
765 static const char *frame_button_restore_xpm
[] = {
782 static const char *checked_menu_xpm
[] = {
783 /* columns rows colors chars-per-pixel */
799 static const char *selected_checked_menu_xpm
[] = {
800 /* columns rows colors chars-per-pixel */
816 static const char *disabled_checked_menu_xpm
[] = {
817 /* columns rows colors chars-per-pixel */
834 static const char *selected_disabled_checked_menu_xpm
[] = {
835 /* columns rows colors chars-per-pixel */
851 // checkbox and radiobox bitmaps below
853 static const char *checked_xpm
[] = {
854 /* columns rows colors chars-per-pixel */
877 static const char *pressed_checked_xpm
[] = {
878 /* columns rows colors chars-per-pixel */
900 static const char *pressed_disabled_checked_xpm
[] = {
901 /* columns rows colors chars-per-pixel */
923 static const char *checked_item_xpm
[] = {
924 /* columns rows colors chars-per-pixel */
945 static const char *unchecked_xpm
[] = {
946 /* columns rows colors chars-per-pixel */
969 static const char *pressed_unchecked_xpm
[] = {
970 /* columns rows colors chars-per-pixel */
992 static const char *unchecked_item_xpm
[] = {
993 /* columns rows colors chars-per-pixel */
1013 static const char *undetermined_xpm
[] = {
1014 /* columns rows colors chars-per-pixel */
1037 static const char *pressed_undetermined_xpm
[] = {
1038 /* columns rows colors chars-per-pixel */
1061 static const char *checked_radio_xpm
[] = {
1062 /* columns rows colors chars-per-pixel */
1085 static const char *pressed_checked_radio_xpm
[] = {
1086 /* columns rows colors chars-per-pixel */
1109 static const char *pressed_disabled_checked_radio_xpm
[] = {
1110 /* columns rows colors chars-per-pixel */
1133 static const char *unchecked_radio_xpm
[] = {
1134 /* columns rows colors chars-per-pixel */
1157 static const char *pressed_unchecked_radio_xpm
[] = {
1158 /* columns rows colors chars-per-pixel */
1181 static const char **
1182 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1187 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1190 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1193 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1199 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1202 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1205 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1211 { checked_menu_xpm
, NULL
, NULL
},
1214 { selected_checked_menu_xpm
, NULL
, NULL
},
1217 { disabled_checked_menu_xpm
, NULL
, NULL
},
1219 // disabled selected state
1220 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1224 static const char **xpmChecked
[IndicatorStatus_Max
] =
1230 // ============================================================================
1232 // ============================================================================
1234 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1236 // ----------------------------------------------------------------------------
1238 // ----------------------------------------------------------------------------
1240 wxWin32Theme::wxWin32Theme()
1244 m_handlerDefault
= NULL
;
1245 m_artProvider
= NULL
;
1248 wxWin32Theme::~wxWin32Theme()
1250 size_t count
= m_handlers
.GetCount();
1251 for ( size_t n
= 0; n
< count
; n
++ )
1253 if ( m_handlers
[n
] != m_handlerDefault
)
1254 delete m_handlers
[n
];
1257 delete m_handlerDefault
;
1261 wxArtProvider::RemoveProvider(m_artProvider
);
1264 wxRenderer
*wxWin32Theme::GetRenderer()
1268 m_renderer
= new wxWin32Renderer(GetColourScheme());
1274 wxArtProvider
*wxWin32Theme::GetArtProvider()
1276 if ( !m_artProvider
)
1278 m_artProvider
= new wxWin32ArtProvider
;
1281 return m_artProvider
;
1284 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1286 if ( !m_handlerDefault
)
1288 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1291 return m_handlerDefault
;
1294 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1296 wxInputHandler
*handler
;
1297 int n
= m_handlerNames
.Index(control
);
1298 if ( n
== wxNOT_FOUND
)
1300 // create a new handler
1301 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1302 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1303 GetDefaultInputHandler());
1305 else if ( control
== wxINP_HANDLER_BUTTON
)
1306 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1307 #endif // wxUSE_BUTTON
1309 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1310 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1311 #endif // wxUSE_CHECKBOX
1313 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1314 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1315 #endif // wxUSE_COMBOBOX
1317 else if ( control
== wxINP_HANDLER_LISTBOX
)
1318 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1319 #endif // wxUSE_LISTBOX
1320 #if wxUSE_CHECKLISTBOX
1321 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1322 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1323 #endif // wxUSE_CHECKLISTBOX
1325 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1326 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1327 #endif // wxUSE_TEXTCTRL
1329 else if ( control
== wxINP_HANDLER_SLIDER
)
1330 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1331 #endif // wxUSE_SLIDER
1333 else if ( control
== wxINP_HANDLER_SPINBTN
)
1334 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1335 #endif // wxUSE_SPINBTN
1337 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1338 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1339 #endif // wxUSE_NOTEBOOK
1341 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1342 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1343 #endif // wxUSE_STATUSBAR
1345 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1346 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1347 #endif // wxUSE_TOOLBAR
1348 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1349 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1351 handler
= GetDefaultInputHandler();
1353 n
= m_handlerNames
.Add(control
);
1354 m_handlers
.Insert(handler
, n
);
1356 else // we already have it
1358 handler
= m_handlers
[n
];
1364 wxColourScheme
*wxWin32Theme::GetColourScheme()
1368 m_scheme
= new wxWin32ColourScheme
;
1373 // ============================================================================
1374 // wxWin32ColourScheme
1375 // ============================================================================
1377 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1380 if ( win
->UseBgCol() )
1382 // use the user specified colour
1383 col
= win
->GetBackgroundColour();
1386 if ( !win
->ShouldInheritColours() )
1388 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1390 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1398 if ( !win
->IsEnabled() ) // not IsEditable()
1404 // doesn't depend on the state
1411 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1415 int flags
= win
->GetStateFlags();
1417 // the colour set by the user should be used for the normal state
1418 // and for the states for which we don't have any specific colours
1419 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1421 if ( wxDynamicCast(win
, wxScrollBar
) )
1422 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1432 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1436 // use the system colours under Windows
1437 #if defined(__WXMSW__)
1438 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1440 case CONTROL_PRESSED
:
1441 case CONTROL_CURRENT
:
1442 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1444 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1446 #if defined(COLOR_3DLIGHT)
1447 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1449 case SCROLLBAR
: return wxColour(0xe0e0e0);
1451 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1453 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1454 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1456 #if defined(COLOR_3DDKSHADOW)
1457 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1459 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1462 case CONTROL_TEXT_DISABLED
:
1463 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1465 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1467 case CONTROL_TEXT_DISABLED_SHADOW
:
1468 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1470 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1471 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1472 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1473 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1475 case DESKTOP
: return wxColour(0x808000);
1477 // use the standard Windows colours elsewhere
1478 case WINDOW
: return *wxWHITE
;
1480 case CONTROL_PRESSED
:
1481 case CONTROL_CURRENT
:
1482 case CONTROL
: return wxColour(0xc0c0c0);
1484 case CONTROL_TEXT
: return *wxBLACK
;
1486 case SCROLLBAR
: return wxColour(0xe0e0e0);
1487 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1489 case HIGHLIGHT
: return wxColour(0x800000);
1490 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1492 case SHADOW_DARK
: return *wxBLACK
;
1494 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1495 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1497 case SHADOW_IN
: return wxColour(0xc0c0c0);
1499 case CONTROL_TEXT_DISABLED_SHADOW
:
1500 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1502 case TITLEBAR
: return wxColour(0xaeaaae);
1503 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1504 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1505 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1507 case DESKTOP
: return wxColour(0x808000);
1510 case GAUGE
: return Get(HIGHLIGHT
);
1514 wxFAIL_MSG(_T("invalid standard colour"));
1519 // ============================================================================
1521 // ============================================================================
1523 // ----------------------------------------------------------------------------
1525 // ----------------------------------------------------------------------------
1527 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1531 m_sizeScrollbarArrow
= wxSize(16, 16);
1533 // init colours and pens
1534 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1536 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1537 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1539 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1541 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1542 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1544 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1545 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1547 // init the arrow bitmaps
1548 static const size_t ARROW_WIDTH
= 7;
1549 static const size_t ARROW_LENGTH
= 4;
1552 wxMemoryDC dcNormal
,
1555 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1557 bool isVertical
= n
> Arrow_Right
;
1570 // disabled arrow is larger because of the shadow
1571 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1572 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1574 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1575 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1577 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1578 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1582 dcNormal
.SetPen(m_penBlack
);
1583 dcDisabled
.SetPen(m_penDarkGrey
);
1585 // calculate the position of the point of the arrow
1589 x1
= (ARROW_WIDTH
- 1)/2;
1590 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1594 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1595 y1
= (ARROW_WIDTH
- 1)/2;
1606 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1608 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1609 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1616 if ( n
== Arrow_Up
)
1627 else // left or right arrow
1632 if ( n
== Arrow_Left
)
1645 // draw the shadow for the disabled one
1646 dcDisabled
.SetPen(m_penHighlight
);
1651 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1655 x1
= ARROW_LENGTH
- 1;
1656 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1659 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1660 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1665 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1669 x1
= ARROW_WIDTH
- 1;
1671 x2
= (ARROW_WIDTH
- 1)/2;
1673 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1674 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1679 // create the inversed bitmap but only for the right arrow as we only
1680 // use it for the menus
1681 if ( n
== Arrow_Right
)
1683 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1684 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1686 dcInverse
.Blit(0, 0, w
, h
,
1689 dcInverse
.SelectObject(wxNullBitmap
);
1691 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1692 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1694 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1695 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1697 dcInverse
.Blit(0, 0, w
, h
,
1700 dcInverse
.SelectObject(wxNullBitmap
);
1702 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1703 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1706 dcNormal
.SelectObject(wxNullBitmap
);
1707 dcDisabled
.SelectObject(wxNullBitmap
);
1709 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1710 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1711 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1712 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1714 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1717 // init the frame buttons bitmaps
1718 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1719 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1720 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1721 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1722 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1725 // ----------------------------------------------------------------------------
1727 // ----------------------------------------------------------------------------
1730 The raised border in Win32 looks like this:
1732 IIIIIIIIIIIIIIIIIIIIIIB
1734 I GB I = white (HILIGHT)
1735 I GB H = light grey (LIGHT)
1736 I GB G = dark grey (SHADOI)
1737 I GB B = black (DKSHADOI)
1738 I GB I = hIghlight (COLOR_3DHILIGHT)
1740 IGGGGGGGGGGGGGGGGGGGGGB
1741 BBBBBBBBBBBBBBBBBBBBBBB
1743 The sunken border looks like this:
1745 GGGGGGGGGGGGGGGGGGGGGGI
1746 GBBBBBBBBBBBBBBBBBBBBHI
1753 GHHHHHHHHHHHHHHHHHHHHHI
1754 IIIIIIIIIIIIIIIIIIIIIII
1756 The static border (used for the controls which don't get focus) is like
1759 GGGGGGGGGGGGGGGGGGGGGGW
1767 WWWWWWWWWWWWWWWWWWWWWWW
1769 The most complicated is the double border:
1771 HHHHHHHHHHHHHHHHHHHHHHB
1772 HWWWWWWWWWWWWWWWWWWWWGB
1773 HWHHHHHHHHHHHHHHHHHHHGB
1778 HWHHHHHHHHHHHHHHHHHHHGB
1779 HGGGGGGGGGGGGGGGGGGGGGB
1780 BBBBBBBBBBBBBBBBBBBBBBB
1782 And the simple border is, well, simple:
1784 BBBBBBBBBBBBBBBBBBBBBBB
1793 BBBBBBBBBBBBBBBBBBBBBBB
1796 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1800 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1801 dc
.DrawRectangle(*rect
);
1807 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1809 // draw the bottom and right sides
1811 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1812 rect
->GetRight() + 1, rect
->GetBottom());
1813 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1814 rect
->GetRight(), rect
->GetBottom());
1820 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1821 const wxPen
& pen1
, const wxPen
& pen2
)
1823 // draw the rectangle
1825 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1826 rect
->GetLeft(), rect
->GetBottom());
1827 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1828 rect
->GetRight(), rect
->GetTop());
1830 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1831 rect
->GetRight(), rect
->GetBottom());
1832 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1833 rect
->GetRight() + 1, rect
->GetBottom());
1839 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1841 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1842 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1845 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1847 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1848 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1851 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1855 DrawRect(dc
, rect
, m_penDarkGrey
);
1857 // the arrow is usually drawn inside border of width 2 and is offset by
1858 // another pixel in both directions when it's pressed - as the border
1859 // in this case is more narrow as well, we have to adjust rect like
1867 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1868 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1872 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1874 const wxRect
& rectTotal
,
1875 int WXUNUSED(flags
),
1880 wxRect rect
= rectTotal
;
1884 case wxBORDER_SUNKEN
:
1885 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1887 DrawSunkenBorder(dc
, &rect
);
1891 case wxBORDER_STATIC
:
1892 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1895 case wxBORDER_RAISED
:
1896 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1898 DrawRaisedBorder(dc
, &rect
);
1902 case wxBORDER_DOUBLE
:
1903 DrawArrowBorder(dc
, &rect
);
1904 DrawRect(dc
, &rect
, m_penLightGrey
);
1907 case wxBORDER_SIMPLE
:
1908 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1910 DrawRect(dc
, &rect
, m_penBlack
);
1915 wxFAIL_MSG(_T("unknown border type"));
1918 case wxBORDER_DEFAULT
:
1927 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1932 case wxBORDER_RAISED
:
1933 case wxBORDER_SUNKEN
:
1934 width
= BORDER_THICKNESS
;
1937 case wxBORDER_SIMPLE
:
1938 case wxBORDER_STATIC
:
1942 case wxBORDER_DOUBLE
:
1948 // char *crash = NULL;
1950 wxFAIL_MSG(_T("unknown border type"));
1954 case wxBORDER_DEFAULT
:
1964 rect
.height
= width
;
1969 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1974 // ----------------------------------------------------------------------------
1976 // ----------------------------------------------------------------------------
1978 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1984 // text controls are not special under windows
1985 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1988 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1989 const wxRect
& rectTotal
,
1993 wxRect rect
= rectTotal
;
1995 if ( flags
& wxCONTROL_PRESSED
)
1997 // button pressed: draw a double border around it
1998 DrawRect(dc
, &rect
, m_penBlack
);
1999 DrawRect(dc
, &rect
, m_penDarkGrey
);
2003 // button not pressed
2005 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
2007 // button either default or focused (or both): add an extra border around it
2008 DrawRect(dc
, &rect
, m_penBlack
);
2011 // now draw a normal button
2012 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
2013 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
2022 // ----------------------------------------------------------------------------
2024 // ----------------------------------------------------------------------------
2026 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
2027 wxCoord y
, wxCoord x1
, wxCoord x2
)
2029 dc
.SetPen(m_penDarkGrey
);
2030 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2031 dc
.SetPen(m_penHighlight
);
2033 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2036 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
2037 wxCoord x
, wxCoord y1
, wxCoord y2
)
2039 dc
.SetPen(m_penDarkGrey
);
2040 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2041 dc
.SetPen(m_penHighlight
);
2043 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2046 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
2047 const wxString
& label
,
2053 wxCoord height
= 0; // of the label
2054 wxRect rectFrame
= rect
;
2055 if ( !label
.empty() )
2057 // the text should touch the top border of the rect, so the frame
2058 // itself should be lower
2059 dc
.GetTextExtent(label
, NULL
, &height
);
2060 rectFrame
.y
+= height
/ 2;
2061 rectFrame
.height
-= height
/ 2;
2063 // we have to draw each part of the frame individually as we can't
2064 // erase the background beyond the label as it might contain some
2065 // pixmap already, so drawing everything and then overwriting part of
2066 // the frame with label doesn't work
2068 // TODO: the +5 and space insertion should be customizable
2071 rectText
.x
= rectFrame
.x
+ 5;
2072 rectText
.y
= rect
.y
;
2073 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2074 rectText
.height
= height
;
2077 label2
<< _T(' ') << label
<< _T(' ');
2078 if ( indexAccel
!= -1 )
2080 // adjust it as we prepended a space
2085 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2087 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2091 // just draw the complete frame
2092 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2093 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2097 // ----------------------------------------------------------------------------
2099 // ----------------------------------------------------------------------------
2101 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2103 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2104 // pixels each while we really need dots here... PS_ALTERNATE might
2105 // work, but it is for NT 5 only
2107 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2109 // draw the pixels manually: note that to behave in the same manner as
2110 // DrawRect(), we must exclude the bottom and right borders from the
2112 wxCoord x1
= rect
.GetLeft(),
2114 x2
= rect
.GetRight(),
2115 y2
= rect
.GetBottom();
2117 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2119 // this seems to be closer than what Windows does than wxINVERT although
2120 // I'm still not sure if it's correct
2121 dc
.SetLogicalFunction(wxAND_REVERSE
);
2124 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2125 dc
.DrawPoint(z
, rect
.GetTop());
2127 wxCoord shift
= z
== x2
? 0 : 1;
2128 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2129 dc
.DrawPoint(x2
, z
);
2131 shift
= z
== y2
? 0 : 1;
2132 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2133 dc
.DrawPoint(z
, y2
);
2135 shift
= z
== x1
? 0 : 1;
2136 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2137 dc
.DrawPoint(x1
, z
);
2139 dc
.SetLogicalFunction(wxCOPY
);
2143 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2144 const wxString
& label
,
2149 // draw shadow of the text
2150 dc
.SetTextForeground(m_colHighlight
);
2151 wxRect rectShadow
= rect
;
2154 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2156 // make the text grey
2157 dc
.SetTextForeground(m_colDarkGrey
);
2160 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2161 const wxString
& label
,
2168 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2171 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2172 const wxString
& label
,
2178 const wxPoint
& focusOffset
)
2180 // the underscores are not drawn for focused controls in wxMSW
2181 if ( flags
& wxCONTROL_FOCUSED
)
2186 if ( flags
& wxCONTROL_DISABLED
)
2188 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2189 // currently only can happen for a menu item and it seems that Windows
2190 // doesn't draw the shadow in this case, so we don't do it neither
2191 if ( flags
& wxCONTROL_SELECTED
)
2193 // just make the label text greyed out
2194 dc
.SetTextForeground(m_colDarkGrey
);
2196 else // draw normal disabled label
2198 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2203 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2205 if ( flags
& wxCONTROL_DISABLED
)
2207 // restore the fg colour
2208 dc
.SetTextForeground(*wxBLACK
);
2211 if ( flags
& wxCONTROL_FOCUSED
)
2213 if ( focusOffset
.x
|| focusOffset
.y
)
2215 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2218 DrawFocusRect(dc
, rectLabel
);
2222 *rectBounds
= rectLabel
;
2225 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2226 const wxString
& label
,
2227 const wxBitmap
& image
,
2234 // the underscores are not drawn for focused controls in wxMSW
2235 if ( flags
& wxCONTROL_PRESSED
)
2240 wxRect rectLabel
= rect
;
2241 if ( !label
.empty() )
2243 // shift the label if a button is pressed
2244 if ( flags
& wxCONTROL_PRESSED
)
2250 if ( flags
& wxCONTROL_DISABLED
)
2252 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2255 // leave enough space for the focus rectangle
2256 if ( flags
& wxCONTROL_FOCUSED
)
2258 rectLabel
.Inflate(-2);
2262 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2264 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2266 if ( flags
& wxCONTROL_PRESSED
)
2268 // the focus rectangle is never pressed, so undo the shift done
2276 DrawFocusRect(dc
, rectLabel
);
2280 // ----------------------------------------------------------------------------
2281 // (check)listbox items
2282 // ----------------------------------------------------------------------------
2284 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2285 const wxString
& label
,
2289 wxDCTextColourChanger
colChanger(dc
);
2291 if ( flags
& wxCONTROL_SELECTED
)
2293 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2295 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2296 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2297 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2298 dc
.DrawRectangle(rect
);
2301 wxRect rectText
= rect
;
2303 rectText
.width
-= 2;
2304 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2306 if ( flags
& wxCONTROL_FOCUSED
)
2308 DrawFocusRect(dc
, rect
);
2312 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2313 const wxString
& label
,
2314 const wxBitmap
& bitmap
,
2323 else // use default bitmap
2325 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2326 ? IndicatorStatus_Checked
2327 : IndicatorStatus_Unchecked
;
2329 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2331 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2334 bmp
= m_bmpCheckBitmaps
[i
];
2337 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2338 true /* use mask */);
2340 wxRect rectLabel
= rect
;
2341 int bmpWidth
= bmp
.GetWidth();
2342 rectLabel
.x
+= bmpWidth
;
2343 rectLabel
.width
-= bmpWidth
;
2345 DrawItem(dc
, label
, rectLabel
, flags
);
2348 // ----------------------------------------------------------------------------
2349 // check/radio buttons
2350 // ----------------------------------------------------------------------------
2352 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2354 IndicatorState indState
;
2355 if ( flags
& wxCONTROL_SELECTED
)
2356 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2357 : IndicatorState_Selected
;
2358 else if ( flags
& wxCONTROL_DISABLED
)
2359 indState
= IndicatorState_Disabled
;
2360 else if ( flags
& wxCONTROL_PRESSED
)
2361 indState
= IndicatorState_Pressed
;
2363 indState
= IndicatorState_Normal
;
2365 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2366 ? IndicatorStatus_Checked
2367 : ( flags
& wxCONTROL_UNDETERMINED
2368 ? IndicatorStatus_Undeterminated
2369 : IndicatorStatus_Unchecked
);
2371 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2374 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2377 // create and cache it
2378 bmp
= wxBitmap(xpm
);
2379 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2386 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2387 const wxString
& label
,
2388 const wxBitmap
& bitmap
,
2393 wxCoord focusOffsetY
)
2395 // calculate the position of the bitmap and of the label
2396 wxCoord heightBmp
= bitmap
.GetHeight();
2398 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2401 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2402 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2404 // align label vertically with the bitmap - looks nicer like this
2405 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2407 // calc horz position
2408 if ( align
== wxALIGN_RIGHT
)
2410 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2411 rectLabel
.x
= rect
.x
+ 3;
2412 rectLabel
.SetRight(xBmp
);
2414 else // normal (checkbox to the left of the text) case
2417 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2418 rectLabel
.SetRight(rect
.GetRight());
2421 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2424 dc
, label
, rectLabel
,
2426 wxALIGN_LEFT
| wxALIGN_TOP
,
2428 NULL
, // we don't need bounding rect
2429 // use custom vert focus rect offset
2430 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2434 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2435 const wxString
& label
,
2436 const wxBitmap
& bitmap
,
2446 bmp
= GetRadioBitmap(flags
);
2448 DrawCheckOrRadioButton(dc
, label
,
2450 rect
, flags
, align
, indexAccel
,
2451 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2454 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2455 const wxString
& label
,
2456 const wxBitmap
& bitmap
,
2466 bmp
= GetCheckBitmap(flags
);
2468 DrawCheckOrRadioButton(dc
, label
,
2470 rect
, flags
, align
, indexAccel
,
2471 0); // no focus rect offset for checkboxes
2474 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2475 const wxString
& label
,
2476 const wxBitmap
& bitmap
,
2477 const wxRect
& rectOrig
,
2481 if (style
== wxTOOL_STYLE_BUTTON
)
2483 wxRect rect
= rectOrig
;
2484 rect
.Deflate(BORDER_THICKNESS
);
2486 if ( flags
& wxCONTROL_PRESSED
)
2488 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2490 else if ( flags
& wxCONTROL_CURRENT
)
2492 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2495 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2497 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2499 // leave a small gap aroudn the line, also account for the toolbar
2501 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2502 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2503 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2505 // don't draw wxTOOL_STYLE_CONTROL
2508 // ----------------------------------------------------------------------------
2510 // ----------------------------------------------------------------------------
2512 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2513 const wxString
& text
,
2519 // nothing special to do here
2520 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2524 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2525 const wxRect
& WXUNUSED(rect
))
2527 // we don't draw them
2530 // ----------------------------------------------------------------------------
2532 // ----------------------------------------------------------------------------
2534 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2535 const wxRect
& rectOrig
,
2537 const wxString
& label
,
2538 const wxBitmap
& bitmap
,
2542 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2543 #define REVERSE_FOR_VERTICAL(X,Y) \
2544 SELECT_FOR_VERTICAL(X,Y) \
2546 SELECT_FOR_VERTICAL(Y,X)
2548 wxRect rect
= rectOrig
;
2550 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2552 // the current tab is drawn indented (to the top for default case) and
2553 // bigger than the other ones
2554 const wxSize indent
= GetTabIndent();
2555 if ( flags
& wxCONTROL_SELECTED
)
2557 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
2558 SELECT_FOR_VERTICAL( 0, indent
.y
));
2562 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2569 rect
.height
+= indent
.y
;
2576 rect
.width
+= indent
.x
;
2581 // draw the text, image and the focus around them (if necessary)
2582 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2583 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2585 rectLabel
.Deflate(1, 1);
2588 // draw it horizontally into memory and rotate for screen
2590 wxBitmap bitmapRotated
,
2591 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2592 rectLabel
.y
+ rectLabel
.height
);
2593 dcMem
.SelectObject(bitmapMem
);
2594 dcMem
.SetBackground(dc
.GetBackground());
2595 dcMem
.SetFont(dc
.GetFont());
2596 dcMem
.SetTextForeground(dc
.GetTextForeground());
2598 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
2599 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2600 flags
, wxALIGN_CENTRE
, indexAccel
);
2601 dcMem
.SelectObject(wxNullBitmap
);
2602 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2603 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2604 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2608 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2609 flags
, wxALIGN_CENTRE
, indexAccel
);
2612 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2613 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2614 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2615 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2616 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2617 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2619 // FIXME: all this code will break if the tab indent or the border width,
2620 // it is tied to the fact that both of them are equal to 2
2626 // left orientation looks like top but IsVertical makes x and y reversed
2628 // top is not vertical so use coordinates in written order
2629 dc
.SetPen(m_penHighlight
);
2630 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2631 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2632 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2633 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2634 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2635 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2637 dc
.SetPen(m_penBlack
);
2638 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2639 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2640 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2641 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2643 dc
.SetPen(m_penDarkGrey
);
2644 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2645 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2647 if ( flags
& wxCONTROL_SELECTED
)
2649 dc
.SetPen(m_penLightGrey
);
2651 // overwrite the part of the border below this tab
2652 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2653 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2655 // and the shadow of the tab to the left of us
2656 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2657 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2662 // right orientation looks like bottom but IsVertical makes x and y reversed
2664 // bottom is not vertical so use coordinates in written order
2665 dc
.SetPen(m_penHighlight
);
2666 // we need to continue one pixel further to overwrite the corner of
2667 // the border for the selected tab
2668 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
2669 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2670 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2671 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2673 dc
.SetPen(m_penBlack
);
2674 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2675 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2676 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2677 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2678 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2679 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2681 dc
.SetPen(m_penDarkGrey
);
2682 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2683 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2684 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2685 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2687 if ( flags
& wxCONTROL_SELECTED
)
2689 dc
.SetPen(m_penLightGrey
);
2691 // overwrite the part of the (double!) border above this tab
2692 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2693 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2694 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2695 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2697 // and the shadow of the tab to the left of us
2698 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2699 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2704 #undef SELECT_FOR_VERTICAL
2705 #undef REVERSE_FOR_VERTICAL
2708 // ----------------------------------------------------------------------------
2710 // ----------------------------------------------------------------------------
2713 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2715 wxOrientation orient
) const
2718 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2719 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2721 if (orient
== wxHORIZONTAL
)
2735 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2737 wxOrientation orient
,
2740 bool transpose
= (orient
== wxVERTICAL
);
2741 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2742 (((style
& wxSL_TOP
) != 0) & !transpose
|
2743 ((style
& wxSL_LEFT
) != 0) & transpose
|
2744 ((style
& wxSL_BOTH
) != 0));
2745 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2746 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2747 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2748 ((style
& wxSL_BOTH
) != 0));
2750 wxRect rect
= rectOrig
;
2752 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2754 if (orient
== wxHORIZONTAL
) {
2755 rect
.x
+= SLIDER_MARGIN
;
2758 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2762 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2766 rect
.y
+= sizeThumb
.y
/2;
2768 rect
.width
-= 2*SLIDER_MARGIN
;
2769 rect
.height
= 2*BORDER_THICKNESS
;
2773 rect
.y
+= SLIDER_MARGIN
;
2776 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2780 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2784 rect
.x
+= sizeThumb
.x
/2;
2786 rect
.width
= 2*BORDER_THICKNESS
;
2787 rect
.height
-= 2*SLIDER_MARGIN
;
2793 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2794 const wxRect
& rectOrig
,
2796 wxOrientation orient
,
2801 /* show shaft geometry
2819 if (flags
& wxCONTROL_FOCUSED
) {
2820 DrawFocusRect(dc
, rectOrig
);
2823 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2825 if (rectShaft
) *rectShaft
= rect
;
2827 DrawSunkenBorder(dc
, &rect
);
2830 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2832 wxOrientation orient
,
2836 /* show thumb geometry
2845 H D B where H is hightlight colour
2859 The interior of this shape is filled with the hatched brush if the thumb
2863 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2865 bool transpose
= (orient
== wxVERTICAL
);
2866 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2867 (((style
& wxSL_TOP
) != 0) & !transpose
|
2868 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2869 ((style
& wxSL_BOTH
) == 0);
2870 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2871 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2872 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2873 ((style
& wxSL_BOTH
) == 0);
2875 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2876 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2878 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2879 x1
= (transpose
? rect
.y
: rect
.x
);
2880 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2881 x3
= (x1
-1+c
) + sizeArrow
;
2882 y1
= (transpose
? rect
.x
: rect
.y
);
2883 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2884 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2885 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2887 dc
.SetPen(m_penBlack
);
2889 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2891 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2894 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2898 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2901 dc
.SetPen(m_penDarkGrey
);
2902 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2904 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2908 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2911 dc
.SetPen(m_penHighlight
);
2914 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2915 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2919 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2921 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2924 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2927 if (flags
& wxCONTROL_PRESSED
) {
2928 // TODO: MSW fills the entire area inside, not just the rect
2929 wxRect rectInt
= rect
;
2932 rectInt
.SetLeft(y3
);
2933 rectInt
.SetRight(y4
);
2938 rectInt
.SetBottom(y4
);
2942 #if !defined(__WXMGL__)
2943 static const char *stipple_xpm
[] = {
2944 /* columns rows colors chars-per-pixel */
2953 // VS: MGL can only do 8x8 stipple brushes
2954 static const char *stipple_xpm
[] = {
2955 /* columns rows colors chars-per-pixel */
2970 dc
.SetBrush(wxBrush(stipple_xpm
));
2972 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2973 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2974 dc
.SetPen(*wxTRANSPARENT_PEN
);
2975 dc
.DrawRectangle(rectInt
);
2979 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2982 wxOrientation orient
,
2986 int WXUNUSED(flags
),
2989 /* show ticks geometry
3004 if (end
== start
) return;
3006 bool transpose
= (orient
== wxVERTICAL
);
3007 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
3008 (((style
& wxSL_TOP
) != 0) & !transpose
|
3009 ((style
& wxSL_LEFT
) != 0) & transpose
|
3010 ((style
& wxSL_BOTH
) != 0));
3011 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
3012 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
3013 ((style
& wxSL_RIGHT
) != 0) & transpose
|
3014 ((style
& wxSL_BOTH
) != 0));
3016 // default thumb size
3017 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
3018 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
3020 // normal thumb size
3021 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
3022 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
3024 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
3026 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
3027 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
3028 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
3029 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
3030 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
3031 y3
= (transpose
? rect
.x
: rect
.y
);
3032 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
3035 dc
.SetPen(m_penBlack
);
3037 int range
= end
- start
;
3038 for ( int n
= 0; n
< range
; n
+= step
) {
3039 wxCoord x
= x1
+ (len
*n
) / range
;
3041 if (left
& (y1
> y3
)) {
3042 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
3044 if (right
& (y4
> y2
)) {
3045 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
3048 // always draw the line at the end position
3049 if (left
& (y1
> y3
)) {
3050 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3052 if (right
& (y4
> y2
)) {
3053 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3057 // ----------------------------------------------------------------------------
3059 // ----------------------------------------------------------------------------
3061 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3062 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3065 virtual wxSize
GetSize() const { return m_size
; }
3067 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3068 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3070 wxCoord
GetItemHeight() const { return m_heightItem
; }
3073 // the total size of the menu
3076 // the offset of the start of the menu item label
3079 // the offset of the start of the accel label
3082 // the height of a normal (not separator) item
3083 wxCoord m_heightItem
;
3085 friend wxMenuGeometryInfo
*
3086 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3089 // FIXME: all constants are hardcoded but shouldn't be
3090 static const wxCoord MENU_LEFT_MARGIN
= 9;
3091 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3092 static const wxCoord MENU_VERT_MARGIN
= 3;
3094 // the margin around bitmap/check marks (on each side)
3095 static const wxCoord MENU_BMP_MARGIN
= 2;
3097 // the margin between the labels and accel strings
3098 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3100 // the separator height in pixels: in fact, strangely enough, the real height
3101 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3103 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3105 // the size of the standard checkmark bitmap
3106 static const wxCoord MENU_CHECK_SIZE
= 9;
3108 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3109 const wxRect
& rectOrig
,
3110 const wxString
& label
,
3114 wxRect rect
= rectOrig
;
3117 wxDCTextColourChanger
colChanger(dc
);
3119 if ( flags
& wxCONTROL_SELECTED
)
3121 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3123 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3124 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3125 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3126 dc
.DrawRectangle(rect
);
3129 // don't draw the focus rect around menu bar items
3130 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3131 wxALIGN_CENTRE
, indexAccel
);
3134 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3136 const wxMenuGeometryInfo
& gi
,
3137 const wxString
& label
,
3138 const wxString
& accel
,
3139 const wxBitmap
& bitmap
,
3143 const wxWin32MenuGeometryInfo
& geometryInfo
=
3144 (const wxWin32MenuGeometryInfo
&)gi
;
3149 rect
.width
= geometryInfo
.GetSize().x
;
3150 rect
.height
= geometryInfo
.GetItemHeight();
3152 // draw the selected item specially
3153 wxDCTextColourChanger
colChanger(dc
);
3154 if ( flags
& wxCONTROL_SELECTED
)
3156 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3158 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3159 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3160 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3161 dc
.DrawRectangle(rect
);
3164 // draw the bitmap: use the bitmap provided or the standard checkmark for
3165 // the checkable items
3166 wxBitmap bmp
= bitmap
;
3167 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3169 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3174 rect
.SetRight(geometryInfo
.GetLabelOffset());
3175 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3179 rect
.x
= geometryInfo
.GetLabelOffset();
3180 rect
.SetRight(geometryInfo
.GetAccelOffset());
3182 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3184 // draw the accel string
3185 rect
.x
= geometryInfo
.GetAccelOffset();
3186 rect
.SetRight(geometryInfo
.GetSize().x
);
3188 // NB: no accel index here
3189 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3191 // draw the submenu indicator
3192 if ( flags
& wxCONTROL_ISSUBMENU
)
3194 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3195 rect
.width
= MENU_RIGHT_MARGIN
;
3197 wxArrowStyle arrowStyle
;
3198 if ( flags
& wxCONTROL_DISABLED
)
3199 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
3201 else if ( flags
& wxCONTROL_SELECTED
)
3202 arrowStyle
= Arrow_Inversed
;
3204 arrowStyle
= Arrow_Normal
;
3206 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3210 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3212 const wxMenuGeometryInfo
& geomInfo
)
3214 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3217 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3219 wxSize size
= sizeText
;
3221 // FIXME: menubar height is configurable under Windows
3228 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3229 const wxMenu
& menu
) const
3231 // prepare the dc: for now we draw all the items with the system font
3233 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3235 // the height of a normal item
3236 wxCoord heightText
= dc
.GetCharHeight();
3241 // the max length of label and accel strings: the menu width is the sum of
3242 // them, even if they're for different items (as the accels should be
3245 // the max length of the bitmap is never 0 as Windows always leaves enough
3246 // space for a check mark indicator
3247 wxCoord widthLabelMax
= 0,
3249 widthBmpMax
= MENU_LEFT_MARGIN
;
3251 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3253 node
= node
->GetNext() )
3255 // height of this item
3258 wxMenuItem
*item
= node
->GetData();
3259 if ( item
->IsSeparator() )
3261 h
= MENU_SEPARATOR_HEIGHT
;
3263 else // not separator
3268 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3269 if ( widthLabel
> widthLabelMax
)
3271 widthLabelMax
= widthLabel
;
3275 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3276 if ( widthAccel
> widthAccelMax
)
3278 widthAccelMax
= widthAccel
;
3281 const wxBitmap
& bmp
= item
->GetBitmap();
3284 wxCoord widthBmp
= bmp
.GetWidth();
3285 if ( widthBmp
> widthBmpMax
)
3286 widthBmpMax
= widthBmp
;
3288 //else if ( item->IsCheckable() ): no need to check for this as
3289 // MENU_LEFT_MARGIN is big enough to show the check mark
3292 h
+= 2*MENU_VERT_MARGIN
;
3294 // remember the item position and height
3295 item
->SetGeometry(height
, h
);
3300 // bundle the metrics into a struct and return it
3301 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3303 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3304 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3305 if ( widthAccelMax
> 0 )
3307 // if we actually have any accesl, add a margin
3308 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3311 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3313 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3314 gi
->m_size
.y
= height
;
3319 // ----------------------------------------------------------------------------
3321 // ----------------------------------------------------------------------------
3323 static const wxCoord STATBAR_BORDER_X
= 2;
3324 static const wxCoord STATBAR_BORDER_Y
= 2;
3326 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3328 if ( borderBetweenFields
)
3329 *borderBetweenFields
= 2;
3331 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3334 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3336 const wxString
& label
,
3337 int flags
, int style
/*=0*/)
3341 if ( flags
& wxCONTROL_ISDEFAULT
)
3343 // draw the size grip: it is a normal rect except that in the lower
3344 // right corner we have several bands which may be used for dragging
3345 // the status bar corner
3347 // each band consists of 4 stripes: m_penHighlight, double
3348 // m_penDarkGrey and transparent one
3349 wxCoord x2
= rect
.GetRight(),
3350 y2
= rect
.GetBottom();
3352 // draw the upper left part of the rect normally
3353 if (style
!= wxSB_FLAT
)
3355 if (style
== wxSB_RAISED
)
3356 dc
.SetPen(m_penHighlight
);
3358 dc
.SetPen(m_penDarkGrey
);
3359 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3360 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3363 // draw the grey stripes of the grip
3365 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3366 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3368 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3369 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3372 // draw the white stripes
3373 dc
.SetPen(m_penHighlight
);
3374 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3375 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3377 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3380 // draw the remaining rect boundaries
3381 if (style
!= wxSB_FLAT
)
3383 if (style
== wxSB_RAISED
)
3384 dc
.SetPen(m_penDarkGrey
);
3386 dc
.SetPen(m_penHighlight
);
3387 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3388 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3389 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3395 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3399 if (style
== wxSB_RAISED
)
3400 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3401 else if (style
!= wxSB_FLAT
)
3402 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3405 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3407 wxDCClipper
clipper(dc
, rectIn
);
3408 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3411 // ----------------------------------------------------------------------------
3413 // ----------------------------------------------------------------------------
3415 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3416 wxBitmap
* WXUNUSED(bmpFocus
),
3417 wxBitmap
*bmpPressed
,
3418 wxBitmap
*bmpDisabled
)
3420 static const wxCoord widthCombo
= 16;
3421 static const wxCoord heightCombo
= 17;
3427 bmpNormal
->Create(widthCombo
, heightCombo
);
3428 dcMem
.SelectObject(*bmpNormal
);
3429 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3430 Arrow_Down
, Arrow_Normal
);
3435 bmpPressed
->Create(widthCombo
, heightCombo
);
3436 dcMem
.SelectObject(*bmpPressed
);
3437 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3438 Arrow_Down
, Arrow_Pressed
);
3443 bmpDisabled
->Create(widthCombo
, heightCombo
);
3444 dcMem
.SelectObject(*bmpDisabled
);
3445 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3446 Arrow_Down
, Arrow_Disabled
);
3450 // ----------------------------------------------------------------------------
3452 // ----------------------------------------------------------------------------
3454 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3455 const wxColour
& col
,
3457 wxWindow
* WXUNUSED(window
))
3459 wxBrush
brush(col
, wxSOLID
);
3461 dc
.SetPen(*wxTRANSPARENT_PEN
);
3462 dc
.DrawRectangle(rect
);
3465 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3466 const wxColour
& col
,
3468 int WXUNUSED(flags
),
3471 // just fill it with the given or default bg colour
3472 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3473 DoDrawBackground(dc
, colBg
, rect
, window
);
3476 // ----------------------------------------------------------------------------
3478 // ----------------------------------------------------------------------------
3480 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3485 // get the bitmap for this arrow
3486 wxArrowDirection arrowDir
;
3489 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3490 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3491 case wxUP
: arrowDir
= Arrow_Up
; break;
3492 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3495 wxFAIL_MSG(_T("unknown arrow direction"));
3499 wxArrowStyle arrowStyle
;
3500 if ( flags
& wxCONTROL_PRESSED
)
3502 // can't be pressed and disabled
3503 arrowStyle
= Arrow_Pressed
;
3507 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3510 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3513 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3515 wxArrowDirection arrowDir
,
3516 wxArrowStyle arrowStyle
)
3518 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3520 // under Windows the arrows always have the same size so just centre it in
3521 // the provided rectangle
3522 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3523 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3525 // Windows does it like this...
3526 if ( arrowDir
== Arrow_Left
)
3530 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3533 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3534 const wxRect
& rectAll
,
3535 wxArrowDirection arrowDir
,
3536 wxArrowStyle arrowStyle
)
3538 wxRect rect
= rectAll
;
3539 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3540 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3541 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3544 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3545 wxOrientation
WXUNUSED(orient
),
3547 int WXUNUSED(flags
))
3549 // we don't use the flags, the thumb never changes appearance
3550 wxRect rectThumb
= rect
;
3551 DrawArrowBorder(dc
, &rectThumb
);
3552 DrawBackground(dc
, wxNullColour
, rectThumb
);
3555 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3556 wxOrientation
WXUNUSED(orient
),
3557 const wxRect
& rectBar
,
3560 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3561 ? wxColourScheme::SCROLLBAR_PRESSED
3562 : wxColourScheme::SCROLLBAR
;
3563 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3566 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3568 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3571 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3572 wxScrollBar::Element elem
,
3575 return StandardGetScrollbarRect(scrollbar
, elem
,
3576 thumbPos
, m_sizeScrollbarArrow
);
3579 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3581 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3584 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3585 const wxPoint
& pt
) const
3587 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3590 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3593 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3596 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3599 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3602 // ----------------------------------------------------------------------------
3603 // top level windows
3604 // ----------------------------------------------------------------------------
3606 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3608 wxRect client
= GetFrameClientArea(rect
, flags
);
3610 if ( client
.Inside(pt
) )
3611 return wxHT_TOPLEVEL_CLIENT_AREA
;
3613 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3615 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3617 if ( flags
& wxTOPLEVEL_ICON
)
3619 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3620 return wxHT_TOPLEVEL_ICON
;
3623 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3624 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3625 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3627 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3629 if ( btnRect
.Inside(pt
) )
3630 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3631 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3633 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3635 if ( btnRect
.Inside(pt
) )
3636 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3637 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3639 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3641 if ( btnRect
.Inside(pt
) )
3642 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3643 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3645 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3647 if ( btnRect
.Inside(pt
) )
3648 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3649 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3651 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3653 if ( btnRect
.Inside(pt
) )
3654 return wxHT_TOPLEVEL_BUTTON_HELP
;
3655 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3658 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3659 return wxHT_TOPLEVEL_TITLEBAR
;
3662 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3664 // we are certainly at one of borders, lets decide which one:
3667 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3668 if ( pt
.x
< client
.x
)
3669 border
|= wxHT_TOPLEVEL_BORDER_W
;
3670 else if ( pt
.x
>= client
.width
+ client
.x
)
3671 border
|= wxHT_TOPLEVEL_BORDER_E
;
3672 if ( pt
.y
< client
.y
)
3673 border
|= wxHT_TOPLEVEL_BORDER_N
;
3674 else if ( pt
.y
>= client
.height
+ client
.y
)
3675 border
|= wxHT_TOPLEVEL_BORDER_S
;
3679 return wxHT_NOWHERE
;
3682 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3684 const wxString
& title
,
3688 int specialButtonFlags
)
3690 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3692 DrawFrameBorder(dc
, rect
, flags
);
3694 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3696 DrawFrameBackground(dc
, rect
, flags
);
3697 if ( flags
& wxTOPLEVEL_ICON
)
3698 DrawFrameIcon(dc
, rect
, icon
, flags
);
3699 DrawFrameTitle(dc
, rect
, title
, flags
);
3701 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3703 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3704 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3706 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3708 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3709 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3710 specialButtonFlags
: 0);
3711 x
-= FRAME_BUTTON_WIDTH
+ 2;
3713 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3715 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3716 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3717 specialButtonFlags
: 0);
3718 x
-= FRAME_BUTTON_WIDTH
;
3720 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3722 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3723 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3724 specialButtonFlags
: 0);
3725 x
-= FRAME_BUTTON_WIDTH
;
3727 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3729 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3730 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3731 specialButtonFlags
: 0);
3732 x
-= FRAME_BUTTON_WIDTH
;
3734 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3736 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3737 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3738 specialButtonFlags
: 0);
3743 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3747 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3751 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3752 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3753 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3754 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3755 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3758 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3762 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3764 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3765 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3766 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3768 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3769 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3771 DrawBackground(dc
, col
, r
);
3774 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3776 const wxString
& title
,
3779 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3780 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3781 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3783 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3784 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3785 if ( flags
& wxTOPLEVEL_ICON
)
3787 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3788 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3796 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3797 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3798 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3799 r
.width
-= FRAME_BUTTON_WIDTH
;
3800 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3801 r
.width
-= FRAME_BUTTON_WIDTH
;
3802 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3803 r
.width
-= FRAME_BUTTON_WIDTH
;
3804 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3805 r
.width
-= FRAME_BUTTON_WIDTH
;
3807 dc
.SetFont(m_titlebarFont
);
3808 dc
.SetTextForeground(col
);
3811 dc
.GetTextExtent(title
, &textW
, NULL
);
3812 if ( textW
> r
.width
)
3814 // text is too big, let's shorten it and add "..." after it:
3815 size_t len
= title
.length();
3816 wxCoord WSoFar
, letterW
;
3818 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3819 if ( WSoFar
> r
.width
)
3821 // not enough space to draw anything
3827 for (size_t i
= 0; i
< len
; i
++)
3829 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3830 if ( letterW
+ WSoFar
> r
.width
)
3836 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3837 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3840 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3841 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3844 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3851 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3852 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3856 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3857 wxCoord x
, wxCoord y
,
3861 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3866 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3867 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3868 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3869 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3870 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3872 wxFAIL_MSG(wxT("incorrect button specification"));
3875 if ( flags
& wxCONTROL_PRESSED
)
3877 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3878 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3879 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3880 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3884 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3885 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3886 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3887 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3892 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3897 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3899 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3900 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3901 FRAME_BORDER_THICKNESS
;
3904 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3906 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3907 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3913 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3916 wxSize
s(clientSize
);
3918 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3920 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3921 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3922 FRAME_BORDER_THICKNESS
;
3926 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3927 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3932 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3936 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3938 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3939 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3940 FRAME_BORDER_THICKNESS
;
3945 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3947 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3949 if ( flags
& wxTOPLEVEL_ICON
)
3950 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3951 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3952 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3953 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3954 s
.x
+= FRAME_BUTTON_WIDTH
;
3955 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3956 s
.x
+= FRAME_BUTTON_WIDTH
;
3957 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3958 s
.x
+= FRAME_BUTTON_WIDTH
;
3959 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3960 s
.x
+= FRAME_BUTTON_WIDTH
;
3966 wxSize
wxWin32Renderer::GetFrameIconSize() const
3968 return wxSize(16, 16);
3972 // ----------------------------------------------------------------------------
3974 // ----------------------------------------------------------------------------
3976 static char *error_xpm
[]={
3983 "...........########.............",
3984 "........###aaaaaaaa###..........",
3985 ".......#aaaaaaaaaaaaaa#.........",
3986 ".....##aaaaaaaaaaaaaaaa##.......",
3987 "....#aaaaaaaaaaaaaaaaaaaa#......",
3988 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3989 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3990 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3991 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3992 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3993 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3994 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3995 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3996 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3997 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3998 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3999 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
4000 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
4001 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
4002 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
4003 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
4004 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
4005 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
4006 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
4007 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
4008 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
4009 ".....##aaaaaaaaaaaaaaaa##bbbb...",
4010 "......b#aaaaaaaaaaaaaa#bbbbb....",
4011 ".......b###aaaaaaaa###bbbbb.....",
4012 ".........bb########bbbbbb.......",
4013 "..........bbbbbbbbbbbbbb........",
4014 ".............bbbbbbbb..........."};
4016 static char *info_xpm
[]={
4024 "...........########.............",
4025 "........###abbbbbba###..........",
4026 "......##abbbbbbbbbbbba##........",
4027 ".....#abbbbbbbbbbbbbbbba#.......",
4028 "....#bbbbbbbaccccabbbbbbbd......",
4029 "...#bbbbbbbbccccccbbbbbbbbd.....",
4030 "..#bbbbbbbbbccccccbbbbbbbbbd....",
4031 ".#abbbbbbbbbaccccabbbbbbbbbad...",
4032 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
4033 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
4034 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
4035 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
4036 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
4037 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
4038 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
4039 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
4040 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
4041 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
4042 "..#bbbbbbbbcccccccccbbbbbbbd###.",
4043 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
4044 "....dbbbbbbbbbbbbbbbbbbbbd####..",
4045 ".....dabbbbbbbbbbbbbbbbad####...",
4046 "......ddabbbbbbbbbbbbadd####....",
4047 ".......#dddabbbbbbaddd#####.....",
4048 "........###dddabbbd#######......",
4049 "..........####dbbbd#####........",
4050 ".............#dbbbd##...........",
4051 "...............dbbd##...........",
4052 "................dbd##...........",
4053 ".................dd##...........",
4054 "..................###...........",
4055 "...................##..........."};
4057 static char *question_xpm
[]={
4065 "...........########.............",
4066 "........###abbbbbba###..........",
4067 "......##abbbbbbbbbbbba##........",
4068 ".....#abbbbbbbbbbbbbbbba#.......",
4069 "....#bbbbbbbbbbbbbbbbbbbbc......",
4070 "...#bbbbbbbaddddddabbbbbbbc.....",
4071 "..#bbbbbbbadabbddddabbbbbbbc....",
4072 ".#abbbbbbbddbbbbddddbbbbbbbac...",
4073 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
4074 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
4075 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
4076 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
4077 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
4078 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
4079 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
4080 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
4081 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
4082 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
4083 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
4084 "...cbbbbbbbbbaddabbbbbbbbbc####.",
4085 "....cbbbbbbbbbbbbbbbbbbbbc####..",
4086 ".....cabbbbbbbbbbbbbbbbac####...",
4087 "......ccabbbbbbbbbbbbacc####....",
4088 ".......#cccabbbbbbaccc#####.....",
4089 "........###cccabbbc#######......",
4090 "..........####cbbbc#####........",
4091 ".............#cbbbc##...........",
4092 "...............cbbc##...........",
4093 "................cbc##...........",
4094 ".................cc##...........",
4095 "..................###...........",
4096 "...................##..........."};
4098 static char *warning_xpm
[]={
4106 ".............###................",
4107 "............#aabc...............",
4108 "...........#aaaabcd.............",
4109 "...........#aaaaacdd............",
4110 "..........#aaaaaabcdd...........",
4111 "..........#aaaaaaacdd...........",
4112 ".........#aaaaaaaabcdd..........",
4113 ".........#aaaaaaaaacdd..........",
4114 "........#aaaaaaaaaabcdd.........",
4115 "........#aaabcccbaaacdd.........",
4116 ".......#aaaacccccaaabcdd........",
4117 ".......#aaaacccccaaaacdd........",
4118 "......#aaaaacccccaaaabcdd.......",
4119 "......#aaaaacccccaaaaacdd.......",
4120 ".....#aaaaaacccccaaaaabcdd......",
4121 ".....#aaaaaa#ccc#aaaaaacdd......",
4122 "....#aaaaaaabcccbaaaaaabcdd.....",
4123 "....#aaaaaaaacccaaaaaaaacdd.....",
4124 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
4125 "...#aaaaaaaaabcbaaaaaaaaacdd....",
4126 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
4127 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
4128 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
4129 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
4130 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
4131 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
4132 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
4133 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
4134 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
4135 "..#ccccccccccccccccccccccccddddd",
4136 "....ddddddddddddddddddddddddddd.",
4137 ".....ddddddddddddddddddddddddd.."};
4139 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4140 const wxArtClient
& WXUNUSED(client
),
4141 const wxSize
& WXUNUSED(size
))
4143 if ( id
== wxART_INFORMATION
)
4144 return wxBitmap(info_xpm
);
4145 if ( id
== wxART_ERROR
)
4146 return wxBitmap(error_xpm
);
4147 if ( id
== wxART_WARNING
)
4148 return wxBitmap(warning_xpm
);
4149 if ( id
== wxART_QUESTION
)
4150 return wxBitmap(question_xpm
);
4151 return wxNullBitmap
;
4155 // ----------------------------------------------------------------------------
4156 // text control geometry
4157 // ----------------------------------------------------------------------------
4159 static inline int GetTextBorderWidth()
4165 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4166 const wxRect
& rect
) const
4168 wxRect rectTotal
= rect
;
4170 wxCoord widthBorder
= GetTextBorderWidth();
4171 rectTotal
.Inflate(widthBorder
);
4173 // this is what Windows does
4180 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4182 wxCoord
*extraSpaceBeyond
) const
4184 wxRect rectText
= rect
;
4186 // undo GetTextTotalArea()
4187 if ( rectText
.height
> 0 )
4190 wxCoord widthBorder
= GetTextBorderWidth();
4191 rectText
.Inflate(-widthBorder
);
4193 if ( extraSpaceBeyond
)
4194 *extraSpaceBeyond
= 0;
4199 // ----------------------------------------------------------------------------
4201 // ----------------------------------------------------------------------------
4203 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4206 if ( wxDynamicCast(window
, wxScrollBar
) )
4208 // we only set the width of vert scrollbars and height of the
4210 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4211 size
->y
= m_sizeScrollbarArrow
.y
;
4213 size
->x
= m_sizeScrollbarArrow
.x
;
4215 // skip border width adjustments, they don't make sense for us
4218 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4221 if ( wxDynamicCast(window
, wxBitmapButton
) )
4225 #endif // wxUSE_BMPBUTTON
4227 if ( wxDynamicCast(window
, wxButton
) )
4229 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4231 // TODO: don't harcode all this
4232 size
->x
+= 3*window
->GetCharWidth();
4234 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4235 if ( size
->y
< heightBtn
- 8 )
4236 size
->y
= heightBtn
;
4241 // for compatibility with other ports, the buttons default size is never
4242 // less than the standard one, but not when display not PDAs.
4243 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4245 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4247 wxSize szDef
= wxButton::GetDefaultSize();
4248 if ( size
->x
< szDef
.x
)
4253 // no border width adjustments for buttons
4256 #endif // wxUSE_BUTTON
4258 // take into account the border width
4259 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4260 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4261 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4264 // ============================================================================
4266 // ============================================================================
4268 // ----------------------------------------------------------------------------
4269 // wxWin32InputHandler
4270 // ----------------------------------------------------------------------------
4272 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4274 m_renderer
= renderer
;
4277 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4278 const wxKeyEvent
& WXUNUSED(event
),
4279 bool WXUNUSED(pressed
))
4284 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4285 const wxMouseEvent
& event
)
4287 // clicking on the control gives it focus
4288 if ( event
.ButtonDown() )
4290 wxWindow
*win
= control
->GetInputWindow();
4292 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4293 ( win
->AcceptsFocus() ) )
4304 // ----------------------------------------------------------------------------
4305 // wxWin32ScrollBarInputHandler
4306 // ----------------------------------------------------------------------------
4308 wxWin32ScrollBarInputHandler::
4309 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4310 wxInputHandler
*handler
)
4311 : wxStdScrollBarInputHandler(renderer
, handler
)
4313 m_scrollPaused
= false;
4317 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4318 const wxControlAction
& action
)
4320 // stop if went beyond the position of the original click (this can only
4321 // happen when we scroll by pages)
4323 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4325 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4326 != wxHT_SCROLLBAR_BAR_2
;
4328 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4330 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4331 != wxHT_SCROLLBAR_BAR_1
;
4336 StopScrolling(scrollbar
);
4338 scrollbar
->Refresh();
4343 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4346 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4347 const wxMouseEvent
& event
)
4349 // remember the current state
4350 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4352 // do process the message
4353 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4355 // analyse the changes
4356 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4358 // we just started dragging the thumb, remember its initial position to
4359 // be able to restore it if the drag is cancelled later
4360 m_eventStartDrag
= event
;
4366 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4367 const wxMouseEvent
& event
)
4369 // we don't highlight scrollbar elements, so there is no need to process
4370 // mouse move events normally - only do it while mouse is captured (i.e.
4371 // when we're dragging the thumb or pressing on something)
4372 if ( !m_winCapture
)
4375 if ( event
.Entering() )
4377 // we're not interested in this at all
4381 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4383 if ( m_scrollPaused
)
4385 // check if the mouse returned to its original location
4387 if ( event
.Leaving() )
4393 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4394 if ( ht
== m_htLast
)
4396 // yes it did, resume scrolling
4397 m_scrollPaused
= false;
4398 if ( m_timerScroll
)
4400 // we were scrolling by line/page, restart timer
4401 m_timerScroll
->Start(m_interval
);
4403 Press(scrollbar
, true);
4405 else // we were dragging the thumb
4407 // restore its last location
4408 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4414 else // normal case, scrolling hasn't been paused
4416 // if we're scrolling the scrollbar because the arrow or the shaft was
4417 // pressed, check that the mouse stays on the same scrollbar element
4420 // Always let thumb jump back if we leave the scrollbar
4421 if ( event
.Moving() )
4423 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4425 else // event.Leaving()
4430 // Jump back only if we get far away from it
4431 wxPoint pos
= event
.GetPosition();
4432 if (scrollbar
->HasFlag( wxVERTICAL
))
4434 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4439 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4442 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4445 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4446 // is still ok - we only want to catch the case when the mouse leaves
4447 // the scrollbar here
4448 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4450 ht
= wxHT_SCROLLBAR_THUMB
;
4453 if ( ht
!= m_htLast
)
4455 // what were we doing? 2 possibilities: either an arrow/shaft was
4456 // pressed in which case we have a timer and so we just stop it or
4457 // we were dragging the thumb
4458 if ( m_timerScroll
)
4461 m_interval
= m_timerScroll
->GetInterval();
4462 m_timerScroll
->Stop();
4463 m_scrollPaused
= true;
4465 // unpress the arrow
4466 Press(scrollbar
, false);
4468 else // we were dragging the thumb
4470 // remember the current thumb position to be able to restore it
4471 // if the mouse returns to it later
4472 m_eventLastDrag
= event
;
4474 // and restore the original position (before dragging) of the
4476 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4483 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4486 // ----------------------------------------------------------------------------
4487 // wxWin32CheckboxInputHandler
4488 // ----------------------------------------------------------------------------
4490 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4491 const wxKeyEvent
& event
,
4496 wxControlAction action
;
4497 int keycode
= event
.GetKeyCode();
4501 action
= wxACTION_CHECKBOX_TOGGLE
;
4505 case WXK_NUMPAD_SUBTRACT
:
4506 action
= wxACTION_CHECKBOX_CHECK
;
4510 case WXK_NUMPAD_ADD
:
4511 case WXK_NUMPAD_EQUAL
:
4512 action
= wxACTION_CHECKBOX_CLEAR
;
4516 if ( !action
.IsEmpty() )
4518 control
->PerformAction(action
);
4527 // ----------------------------------------------------------------------------
4528 // wxWin32TextCtrlInputHandler
4529 // ----------------------------------------------------------------------------
4531 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4532 const wxKeyEvent
& event
,
4535 // handle only MSW-specific text bindings here, the others are handled in
4539 int keycode
= event
.GetKeyCode();
4541 wxControlAction action
;
4542 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4544 action
= wxACTION_TEXT_CUT
;
4546 else if ( keycode
== WXK_INSERT
)
4548 if ( event
.ControlDown() )
4549 action
= wxACTION_TEXT_COPY
;
4550 else if ( event
.ShiftDown() )
4551 action
= wxACTION_TEXT_PASTE
;
4554 if ( action
!= wxACTION_NONE
)
4556 control
->PerformAction(action
);
4562 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4565 // ----------------------------------------------------------------------------
4566 // wxWin32StatusBarInputHandler
4567 // ----------------------------------------------------------------------------
4569 wxWin32StatusBarInputHandler::
4570 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4571 : wxStdInputHandler(handler
)
4576 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4577 const wxPoint
& pt
) const
4579 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4580 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4583 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4585 wxCHECK_MSG( parentTLW
, false,
4586 _T("the status bar should be a child of a TLW") );
4588 // a maximized window can't be resized anyhow
4589 if ( !parentTLW
->IsMaximized() )
4591 // VZ: I think that the standard Windows behaviour is to only
4592 // show the resizing cursor when the mouse is on top of the
4593 // grip itself but apparently different Windows versions behave
4594 // differently (?) and it seems a better UI to allow resizing
4595 // the status bar even when the mouse is above the grip
4596 wxSize sizeSbar
= statbar
->GetSize();
4598 int diff
= sizeSbar
.x
- pt
.x
;
4599 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4606 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4607 const wxMouseEvent
& event
)
4609 if ( event
.Button(1) )
4611 if ( event
.ButtonDown(1) )
4613 wxWindow
*statbar
= consumer
->GetInputWindow();
4615 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4617 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4621 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4622 wxHT_TOPLEVEL_BORDER_SE
);
4624 statbar
->SetCursor(m_cursorOld
);
4632 return wxStdInputHandler::HandleMouse(consumer
, event
);
4635 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4636 const wxMouseEvent
& event
)
4638 wxWindow
*statbar
= consumer
->GetInputWindow();
4640 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4641 if ( isOnGrip
!= m_isOnGrip
)
4643 m_isOnGrip
= isOnGrip
;
4646 m_cursorOld
= statbar
->GetCursor();
4647 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4651 statbar
->SetCursor(m_cursorOld
);
4655 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4658 // ----------------------------------------------------------------------------
4659 // wxWin32FrameInputHandler
4660 // ----------------------------------------------------------------------------
4662 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4665 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4667 void Attach(wxInputConsumer
*consumer
);
4671 DECLARE_EVENT_TABLE()
4672 void OnSystemMenu(wxCommandEvent
&event
);
4673 void OnCloseFrame(wxCommandEvent
&event
);
4674 void OnClose(wxCloseEvent
&event
);
4676 wxWin32FrameInputHandler
*m_inputHnd
;
4677 wxTopLevelWindow
*m_wnd
;
4679 wxAcceleratorTable m_oldAccelTable
;
4683 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4684 wxWin32FrameInputHandler
*handler
)
4686 m_inputHnd
= handler
;
4690 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4692 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4694 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4695 m_wnd
->PushEventHandler(this);
4698 // VS: This code relies on using generic implementation of
4699 // wxAcceleratorTable in wxUniv!
4700 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4701 m_oldAccelTable
= table
;
4702 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4703 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4704 m_wnd
->SetAcceleratorTable(table
);
4708 void wxWin32SystemMenuEvtHandler::Detach()
4713 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4715 m_wnd
->RemoveEventHandler(this);
4720 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4721 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4722 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4723 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4726 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4728 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4729 !m_wnd
->IsMaximized()) ?
4730 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4731 FRAME_BORDER_THICKNESS
;
4732 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4733 pt
.x
= -pt
.x
+ border
;
4734 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4737 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4738 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4741 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4744 m_wnd
->SetAcceleratorTable(table
);
4748 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4750 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4751 wxTOPLEVEL_BUTTON_CLOSE
);
4754 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4761 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4762 : wxStdFrameInputHandler(handler
)
4764 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4767 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4769 if ( m_menuHandler
)
4771 m_menuHandler
->Detach();
4772 delete m_menuHandler
;
4776 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4777 const wxMouseEvent
& event
)
4779 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4781 wxTopLevelWindow
*tlw
=
4782 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4784 long hit
= tlw
->HitTest(event
.GetPosition());
4786 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4788 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4789 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4790 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4793 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4795 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4796 (event
.RightDown() &&
4797 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4798 hit
== wxHT_TOPLEVEL_ICON
)) )
4800 PopupSystemMenu(tlw
, event
.GetPosition());
4806 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4809 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4810 const wxPoint
& pos
) const
4812 wxMenu
*menu
= new wxMenu
;
4814 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4815 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4816 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4817 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4818 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4819 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4820 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4821 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4822 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4823 menu
->AppendSeparator();
4824 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4826 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4828 if ( window
->IsMaximized() )
4830 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4831 menu
->Enable(wxID_MOVE_FRAME
, false);
4832 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4833 menu
->Enable(wxID_RESIZE_FRAME
, false);
4836 menu
->Enable(wxID_RESTORE_FRAME
, false);
4839 window
->PopupMenu(menu
, pos
);
4843 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4846 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4848 // always detach if active frame changed:
4849 m_menuHandler
->Detach();
4853 m_menuHandler
->Attach(consumer
);
4857 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);