1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/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/bmpbuttn.h"
37 #include "wx/listbox.h"
38 #include "wx/checklst.h"
39 #include "wx/combobox.h"
40 #include "wx/scrolbar.h"
41 #include "wx/slider.h"
42 #include "wx/textctrl.h"
43 #include "wx/toolbar.h"
44 #include "wx/statusbr.h"
47 // for COLOR_* constants
48 #include "wx/msw/private.h"
51 #include "wx/settings.h"
52 #include "wx/toplevel.h"
56 #include "wx/notebook.h"
57 #include "wx/spinbutt.h"
58 #include "wx/artprov.h"
59 #ifdef wxUSE_TOGGLEBTN
60 #include "wx/tglbtn.h"
61 #endif // wxUSE_TOGGLEBTN
63 #include "wx/univ/scrtimer.h"
64 #include "wx/univ/renderer.h"
65 #include "wx/univ/inphand.h"
66 #include "wx/univ/colschem.h"
67 #include "wx/univ/theme.h"
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 static const int BORDER_THICKNESS
= 2;
75 // the offset between the label and focus rect around it
76 static const int FOCUS_RECT_OFFSET_X
= 1;
77 static const int FOCUS_RECT_OFFSET_Y
= 1;
79 static const int FRAME_BORDER_THICKNESS
= 3;
80 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
81 static const int FRAME_TITLEBAR_HEIGHT
= 18;
82 static const int FRAME_BUTTON_WIDTH
= 16;
83 static const int FRAME_BUTTON_HEIGHT
= 14;
85 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
86 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
87 static const size_t STATUSBAR_GRIP_SIZE
=
88 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
90 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
91 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
92 static const wxCoord SLIDER_TICK_LENGTH
= 6;
104 IndicatorState_Normal
,
105 IndicatorState_Pressed
, // this one is for check/radioboxes
106 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
107 IndicatorState_Disabled
,
108 IndicatorState_SelectedDisabled
, // only for the menus
114 IndicatorStatus_Checked
,
115 IndicatorStatus_Unchecked
,
116 IndicatorStatus_Undeterminated
,
120 // wxWin32Renderer: draw the GUI elements in Win32 style
121 // ----------------------------------------------------------------------------
123 class wxWin32Renderer
: public wxRenderer
127 enum wxArrowDirection
142 Arrow_InvertedDisabled
,
146 enum wxFrameButtonType
149 FrameButton_Minimize
,
150 FrameButton_Maximize
,
157 wxWin32Renderer(const wxColourScheme
*scheme
);
159 // implement the base class pure virtuals
160 virtual void DrawBackground(wxDC
& dc
,
164 wxWindow
*window
= NULL
);
165 virtual void DrawLabel(wxDC
& dc
,
166 const wxString
& label
,
169 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
171 wxRect
*rectBounds
= NULL
);
172 virtual void DrawButtonLabel(wxDC
& dc
,
173 const wxString
& label
,
174 const wxBitmap
& image
,
177 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
179 wxRect
*rectBounds
= NULL
);
180 virtual void DrawBorder(wxDC
& dc
,
184 wxRect
*rectIn
= (wxRect
*)NULL
);
185 virtual void DrawHorizontalLine(wxDC
& dc
,
186 wxCoord y
, wxCoord x1
, wxCoord x2
);
187 virtual void DrawVerticalLine(wxDC
& dc
,
188 wxCoord x
, wxCoord y1
, wxCoord y2
);
189 virtual void DrawFrame(wxDC
& dc
,
190 const wxString
& label
,
193 int alignment
= wxALIGN_LEFT
,
194 int indexAccel
= -1);
195 virtual void DrawTextBorder(wxDC
& dc
,
199 wxRect
*rectIn
= (wxRect
*)NULL
);
200 virtual void DrawButtonBorder(wxDC
& dc
,
203 wxRect
*rectIn
= (wxRect
*)NULL
);
204 virtual void DrawArrow(wxDC
& dc
,
208 virtual void DrawScrollbarArrow(wxDC
& dc
,
212 { DrawArrow(dc
, dir
, rect
, flags
); }
213 virtual void DrawScrollbarThumb(wxDC
& dc
,
214 wxOrientation orient
,
217 virtual void DrawScrollbarShaft(wxDC
& dc
,
218 wxOrientation orient
,
221 virtual void DrawScrollCorner(wxDC
& dc
,
223 virtual void DrawItem(wxDC
& dc
,
224 const wxString
& label
,
227 virtual void DrawCheckItem(wxDC
& dc
,
228 const wxString
& label
,
229 const wxBitmap
& bitmap
,
232 virtual void DrawCheckButton(wxDC
& dc
,
233 const wxString
& label
,
234 const wxBitmap
& bitmap
,
237 wxAlignment align
= wxALIGN_LEFT
,
238 int indexAccel
= -1);
239 virtual void DrawRadioButton(wxDC
& dc
,
240 const wxString
& label
,
241 const wxBitmap
& bitmap
,
244 wxAlignment align
= wxALIGN_LEFT
,
245 int indexAccel
= -1);
247 virtual void DrawToolBarButton(wxDC
& dc
,
248 const wxString
& label
,
249 const wxBitmap
& bitmap
,
254 #endif // wxUSE_TOOLBAR
255 virtual void DrawTextLine(wxDC
& dc
,
256 const wxString
& text
,
261 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
262 virtual void DrawTab(wxDC
& dc
,
265 const wxString
& label
,
266 const wxBitmap
& bitmap
= wxNullBitmap
,
268 int indexAccel
= -1);
271 virtual void DrawSliderShaft(wxDC
& dc
,
274 wxOrientation orient
,
277 wxRect
*rectShaft
= NULL
);
278 virtual void DrawSliderThumb(wxDC
& dc
,
280 wxOrientation orient
,
283 virtual void DrawSliderTicks(wxDC
& dc
,
286 wxOrientation orient
,
292 #endif // wxUSE_SLIDER
295 virtual void DrawMenuBarItem(wxDC
& dc
,
297 const wxString
& label
,
299 int indexAccel
= -1);
300 virtual void DrawMenuItem(wxDC
& dc
,
302 const wxMenuGeometryInfo
& geometryInfo
,
303 const wxString
& label
,
304 const wxString
& accel
,
305 const wxBitmap
& bitmap
= wxNullBitmap
,
307 int indexAccel
= -1);
308 virtual void DrawMenuSeparator(wxDC
& dc
,
310 const wxMenuGeometryInfo
& geomInfo
);
311 #endif // wxUSE_MENUS
314 virtual void DrawStatusField(wxDC
& dc
,
316 const wxString
& label
,
317 int flags
= 0, int style
= 0);
318 #endif // wxUSE_STATUSBAR
321 virtual void DrawFrameTitleBar(wxDC
& dc
,
323 const wxString
& title
,
326 int specialButton
= 0,
327 int specialButtonFlags
= 0);
328 virtual void DrawFrameBorder(wxDC
& dc
,
331 virtual void DrawFrameBackground(wxDC
& dc
,
334 virtual void DrawFrameTitle(wxDC
& dc
,
336 const wxString
& title
,
338 virtual void DrawFrameIcon(wxDC
& dc
,
342 virtual void DrawFrameButton(wxDC
& dc
,
343 wxCoord x
, wxCoord y
,
346 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
347 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
348 virtual wxSize
GetFrameMinSize(int flags
) const;
349 virtual wxSize
GetFrameIconSize() const;
350 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
352 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
354 wxBitmap
*bmpPressed
,
355 wxBitmap
*bmpDisabled
);
357 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
358 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
359 virtual bool AreScrollbarsInsideBorder() const;
361 virtual wxSize
GetScrollbarArrowSize() const
362 { return m_sizeScrollbarArrow
; }
365 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
366 wxScrollBar::Element elem
,
367 int thumbPos
= -1) const;
368 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
369 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
370 const wxPoint
& pt
) const;
371 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
373 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
374 #endif // wxUSE_SCROLLBAR
376 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
377 { return fontHeight
+ 2; }
378 virtual wxSize
GetCheckBitmapSize() const
379 { return wxSize(13, 13); }
380 virtual wxSize
GetRadioBitmapSize() const
381 { return wxSize(12, 12); }
382 virtual wxCoord
GetCheckItemMargin() const
385 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
386 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
387 virtual wxSize
GetToolBarMargin() const
388 { return wxSize(4, 4); }
391 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
392 const wxRect
& rect
) const;
393 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
395 wxCoord
*extraSpaceBeyond
) const;
396 #endif // wxUSE_TEXTCTRL
398 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
399 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
403 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
404 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
405 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
407 wxOrientation orient
,
408 long style
= 0) const;
409 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
411 wxOrientation orient
) const;
412 #endif // wxUSE_SLIDER
414 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
417 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
418 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
419 const wxMenu
& menu
) const;
420 #endif // wxUSE_MENUS
423 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
424 #endif // wxUSE_STATUSBAR
427 // helper of DrawLabel() and DrawCheckOrRadioButton()
428 void DoDrawLabel(wxDC
& dc
,
429 const wxString
& label
,
432 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
434 wxRect
*rectBounds
= NULL
,
435 const wxPoint
& focusOffset
436 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
438 // common part of DrawLabel() and DrawItem()
439 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
441 // DrawLabel() and DrawButtonLabel() helper
442 void DrawLabelShadow(wxDC
& dc
,
443 const wxString
& label
,
448 // DrawButtonBorder() helper
449 void DoDrawBackground(wxDC
& dc
,
452 wxWindow
*window
= NULL
);
454 // DrawBorder() helpers: all of them shift and clip the DC after drawing
457 // just draw a rectangle with the given pen
458 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
460 // draw the lower left part of rectangle
461 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
463 // draw the rectange using the first brush for the left and top sides and
464 // the second one for the bottom and right ones
465 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
466 const wxPen
& pen1
, const wxPen
& pen2
);
468 // draw the normal 3D border
469 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
471 // draw the sunken 3D border
472 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
474 // draw the border used for scrollbar arrows
475 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
477 // public DrawArrow()s helper
478 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
479 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
481 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
482 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
483 wxArrowDirection arrowDir
,
484 wxArrowStyle arrowStyle
);
486 // DrawCheckButton/DrawRadioButton helper
487 void DrawCheckOrRadioButton(wxDC
& dc
,
488 const wxString
& label
,
489 const wxBitmap
& bitmap
,
494 wxCoord focusOffsetY
);
496 // draw a normal or transposed line (useful for using the same code fo both
497 // horizontal and vertical widgets)
498 void DrawLine(wxDC
& dc
,
499 wxCoord x1
, wxCoord y1
,
500 wxCoord x2
, wxCoord y2
,
501 bool transpose
= false)
504 dc
.DrawLine(y1
, x1
, y2
, x2
);
506 dc
.DrawLine(x1
, y1
, x2
, y2
);
509 // get the standard check/radio button bitmap
510 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
511 wxBitmap
GetCheckBitmap(int flags
)
512 { return GetIndicator(IndicatorType_Check
, flags
); }
513 wxBitmap
GetRadioBitmap(int flags
)
514 { return GetIndicator(IndicatorType_Radio
, flags
); }
517 const wxColourScheme
*m_scheme
;
519 // the sizing parameters (TODO make them changeable)
520 wxSize m_sizeScrollbarArrow
;
522 // GDI objects we use for drawing
523 wxColour m_colDarkGrey
,
531 wxFont m_titlebarFont
;
533 // the checked and unchecked bitmaps for DrawCheckItem()
534 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
536 // the bitmaps returned by GetIndicator()
537 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
539 [IndicatorStatus_Max
];
542 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
544 // first row is for the normal state, second - for the disabled
545 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
548 // ----------------------------------------------------------------------------
549 // wxWin32InputHandler and derived classes: process the keyboard and mouse
550 // messages according to Windows standards
551 // ----------------------------------------------------------------------------
553 class wxWin32InputHandler
: public wxInputHandler
556 wxWin32InputHandler(wxWin32Renderer
*renderer
);
558 virtual bool HandleKey(wxInputConsumer
*control
,
559 const wxKeyEvent
& event
,
561 virtual bool HandleMouse(wxInputConsumer
*control
,
562 const wxMouseEvent
& event
);
565 wxWin32Renderer
*m_renderer
;
569 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
572 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
573 wxInputHandler
*handler
);
575 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
576 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
578 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
579 const wxControlAction
& action
);
582 virtual bool IsAllowedButton(int button
) { return button
== 1; }
584 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
587 // we don't highlight anything
590 // the first and last event which caused the thumb to move
591 wxMouseEvent m_eventStartDrag
,
594 // have we paused the scrolling because the mouse moved?
597 // we remember the interval of the timer to be able to restart it
600 #endif // wxUSE_SCROLLBAR
603 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
606 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
607 : wxStdCheckboxInputHandler(handler
) { }
609 virtual bool HandleKey(wxInputConsumer
*control
,
610 const wxKeyEvent
& event
,
613 #endif // wxUSE_CHECKBOX
616 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
619 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
620 : wxStdTextCtrlInputHandler(handler
) { }
622 virtual bool HandleKey(wxInputConsumer
*control
,
623 const wxKeyEvent
& event
,
626 #endif // wxUSE_TEXTCTRL
628 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
631 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
633 virtual bool HandleMouse(wxInputConsumer
*consumer
,
634 const wxMouseEvent
& event
);
636 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
637 const wxMouseEvent
& event
);
640 // is the given point over the statusbar grip?
641 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
644 // the cursor we had replaced with the resize one
645 wxCursor m_cursorOld
;
647 // was the mouse over the grip last time we checked?
651 class wxWin32SystemMenuEvtHandler
;
653 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
656 wxWin32FrameInputHandler(wxInputHandler
*handler
);
657 ~wxWin32FrameInputHandler();
659 virtual bool HandleMouse(wxInputConsumer
*control
,
660 const wxMouseEvent
& event
);
662 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
665 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
666 #endif // wxUSE_MENUS
669 // was the mouse over the grip last time we checked?
670 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
673 // ----------------------------------------------------------------------------
674 // wxWin32ColourScheme: uses (default) Win32 colours
675 // ----------------------------------------------------------------------------
677 class wxWin32ColourScheme
: public wxColourScheme
680 virtual wxColour
Get(StdColour col
) const;
681 virtual wxColour
GetBackground(wxWindow
*win
) const;
684 // ----------------------------------------------------------------------------
685 // wxWin32ArtProvider
686 // ----------------------------------------------------------------------------
688 class wxWin32ArtProvider
: public wxArtProvider
691 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
692 const wxArtClient
& client
,
696 // ----------------------------------------------------------------------------
698 // ----------------------------------------------------------------------------
700 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
702 class wxWin32Theme
: public wxTheme
706 virtual ~wxWin32Theme();
708 virtual wxRenderer
*GetRenderer();
709 virtual wxArtProvider
*GetArtProvider();
710 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
711 virtual wxColourScheme
*GetColourScheme();
714 // get the default input handler
715 wxInputHandler
*GetDefaultInputHandler();
717 wxWin32Renderer
*m_renderer
;
719 wxWin32ArtProvider
*m_artProvider
;
721 // the names of the already created handlers and the handlers themselves
722 // (these arrays are synchronized)
723 wxSortedArrayString m_handlerNames
;
724 wxArrayHandlers m_handlers
;
726 wxWin32InputHandler
*m_handlerDefault
;
728 wxWin32ColourScheme
*m_scheme
;
730 WX_DECLARE_THEME(win32
)
733 // ----------------------------------------------------------------------------
735 // ----------------------------------------------------------------------------
737 // frame buttons bitmaps
739 static const char *frame_button_close_xpm
[] = {
754 static const char *frame_button_help_xpm
[] = {
769 static const char *frame_button_maximize_xpm
[] = {
784 static const char *frame_button_minimize_xpm
[] = {
799 static const char *frame_button_restore_xpm
[] = {
816 static const char *checked_menu_xpm
[] = {
817 /* columns rows colors chars-per-pixel */
833 static const char *selected_checked_menu_xpm
[] = {
834 /* columns rows colors chars-per-pixel */
850 static const char *disabled_checked_menu_xpm
[] = {
851 /* columns rows colors chars-per-pixel */
868 static const char *selected_disabled_checked_menu_xpm
[] = {
869 /* columns rows colors chars-per-pixel */
885 // checkbox and radiobox bitmaps below
887 static const char *checked_xpm
[] = {
888 /* columns rows colors chars-per-pixel */
911 static const char *pressed_checked_xpm
[] = {
912 /* columns rows colors chars-per-pixel */
934 static const char *pressed_disabled_checked_xpm
[] = {
935 /* columns rows colors chars-per-pixel */
957 static const char *checked_item_xpm
[] = {
958 /* columns rows colors chars-per-pixel */
979 static const char *unchecked_xpm
[] = {
980 /* columns rows colors chars-per-pixel */
1003 static const char *pressed_unchecked_xpm
[] = {
1004 /* columns rows colors chars-per-pixel */
1026 static const char *unchecked_item_xpm
[] = {
1027 /* columns rows colors chars-per-pixel */
1047 static const char *undetermined_xpm
[] = {
1048 /* columns rows colors chars-per-pixel */
1071 static const char *pressed_undetermined_xpm
[] = {
1072 /* columns rows colors chars-per-pixel */
1095 static const char *checked_radio_xpm
[] = {
1096 /* columns rows colors chars-per-pixel */
1119 static const char *pressed_checked_radio_xpm
[] = {
1120 /* columns rows colors chars-per-pixel */
1143 static const char *pressed_disabled_checked_radio_xpm
[] = {
1144 /* columns rows colors chars-per-pixel */
1167 static const char *unchecked_radio_xpm
[] = {
1168 /* columns rows colors chars-per-pixel */
1191 static const char *pressed_unchecked_radio_xpm
[] = {
1192 /* columns rows colors chars-per-pixel */
1215 static const char **
1216 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1221 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1224 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1227 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1233 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1236 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1239 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1245 { checked_menu_xpm
, NULL
, NULL
},
1248 { selected_checked_menu_xpm
, NULL
, NULL
},
1251 { disabled_checked_menu_xpm
, NULL
, NULL
},
1253 // disabled selected state
1254 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1258 static const char **xpmChecked
[IndicatorStatus_Max
] =
1264 // ============================================================================
1266 // ============================================================================
1268 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1270 // ----------------------------------------------------------------------------
1272 // ----------------------------------------------------------------------------
1274 wxWin32Theme::wxWin32Theme()
1278 m_handlerDefault
= NULL
;
1279 m_artProvider
= NULL
;
1282 wxWin32Theme::~wxWin32Theme()
1284 size_t count
= m_handlers
.GetCount();
1285 for ( size_t n
= 0; n
< count
; n
++ )
1287 if ( m_handlers
[n
] != m_handlerDefault
)
1288 delete m_handlers
[n
];
1291 delete m_handlerDefault
;
1295 wxArtProvider::RemoveProvider(m_artProvider
);
1298 wxRenderer
*wxWin32Theme::GetRenderer()
1302 m_renderer
= new wxWin32Renderer(GetColourScheme());
1308 wxArtProvider
*wxWin32Theme::GetArtProvider()
1310 if ( !m_artProvider
)
1312 m_artProvider
= new wxWin32ArtProvider
;
1315 return m_artProvider
;
1318 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1320 if ( !m_handlerDefault
)
1322 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1325 return m_handlerDefault
;
1328 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1330 wxInputHandler
*handler
= NULL
;
1331 int n
= m_handlerNames
.Index(control
);
1332 if ( n
== wxNOT_FOUND
)
1334 // create a new handler
1335 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1338 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1339 GetDefaultInputHandler());
1340 #endif // wxUSE_SCROLLBAR
1343 else if ( control
== wxINP_HANDLER_BUTTON
)
1344 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1345 #endif // wxUSE_BUTTON
1347 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1348 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1349 #endif // wxUSE_CHECKBOX
1351 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1352 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1353 #endif // wxUSE_COMBOBOX
1355 else if ( control
== wxINP_HANDLER_LISTBOX
)
1356 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1357 #endif // wxUSE_LISTBOX
1358 #if wxUSE_CHECKLISTBOX
1359 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1360 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1361 #endif // wxUSE_CHECKLISTBOX
1363 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1364 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1365 #endif // wxUSE_TEXTCTRL
1367 else if ( control
== wxINP_HANDLER_SLIDER
)
1368 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1369 #endif // wxUSE_SLIDER
1371 else if ( control
== wxINP_HANDLER_SPINBTN
)
1372 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1373 #endif // wxUSE_SPINBTN
1375 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1376 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1377 #endif // wxUSE_NOTEBOOK
1379 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1380 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1381 #endif // wxUSE_STATUSBAR
1383 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1384 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1385 #endif // wxUSE_TOOLBAR
1386 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1387 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1390 handler
= GetDefaultInputHandler();
1392 n
= m_handlerNames
.Add(control
);
1393 m_handlers
.Insert(handler
, n
);
1395 else // we already have it
1397 handler
= m_handlers
[n
];
1403 wxColourScheme
*wxWin32Theme::GetColourScheme()
1407 m_scheme
= new wxWin32ColourScheme
;
1412 // ============================================================================
1413 // wxWin32ColourScheme
1414 // ============================================================================
1416 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1419 if ( win
->UseBgCol() )
1421 // use the user specified colour
1422 col
= win
->GetBackgroundColour();
1425 if ( !win
->ShouldInheritColours() )
1428 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1429 #endif // wxUSE_TEXTCTRL
1431 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1432 #endif // wxUSE_LISTBOX
1441 if ( !win
->IsEnabled() ) // not IsEditable()
1447 // doesn't depend on the state
1452 #endif // wxUSE_TEXTCTRL
1455 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1459 int flags
= win
->GetStateFlags();
1461 // the colour set by the user should be used for the normal state
1462 // and for the states for which we don't have any specific colours
1463 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1466 if ( wxDynamicCast(win
, wxScrollBar
) )
1467 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1470 #endif // wxUSE_SCROLLBAR
1478 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1482 // use the system colours under Windows
1483 #if defined(__WXMSW__)
1484 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1486 case CONTROL_PRESSED
:
1487 case CONTROL_CURRENT
:
1488 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1490 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1492 #if defined(COLOR_3DLIGHT)
1493 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1495 case SCROLLBAR
: return wxColour(0xe0e0e0);
1497 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1499 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1500 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1502 #if defined(COLOR_3DDKSHADOW)
1503 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1505 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1508 case CONTROL_TEXT_DISABLED
:
1509 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1511 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1513 case CONTROL_TEXT_DISABLED_SHADOW
:
1514 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1516 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1517 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1518 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1519 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1521 case DESKTOP
: return wxColour(0x808000);
1523 // use the standard Windows colours elsewhere
1524 case WINDOW
: return *wxWHITE
;
1526 case CONTROL_PRESSED
:
1527 case CONTROL_CURRENT
:
1528 case CONTROL
: return wxColour(0xc0c0c0);
1530 case CONTROL_TEXT
: return *wxBLACK
;
1532 case SCROLLBAR
: return wxColour(0xe0e0e0);
1533 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1535 case HIGHLIGHT
: return wxColour(0x800000);
1536 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1538 case SHADOW_DARK
: return *wxBLACK
;
1540 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1541 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1543 case SHADOW_IN
: return wxColour(0xc0c0c0);
1545 case CONTROL_TEXT_DISABLED_SHADOW
:
1546 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1548 case TITLEBAR
: return wxColour(0xaeaaae);
1549 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1550 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1551 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1553 case DESKTOP
: return wxColour(0x808000);
1556 case GAUGE
: return Get(HIGHLIGHT
);
1560 wxFAIL_MSG(_T("invalid standard colour"));
1565 // ============================================================================
1567 // ============================================================================
1569 // ----------------------------------------------------------------------------
1571 // ----------------------------------------------------------------------------
1573 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1577 m_sizeScrollbarArrow
= wxSize(16, 16);
1579 // init colours and pens
1580 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1582 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1583 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1585 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1587 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1588 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1590 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1591 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1593 // init the arrow bitmaps
1594 static const size_t ARROW_WIDTH
= 7;
1595 static const size_t ARROW_LENGTH
= 4;
1598 wxMemoryDC dcNormal
,
1601 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1603 bool isVertical
= n
> Arrow_Right
;
1616 // disabled arrow is larger because of the shadow
1617 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1618 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1620 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1621 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1623 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1624 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1628 dcNormal
.SetPen(m_penBlack
);
1629 dcDisabled
.SetPen(m_penDarkGrey
);
1631 // calculate the position of the point of the arrow
1635 x1
= (ARROW_WIDTH
- 1)/2;
1636 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1640 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1641 y1
= (ARROW_WIDTH
- 1)/2;
1652 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1654 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1655 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1662 if ( n
== Arrow_Up
)
1673 else // left or right arrow
1678 if ( n
== Arrow_Left
)
1691 // draw the shadow for the disabled one
1692 dcDisabled
.SetPen(m_penHighlight
);
1697 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1701 x1
= ARROW_LENGTH
- 1;
1702 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1705 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1706 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1711 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1715 x1
= ARROW_WIDTH
- 1;
1717 x2
= (ARROW_WIDTH
- 1)/2;
1719 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1720 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1725 // create the inverted bitmap but only for the right arrow as we only
1726 // use it for the menus
1727 if ( n
== Arrow_Right
)
1729 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1730 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1732 dcInverse
.Blit(0, 0, w
, h
,
1735 dcInverse
.SelectObject(wxNullBitmap
);
1737 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1738 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1740 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1741 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1743 dcInverse
.Blit(0, 0, w
, h
,
1746 dcInverse
.SelectObject(wxNullBitmap
);
1748 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1749 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1752 dcNormal
.SelectObject(wxNullBitmap
);
1753 dcDisabled
.SelectObject(wxNullBitmap
);
1755 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1756 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1757 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1758 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1760 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1763 // init the frame buttons bitmaps
1764 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1765 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1766 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1767 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1768 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1771 // ----------------------------------------------------------------------------
1773 // ----------------------------------------------------------------------------
1776 The raised border in Win32 looks like this:
1778 IIIIIIIIIIIIIIIIIIIIIIB
1780 I GB I = white (HILIGHT)
1781 I GB H = light grey (LIGHT)
1782 I GB G = dark grey (SHADOI)
1783 I GB B = black (DKSHADOI)
1784 I GB I = hIghlight (COLOR_3DHILIGHT)
1786 IGGGGGGGGGGGGGGGGGGGGGB
1787 BBBBBBBBBBBBBBBBBBBBBBB
1789 The sunken border looks like this:
1791 GGGGGGGGGGGGGGGGGGGGGGI
1792 GBBBBBBBBBBBBBBBBBBBBHI
1799 GHHHHHHHHHHHHHHHHHHHHHI
1800 IIIIIIIIIIIIIIIIIIIIIII
1802 The static border (used for the controls which don't get focus) is like
1805 GGGGGGGGGGGGGGGGGGGGGGW
1813 WWWWWWWWWWWWWWWWWWWWWWW
1815 The most complicated is the double border:
1817 HHHHHHHHHHHHHHHHHHHHHHB
1818 HWWWWWWWWWWWWWWWWWWWWGB
1819 HWHHHHHHHHHHHHHHHHHHHGB
1824 HWHHHHHHHHHHHHHHHHHHHGB
1825 HGGGGGGGGGGGGGGGGGGGGGB
1826 BBBBBBBBBBBBBBBBBBBBBBB
1828 And the simple border is, well, simple:
1830 BBBBBBBBBBBBBBBBBBBBBBB
1839 BBBBBBBBBBBBBBBBBBBBBBB
1842 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1846 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1847 dc
.DrawRectangle(*rect
);
1853 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1855 // draw the bottom and right sides
1857 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1858 rect
->GetRight() + 1, rect
->GetBottom());
1859 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1860 rect
->GetRight(), rect
->GetBottom());
1866 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1867 const wxPen
& pen1
, const wxPen
& pen2
)
1869 // draw the rectangle
1871 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1872 rect
->GetLeft(), rect
->GetBottom());
1873 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1874 rect
->GetRight(), rect
->GetTop());
1876 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1877 rect
->GetRight(), rect
->GetBottom());
1878 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1879 rect
->GetRight() + 1, rect
->GetBottom());
1885 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1887 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1888 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1891 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1893 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1894 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1897 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1901 DrawRect(dc
, rect
, m_penDarkGrey
);
1903 // the arrow is usually drawn inside border of width 2 and is offset by
1904 // another pixel in both directions when it's pressed - as the border
1905 // in this case is more narrow as well, we have to adjust rect like
1913 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1914 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1918 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1920 const wxRect
& rectTotal
,
1921 int WXUNUSED(flags
),
1926 wxRect rect
= rectTotal
;
1930 case wxBORDER_SUNKEN
:
1931 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1933 DrawSunkenBorder(dc
, &rect
);
1937 case wxBORDER_STATIC
:
1938 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1941 case wxBORDER_RAISED
:
1942 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1944 DrawRaisedBorder(dc
, &rect
);
1948 case wxBORDER_DOUBLE
:
1949 DrawArrowBorder(dc
, &rect
);
1950 DrawRect(dc
, &rect
, m_penLightGrey
);
1953 case wxBORDER_SIMPLE
:
1954 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1956 DrawRect(dc
, &rect
, m_penBlack
);
1961 wxFAIL_MSG(_T("unknown border type"));
1964 case wxBORDER_DEFAULT
:
1973 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1978 case wxBORDER_RAISED
:
1979 case wxBORDER_SUNKEN
:
1980 width
= BORDER_THICKNESS
;
1983 case wxBORDER_SIMPLE
:
1984 case wxBORDER_STATIC
:
1988 case wxBORDER_DOUBLE
:
1994 // char *crash = NULL;
1996 wxFAIL_MSG(_T("unknown border type"));
2000 case wxBORDER_DEFAULT
:
2010 rect
.height
= width
;
2015 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
2020 // ----------------------------------------------------------------------------
2022 // ----------------------------------------------------------------------------
2024 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
2030 // text controls are not special under windows
2031 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
2034 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
2035 const wxRect
& rectTotal
,
2039 wxRect rect
= rectTotal
;
2041 if ( flags
& wxCONTROL_PRESSED
)
2043 // button pressed: draw a double border around it
2044 DrawRect(dc
, &rect
, m_penBlack
);
2045 DrawRect(dc
, &rect
, m_penDarkGrey
);
2049 // button not pressed
2051 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
2053 // button either default or focused (or both): add an extra border around it
2054 DrawRect(dc
, &rect
, m_penBlack
);
2057 // now draw a normal button
2058 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
2059 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
2068 // ----------------------------------------------------------------------------
2070 // ----------------------------------------------------------------------------
2072 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
2073 wxCoord y
, wxCoord x1
, wxCoord x2
)
2075 dc
.SetPen(m_penDarkGrey
);
2076 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2077 dc
.SetPen(m_penHighlight
);
2079 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2082 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
2083 wxCoord x
, wxCoord y1
, wxCoord y2
)
2085 dc
.SetPen(m_penDarkGrey
);
2086 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2087 dc
.SetPen(m_penHighlight
);
2089 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2092 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
2093 const wxString
& label
,
2099 wxCoord height
= 0; // of the label
2100 wxRect rectFrame
= rect
;
2101 if ( !label
.empty() )
2103 // the text should touch the top border of the rect, so the frame
2104 // itself should be lower
2105 dc
.GetTextExtent(label
, NULL
, &height
);
2106 rectFrame
.y
+= height
/ 2;
2107 rectFrame
.height
-= height
/ 2;
2109 // we have to draw each part of the frame individually as we can't
2110 // erase the background beyond the label as it might contain some
2111 // pixmap already, so drawing everything and then overwriting part of
2112 // the frame with label doesn't work
2114 // TODO: the +5 and space insertion should be customizable
2117 rectText
.x
= rectFrame
.x
+ 5;
2118 rectText
.y
= rect
.y
;
2119 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2120 rectText
.height
= height
;
2123 label2
<< _T(' ') << label
<< _T(' ');
2124 if ( indexAccel
!= -1 )
2126 // adjust it as we prepended a space
2131 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2133 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2137 // just draw the complete frame
2138 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2139 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2143 // ----------------------------------------------------------------------------
2145 // ----------------------------------------------------------------------------
2147 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2149 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2150 // pixels each while we really need dots here... PS_ALTERNATE might
2151 // work, but it is for NT 5 only
2153 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2155 // draw the pixels manually: note that to behave in the same manner as
2156 // DrawRect(), we must exclude the bottom and right borders from the
2158 wxCoord x1
= rect
.GetLeft(),
2160 x2
= rect
.GetRight(),
2161 y2
= rect
.GetBottom();
2163 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2165 // this seems to be closer than what Windows does than wxINVERT although
2166 // I'm still not sure if it's correct
2167 dc
.SetLogicalFunction(wxAND_REVERSE
);
2170 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2171 dc
.DrawPoint(z
, rect
.GetTop());
2173 wxCoord shift
= z
== x2
? 0 : 1;
2174 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2175 dc
.DrawPoint(x2
, z
);
2177 shift
= z
== y2
? 0 : 1;
2178 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2179 dc
.DrawPoint(z
, y2
);
2181 shift
= z
== x1
? 0 : 1;
2182 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2183 dc
.DrawPoint(x1
, z
);
2185 dc
.SetLogicalFunction(wxCOPY
);
2189 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2190 const wxString
& label
,
2195 // draw shadow of the text
2196 dc
.SetTextForeground(m_colHighlight
);
2197 wxRect rectShadow
= rect
;
2200 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2202 // make the text grey
2203 dc
.SetTextForeground(m_colDarkGrey
);
2206 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2207 const wxString
& label
,
2214 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2217 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2218 const wxString
& label
,
2224 const wxPoint
& focusOffset
)
2226 // the underscores are not drawn for focused controls in wxMSW
2227 if ( flags
& wxCONTROL_FOCUSED
)
2232 if ( flags
& wxCONTROL_DISABLED
)
2234 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2235 // currently only can happen for a menu item and it seems that Windows
2236 // doesn't draw the shadow in this case, so we don't do it neither
2237 if ( flags
& wxCONTROL_SELECTED
)
2239 // just make the label text greyed out
2240 dc
.SetTextForeground(m_colDarkGrey
);
2242 else // draw normal disabled label
2244 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2249 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2251 if ( flags
& wxCONTROL_DISABLED
)
2253 // restore the fg colour
2254 dc
.SetTextForeground(*wxBLACK
);
2257 if ( flags
& wxCONTROL_FOCUSED
)
2259 if ( focusOffset
.x
|| focusOffset
.y
)
2261 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2264 DrawFocusRect(dc
, rectLabel
);
2268 *rectBounds
= rectLabel
;
2271 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2272 const wxString
& label
,
2273 const wxBitmap
& image
,
2280 // the underscores are not drawn for focused controls in wxMSW
2281 if ( flags
& wxCONTROL_PRESSED
)
2286 wxRect rectLabel
= rect
;
2287 if ( !label
.empty() )
2289 // shift the label if a button is pressed
2290 if ( flags
& wxCONTROL_PRESSED
)
2296 if ( flags
& wxCONTROL_DISABLED
)
2298 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2301 // leave enough space for the focus rectangle
2302 if ( flags
& wxCONTROL_FOCUSED
)
2304 rectLabel
.Inflate(-2);
2308 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2310 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2312 if ( flags
& wxCONTROL_PRESSED
)
2314 // the focus rectangle is never pressed, so undo the shift done
2322 DrawFocusRect(dc
, rectLabel
);
2326 // ----------------------------------------------------------------------------
2327 // (check)listbox items
2328 // ----------------------------------------------------------------------------
2330 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2331 const wxString
& label
,
2335 wxDCTextColourChanger
colChanger(dc
);
2337 if ( flags
& wxCONTROL_SELECTED
)
2339 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2341 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2342 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2343 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2344 dc
.DrawRectangle(rect
);
2347 wxRect rectText
= rect
;
2349 rectText
.width
-= 2;
2350 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2352 if ( flags
& wxCONTROL_FOCUSED
)
2354 DrawFocusRect(dc
, rect
);
2358 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2359 const wxString
& label
,
2360 const wxBitmap
& bitmap
,
2369 else // use default bitmap
2371 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2372 ? IndicatorStatus_Checked
2373 : IndicatorStatus_Unchecked
;
2375 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2377 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2380 bmp
= m_bmpCheckBitmaps
[i
];
2383 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2384 true /* use mask */);
2386 wxRect rectLabel
= rect
;
2387 int bmpWidth
= bmp
.GetWidth();
2388 rectLabel
.x
+= bmpWidth
;
2389 rectLabel
.width
-= bmpWidth
;
2391 DrawItem(dc
, label
, rectLabel
, flags
);
2394 // ----------------------------------------------------------------------------
2395 // check/radio buttons
2396 // ----------------------------------------------------------------------------
2398 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2400 IndicatorState indState
;
2401 if ( flags
& wxCONTROL_SELECTED
)
2402 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2403 : IndicatorState_Selected
;
2404 else if ( flags
& wxCONTROL_DISABLED
)
2405 indState
= IndicatorState_Disabled
;
2406 else if ( flags
& wxCONTROL_PRESSED
)
2407 indState
= IndicatorState_Pressed
;
2409 indState
= IndicatorState_Normal
;
2411 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2412 ? IndicatorStatus_Checked
2413 : ( flags
& wxCONTROL_UNDETERMINED
2414 ? IndicatorStatus_Undeterminated
2415 : IndicatorStatus_Unchecked
);
2417 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2420 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2423 // create and cache it
2424 bmp
= wxBitmap(xpm
);
2425 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2432 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2433 const wxString
& label
,
2434 const wxBitmap
& bitmap
,
2439 wxCoord focusOffsetY
)
2441 // calculate the position of the bitmap and of the label
2442 wxCoord heightBmp
= bitmap
.GetHeight();
2444 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2447 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2448 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2450 // align label vertically with the bitmap - looks nicer like this
2451 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2453 // calc horz position
2454 if ( align
== wxALIGN_RIGHT
)
2456 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2457 rectLabel
.x
= rect
.x
+ 3;
2458 rectLabel
.SetRight(xBmp
);
2460 else // normal (checkbox to the left of the text) case
2463 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2464 rectLabel
.SetRight(rect
.GetRight());
2467 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2470 dc
, label
, rectLabel
,
2472 wxALIGN_LEFT
| wxALIGN_TOP
,
2474 NULL
, // we don't need bounding rect
2475 // use custom vert focus rect offset
2476 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2480 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2481 const wxString
& label
,
2482 const wxBitmap
& bitmap
,
2492 bmp
= GetRadioBitmap(flags
);
2494 DrawCheckOrRadioButton(dc
, label
,
2496 rect
, flags
, align
, indexAccel
,
2497 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2500 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2501 const wxString
& label
,
2502 const wxBitmap
& bitmap
,
2512 bmp
= GetCheckBitmap(flags
);
2514 DrawCheckOrRadioButton(dc
, label
,
2516 rect
, flags
, align
, indexAccel
,
2517 0); // no focus rect offset for checkboxes
2521 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2522 const wxString
& label
,
2523 const wxBitmap
& bitmap
,
2524 const wxRect
& rectOrig
,
2529 if (style
== wxTOOL_STYLE_BUTTON
)
2531 wxRect rect
= rectOrig
;
2532 rect
.Deflate(BORDER_THICKNESS
);
2534 if ( flags
& wxCONTROL_PRESSED
)
2536 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2538 else if ( flags
& wxCONTROL_CURRENT
)
2540 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2543 if(tbarStyle
& wxTB_TEXT
)
2545 if(tbarStyle
& wxTB_HORIZONTAL
)
2547 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2551 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
2556 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
2557 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
2558 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
2561 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2563 // leave a small gap aroudn the line, also account for the toolbar
2565 if(rectOrig
.height
> rectOrig
.width
)
2568 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2569 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2570 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2575 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
2576 rectOrig
.x
+ 2*BORDER_THICKNESS
,
2577 rectOrig
.GetRight() - BORDER_THICKNESS
);
2580 // don't draw wxTOOL_STYLE_CONTROL
2582 #endif // wxUSE_TOOLBAR
2584 // ----------------------------------------------------------------------------
2586 // ----------------------------------------------------------------------------
2588 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2589 const wxString
& text
,
2595 // nothing special to do here
2596 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2600 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2601 const wxRect
& WXUNUSED(rect
))
2603 // we don't draw them
2606 // ----------------------------------------------------------------------------
2608 // ----------------------------------------------------------------------------
2610 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2611 const wxRect
& rectOrig
,
2613 const wxString
& label
,
2614 const wxBitmap
& bitmap
,
2618 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2619 #define REVERSE_FOR_VERTICAL(X,Y) \
2620 SELECT_FOR_VERTICAL(X,Y) \
2622 SELECT_FOR_VERTICAL(Y,X)
2624 wxRect rect
= rectOrig
;
2626 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2628 // the current tab is drawn indented (to the top for default case) and
2629 // bigger than the other ones
2630 const wxSize indent
= GetTabIndent();
2631 if ( flags
& wxCONTROL_SELECTED
)
2633 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
2634 SELECT_FOR_VERTICAL( 0, indent
.y
));
2638 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2645 rect
.height
+= indent
.y
;
2652 rect
.width
+= indent
.x
;
2657 // draw the text, image and the focus around them (if necessary)
2658 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2659 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2661 rectLabel
.Deflate(1, 1);
2664 // draw it horizontally into memory and rotate for screen
2666 wxBitmap bitmapRotated
,
2667 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2668 rectLabel
.y
+ rectLabel
.height
);
2669 dcMem
.SelectObject(bitmapMem
);
2670 dcMem
.SetBackground(dc
.GetBackground());
2671 dcMem
.SetFont(dc
.GetFont());
2672 dcMem
.SetTextForeground(dc
.GetTextForeground());
2676 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
2679 #endif // wxUSE_IMAGE
2681 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2682 flags
, wxALIGN_CENTRE
, indexAccel
);
2683 dcMem
.SelectObject(wxNullBitmap
);
2684 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2686 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2687 #endif // wxUSE_IMAGE
2688 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2692 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2693 flags
, wxALIGN_CENTRE
, indexAccel
);
2696 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2697 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2698 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2699 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2700 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2701 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2703 // FIXME: all this code will break if the tab indent or the border width,
2704 // it is tied to the fact that both of them are equal to 2
2710 // left orientation looks like top but IsVertical makes x and y reversed
2712 // top is not vertical so use coordinates in written order
2713 dc
.SetPen(m_penHighlight
);
2714 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2715 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2716 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2717 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2718 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2719 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2721 dc
.SetPen(m_penBlack
);
2722 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2723 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2724 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2725 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2727 dc
.SetPen(m_penDarkGrey
);
2728 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2729 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2731 if ( flags
& wxCONTROL_SELECTED
)
2733 dc
.SetPen(m_penLightGrey
);
2735 // overwrite the part of the border below this tab
2736 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2737 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2739 // and the shadow of the tab to the left of us
2740 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2741 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2746 // right orientation looks like bottom but IsVertical makes x and y reversed
2748 // bottom is not vertical so use coordinates in written order
2749 dc
.SetPen(m_penHighlight
);
2750 // we need to continue one pixel further to overwrite the corner of
2751 // the border for the selected tab
2752 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
2753 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2754 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2755 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2757 dc
.SetPen(m_penBlack
);
2758 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2759 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2760 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2761 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2762 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2763 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2765 dc
.SetPen(m_penDarkGrey
);
2766 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2767 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2768 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2769 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2771 if ( flags
& wxCONTROL_SELECTED
)
2773 dc
.SetPen(m_penLightGrey
);
2775 // overwrite the part of the (double!) border above this tab
2776 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2777 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2778 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2779 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2781 // and the shadow of the tab to the left of us
2782 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2783 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2788 #undef SELECT_FOR_VERTICAL
2789 #undef REVERSE_FOR_VERTICAL
2794 // ----------------------------------------------------------------------------
2796 // ----------------------------------------------------------------------------
2799 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2801 wxOrientation orient
) const
2804 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2805 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2807 if (orient
== wxHORIZONTAL
)
2821 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2823 wxOrientation orient
,
2826 bool transpose
= (orient
== wxVERTICAL
);
2827 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2828 (((style
& wxSL_TOP
) != 0) & !transpose
|
2829 ((style
& wxSL_LEFT
) != 0) & transpose
|
2830 ((style
& wxSL_BOTH
) != 0));
2831 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2832 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2833 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2834 ((style
& wxSL_BOTH
) != 0));
2836 wxRect rect
= rectOrig
;
2838 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2840 if (orient
== wxHORIZONTAL
) {
2841 rect
.x
+= SLIDER_MARGIN
;
2844 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2848 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2852 rect
.y
+= sizeThumb
.y
/2;
2854 rect
.width
-= 2*SLIDER_MARGIN
;
2855 rect
.height
= 2*BORDER_THICKNESS
;
2859 rect
.y
+= SLIDER_MARGIN
;
2862 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2866 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2870 rect
.x
+= sizeThumb
.x
/2;
2872 rect
.width
= 2*BORDER_THICKNESS
;
2873 rect
.height
-= 2*SLIDER_MARGIN
;
2879 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2880 const wxRect
& rectOrig
,
2882 wxOrientation orient
,
2887 /* show shaft geometry
2905 if (flags
& wxCONTROL_FOCUSED
) {
2906 DrawFocusRect(dc
, rectOrig
);
2909 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2911 if (rectShaft
) *rectShaft
= rect
;
2913 DrawSunkenBorder(dc
, &rect
);
2916 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2918 wxOrientation orient
,
2922 /* show thumb geometry
2931 H D B where H is highlight colour
2945 The interior of this shape is filled with the hatched brush if the thumb
2949 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2951 bool transpose
= (orient
== wxVERTICAL
);
2952 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2953 (((style
& wxSL_TOP
) != 0) & !transpose
|
2954 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2955 ((style
& wxSL_BOTH
) == 0);
2956 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2957 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2958 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2959 ((style
& wxSL_BOTH
) == 0);
2961 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2962 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2964 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2965 x1
= (transpose
? rect
.y
: rect
.x
);
2966 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2967 x3
= (x1
-1+c
) + sizeArrow
;
2968 y1
= (transpose
? rect
.x
: rect
.y
);
2969 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2970 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2971 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2973 dc
.SetPen(m_penBlack
);
2975 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2977 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2980 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2984 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2987 dc
.SetPen(m_penDarkGrey
);
2988 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2990 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2994 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2997 dc
.SetPen(m_penHighlight
);
3000 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
3001 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
3005 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
3007 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
3010 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
3013 if (flags
& wxCONTROL_PRESSED
) {
3014 // TODO: MSW fills the entire area inside, not just the rect
3015 wxRect rectInt
= rect
;
3018 rectInt
.SetLeft(y3
);
3019 rectInt
.SetRight(y4
);
3024 rectInt
.SetBottom(y4
);
3028 #if !defined(__WXMGL__)
3029 static const char *stipple_xpm
[] = {
3030 /* columns rows colors chars-per-pixel */
3039 // VS: MGL can only do 8x8 stipple brushes
3040 static const char *stipple_xpm
[] = {
3041 /* columns rows colors chars-per-pixel */
3056 dc
.SetBrush(wxBrush(stipple_xpm
));
3058 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
3059 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
3060 dc
.SetPen(*wxTRANSPARENT_PEN
);
3061 dc
.DrawRectangle(rectInt
);
3065 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
3068 wxOrientation orient
,
3072 int WXUNUSED(flags
),
3075 /* show ticks geometry
3090 if (end
== start
) return;
3092 bool transpose
= (orient
== wxVERTICAL
);
3093 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
3094 (((style
& wxSL_TOP
) != 0) & !transpose
|
3095 ((style
& wxSL_LEFT
) != 0) & transpose
|
3096 ((style
& wxSL_BOTH
) != 0));
3097 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
3098 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
3099 ((style
& wxSL_RIGHT
) != 0) & transpose
|
3100 ((style
& wxSL_BOTH
) != 0));
3102 // default thumb size
3103 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
3104 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
3106 // normal thumb size
3107 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
3108 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
3110 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
3112 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
3113 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
3114 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
3115 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
3116 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
3117 y3
= (transpose
? rect
.x
: rect
.y
);
3118 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
3121 dc
.SetPen(m_penBlack
);
3123 int range
= end
- start
;
3124 for ( int n
= 0; n
< range
; n
+= step
) {
3125 wxCoord x
= x1
+ (len
*n
) / range
;
3127 if (left
& (y1
> y3
)) {
3128 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
3130 if (right
& (y4
> y2
)) {
3131 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
3134 // always draw the line at the end position
3135 if (left
& (y1
> y3
)) {
3136 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3138 if (right
& (y4
> y2
)) {
3139 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3143 #endif // wxUSE_SLIDER
3147 // ----------------------------------------------------------------------------
3149 // ----------------------------------------------------------------------------
3151 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3152 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3155 virtual wxSize
GetSize() const { return m_size
; }
3157 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3158 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3160 wxCoord
GetItemHeight() const { return m_heightItem
; }
3163 // the total size of the menu
3166 // the offset of the start of the menu item label
3169 // the offset of the start of the accel label
3172 // the height of a normal (not separator) item
3173 wxCoord m_heightItem
;
3175 friend wxMenuGeometryInfo
*
3176 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3179 // FIXME: all constants are hardcoded but shouldn't be
3180 static const wxCoord MENU_LEFT_MARGIN
= 9;
3181 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3182 static const wxCoord MENU_VERT_MARGIN
= 3;
3184 // the margin around bitmap/check marks (on each side)
3185 static const wxCoord MENU_BMP_MARGIN
= 2;
3187 // the margin between the labels and accel strings
3188 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3190 // the separator height in pixels: in fact, strangely enough, the real height
3191 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3193 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3195 // the size of the standard checkmark bitmap
3196 static const wxCoord MENU_CHECK_SIZE
= 9;
3198 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3199 const wxRect
& rectOrig
,
3200 const wxString
& label
,
3204 wxRect rect
= rectOrig
;
3207 wxDCTextColourChanger
colChanger(dc
);
3209 if ( flags
& wxCONTROL_SELECTED
)
3211 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3213 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3214 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3215 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3216 dc
.DrawRectangle(rect
);
3219 // don't draw the focus rect around menu bar items
3220 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3221 wxALIGN_CENTRE
, indexAccel
);
3224 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3226 const wxMenuGeometryInfo
& gi
,
3227 const wxString
& label
,
3228 const wxString
& accel
,
3229 const wxBitmap
& bitmap
,
3233 const wxWin32MenuGeometryInfo
& geometryInfo
=
3234 (const wxWin32MenuGeometryInfo
&)gi
;
3239 rect
.width
= geometryInfo
.GetSize().x
;
3240 rect
.height
= geometryInfo
.GetItemHeight();
3242 // draw the selected item specially
3243 wxDCTextColourChanger
colChanger(dc
);
3244 if ( flags
& wxCONTROL_SELECTED
)
3246 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3248 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3249 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3250 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3251 dc
.DrawRectangle(rect
);
3254 // draw the bitmap: use the bitmap provided or the standard checkmark for
3255 // the checkable items
3256 wxBitmap bmp
= bitmap
;
3257 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3259 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3264 rect
.SetRight(geometryInfo
.GetLabelOffset());
3265 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3269 rect
.x
= geometryInfo
.GetLabelOffset();
3270 rect
.SetRight(geometryInfo
.GetAccelOffset());
3272 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3274 // draw the accel string
3275 rect
.x
= geometryInfo
.GetAccelOffset();
3276 rect
.SetRight(geometryInfo
.GetSize().x
);
3278 // NB: no accel index here
3279 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3281 // draw the submenu indicator
3282 if ( flags
& wxCONTROL_ISSUBMENU
)
3284 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3285 rect
.width
= MENU_RIGHT_MARGIN
;
3287 wxArrowStyle arrowStyle
;
3288 if ( flags
& wxCONTROL_DISABLED
)
3289 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
3291 else if ( flags
& wxCONTROL_SELECTED
)
3292 arrowStyle
= Arrow_Inverted
;
3294 arrowStyle
= Arrow_Normal
;
3296 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3300 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3302 const wxMenuGeometryInfo
& geomInfo
)
3304 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3307 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3309 wxSize size
= sizeText
;
3311 // FIXME: menubar height is configurable under Windows
3318 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3319 const wxMenu
& menu
) const
3321 // prepare the dc: for now we draw all the items with the system font
3323 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3325 // the height of a normal item
3326 wxCoord heightText
= dc
.GetCharHeight();
3331 // the max length of label and accel strings: the menu width is the sum of
3332 // them, even if they're for different items (as the accels should be
3335 // the max length of the bitmap is never 0 as Windows always leaves enough
3336 // space for a check mark indicator
3337 wxCoord widthLabelMax
= 0,
3339 widthBmpMax
= MENU_LEFT_MARGIN
;
3341 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3343 node
= node
->GetNext() )
3345 // height of this item
3348 wxMenuItem
*item
= node
->GetData();
3349 if ( item
->IsSeparator() )
3351 h
= MENU_SEPARATOR_HEIGHT
;
3353 else // not separator
3358 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3359 if ( widthLabel
> widthLabelMax
)
3361 widthLabelMax
= widthLabel
;
3365 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3366 if ( widthAccel
> widthAccelMax
)
3368 widthAccelMax
= widthAccel
;
3371 const wxBitmap
& bmp
= item
->GetBitmap();
3374 wxCoord widthBmp
= bmp
.GetWidth();
3375 if ( widthBmp
> widthBmpMax
)
3376 widthBmpMax
= widthBmp
;
3378 //else if ( item->IsCheckable() ): no need to check for this as
3379 // MENU_LEFT_MARGIN is big enough to show the check mark
3382 h
+= 2*MENU_VERT_MARGIN
;
3384 // remember the item position and height
3385 item
->SetGeometry(height
, h
);
3390 // bundle the metrics into a struct and return it
3391 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3393 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3394 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3395 if ( widthAccelMax
> 0 )
3397 // if we actually have any accesl, add a margin
3398 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3401 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3403 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3404 gi
->m_size
.y
= height
;
3409 #endif // wxUSE_MENUS
3413 // ----------------------------------------------------------------------------
3415 // ----------------------------------------------------------------------------
3417 static const wxCoord STATBAR_BORDER_X
= 2;
3418 static const wxCoord STATBAR_BORDER_Y
= 2;
3420 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3422 if ( borderBetweenFields
)
3423 *borderBetweenFields
= 2;
3425 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3428 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3430 const wxString
& label
,
3431 int flags
, int style
/*=0*/)
3435 if ( flags
& wxCONTROL_ISDEFAULT
)
3437 // draw the size grip: it is a normal rect except that in the lower
3438 // right corner we have several bands which may be used for dragging
3439 // the status bar corner
3441 // each band consists of 4 stripes: m_penHighlight, double
3442 // m_penDarkGrey and transparent one
3443 wxCoord x2
= rect
.GetRight(),
3444 y2
= rect
.GetBottom();
3446 // draw the upper left part of the rect normally
3447 if (style
!= wxSB_FLAT
)
3449 if (style
== wxSB_RAISED
)
3450 dc
.SetPen(m_penHighlight
);
3452 dc
.SetPen(m_penDarkGrey
);
3453 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3454 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3457 // draw the grey stripes of the grip
3459 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3460 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3462 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3463 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3466 // draw the white stripes
3467 dc
.SetPen(m_penHighlight
);
3468 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3469 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3471 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3474 // draw the remaining rect boundaries
3475 if (style
!= wxSB_FLAT
)
3477 if (style
== wxSB_RAISED
)
3478 dc
.SetPen(m_penDarkGrey
);
3480 dc
.SetPen(m_penHighlight
);
3481 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3482 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3483 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3489 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3493 if (style
== wxSB_RAISED
)
3494 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3495 else if (style
!= wxSB_FLAT
)
3496 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3499 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3501 wxDCClipper
clipper(dc
, rectIn
);
3502 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3505 #endif // wxUSE_STATUSBAR
3507 // ----------------------------------------------------------------------------
3509 // ----------------------------------------------------------------------------
3511 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3512 wxBitmap
* WXUNUSED(bmpFocus
),
3513 wxBitmap
*bmpPressed
,
3514 wxBitmap
*bmpDisabled
)
3516 static const wxCoord widthCombo
= 16;
3517 static const wxCoord heightCombo
= 17;
3523 bmpNormal
->Create(widthCombo
, heightCombo
);
3524 dcMem
.SelectObject(*bmpNormal
);
3525 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3526 Arrow_Down
, Arrow_Normal
);
3531 bmpPressed
->Create(widthCombo
, heightCombo
);
3532 dcMem
.SelectObject(*bmpPressed
);
3533 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3534 Arrow_Down
, Arrow_Pressed
);
3539 bmpDisabled
->Create(widthCombo
, heightCombo
);
3540 dcMem
.SelectObject(*bmpDisabled
);
3541 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3542 Arrow_Down
, Arrow_Disabled
);
3546 // ----------------------------------------------------------------------------
3548 // ----------------------------------------------------------------------------
3550 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3551 const wxColour
& col
,
3553 wxWindow
* WXUNUSED(window
))
3555 wxBrush
brush(col
, wxSOLID
);
3557 dc
.SetPen(*wxTRANSPARENT_PEN
);
3558 dc
.DrawRectangle(rect
);
3561 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3562 const wxColour
& col
,
3564 int WXUNUSED(flags
),
3567 // just fill it with the given or default bg colour
3568 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3569 DoDrawBackground(dc
, colBg
, rect
, window
);
3572 // ----------------------------------------------------------------------------
3574 // ----------------------------------------------------------------------------
3576 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3581 // get the bitmap for this arrow
3582 wxArrowDirection arrowDir
;
3585 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3586 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3587 case wxUP
: arrowDir
= Arrow_Up
; break;
3588 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3591 wxFAIL_MSG(_T("unknown arrow direction"));
3595 wxArrowStyle arrowStyle
;
3596 if ( flags
& wxCONTROL_PRESSED
)
3598 // can't be pressed and disabled
3599 arrowStyle
= Arrow_Pressed
;
3603 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3606 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3609 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3611 wxArrowDirection arrowDir
,
3612 wxArrowStyle arrowStyle
)
3614 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3616 // under Windows the arrows always have the same size so just centre it in
3617 // the provided rectangle
3618 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3619 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3621 // Windows does it like this...
3622 if ( arrowDir
== Arrow_Left
)
3626 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3629 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3630 const wxRect
& rectAll
,
3631 wxArrowDirection arrowDir
,
3632 wxArrowStyle arrowStyle
)
3634 wxRect rect
= rectAll
;
3635 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3636 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3637 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3640 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3641 wxOrientation
WXUNUSED(orient
),
3643 int WXUNUSED(flags
))
3645 // we don't use the flags, the thumb never changes appearance
3646 wxRect rectThumb
= rect
;
3647 DrawArrowBorder(dc
, &rectThumb
);
3648 DrawBackground(dc
, wxNullColour
, rectThumb
);
3651 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3652 wxOrientation
WXUNUSED(orient
),
3653 const wxRect
& rectBar
,
3656 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3657 ? wxColourScheme::SCROLLBAR_PRESSED
3658 : wxColourScheme::SCROLLBAR
;
3659 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3662 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3664 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3669 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3670 wxScrollBar::Element elem
,
3673 return StandardGetScrollbarRect(scrollbar
, elem
,
3674 thumbPos
, m_sizeScrollbarArrow
);
3677 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3679 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3682 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3683 const wxPoint
& pt
) const
3685 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3688 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3691 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3694 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3697 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3700 #endif // wxUSE_SCROLLBAR
3702 // ----------------------------------------------------------------------------
3703 // top level windows
3704 // ----------------------------------------------------------------------------
3706 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3708 wxRect client
= GetFrameClientArea(rect
, flags
);
3710 if ( client
.Inside(pt
) )
3711 return wxHT_TOPLEVEL_CLIENT_AREA
;
3713 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3715 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3717 if ( flags
& wxTOPLEVEL_ICON
)
3719 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3720 return wxHT_TOPLEVEL_ICON
;
3723 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3724 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3725 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3727 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3729 if ( btnRect
.Inside(pt
) )
3730 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3731 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3733 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3735 if ( btnRect
.Inside(pt
) )
3736 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3737 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3739 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3741 if ( btnRect
.Inside(pt
) )
3742 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3743 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3745 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3747 if ( btnRect
.Inside(pt
) )
3748 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3749 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3751 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3753 if ( btnRect
.Inside(pt
) )
3754 return wxHT_TOPLEVEL_BUTTON_HELP
;
3755 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3758 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3759 return wxHT_TOPLEVEL_TITLEBAR
;
3762 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3764 // we are certainly at one of borders, lets decide which one:
3767 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3768 if ( pt
.x
< client
.x
)
3769 border
|= wxHT_TOPLEVEL_BORDER_W
;
3770 else if ( pt
.x
>= client
.width
+ client
.x
)
3771 border
|= wxHT_TOPLEVEL_BORDER_E
;
3772 if ( pt
.y
< client
.y
)
3773 border
|= wxHT_TOPLEVEL_BORDER_N
;
3774 else if ( pt
.y
>= client
.height
+ client
.y
)
3775 border
|= wxHT_TOPLEVEL_BORDER_S
;
3779 return wxHT_NOWHERE
;
3782 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3784 const wxString
& title
,
3788 int specialButtonFlags
)
3790 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3792 DrawFrameBorder(dc
, rect
, flags
);
3794 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3796 DrawFrameBackground(dc
, rect
, flags
);
3797 if ( flags
& wxTOPLEVEL_ICON
)
3798 DrawFrameIcon(dc
, rect
, icon
, flags
);
3799 DrawFrameTitle(dc
, rect
, title
, flags
);
3801 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3803 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3804 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3806 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3808 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3809 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3810 specialButtonFlags
: 0);
3811 x
-= FRAME_BUTTON_WIDTH
+ 2;
3813 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3815 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3816 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3817 specialButtonFlags
: 0);
3818 x
-= FRAME_BUTTON_WIDTH
;
3820 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3822 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3823 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3824 specialButtonFlags
: 0);
3825 x
-= FRAME_BUTTON_WIDTH
;
3827 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3829 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3830 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3831 specialButtonFlags
: 0);
3832 x
-= FRAME_BUTTON_WIDTH
;
3834 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3836 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3837 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3838 specialButtonFlags
: 0);
3843 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3847 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3851 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3852 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3853 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3854 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3855 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3858 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3862 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3864 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3865 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3866 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3868 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3869 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3871 DrawBackground(dc
, col
, r
);
3874 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3876 const wxString
& title
,
3879 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3880 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3881 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3883 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3884 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3885 if ( flags
& wxTOPLEVEL_ICON
)
3887 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3888 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3896 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3897 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3898 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3899 r
.width
-= FRAME_BUTTON_WIDTH
;
3900 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3901 r
.width
-= FRAME_BUTTON_WIDTH
;
3902 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3903 r
.width
-= FRAME_BUTTON_WIDTH
;
3904 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3905 r
.width
-= FRAME_BUTTON_WIDTH
;
3907 dc
.SetFont(m_titlebarFont
);
3908 dc
.SetTextForeground(col
);
3911 dc
.GetTextExtent(title
, &textW
, NULL
);
3912 if ( textW
> r
.width
)
3914 // text is too big, let's shorten it and add "..." after it:
3915 size_t len
= title
.length();
3916 wxCoord WSoFar
, letterW
;
3918 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3919 if ( WSoFar
> r
.width
)
3921 // not enough space to draw anything
3927 for (size_t i
= 0; i
< len
; i
++)
3929 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3930 if ( letterW
+ WSoFar
> r
.width
)
3936 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3937 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3940 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3941 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3944 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3951 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3952 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3956 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3957 wxCoord x
, wxCoord y
,
3961 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3966 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3967 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3968 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3969 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3970 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3972 wxFAIL_MSG(wxT("incorrect button specification"));
3975 if ( flags
& wxCONTROL_PRESSED
)
3977 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3978 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3979 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3980 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3984 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3985 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3986 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3987 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3992 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3997 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3999 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
4000 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4001 FRAME_BORDER_THICKNESS
;
4004 if ( flags
& wxTOPLEVEL_TITLEBAR
)
4006 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
4007 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
4013 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
4016 wxSize
s(clientSize
);
4018 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
4020 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
4021 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4022 FRAME_BORDER_THICKNESS
;
4026 if ( flags
& wxTOPLEVEL_TITLEBAR
)
4027 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
4032 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
4036 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
4038 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
4039 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4040 FRAME_BORDER_THICKNESS
;
4045 if ( flags
& wxTOPLEVEL_TITLEBAR
)
4047 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
4049 if ( flags
& wxTOPLEVEL_ICON
)
4050 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
4051 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
4052 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
4053 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
4054 s
.x
+= FRAME_BUTTON_WIDTH
;
4055 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
4056 s
.x
+= FRAME_BUTTON_WIDTH
;
4057 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
4058 s
.x
+= FRAME_BUTTON_WIDTH
;
4059 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
4060 s
.x
+= FRAME_BUTTON_WIDTH
;
4066 wxSize
wxWin32Renderer::GetFrameIconSize() const
4068 return wxSize(16, 16);
4072 // ----------------------------------------------------------------------------
4074 // ----------------------------------------------------------------------------
4076 /* Copyright (c) Julian Smart */
4077 static char *error_xpm
[]={
4078 /* columns rows colors chars-per-pixel */
4155 " $oooooooooooo%& ",
4156 " *=-ooooooooooooo;: ",
4157 " *oooooooooooooooooo> ",
4158 " =ooooooooooooooooooo, ",
4159 " $-ooooooooooooooooooo<1 ",
4160 " .oooooo2334ooo533oooooo6 ",
4161 " +ooooooo789oo2883oooooo0q ",
4162 " oooooooo2w83o78eoooooooor ",
4163 " toooooooooy88u884oooooooori ",
4164 " Xooooooooooe888poooooooooas ",
4165 " ooooooooooo4889doooooooooof ",
4166 " ooooooooooo588w2oooooooooofi ",
4167 " oooooooooodw8887oooooooooofi ",
4168 " goooooooooh8w588jooooooookli ",
4169 " tooooooooz885op8wdooooooorix ",
4170 " oooooood98cood98cooooooori ",
4171 " @oooooop8w2ooo5885ooooovbi ",
4172 " n%ooooooooooooooooooooomiM ",
4173 " &;oooooooooooooooooooNBiV ",
4174 " :ooooooooooooooooooCZiA ",
4175 " nSooooooooooooooooCDiF ",
4176 " nG<oooooooooooooNZiiH ",
4177 " 160ooooooooovmBiFH ",
4178 " nqrraoookrrbiiA ",
4185 /* Copyright (c) Julian Smart */
4186 static char *info_xpm
[]={
4187 /* columns rows colors chars-per-pixel */
4209 " ..XXXXXXXXXXXXX.. ",
4210 " .XXXXXXXXXXXXXXXXX. ",
4211 " .XXXXXXXXoO+XXXXXXXX. ",
4212 " .XXXXXXXXX@#OXXXXXXXXX. ",
4213 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
4214 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
4215 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
4216 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
4217 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
4218 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
4219 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4220 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4221 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
4222 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
4223 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
4224 " .XXXXXXXXXXXXXXXXX.%%%% ",
4225 " ..XXXXXXXXXXXXX..%%%% ",
4226 " %...XXXXXXXX..%%%%% ",
4227 " %%%..XXXXXX.%%%%% ",
4241 /* Copyright (c) Julian Smart */
4242 static char *question_xpm
[]={
4243 /* columns rows colors chars-per-pixel */
4264 " ..XXXXXXXXXXXXX.. ",
4265 " .XXXXXXoO++@XXXXXX. ",
4266 " .XXXXXXO#$$$$#%XXXXX. ",
4267 " .XXXXXX@$$#&&#$#oXXXXX. ",
4268 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
4269 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
4270 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
4271 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
4272 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
4273 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
4274 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
4275 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
4276 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
4277 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
4278 " .XXXXXXXX-$$XXXXXXXX.:::: ",
4279 " .XXXXXXXO++XXXXXXX.:::: ",
4280 " ..XXXXXXXXXXXXX..:::: ",
4281 " :...XXXXXXXX..::::: ",
4282 " :::..XXXXXX.::::: ",
4296 /* Copyright (c) Julian Smart */
4297 static char *warning_xpm
[]={
4298 /* columns rows colors chars-per-pixel */
4324 " ..XXXXO@#XXX... ",
4325 " ...XXXXO@#XXXX.. ",
4326 " ..XXXXXO@#XXXX... ",
4327 " ...XXXXXo@OXXXXX.. ",
4328 " ...XXXXXXo@OXXXXXX.. ",
4329 " ..XXXXXXX$@OXXXXXX... ",
4330 " ...XXXXXXXX@XXXXXXXX.. ",
4331 " ...XXXXXXXXXXXXXXXXXX... ",
4332 " ..XXXXXXXXXXOXXXXXXXXX.. ",
4333 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
4334 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
4335 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
4336 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
4337 " .............................. ",
4338 " .............................. ",
4345 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4346 const wxArtClient
& WXUNUSED(client
),
4347 const wxSize
& WXUNUSED(size
))
4349 if ( id
== wxART_INFORMATION
)
4350 return wxBitmap(info_xpm
);
4351 if ( id
== wxART_ERROR
)
4352 return wxBitmap(error_xpm
);
4353 if ( id
== wxART_WARNING
)
4354 return wxBitmap(warning_xpm
);
4355 if ( id
== wxART_QUESTION
)
4356 return wxBitmap(question_xpm
);
4357 return wxNullBitmap
;
4363 // ----------------------------------------------------------------------------
4364 // text control geometry
4365 // ----------------------------------------------------------------------------
4367 static inline int GetTextBorderWidth()
4373 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4374 const wxRect
& rect
) const
4376 wxRect rectTotal
= rect
;
4378 wxCoord widthBorder
= GetTextBorderWidth();
4379 rectTotal
.Inflate(widthBorder
);
4381 // this is what Windows does
4388 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4390 wxCoord
*extraSpaceBeyond
) const
4392 wxRect rectText
= rect
;
4394 // undo GetTextTotalArea()
4395 if ( rectText
.height
> 0 )
4398 wxCoord widthBorder
= GetTextBorderWidth();
4399 rectText
.Inflate(-widthBorder
);
4401 if ( extraSpaceBeyond
)
4402 *extraSpaceBeyond
= 0;
4407 #endif // wxUSE_TEXTCTRL
4409 // ----------------------------------------------------------------------------
4411 // ----------------------------------------------------------------------------
4413 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4416 if ( wxDynamicCast(window
, wxScrollBar
) )
4418 // we only set the width of vert scrollbars and height of the
4420 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4421 size
->y
= m_sizeScrollbarArrow
.y
;
4423 size
->x
= m_sizeScrollbarArrow
.x
;
4425 // skip border width adjustments, they don't make sense for us
4428 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4431 if ( wxDynamicCast(window
, wxBitmapButton
) )
4435 #endif // wxUSE_BMPBUTTON
4436 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
4439 || wxDynamicCast(window
, wxButton
)
4440 # endif // wxUSE_BUTTON
4441 # if wxUSE_TOGGLEBTN
4442 || wxDynamicCast(window
, wxToggleButton
)
4443 # endif // wxUSE_TOGGLEBTN
4446 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4448 // TODO: don't harcode all this
4449 size
->x
+= 3*window
->GetCharWidth();
4451 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4452 if ( size
->y
< heightBtn
- 8 )
4453 size
->y
= heightBtn
;
4458 // for compatibility with other ports, the buttons default size is never
4459 // less than the standard one, but not when display not PDAs.
4460 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4462 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4464 wxSize szDef
= wxButton::GetDefaultSize();
4465 if ( size
->x
< szDef
.x
)
4470 // no border width adjustments for buttons
4473 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
4475 // take into account the border width
4476 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4477 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4478 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4481 // ============================================================================
4483 // ============================================================================
4485 // ----------------------------------------------------------------------------
4486 // wxWin32InputHandler
4487 // ----------------------------------------------------------------------------
4489 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4491 m_renderer
= renderer
;
4494 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4495 const wxKeyEvent
& WXUNUSED(event
),
4496 bool WXUNUSED(pressed
))
4501 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4502 const wxMouseEvent
& event
)
4504 // clicking on the control gives it focus
4505 if ( event
.ButtonDown() )
4507 wxWindow
*win
= control
->GetInputWindow();
4509 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4510 ( win
->AcceptsFocus() ) )
4523 // ----------------------------------------------------------------------------
4524 // wxWin32ScrollBarInputHandler
4525 // ----------------------------------------------------------------------------
4527 wxWin32ScrollBarInputHandler::
4528 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4529 wxInputHandler
*handler
)
4530 : wxStdScrollBarInputHandler(renderer
, handler
)
4532 m_scrollPaused
= false;
4536 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4537 const wxControlAction
& action
)
4539 // stop if went beyond the position of the original click (this can only
4540 // happen when we scroll by pages)
4542 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4544 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4545 != wxHT_SCROLLBAR_BAR_2
;
4547 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4549 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4550 != wxHT_SCROLLBAR_BAR_1
;
4555 StopScrolling(scrollbar
);
4557 scrollbar
->Refresh();
4562 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4565 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4566 const wxMouseEvent
& event
)
4568 // remember the current state
4569 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4571 // do process the message
4572 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4574 // analyse the changes
4575 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4577 // we just started dragging the thumb, remember its initial position to
4578 // be able to restore it if the drag is cancelled later
4579 m_eventStartDrag
= event
;
4585 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4586 const wxMouseEvent
& event
)
4588 // we don't highlight scrollbar elements, so there is no need to process
4589 // mouse move events normally - only do it while mouse is captured (i.e.
4590 // when we're dragging the thumb or pressing on something)
4591 if ( !m_winCapture
)
4594 if ( event
.Entering() )
4596 // we're not interested in this at all
4600 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4602 if ( m_scrollPaused
)
4604 // check if the mouse returned to its original location
4606 if ( event
.Leaving() )
4612 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4613 if ( ht
== m_htLast
)
4615 // yes it did, resume scrolling
4616 m_scrollPaused
= false;
4617 if ( m_timerScroll
)
4619 // we were scrolling by line/page, restart timer
4620 m_timerScroll
->Start(m_interval
);
4622 Press(scrollbar
, true);
4624 else // we were dragging the thumb
4626 // restore its last location
4627 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4633 else // normal case, scrolling hasn't been paused
4635 // if we're scrolling the scrollbar because the arrow or the shaft was
4636 // pressed, check that the mouse stays on the same scrollbar element
4639 // Always let thumb jump back if we leave the scrollbar
4640 if ( event
.Moving() )
4642 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4644 else // event.Leaving()
4649 // Jump back only if we get far away from it
4650 wxPoint pos
= event
.GetPosition();
4651 if (scrollbar
->HasFlag( wxVERTICAL
))
4653 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4658 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4661 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4664 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4665 // is still ok - we only want to catch the case when the mouse leaves
4666 // the scrollbar here
4667 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4669 ht
= wxHT_SCROLLBAR_THUMB
;
4672 if ( ht
!= m_htLast
)
4674 // what were we doing? 2 possibilities: either an arrow/shaft was
4675 // pressed in which case we have a timer and so we just stop it or
4676 // we were dragging the thumb
4677 if ( m_timerScroll
)
4680 m_interval
= m_timerScroll
->GetInterval();
4681 m_timerScroll
->Stop();
4682 m_scrollPaused
= true;
4684 // unpress the arrow
4685 Press(scrollbar
, false);
4687 else // we were dragging the thumb
4689 // remember the current thumb position to be able to restore it
4690 // if the mouse returns to it later
4691 m_eventLastDrag
= event
;
4693 // and restore the original position (before dragging) of the
4695 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4702 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4705 #endif // wxUSE_SCROLLBAR
4709 // ----------------------------------------------------------------------------
4710 // wxWin32CheckboxInputHandler
4711 // ----------------------------------------------------------------------------
4713 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4714 const wxKeyEvent
& event
,
4719 wxControlAction action
;
4720 int keycode
= event
.GetKeyCode();
4724 action
= wxACTION_CHECKBOX_TOGGLE
;
4728 case WXK_NUMPAD_SUBTRACT
:
4729 action
= wxACTION_CHECKBOX_CHECK
;
4733 case WXK_NUMPAD_ADD
:
4734 case WXK_NUMPAD_EQUAL
:
4735 action
= wxACTION_CHECKBOX_CLEAR
;
4739 if ( !action
.IsEmpty() )
4741 control
->PerformAction(action
);
4750 #endif // wxUSE_CHECKBOX
4754 // ----------------------------------------------------------------------------
4755 // wxWin32TextCtrlInputHandler
4756 // ----------------------------------------------------------------------------
4758 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4759 const wxKeyEvent
& event
,
4762 // handle only MSW-specific text bindings here, the others are handled in
4766 int keycode
= event
.GetKeyCode();
4768 wxControlAction action
;
4769 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4771 action
= wxACTION_TEXT_CUT
;
4773 else if ( keycode
== WXK_INSERT
)
4775 if ( event
.ControlDown() )
4776 action
= wxACTION_TEXT_COPY
;
4777 else if ( event
.ShiftDown() )
4778 action
= wxACTION_TEXT_PASTE
;
4781 if ( action
!= wxACTION_NONE
)
4783 control
->PerformAction(action
);
4789 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4792 #endif // wxUSE_TEXTCTRL
4796 // ----------------------------------------------------------------------------
4797 // wxWin32StatusBarInputHandler
4798 // ----------------------------------------------------------------------------
4800 wxWin32StatusBarInputHandler::
4801 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4802 : wxStdInputHandler(handler
)
4807 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4808 const wxPoint
& pt
) const
4810 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4811 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4814 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4816 wxCHECK_MSG( parentTLW
, false,
4817 _T("the status bar should be a child of a TLW") );
4819 // a maximized window can't be resized anyhow
4820 if ( !parentTLW
->IsMaximized() )
4822 // VZ: I think that the standard Windows behaviour is to only
4823 // show the resizing cursor when the mouse is on top of the
4824 // grip itself but apparently different Windows versions behave
4825 // differently (?) and it seems a better UI to allow resizing
4826 // the status bar even when the mouse is above the grip
4827 wxSize sizeSbar
= statbar
->GetSize();
4829 int diff
= sizeSbar
.x
- pt
.x
;
4830 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4837 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4838 const wxMouseEvent
& event
)
4840 if ( event
.Button(1) )
4842 if ( event
.ButtonDown(1) )
4844 wxWindow
*statbar
= consumer
->GetInputWindow();
4846 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4848 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4852 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4853 wxHT_TOPLEVEL_BORDER_SE
);
4855 statbar
->SetCursor(m_cursorOld
);
4863 return wxStdInputHandler::HandleMouse(consumer
, event
);
4866 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4867 const wxMouseEvent
& event
)
4869 wxWindow
*statbar
= consumer
->GetInputWindow();
4871 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4872 if ( isOnGrip
!= m_isOnGrip
)
4874 m_isOnGrip
= isOnGrip
;
4877 m_cursorOld
= statbar
->GetCursor();
4878 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4882 statbar
->SetCursor(m_cursorOld
);
4886 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4889 #endif // wxUSE_STATUSBAR
4891 // ----------------------------------------------------------------------------
4892 // wxWin32FrameInputHandler
4893 // ----------------------------------------------------------------------------
4895 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4898 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4900 void Attach(wxInputConsumer
*consumer
);
4904 DECLARE_EVENT_TABLE()
4905 void OnSystemMenu(wxCommandEvent
&event
);
4906 void OnCloseFrame(wxCommandEvent
&event
);
4907 void OnClose(wxCloseEvent
&event
);
4909 wxWin32FrameInputHandler
*m_inputHnd
;
4910 wxTopLevelWindow
*m_wnd
;
4912 wxAcceleratorTable m_oldAccelTable
;
4916 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4917 wxWin32FrameInputHandler
*handler
)
4919 m_inputHnd
= handler
;
4923 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4925 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4927 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4928 m_wnd
->PushEventHandler(this);
4931 // VS: This code relies on using generic implementation of
4932 // wxAcceleratorTable in wxUniv!
4933 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4934 m_oldAccelTable
= table
;
4935 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4936 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4937 m_wnd
->SetAcceleratorTable(table
);
4941 void wxWin32SystemMenuEvtHandler::Detach()
4946 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4948 m_wnd
->RemoveEventHandler(this);
4953 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4954 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4955 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4956 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4959 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4961 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4962 !m_wnd
->IsMaximized()) ?
4963 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4964 FRAME_BORDER_THICKNESS
;
4965 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4966 pt
.x
= -pt
.x
+ border
;
4967 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4970 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4971 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4975 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4976 #endif // wxUSE_MENUS
4979 m_wnd
->SetAcceleratorTable(table
);
4983 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4985 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4986 wxTOPLEVEL_BUTTON_CLOSE
);
4989 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4996 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4997 : wxStdFrameInputHandler(handler
)
4999 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
5002 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
5004 if ( m_menuHandler
)
5006 m_menuHandler
->Detach();
5007 delete m_menuHandler
;
5011 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
5012 const wxMouseEvent
& event
)
5014 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
5016 wxTopLevelWindow
*tlw
=
5017 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
5019 long hit
= tlw
->HitTest(event
.GetPosition());
5021 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
5023 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
5024 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
5025 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
5028 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
5030 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
5031 (event
.RightDown() &&
5032 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
5033 hit
== wxHT_TOPLEVEL_ICON
)) )
5036 PopupSystemMenu(tlw
, event
.GetPosition());
5037 #endif // wxUSE_MENUS
5043 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
5048 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
5049 const wxPoint
& pos
) const
5051 wxMenu
*menu
= new wxMenu
;
5053 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
5054 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
5055 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
5056 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
5057 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
5058 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
5059 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
5060 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
5061 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
5062 menu
->AppendSeparator();
5063 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
5065 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
5067 if ( window
->IsMaximized() )
5069 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
5070 menu
->Enable(wxID_MOVE_FRAME
, false);
5071 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
5072 menu
->Enable(wxID_RESIZE_FRAME
, false);
5075 menu
->Enable(wxID_RESTORE_FRAME
, false);
5078 window
->PopupMenu(menu
, pos
);
5082 #endif // wxUSE_MENUS
5084 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
5087 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
5089 // always detach if active frame changed:
5090 m_menuHandler
->Detach();
5094 m_menuHandler
->Attach(consumer
);
5098 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);