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"
27 #include "wx/univ/theme.h"
35 #include "wx/window.h"
37 #include "wx/dcmemory.h"
38 #include "wx/dcclient.h"
40 #include "wx/button.h"
41 #include "wx/bmpbuttn.h"
42 #include "wx/listbox.h"
43 #include "wx/checklst.h"
44 #include "wx/combobox.h"
45 #include "wx/scrolbar.h"
46 #include "wx/slider.h"
47 #include "wx/textctrl.h"
48 #include "wx/toolbar.h"
49 #include "wx/statusbr.h"
52 // for COLOR_* constants
53 #include "wx/msw/private.h"
56 #include "wx/settings.h"
57 #include "wx/toplevel.h"
61 #include "wx/notebook.h"
62 #include "wx/spinbutt.h"
63 #include "wx/artprov.h"
64 #ifdef wxUSE_TOGGLEBTN
65 #include "wx/tglbtn.h"
66 #endif // wxUSE_TOGGLEBTN
68 #include "wx/univ/scrtimer.h"
69 #include "wx/univ/stdrend.h"
70 #include "wx/univ/inpcons.h"
71 #include "wx/univ/inphand.h"
72 #include "wx/univ/colschem.h"
74 // ----------------------------------------------------------------------------
76 // ----------------------------------------------------------------------------
78 static const int BORDER_THICKNESS
= 2;
80 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
81 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
82 static const size_t STATUSBAR_GRIP_SIZE
=
83 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
85 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
86 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
87 static const wxCoord SLIDER_TICK_LENGTH
= 6;
89 // wxWin32Renderer: draw the GUI elements in Win32 style
90 // ----------------------------------------------------------------------------
92 class wxWin32Renderer
: public wxStdRenderer
96 wxWin32Renderer(const wxColourScheme
*scheme
);
98 // reimplement the renderer methods which are different for this theme
99 virtual void DrawLabel(wxDC
& dc
,
100 const wxString
& label
,
103 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
105 wxRect
*rectBounds
= NULL
);
106 virtual void DrawButtonLabel(wxDC
& dc
,
107 const wxString
& label
,
108 const wxBitmap
& image
,
111 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
113 wxRect
*rectBounds
= NULL
);
114 virtual void DrawButtonBorder(wxDC
& dc
,
117 wxRect
*rectIn
= NULL
);
119 virtual void DrawArrow(wxDC
& dc
,
123 virtual void DrawScrollbarThumb(wxDC
& dc
,
124 wxOrientation orient
,
127 virtual void DrawScrollbarShaft(wxDC
& dc
,
128 wxOrientation orient
,
133 virtual void DrawToolBarButton(wxDC
& dc
,
134 const wxString
& label
,
135 const wxBitmap
& bitmap
,
140 #endif // wxUSE_TOOLBAR
143 virtual void DrawTab(wxDC
& dc
,
146 const wxString
& label
,
147 const wxBitmap
& bitmap
= wxNullBitmap
,
149 int indexAccel
= -1);
150 #endif // wxUSE_NOTEBOOK
153 virtual void DrawSliderShaft(wxDC
& dc
,
156 wxOrientation orient
,
159 wxRect
*rectShaft
= NULL
);
160 virtual void DrawSliderThumb(wxDC
& dc
,
162 wxOrientation orient
,
165 virtual void DrawSliderTicks(wxDC
& dc
,
168 wxOrientation orient
,
174 #endif // wxUSE_SLIDER
177 virtual void DrawMenuBarItem(wxDC
& dc
,
179 const wxString
& label
,
181 int indexAccel
= -1);
182 virtual void DrawMenuItem(wxDC
& dc
,
184 const wxMenuGeometryInfo
& geometryInfo
,
185 const wxString
& label
,
186 const wxString
& accel
,
187 const wxBitmap
& bitmap
= wxNullBitmap
,
189 int indexAccel
= -1);
190 virtual void DrawMenuSeparator(wxDC
& dc
,
192 const wxMenuGeometryInfo
& geomInfo
);
193 #endif // wxUSE_MENUS
196 virtual void DrawStatusField(wxDC
& dc
,
198 const wxString
& label
,
199 int flags
= 0, int style
= 0);
200 #endif // wxUSE_STATUSBAR
202 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
204 wxBitmap
*bmpPressed
,
205 wxBitmap
*bmpDisabled
);
207 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
208 virtual bool AreScrollbarsInsideBorder() const;
210 virtual wxSize
GetScrollbarArrowSize() const
211 { return m_sizeScrollbarArrow
; }
213 virtual wxSize
GetCheckBitmapSize() const
214 { return wxSize(13, 13); }
215 virtual wxSize
GetRadioBitmapSize() const
216 { return wxSize(12, 12); }
217 virtual wxCoord
GetCheckItemMargin() const
221 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
222 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
223 virtual wxSize
GetToolBarMargin() const
224 { return wxSize(4, 4); }
225 #endif // wxUSE_TOOLBAR
228 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
229 const wxRect
& rect
) const;
230 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
232 wxCoord
*extraSpaceBeyond
) const;
233 #endif // wxUSE_TEXTCTRL
236 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
237 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
238 #endif // wxUSE_NOTEBOOK
242 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
243 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
244 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
246 wxOrientation orient
,
247 long style
= 0) const;
248 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
250 wxOrientation orient
) const;
251 #endif // wxUSE_SLIDER
253 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
256 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
257 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
258 const wxMenu
& menu
) const;
259 #endif // wxUSE_MENUS
262 // overridden wxStdRenderer methods
263 virtual void DrawFrameWithLabel(wxDC
& dc
,
264 const wxString
& label
,
265 const wxRect
& rectFrame
,
266 const wxRect
& rectText
,
271 virtual void DrawCheckItemBitmap(wxDC
& dc
,
272 const wxBitmap
& bitmap
,
277 // draw the border used for scrollbar arrows
278 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
280 // public DrawArrow()s helper
281 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
282 ArrowDirection arrowDir
, ArrowStyle arrowStyle
);
284 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
285 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
286 ArrowDirection arrowDir
,
287 ArrowStyle arrowStyle
);
289 // draw a normal or transposed line (useful for using the same code fo both
290 // horizontal and vertical widgets)
291 void DrawLine(wxDC
& dc
,
292 wxCoord x1
, wxCoord y1
,
293 wxCoord x2
, wxCoord y2
,
294 bool transpose
= false)
297 dc
.DrawLine(y1
, x1
, y2
, x2
);
299 dc
.DrawLine(x1
, y1
, x2
, y2
);
302 // get the standard check/radio button bitmap
303 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
304 virtual wxBitmap
GetCheckBitmap(int flags
)
305 { return GetIndicator(IndicatorType_Check
, flags
); }
306 virtual wxBitmap
GetRadioBitmap(int flags
)
307 { return GetIndicator(IndicatorType_Radio
, flags
); }
309 virtual wxBitmap
GetFrameButtonBitmap(FrameButtonType type
);
312 // Fill the arguments with true or false if this slider has labels on
313 // left/right side (or top/bottom for horizontal sliders) respectively
315 void GetSliderLabelsSides(wxOrientation orient
, long style
,
316 bool *left
, bool *right
)
318 // should we draw ticks at all?
319 if ( !(style
& wxSL_AUTOTICKS
) )
326 // should we draw them on both sides?
327 if ( style
& wxSL_BOTH
)
334 // we draw them on one side only, determine which one
335 if ( ((style
& wxSL_TOP
) && (orient
== wxHORIZONTAL
)) ||
336 ((style
& wxSL_LEFT
) && (orient
== wxVERTICAL
)) )
341 else if ( ((style
& wxSL_BOTTOM
) && (orient
== wxHORIZONTAL
)) ||
342 ((style
& wxSL_RIGHT
) && (orient
== wxVERTICAL
)) )
349 wxFAIL_MSG( "inconsistent wxSlider flags" );
355 #endif // wxUSE_SLIDER
358 // the sizing parameters (TODO make them changeable)
359 wxSize m_sizeScrollbarArrow
;
361 // the checked and unchecked bitmaps for DrawCheckItemBitmap()
362 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
364 // the bitmaps returned by GetIndicator()
365 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
366 [IndicatorState_MaxMenu
]
367 [IndicatorStatus_Max
];
370 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
372 // standard defaults for the above bitmaps
373 static const char **ms_xpmChecked
[IndicatorStatus_Max
];
374 static const char **ms_xpmIndicators
[IndicatorType_Max
]
375 [IndicatorState_MaxMenu
]
376 [IndicatorStatus_Max
];
377 static const char **ms_xpmFrameButtons
[FrameButton_Max
];
379 // first row is for the normal state, second - for the disabled
380 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
383 // ----------------------------------------------------------------------------
384 // wxWin32InputHandler and derived classes: process the keyboard and mouse
385 // messages according to Windows standards
386 // ----------------------------------------------------------------------------
388 class wxWin32InputHandler
: public wxInputHandler
391 wxWin32InputHandler() { }
393 virtual bool HandleKey(wxInputConsumer
*control
,
394 const wxKeyEvent
& event
,
396 virtual bool HandleMouse(wxInputConsumer
*control
,
397 const wxMouseEvent
& event
);
401 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
404 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
,
405 wxInputHandler
*handler
);
407 virtual bool HandleMouse(wxInputConsumer
*control
,
408 const wxMouseEvent
& event
);
409 virtual bool HandleMouseMove(wxInputConsumer
*control
,
410 const wxMouseEvent
& event
);
412 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
413 const wxControlAction
& action
);
416 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
419 // we don't highlight anything
422 // the first and last event which caused the thumb to move
423 wxMouseEvent m_eventStartDrag
,
426 // have we paused the scrolling because the mouse moved?
429 // we remember the interval of the timer to be able to restart it
432 #endif // wxUSE_SCROLLBAR
435 class wxWin32CheckboxInputHandler
: public wxStdInputHandler
438 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
439 : wxStdInputHandler(handler
) { }
441 virtual bool HandleKey(wxInputConsumer
*control
,
442 const wxKeyEvent
& event
,
445 #endif // wxUSE_CHECKBOX
448 class wxWin32TextCtrlInputHandler
: public wxStdInputHandler
451 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
452 : wxStdInputHandler(handler
) { }
454 virtual bool HandleKey(wxInputConsumer
*control
,
455 const wxKeyEvent
& event
,
458 #endif // wxUSE_TEXTCTRL
460 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
463 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
465 virtual bool HandleMouse(wxInputConsumer
*consumer
,
466 const wxMouseEvent
& event
);
468 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
469 const wxMouseEvent
& event
);
472 // is the given point over the statusbar grip?
473 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
476 // the cursor we had replaced with the resize one
477 wxCursor m_cursorOld
;
479 // was the mouse over the grip last time we checked?
483 class wxWin32SystemMenuEvtHandler
;
485 class wxWin32FrameInputHandler
: public wxStdInputHandler
488 wxWin32FrameInputHandler(wxInputHandler
*handler
);
489 virtual ~wxWin32FrameInputHandler();
491 virtual bool HandleMouse(wxInputConsumer
*control
,
492 const wxMouseEvent
& event
);
494 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
497 void PopupSystemMenu(wxTopLevelWindow
*window
) const;
498 #endif // wxUSE_MENUS
501 // was the mouse over the grip last time we checked?
502 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
505 // ----------------------------------------------------------------------------
506 // wxWin32ColourScheme: uses (default) Win32 colours
507 // ----------------------------------------------------------------------------
509 class wxWin32ColourScheme
: public wxColourScheme
512 virtual wxColour
Get(StdColour col
) const;
513 virtual wxColour
GetBackground(wxWindow
*win
) const;
516 // ----------------------------------------------------------------------------
517 // wxWin32ArtProvider
518 // ----------------------------------------------------------------------------
520 class wxWin32ArtProvider
: public wxArtProvider
523 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
524 const wxArtClient
& client
,
528 // ----------------------------------------------------------------------------
530 // ----------------------------------------------------------------------------
532 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
534 class wxWin32Theme
: public wxTheme
538 virtual ~wxWin32Theme();
540 virtual wxRenderer
*GetRenderer();
541 virtual wxArtProvider
*GetArtProvider();
542 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
543 wxInputConsumer
*consumer
);
544 virtual wxColourScheme
*GetColourScheme();
547 wxWin32Renderer
*m_renderer
;
549 wxWin32ArtProvider
*m_artProvider
;
551 // the names of the already created handlers and the handlers themselves
552 // (these arrays are synchronized)
553 wxSortedArrayString m_handlerNames
;
554 wxArrayHandlers m_handlers
;
556 wxWin32ColourScheme
*m_scheme
;
558 WX_DECLARE_THEME(win32
)
561 // ----------------------------------------------------------------------------
563 // ----------------------------------------------------------------------------
565 // frame buttons bitmaps
566 static const char *frame_button_close_xpm
[] = {
581 static const char *frame_button_help_xpm
[] = {
596 static const char *frame_button_maximize_xpm
[] = {
611 static const char *frame_button_minimize_xpm
[] = {
626 static const char *frame_button_restore_xpm
[] = {
641 const char **wxWin32Renderer::ms_xpmFrameButtons
[FrameButton_Max
] =
643 frame_button_close_xpm
,
644 frame_button_minimize_xpm
,
645 frame_button_maximize_xpm
,
646 frame_button_restore_xpm
,
647 frame_button_help_xpm
,
652 static const char *checked_menu_xpm
[] = {
653 /* columns rows colors chars-per-pixel */
669 static const char *selected_checked_menu_xpm
[] = {
670 /* columns rows colors chars-per-pixel */
686 static const char *disabled_checked_menu_xpm
[] = {
687 /* columns rows colors chars-per-pixel */
704 static const char *selected_disabled_checked_menu_xpm
[] = {
705 /* columns rows colors chars-per-pixel */
721 // checkbox and radiobox bitmaps below
723 static const char *checked_xpm
[] = {
724 /* columns rows colors chars-per-pixel */
747 static const char *pressed_checked_xpm
[] = {
748 /* columns rows colors chars-per-pixel */
770 static const char *pressed_disabled_checked_xpm
[] = {
771 /* columns rows colors chars-per-pixel */
793 static const char *checked_item_xpm
[] = {
794 /* columns rows colors chars-per-pixel */
815 static const char *unchecked_xpm
[] = {
816 /* columns rows colors chars-per-pixel */
839 static const char *pressed_unchecked_xpm
[] = {
840 /* columns rows colors chars-per-pixel */
862 static const char *unchecked_item_xpm
[] = {
863 /* columns rows colors chars-per-pixel */
883 static const char *undetermined_xpm
[] = {
884 /* columns rows colors chars-per-pixel */
907 static const char *pressed_undetermined_xpm
[] = {
908 /* columns rows colors chars-per-pixel */
931 static const char *checked_radio_xpm
[] = {
932 /* columns rows colors chars-per-pixel */
955 static const char *pressed_checked_radio_xpm
[] = {
956 /* columns rows colors chars-per-pixel */
979 static const char *pressed_disabled_checked_radio_xpm
[] = {
980 /* columns rows colors chars-per-pixel */
1003 static const char *unchecked_radio_xpm
[] = {
1004 /* columns rows colors chars-per-pixel */
1027 static const char *pressed_unchecked_radio_xpm
[] = {
1028 /* columns rows colors chars-per-pixel */
1051 const char **wxWin32Renderer::ms_xpmIndicators
[IndicatorType_Max
]
1052 [IndicatorState_MaxMenu
]
1053 [IndicatorStatus_Max
] =
1058 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1061 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1064 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1070 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1073 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1076 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1082 { checked_menu_xpm
, NULL
, NULL
},
1085 { selected_checked_menu_xpm
, NULL
, NULL
},
1088 { disabled_checked_menu_xpm
, NULL
, NULL
},
1090 // disabled selected state
1091 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1095 const char **wxWin32Renderer::ms_xpmChecked
[IndicatorStatus_Max
] =
1101 // ============================================================================
1103 // ============================================================================
1105 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1107 // ----------------------------------------------------------------------------
1109 // ----------------------------------------------------------------------------
1111 wxWin32Theme::wxWin32Theme()
1115 m_artProvider
= NULL
;
1118 wxWin32Theme::~wxWin32Theme()
1122 delete m_artProvider
;
1125 wxRenderer
*wxWin32Theme::GetRenderer()
1129 m_renderer
= new wxWin32Renderer(GetColourScheme());
1135 wxArtProvider
*wxWin32Theme::GetArtProvider()
1137 if ( !m_artProvider
)
1139 m_artProvider
= new wxWin32ArtProvider
;
1142 return m_artProvider
;
1146 wxWin32Theme::GetInputHandler(const wxString
& control
,
1147 wxInputConsumer
*consumer
)
1149 wxInputHandler
*handler
= NULL
;
1150 int n
= m_handlerNames
.Index(control
);
1151 if ( n
== wxNOT_FOUND
)
1153 static wxWin32InputHandler s_handlerDef
;
1155 wxInputHandler
* const
1156 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
1158 // create a new handler
1159 if ( control
== wxINP_HANDLER_TOPLEVEL
)
1161 static wxWin32FrameInputHandler
s_handler(handlerStd
);
1163 handler
= &s_handler
;
1166 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1168 static wxWin32CheckboxInputHandler
s_handler(handlerStd
);
1170 handler
= &s_handler
;
1172 #endif // wxUSE_CHECKBOX
1174 else if ( control
== wxINP_HANDLER_SCROLLBAR
)
1176 static wxWin32ScrollBarInputHandler
1177 s_handler(GetRenderer(), handlerStd
);
1179 handler
= &s_handler
;
1181 #endif // wxUSE_SCROLLBAR
1183 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1185 static wxWin32StatusBarInputHandler
s_handler(handlerStd
);
1187 handler
= &s_handler
;
1189 #endif // wxUSE_STATUSBAR
1191 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1193 static wxWin32TextCtrlInputHandler
s_handler(handlerStd
);
1195 handler
= &s_handler
;
1197 #endif // wxUSE_TEXTCTRL
1198 else // no special handler for this control
1200 handler
= handlerStd
;
1203 n
= m_handlerNames
.Add(control
);
1204 m_handlers
.Insert(handler
, n
);
1206 else // we already have it
1208 handler
= m_handlers
[n
];
1214 wxColourScheme
*wxWin32Theme::GetColourScheme()
1218 m_scheme
= new wxWin32ColourScheme
;
1223 // ============================================================================
1224 // wxWin32ColourScheme
1225 // ============================================================================
1227 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1230 if ( win
->UseBgCol() )
1232 // use the user specified colour
1233 col
= win
->GetBackgroundColour();
1236 if ( !win
->ShouldInheritColours() )
1239 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1240 #endif // wxUSE_TEXTCTRL
1242 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1243 #endif // wxUSE_LISTBOX
1252 if ( !win
->IsEnabled() ) // not IsEditable()
1258 // doesn't depend on the state
1263 #endif // wxUSE_TEXTCTRL
1266 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1270 int flags
= win
->GetStateFlags();
1272 // the colour set by the user should be used for the normal state
1273 // and for the states for which we don't have any specific colours
1274 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1277 if ( wxDynamicCast(win
, wxScrollBar
) )
1278 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1281 #endif // wxUSE_SCROLLBAR
1289 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1293 // use the system colours under Windows
1294 #if defined(__WXMSW__)
1295 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1297 case CONTROL_PRESSED
:
1298 case CONTROL_CURRENT
:
1299 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1301 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1303 #if defined(COLOR_3DLIGHT)
1304 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1306 case SCROLLBAR
: return wxColour(0xe0e0e0);
1308 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1310 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1311 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1313 #if defined(COLOR_3DDKSHADOW)
1314 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1316 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1319 case CONTROL_TEXT_DISABLED
:
1320 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1322 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1324 case CONTROL_TEXT_DISABLED_SHADOW
:
1325 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1327 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1328 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1329 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1330 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1332 case DESKTOP
: return wxColour(0x808000);
1333 case FRAME
: return wxColour(GetSysColor(COLOR_APPWORKSPACE
));
1335 // use the standard Windows colours elsewhere
1336 case WINDOW
: return *wxWHITE
;
1338 case CONTROL_PRESSED
:
1339 case CONTROL_CURRENT
:
1340 case CONTROL
: return wxColour(0xc0c0c0);
1342 case CONTROL_TEXT
: return *wxBLACK
;
1344 case SCROLLBAR
: return wxColour(0xe0e0e0);
1345 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1347 case HIGHLIGHT
: return wxColour(0x800000);
1348 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1350 case SHADOW_DARK
: return *wxBLACK
;
1352 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1353 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1355 case SHADOW_IN
: return wxColour(0xc0c0c0);
1357 case CONTROL_TEXT_DISABLED_SHADOW
:
1358 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1360 case TITLEBAR
: return wxColour(0xaeaaae);
1361 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1362 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1363 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1365 case DESKTOP
: return wxColour(0x808000);
1366 case FRAME
: return wxColour(0x808080);
1369 case GAUGE
: return Get(HIGHLIGHT
);
1373 wxFAIL_MSG(wxT("invalid standard colour"));
1378 // ============================================================================
1380 // ============================================================================
1382 // ----------------------------------------------------------------------------
1384 // ----------------------------------------------------------------------------
1386 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1387 : wxStdRenderer(scheme
)
1390 m_sizeScrollbarArrow
= wxSize(16, 16);
1392 // init the arrow bitmaps
1393 static const size_t ARROW_WIDTH
= 7;
1394 static const size_t ARROW_LENGTH
= 4;
1397 wxMemoryDC dcNormal
,
1400 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1402 bool isVertical
= n
> Arrow_Right
;
1415 // disabled arrow is larger because of the shadow
1416 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1417 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1419 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1420 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1422 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1423 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1427 dcNormal
.SetPen(m_penBlack
);
1428 dcDisabled
.SetPen(m_penDarkGrey
);
1430 // calculate the position of the point of the arrow
1434 x1
= (ARROW_WIDTH
- 1)/2;
1435 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1439 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1440 y1
= (ARROW_WIDTH
- 1)/2;
1451 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1453 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1454 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1461 if ( n
== Arrow_Up
)
1472 else // left or right arrow
1477 if ( n
== Arrow_Left
)
1490 // draw the shadow for the disabled one
1491 dcDisabled
.SetPen(m_penHighlight
);
1496 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1500 x1
= ARROW_LENGTH
- 1;
1501 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1504 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1505 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1510 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1514 x1
= ARROW_WIDTH
- 1;
1516 x2
= (ARROW_WIDTH
- 1)/2;
1518 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1519 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1524 // create the inverted bitmap but only for the right arrow as we only
1525 // use it for the menus
1526 if ( n
== Arrow_Right
)
1528 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1529 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1531 dcInverse
.Blit(0, 0, w
, h
,
1534 dcInverse
.SelectObject(wxNullBitmap
);
1536 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1537 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1539 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1540 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1542 dcInverse
.Blit(0, 0, w
, h
,
1545 dcInverse
.SelectObject(wxNullBitmap
);
1547 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1548 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1551 dcNormal
.SelectObject(wxNullBitmap
);
1552 dcDisabled
.SelectObject(wxNullBitmap
);
1554 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1555 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1556 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1557 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1559 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1563 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1568 // ----------------------------------------------------------------------------
1570 // ----------------------------------------------------------------------------
1572 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1573 const wxString
& label
,
1580 // the underscores are not drawn for focused controls in wxMSW
1581 if ( flags
& wxCONTROL_FOCUSED
)
1586 if ( flags
& wxCONTROL_DISABLED
)
1588 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
1589 // currently only can happen for a menu item and it seems that Windows
1590 // doesn't draw the shadow in this case, so we don't do it neither
1591 if ( flags
& wxCONTROL_SELECTED
)
1593 // just make the label text greyed out
1594 dc
.SetTextForeground(m_penDarkGrey
.GetColour());
1596 flags
&= ~wxCONTROL_DISABLED
;
1600 wxStdRenderer::DrawLabel(dc
, label
, rect
, flags
, alignment
,
1601 indexAccel
, rectBounds
);
1604 void wxWin32Renderer::DrawFrameWithLabel(wxDC
& dc
,
1605 const wxString
& label
,
1606 const wxRect
& rectFrame
,
1607 const wxRect
& rectText
,
1613 label2
<< wxT(' ') << label
<< wxT(' ');
1614 if ( indexAccel
!= -1 )
1616 // adjust it as we prepended a space
1620 wxStdRenderer::DrawFrameWithLabel(dc
, label2
, rectFrame
, rectText
,
1621 flags
, alignment
, indexAccel
);
1624 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
1625 const wxString
& label
,
1626 const wxBitmap
& image
,
1633 // the underscores are not drawn for focused controls in wxMSW
1634 if ( flags
& wxCONTROL_PRESSED
)
1639 wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
, alignment
,
1640 indexAccel
, rectBounds
);
1643 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1644 const wxRect
& rectTotal
,
1648 wxRect rect
= rectTotal
;
1650 wxPen
penOut(*wxBLACK
);
1651 if ( flags
& wxCONTROL_PRESSED
)
1653 // button pressed: draw a double border around it
1654 DrawRect(dc
, &rect
, penOut
);
1655 DrawRect(dc
, &rect
, m_penDarkGrey
);
1657 else // button not pressed
1659 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1661 // button either default or focused (or both): add an extra border
1663 DrawRect(dc
, &rect
, penOut
);
1666 // now draw a normal button border
1667 DrawRaisedBorder(dc
, &rect
);
1674 // ----------------------------------------------------------------------------
1675 // (check)listbox items
1676 // ----------------------------------------------------------------------------
1678 void wxWin32Renderer::DrawCheckItemBitmap(wxDC
& dc
,
1679 const wxBitmap
& bitmap
,
1688 else // use default bitmap
1690 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
1691 ? IndicatorStatus_Checked
1692 : IndicatorStatus_Unchecked
;
1694 if ( !m_bmpCheckBitmaps
[i
].Ok() )
1696 m_bmpCheckBitmaps
[i
] = wxBitmap(ms_xpmChecked
[i
]);
1699 bmp
= m_bmpCheckBitmaps
[i
];
1702 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
1703 true /* use mask */);
1706 // ----------------------------------------------------------------------------
1707 // check/radio buttons
1708 // ----------------------------------------------------------------------------
1710 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
1712 IndicatorState indState
;
1713 IndicatorStatus indStatus
;
1714 GetIndicatorsFromFlags(flags
, indState
, indStatus
);
1716 wxBitmap
& bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
1719 const char **xpm
= ms_xpmIndicators
[indType
][indState
][indStatus
];
1722 // create and cache it
1723 bmp
= wxBitmap(xpm
);
1730 // ----------------------------------------------------------------------------
1732 // ----------------------------------------------------------------------------
1735 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
1736 const wxString
& label
,
1737 const wxBitmap
& bitmap
,
1738 const wxRect
& rectOrig
,
1743 if (style
== wxTOOL_STYLE_BUTTON
)
1745 wxRect rect
= rectOrig
;
1746 rect
.Deflate(BORDER_THICKNESS
);
1748 if ( flags
& wxCONTROL_PRESSED
)
1750 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
1752 else if ( flags
& wxCONTROL_CURRENT
)
1754 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
1757 if(tbarStyle
& wxTB_TEXT
)
1759 if(tbarStyle
& wxTB_HORIZONTAL
)
1761 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1765 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1770 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1771 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1772 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
, bitmap
.GetMask() != NULL
);
1775 else if (style
== wxTOOL_STYLE_SEPARATOR
)
1777 // leave a small gap aroudn the line, also account for the toolbar
1779 if(rectOrig
.height
> rectOrig
.width
)
1782 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
1783 rectOrig
.y
+ 2*BORDER_THICKNESS
,
1784 rectOrig
.GetBottom() - BORDER_THICKNESS
);
1789 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
1790 rectOrig
.x
+ 2*BORDER_THICKNESS
,
1791 rectOrig
.GetRight() - BORDER_THICKNESS
);
1794 // don't draw wxTOOL_STYLE_CONTROL
1796 #endif // wxUSE_TOOLBAR
1798 // ----------------------------------------------------------------------------
1800 // ----------------------------------------------------------------------------
1804 void wxWin32Renderer::DrawTab(wxDC
& dc
,
1805 const wxRect
& rectOrig
,
1807 const wxString
& label
,
1808 const wxBitmap
& bitmap
,
1812 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1813 #define REVERSE_FOR_VERTICAL(X,Y) \
1814 SELECT_FOR_VERTICAL(X,Y) \
1816 SELECT_FOR_VERTICAL(Y,X)
1818 wxRect rect
= rectOrig
;
1820 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1822 // the current tab is drawn indented (to the top for default case) and
1823 // bigger than the other ones
1824 const wxSize indent
= GetTabIndent();
1825 if ( flags
& wxCONTROL_SELECTED
)
1827 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1828 SELECT_FOR_VERTICAL( 0, indent
.y
));
1832 wxFAIL_MSG(wxT("invaild notebook tab orientation"));
1839 rect
.height
+= indent
.y
;
1846 rect
.width
+= indent
.x
;
1851 // draw the text, image and the focus around them (if necessary)
1852 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1853 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1855 rectLabel
.Deflate(1, 1);
1858 // draw it horizontally into memory and rotate for screen
1860 wxBitmap bitmapRotated
,
1861 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1862 rectLabel
.y
+ rectLabel
.height
);
1863 dcMem
.SelectObject(bitmapMem
);
1864 dcMem
.SetBackground(dc
.GetBackground());
1865 dcMem
.SetFont(dc
.GetFont());
1866 dcMem
.SetTextForeground(dc
.GetTextForeground());
1870 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1873 #endif // wxUSE_IMAGE
1875 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
1876 flags
, wxALIGN_CENTRE
, indexAccel
);
1877 dcMem
.SelectObject(wxNullBitmap
);
1878 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1880 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
1881 #endif // wxUSE_IMAGE
1882 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1886 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
1887 flags
, wxALIGN_CENTRE
, indexAccel
);
1890 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
1891 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
1892 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1893 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1894 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1895 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1897 // FIXME: all this code will break if the tab indent or the border width,
1898 // it is tied to the fact that both of them are equal to 2
1904 // left orientation looks like top but IsVertical makes x and y reversed
1906 // top is not vertical so use coordinates in written order
1907 dc
.SetPen(m_penHighlight
);
1908 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1909 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
1910 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
1911 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
1912 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
1913 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
1915 dc
.SetPen(m_penBlack
);
1916 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1917 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
1918 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
1919 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
1921 dc
.SetPen(m_penDarkGrey
);
1922 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1923 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
1925 if ( flags
& wxCONTROL_SELECTED
)
1927 dc
.SetPen(m_penLightGrey
);
1929 // overwrite the part of the border below this tab
1930 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1931 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1933 // and the shadow of the tab to the left of us
1934 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
1935 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1940 // right orientation looks like bottom but IsVertical makes x and y reversed
1942 // bottom is not vertical so use coordinates in written order
1943 dc
.SetPen(m_penHighlight
);
1944 // we need to continue one pixel further to overwrite the corner of
1945 // the border for the selected tab
1946 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1947 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
1948 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
1949 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
1951 dc
.SetPen(m_penBlack
);
1952 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
1953 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
1954 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1955 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
1956 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
1957 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
1959 dc
.SetPen(m_penDarkGrey
);
1960 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
1961 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
1962 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1963 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
1965 if ( flags
& wxCONTROL_SELECTED
)
1967 dc
.SetPen(m_penLightGrey
);
1969 // overwrite the part of the (double!) border above this tab
1970 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1971 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1972 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1973 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1975 // and the shadow of the tab to the left of us
1976 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
1977 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1982 #undef SELECT_FOR_VERTICAL
1983 #undef REVERSE_FOR_VERTICAL
1986 #endif // wxUSE_NOTEBOOK
1990 // ----------------------------------------------------------------------------
1992 // ----------------------------------------------------------------------------
1995 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
1997 wxOrientation orient
) const
2000 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2001 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2003 if (orient
== wxHORIZONTAL
)
2017 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2019 wxOrientation orient
,
2023 GetSliderLabelsSides(orient
, style
, &left
, &right
);
2025 wxRect rect
= rectOrig
;
2027 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2029 if (orient
== wxHORIZONTAL
)
2031 rect
.x
+= SLIDER_MARGIN
;
2034 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2038 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2042 rect
.y
+= sizeThumb
.y
/2;
2044 rect
.width
-= 2*SLIDER_MARGIN
;
2045 rect
.height
= 2*BORDER_THICKNESS
;
2047 else // == wxVERTICAL
2049 rect
.y
+= SLIDER_MARGIN
;
2052 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2056 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2060 rect
.x
+= sizeThumb
.x
/2;
2062 rect
.width
= 2*BORDER_THICKNESS
;
2063 rect
.height
-= 2*SLIDER_MARGIN
;
2069 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2070 const wxRect
& rectOrig
,
2072 wxOrientation orient
,
2077 /* show shaft geometry
2095 if (flags
& wxCONTROL_FOCUSED
)
2096 DrawFocusRect(NULL
, dc
, rectOrig
);
2098 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2100 if (rectShaft
) *rectShaft
= rect
;
2102 DrawSunkenBorder(dc
, &rect
);
2105 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2107 wxOrientation orient
,
2111 /* show thumb geometry
2120 H D B where H is highlight colour
2134 The interior of this shape is filled with the hatched brush if the thumb
2138 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2141 GetSliderLabelsSides(orient
, style
, &left
, &right
);
2143 bool isVertical
= orient
== wxVERTICAL
;
2145 wxCoord sizeArrow
= (isVertical
? rect
.height
: rect
.width
) / 2;
2146 wxCoord c
= ((isVertical
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2148 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2149 x1
= (isVertical
? rect
.y
: rect
.x
);
2150 x2
= (isVertical
? rect
.GetBottom() : rect
.GetRight());
2151 x3
= (x1
-1+c
) + sizeArrow
;
2152 y1
= (isVertical
? rect
.x
: rect
.y
);
2153 y2
= (isVertical
? rect
.GetRight() : rect
.GetBottom());
2154 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2155 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2157 dc
.SetPen(m_penBlack
);
2160 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, isVertical
);
2162 DrawLine(dc
, x2
, y3
, x2
, y4
, isVertical
);
2165 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, isVertical
);
2169 DrawLine(dc
, x1
, y2
, x2
, y2
, isVertical
);
2172 dc
.SetPen(m_penDarkGrey
);
2173 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, isVertical
);
2176 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, isVertical
);
2180 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, isVertical
);
2183 dc
.SetPen(m_penHighlight
);
2186 DrawLine(dc
, x1
, y3
, x3
, y1
, isVertical
);
2187 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, isVertical
);
2191 DrawLine(dc
, x1
, y1
, x2
, y1
, isVertical
);
2193 DrawLine(dc
, x1
, y3
, x1
, y4
, isVertical
);
2196 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, isVertical
);
2199 if (flags
& wxCONTROL_PRESSED
)
2201 // TODO: MSW fills the entire area inside, not just the rect
2202 wxRect rectInt
= rect
;
2205 rectInt
.SetLeft(y3
);
2206 rectInt
.SetRight(y4
);
2211 rectInt
.SetBottom(y4
);
2215 #if !defined(__WXMGL__)
2216 static const char *stipple_xpm
[] = {
2217 /* columns rows colors chars-per-pixel */
2226 // VS: MGL can only do 8x8 stipple brushes
2227 static const char *stipple_xpm
[] = {
2228 /* columns rows colors chars-per-pixel */
2243 dc
.SetBrush(wxBrush(stipple_xpm
));
2245 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2246 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2247 dc
.SetPen(*wxTRANSPARENT_PEN
);
2248 dc
.DrawRectangle(rectInt
);
2252 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2255 wxOrientation orient
,
2259 int WXUNUSED(flags
),
2262 /* show ticks geometry
2281 GetSliderLabelsSides(orient
, style
, &left
, &right
);
2283 bool isVertical
= orient
== wxVERTICAL
;
2285 // default thumb size
2286 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2287 wxCoord defaultLen
= (isVertical
? sizeThumb
.x
: sizeThumb
.y
);
2289 // normal thumb size
2290 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2291 wxCoord widthThumb
= (isVertical
? sizeThumb
.y
: sizeThumb
.x
);
2293 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2295 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2296 x1
= (isVertical
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2297 x2
= (isVertical
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2298 y1
= (isVertical
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2299 y2
= (isVertical
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2300 y3
= (isVertical
? rect
.x
: rect
.y
);
2301 y4
= (isVertical
? rect
.GetRight() : rect
.GetBottom());
2304 dc
.SetPen(m_penBlack
);
2306 int range
= end
- start
;
2307 for ( int n
= 0; n
< range
; n
+= step
)
2309 wxCoord x
= x1
+ (len
*n
) / range
;
2311 if (left
& (y1
> y3
))
2313 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2315 if (right
& (y4
> y2
))
2317 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2320 // always draw the line at the end position
2321 if (left
& (y1
> y3
))
2323 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2325 if (right
& (y4
> y2
))
2327 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2331 #endif // wxUSE_SLIDER
2335 // ----------------------------------------------------------------------------
2337 // ----------------------------------------------------------------------------
2339 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2340 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2343 virtual wxSize
GetSize() const { return m_size
; }
2345 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2346 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2348 wxCoord
GetItemHeight() const { return m_heightItem
; }
2351 // the total size of the menu
2354 // the offset of the start of the menu item label
2357 // the offset of the start of the accel label
2360 // the height of a normal (not separator) item
2361 wxCoord m_heightItem
;
2363 friend wxMenuGeometryInfo
*
2364 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2367 // FIXME: all constants are hardcoded but shouldn't be
2368 static const wxCoord MENU_LEFT_MARGIN
= 9;
2369 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2370 static const wxCoord MENU_VERT_MARGIN
= 3;
2372 // the margin around bitmap/check marks (on each side)
2373 static const wxCoord MENU_BMP_MARGIN
= 2;
2375 // the margin between the labels and accel strings
2376 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2378 // the separator height in pixels: in fact, strangely enough, the real height
2379 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2381 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2383 // the size of the standard checkmark bitmap
2384 static const wxCoord MENU_CHECK_SIZE
= 9;
2386 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2387 const wxRect
& rectOrig
,
2388 const wxString
& label
,
2392 wxRect rect
= rectOrig
;
2395 wxDCTextColourChanger
colChanger(dc
);
2397 if ( flags
& wxCONTROL_SELECTED
)
2399 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2401 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2404 dc
.DrawRectangle(rect
);
2407 // don't draw the focus rect around menu bar items
2408 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2409 wxALIGN_CENTRE
, indexAccel
);
2412 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2414 const wxMenuGeometryInfo
& gi
,
2415 const wxString
& label
,
2416 const wxString
& accel
,
2417 const wxBitmap
& bitmap
,
2421 const wxWin32MenuGeometryInfo
& geometryInfo
=
2422 (const wxWin32MenuGeometryInfo
&)gi
;
2427 rect
.width
= geometryInfo
.GetSize().x
;
2428 rect
.height
= geometryInfo
.GetItemHeight();
2430 // draw the selected item specially
2431 wxDCTextColourChanger
colChanger(dc
);
2432 if ( flags
& wxCONTROL_SELECTED
)
2434 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2436 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2439 dc
.DrawRectangle(rect
);
2442 // draw the bitmap: use the bitmap provided or the standard checkmark for
2443 // the checkable items
2444 wxBitmap bmp
= bitmap
;
2445 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2447 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2452 rect
.SetRight(geometryInfo
.GetLabelOffset());
2453 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2457 rect
.x
= geometryInfo
.GetLabelOffset();
2458 rect
.SetRight(geometryInfo
.GetAccelOffset());
2460 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2462 // draw the accel string
2463 rect
.x
= geometryInfo
.GetAccelOffset();
2464 rect
.SetRight(geometryInfo
.GetSize().x
);
2466 // NB: no accel index here
2467 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2469 // draw the submenu indicator
2470 if ( flags
& wxCONTROL_ISSUBMENU
)
2472 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2473 rect
.width
= MENU_RIGHT_MARGIN
;
2475 ArrowStyle arrowStyle
;
2476 if ( flags
& wxCONTROL_DISABLED
)
2477 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
2479 else if ( flags
& wxCONTROL_SELECTED
)
2480 arrowStyle
= Arrow_Inverted
;
2482 arrowStyle
= Arrow_Normal
;
2484 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2488 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2490 const wxMenuGeometryInfo
& geomInfo
)
2492 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2495 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2497 wxSize size
= sizeText
;
2499 // FIXME: menubar height is configurable under Windows
2506 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2507 const wxMenu
& menu
) const
2509 // prepare the dc: for now we draw all the items with the system font
2511 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2513 // the height of a normal item
2514 wxCoord heightText
= dc
.GetCharHeight();
2519 // the max length of label and accel strings: the menu width is the sum of
2520 // them, even if they're for different items (as the accels should be
2523 // the max length of the bitmap is never 0 as Windows always leaves enough
2524 // space for a check mark indicator
2525 wxCoord widthLabelMax
= 0,
2527 widthBmpMax
= MENU_LEFT_MARGIN
;
2529 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
2531 node
= node
->GetNext() )
2533 // height of this item
2536 wxMenuItem
*item
= node
->GetData();
2537 if ( item
->IsSeparator() )
2539 h
= MENU_SEPARATOR_HEIGHT
;
2541 else // not separator
2546 dc
.GetTextExtent(item
->GetItemLabelText(), &widthLabel
, NULL
);
2547 if ( widthLabel
> widthLabelMax
)
2549 widthLabelMax
= widthLabel
;
2553 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2554 if ( widthAccel
> widthAccelMax
)
2556 widthAccelMax
= widthAccel
;
2559 const wxBitmap
& bmp
= item
->GetBitmap();
2562 wxCoord widthBmp
= bmp
.GetWidth();
2563 if ( widthBmp
> widthBmpMax
)
2564 widthBmpMax
= widthBmp
;
2566 //else if ( item->IsCheckable() ): no need to check for this as
2567 // MENU_LEFT_MARGIN is big enough to show the check mark
2570 h
+= 2*MENU_VERT_MARGIN
;
2572 // remember the item position and height
2573 item
->SetGeometry(height
, h
);
2578 // bundle the metrics into a struct and return it
2579 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2581 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2582 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2583 if ( widthAccelMax
> 0 )
2585 // if we actually have any accesl, add a margin
2586 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2589 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2591 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2592 gi
->m_size
.y
= height
;
2597 #endif // wxUSE_MENUS
2601 // ----------------------------------------------------------------------------
2603 // ----------------------------------------------------------------------------
2605 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2607 const wxString
& label
,
2613 if ( flags
& wxCONTROL_SIZEGRIP
)
2615 // draw the size grip: it is a normal rect except that in the lower
2616 // right corner we have several bands which may be used for dragging
2617 // the status bar corner
2619 // each band consists of 4 stripes: m_penHighlight, double
2620 // m_penDarkGrey and transparent one
2621 wxCoord x2
= rect
.GetRight(),
2622 y2
= rect
.GetBottom();
2624 // draw the upper left part of the rect normally
2625 if (style
!= wxSB_FLAT
)
2627 if (style
== wxSB_RAISED
)
2628 dc
.SetPen(m_penHighlight
);
2630 dc
.SetPen(m_penDarkGrey
);
2631 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
2632 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
2635 // draw the grey stripes of the grip
2637 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
2638 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2640 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2641 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
2644 // draw the white stripes
2645 dc
.SetPen(m_penHighlight
);
2646 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
2647 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2649 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2652 // draw the remaining rect boundaries
2653 if (style
!= wxSB_FLAT
)
2655 if (style
== wxSB_RAISED
)
2656 dc
.SetPen(m_penDarkGrey
);
2658 dc
.SetPen(m_penHighlight
);
2659 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
2660 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
2661 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
2667 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
2669 // this will prevent the standard version from drawing any borders
2673 wxStdRenderer::DrawStatusField(dc
, rect
, label
, flags
, style
);
2676 #endif // wxUSE_STATUSBAR
2678 // ----------------------------------------------------------------------------
2680 // ----------------------------------------------------------------------------
2682 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2683 wxBitmap
* WXUNUSED(bmpFocus
),
2684 wxBitmap
*bmpPressed
,
2685 wxBitmap
*bmpDisabled
)
2687 static const wxCoord widthCombo
= 16;
2688 static const wxCoord heightCombo
= 17;
2694 bmpNormal
->Create(widthCombo
, heightCombo
);
2695 dcMem
.SelectObject(*bmpNormal
);
2696 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2697 Arrow_Down
, Arrow_Normal
);
2702 bmpPressed
->Create(widthCombo
, heightCombo
);
2703 dcMem
.SelectObject(*bmpPressed
);
2704 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2705 Arrow_Down
, Arrow_Pressed
);
2710 bmpDisabled
->Create(widthCombo
, heightCombo
);
2711 dcMem
.SelectObject(*bmpDisabled
);
2712 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2713 Arrow_Down
, Arrow_Disabled
);
2717 // ----------------------------------------------------------------------------
2719 // ----------------------------------------------------------------------------
2721 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
2725 DrawRect(dc
, rect
, m_penDarkGrey
);
2727 // the arrow is usually drawn inside border of width 2 and is offset by
2728 // another pixel in both directions when it's pressed - as the border
2729 // in this case is more narrow as well, we have to adjust rect like
2737 DrawAntiSunkenBorder(dc
, rect
);
2741 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
2746 ArrowStyle arrowStyle
;
2747 if ( flags
& wxCONTROL_PRESSED
)
2749 // can't be pressed and disabled
2750 arrowStyle
= Arrow_Pressed
;
2754 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
2757 DrawArrowButton(dc
, rect
, GetArrowDirection(dir
), arrowStyle
);
2760 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
2762 ArrowDirection arrowDir
,
2763 ArrowStyle arrowStyle
)
2765 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
2767 // under Windows the arrows always have the same size so just centre it in
2768 // the provided rectangle
2769 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
2770 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
2772 // Windows does it like this...
2773 if ( arrowDir
== Arrow_Left
)
2777 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
2780 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
2781 const wxRect
& rectAll
,
2782 ArrowDirection arrowDir
,
2783 ArrowStyle arrowStyle
)
2785 wxRect rect
= rectAll
;
2786 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2787 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
2788 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
2791 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
2792 wxOrientation
WXUNUSED(orient
),
2794 int WXUNUSED(flags
))
2796 // we don't use the flags, the thumb never changes appearance
2797 wxRect rectThumb
= rect
;
2798 DrawArrowBorder(dc
, &rectThumb
);
2799 DrawBackground(dc
, wxNullColour
, rectThumb
);
2802 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
2803 wxOrientation
WXUNUSED(orient
),
2804 const wxRect
& rectBar
,
2807 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
2808 ? wxColourScheme::SCROLLBAR_PRESSED
2809 : wxColourScheme::SCROLLBAR
;
2810 DrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
2813 // ----------------------------------------------------------------------------
2815 // ----------------------------------------------------------------------------
2817 /* Copyright (c) Julian Smart */
2818 static const char *error_xpm
[]={
2819 /* columns rows colors chars-per-pixel */
2896 " $oooooooooooo%& ",
2897 " *=-ooooooooooooo;: ",
2898 " *oooooooooooooooooo> ",
2899 " =ooooooooooooooooooo, ",
2900 " $-ooooooooooooooooooo<1 ",
2901 " .oooooo2334ooo533oooooo6 ",
2902 " +ooooooo789oo2883oooooo0q ",
2903 " oooooooo2w83o78eoooooooor ",
2904 " toooooooooy88u884oooooooori ",
2905 " Xooooooooooe888poooooooooas ",
2906 " ooooooooooo4889doooooooooof ",
2907 " ooooooooooo588w2oooooooooofi ",
2908 " oooooooooodw8887oooooooooofi ",
2909 " goooooooooh8w588jooooooookli ",
2910 " tooooooooz885op8wdooooooorix ",
2911 " oooooood98cood98cooooooori ",
2912 " @oooooop8w2ooo5885ooooovbi ",
2913 " n%ooooooooooooooooooooomiM ",
2914 " &;oooooooooooooooooooNBiV ",
2915 " :ooooooooooooooooooCZiA ",
2916 " nSooooooooooooooooCDiF ",
2917 " nG<oooooooooooooNZiiH ",
2918 " 160ooooooooovmBiFH ",
2919 " nqrraoookrrbiiA ",
2926 /* Copyright (c) Julian Smart */
2927 static const char *info_xpm
[]={
2928 /* columns rows colors chars-per-pixel */
2950 " ..XXXXXXXXXXXXX.. ",
2951 " .XXXXXXXXXXXXXXXXX. ",
2952 " .XXXXXXXXoO+XXXXXXXX. ",
2953 " .XXXXXXXXX@#OXXXXXXXXX. ",
2954 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
2955 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
2956 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
2957 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
2958 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
2959 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
2960 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
2961 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
2962 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
2963 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
2964 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
2965 " .XXXXXXXXXXXXXXXXX.%%%% ",
2966 " ..XXXXXXXXXXXXX..%%%% ",
2967 " %...XXXXXXXX..%%%%% ",
2968 " %%%..XXXXXX.%%%%% ",
2982 /* Copyright (c) Julian Smart */
2983 static const char *question_xpm
[]={
2984 /* columns rows colors chars-per-pixel */
3005 " ..XXXXXXXXXXXXX.. ",
3006 " .XXXXXXoO++@XXXXXX. ",
3007 " .XXXXXXO#$$$$#%XXXXX. ",
3008 " .XXXXXX@$$#&&#$#oXXXXX. ",
3009 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
3010 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
3011 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
3012 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
3013 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
3014 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
3015 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
3016 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
3017 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
3018 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
3019 " .XXXXXXXX-$$XXXXXXXX.:::: ",
3020 " .XXXXXXXO++XXXXXXX.:::: ",
3021 " ..XXXXXXXXXXXXX..:::: ",
3022 " :...XXXXXXXX..::::: ",
3023 " :::..XXXXXX.::::: ",
3037 /* Copyright (c) Julian Smart */
3038 static const char *warning_xpm
[]={
3039 /* columns rows colors chars-per-pixel */
3065 " ..XXXXO@#XXX... ",
3066 " ...XXXXO@#XXXX.. ",
3067 " ..XXXXXO@#XXXX... ",
3068 " ...XXXXXo@OXXXXX.. ",
3069 " ...XXXXXXo@OXXXXXX.. ",
3070 " ..XXXXXXX$@OXXXXXX... ",
3071 " ...XXXXXXXX@XXXXXXXX.. ",
3072 " ...XXXXXXXXXXXXXXXXXX... ",
3073 " ..XXXXXXXXXXOXXXXXXXXX.. ",
3074 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
3075 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
3076 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3077 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3078 " .............................. ",
3079 " .............................. ",
3086 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3087 const wxArtClient
& WXUNUSED(client
),
3088 const wxSize
& WXUNUSED(size
))
3090 if ( id
== wxART_INFORMATION
)
3091 return wxBitmap(info_xpm
);
3092 if ( id
== wxART_ERROR
)
3093 return wxBitmap(error_xpm
);
3094 if ( id
== wxART_WARNING
)
3095 return wxBitmap(warning_xpm
);
3096 if ( id
== wxART_QUESTION
)
3097 return wxBitmap(question_xpm
);
3098 return wxNullBitmap
;
3104 // ----------------------------------------------------------------------------
3105 // text control geometry
3106 // ----------------------------------------------------------------------------
3109 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3110 const wxRect
& rect
) const
3112 wxRect rectTotal
= wxStdRenderer::GetTextTotalArea(text
, rect
);
3114 // this is strange but it's what Windows does
3121 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3123 wxCoord
*extraSpaceBeyond
) const
3125 wxRect rectText
= rect
;
3127 // undo GetTextTotalArea()
3128 if ( rectText
.height
> 0 )
3131 return wxStdRenderer::GetTextClientArea(text
, rect
, extraSpaceBeyond
);
3134 #endif // wxUSE_TEXTCTRL
3136 // ----------------------------------------------------------------------------
3138 // ----------------------------------------------------------------------------
3140 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3143 if ( wxDynamicCast(window
, wxScrollBar
) )
3145 // we only set the width of vert scrollbars and height of the
3147 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3148 size
->y
= m_sizeScrollbarArrow
.y
;
3150 size
->x
= m_sizeScrollbarArrow
.x
;
3152 // skip border width adjustments, they don't make sense for us
3155 #endif // wxUSE_SCROLLBAR
3158 if ( wxDynamicCast(window
, wxBitmapButton
) )
3162 #endif // wxUSE_BMPBUTTON
3163 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
3166 || wxDynamicCast(window
, wxButton
)
3167 # endif // wxUSE_BUTTON
3168 # if wxUSE_TOGGLEBTN
3169 || wxDynamicCast(window
, wxToggleButton
)
3170 # endif // wxUSE_TOGGLEBTN
3173 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3175 // TODO: don't harcode all this
3176 size
->x
+= 3*window
->GetCharWidth();
3178 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3179 if ( size
->y
< heightBtn
- 8 )
3180 size
->y
= heightBtn
;
3185 // for compatibility with other ports, the buttons default size is never
3186 // less than the standard one, but not when display not PDAs.
3187 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
3189 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3191 wxSize szDef
= wxButton::GetDefaultSize();
3192 if ( size
->x
< szDef
.x
)
3197 // no border width adjustments for buttons
3200 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
3202 wxStdRenderer::AdjustSize(size
, window
);
3205 wxBitmap
wxWin32Renderer::GetFrameButtonBitmap(FrameButtonType type
)
3207 wxBitmap
& bmp
= m_bmpFrameButtons
[type
];
3210 bmp
= wxBitmap(ms_xpmFrameButtons
[type
]);
3216 // ============================================================================
3218 // ============================================================================
3220 // ----------------------------------------------------------------------------
3221 // wxWin32InputHandler
3222 // ----------------------------------------------------------------------------
3224 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3225 const wxKeyEvent
& WXUNUSED(event
),
3226 bool WXUNUSED(pressed
))
3231 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3232 const wxMouseEvent
& event
)
3234 // clicking on the control gives it focus
3235 if ( event
.ButtonDown() )
3237 wxWindow
* const win
= control
->GetInputWindow();
3239 if ( win
->CanAcceptFocus() && wxWindow::FindFocus() != win
)
3252 // ----------------------------------------------------------------------------
3253 // wxWin32ScrollBarInputHandler
3254 // ----------------------------------------------------------------------------
3256 wxWin32ScrollBarInputHandler::
3257 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
3258 : wxStdScrollBarInputHandler(renderer
, handler
)
3260 m_scrollPaused
= false;
3264 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3265 const wxControlAction
& action
)
3267 // stop if went beyond the position of the original click (this can only
3268 // happen when we scroll by pages)
3270 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3272 stop
= scrollbar
->HitTestBar(m_ptStartScrolling
) != wxHT_SCROLLBAR_BAR_2
;
3274 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3276 stop
= scrollbar
->HitTestBar(m_ptStartScrolling
) != wxHT_SCROLLBAR_BAR_1
;
3281 StopScrolling(scrollbar
);
3283 scrollbar
->Refresh();
3288 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3291 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3292 const wxMouseEvent
& event
)
3294 // remember the current state
3295 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3297 // do process the message
3298 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3300 // analyse the changes
3301 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3303 // we just started dragging the thumb, remember its initial position to
3304 // be able to restore it if the drag is cancelled later
3305 m_eventStartDrag
= event
;
3311 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3312 const wxMouseEvent
& event
)
3314 // we don't highlight scrollbar elements, so there is no need to process
3315 // mouse move events normally - only do it while mouse is captured (i.e.
3316 // when we're dragging the thumb or pressing on something)
3317 if ( !m_winCapture
)
3320 if ( event
.Entering() )
3322 // we're not interested in this at all
3326 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3328 if ( m_scrollPaused
)
3330 // check if the mouse returned to its original location
3332 if ( event
.Leaving() )
3338 ht
= scrollbar
->HitTestBar(event
.GetPosition());
3339 if ( ht
== m_htLast
)
3341 // yes it did, resume scrolling
3342 m_scrollPaused
= false;
3343 if ( m_timerScroll
)
3345 // we were scrolling by line/page, restart timer
3346 m_timerScroll
->Start(m_interval
);
3348 Press(scrollbar
, true);
3350 else // we were dragging the thumb
3352 // restore its last location
3353 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3359 else // normal case, scrolling hasn't been paused
3361 // if we're scrolling the scrollbar because the arrow or the shaft was
3362 // pressed, check that the mouse stays on the same scrollbar element
3365 // Always let thumb jump back if we leave the scrollbar
3366 if ( event
.Moving() )
3368 ht
= scrollbar
->HitTestBar(event
.GetPosition());
3370 else // event.Leaving()
3375 // Jump back only if we get far away from it
3376 wxPoint pos
= event
.GetPosition();
3377 if (scrollbar
->HasFlag( wxVERTICAL
))
3379 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
3384 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
3387 ht
= scrollbar
->HitTestBar(pos
);
3390 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3391 // is still ok - we only want to catch the case when the mouse leaves
3392 // the scrollbar here
3393 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3395 ht
= wxHT_SCROLLBAR_THUMB
;
3398 if ( ht
!= m_htLast
)
3400 // what were we doing? 2 possibilities: either an arrow/shaft was
3401 // pressed in which case we have a timer and so we just stop it or
3402 // we were dragging the thumb
3403 if ( m_timerScroll
)
3406 m_interval
= m_timerScroll
->GetInterval();
3407 m_timerScroll
->Stop();
3408 m_scrollPaused
= true;
3410 // unpress the arrow
3411 Press(scrollbar
, false);
3413 else // we were dragging the thumb
3415 // remember the current thumb position to be able to restore it
3416 // if the mouse returns to it later
3417 m_eventLastDrag
= event
;
3419 // and restore the original position (before dragging) of the
3421 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3428 return wxStdInputHandler::HandleMouseMove(control
, event
);
3431 #endif // wxUSE_SCROLLBAR
3435 // ----------------------------------------------------------------------------
3436 // wxWin32CheckboxInputHandler
3437 // ----------------------------------------------------------------------------
3439 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3440 const wxKeyEvent
& event
,
3445 wxControlAction action
;
3446 int keycode
= event
.GetKeyCode();
3450 action
= wxACTION_CHECKBOX_TOGGLE
;
3454 case WXK_NUMPAD_SUBTRACT
:
3455 action
= wxACTION_CHECKBOX_CHECK
;
3459 case WXK_NUMPAD_ADD
:
3460 case WXK_NUMPAD_EQUAL
:
3461 action
= wxACTION_CHECKBOX_CLEAR
;
3465 if ( !action
.IsEmpty() )
3467 control
->PerformAction(action
);
3476 #endif // wxUSE_CHECKBOX
3480 // ----------------------------------------------------------------------------
3481 // wxWin32TextCtrlInputHandler
3482 // ----------------------------------------------------------------------------
3484 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3485 const wxKeyEvent
& event
,
3488 // handle only MSW-specific text bindings here, the others are handled in
3492 int keycode
= event
.GetKeyCode();
3494 wxControlAction action
;
3495 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
3497 action
= wxACTION_TEXT_CUT
;
3499 else if ( keycode
== WXK_INSERT
)
3501 if ( event
.ControlDown() )
3502 action
= wxACTION_TEXT_COPY
;
3503 else if ( event
.ShiftDown() )
3504 action
= wxACTION_TEXT_PASTE
;
3507 if ( action
!= wxACTION_NONE
)
3509 control
->PerformAction(action
);
3515 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
3518 #endif // wxUSE_TEXTCTRL
3522 // ----------------------------------------------------------------------------
3523 // wxWin32StatusBarInputHandler
3524 // ----------------------------------------------------------------------------
3526 wxWin32StatusBarInputHandler::
3527 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
3528 : wxStdInputHandler(handler
)
3533 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
3534 const wxPoint
& pt
) const
3536 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
3537 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
3540 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
3542 wxCHECK_MSG( parentTLW
, false,
3543 wxT("the status bar should be a child of a TLW") );
3545 // a maximized window can't be resized anyhow
3546 if ( !parentTLW
->IsMaximized() )
3548 // VZ: I think that the standard Windows behaviour is to only
3549 // show the resizing cursor when the mouse is on top of the
3550 // grip itself but apparently different Windows versions behave
3551 // differently (?) and it seems a better UI to allow resizing
3552 // the status bar even when the mouse is above the grip
3553 wxSize sizeSbar
= statbar
->GetSize();
3555 int diff
= sizeSbar
.x
- pt
.x
;
3556 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
3563 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
3564 const wxMouseEvent
& event
)
3566 if ( event
.Button(1) )
3568 if ( event
.ButtonDown(1) )
3570 wxWindow
*statbar
= consumer
->GetInputWindow();
3572 if ( IsOnGrip(statbar
, event
.GetPosition()) )
3574 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
3578 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
3579 wxHT_TOPLEVEL_BORDER_SE
);
3581 statbar
->SetCursor(m_cursorOld
);
3589 return wxStdInputHandler::HandleMouse(consumer
, event
);
3592 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
3593 const wxMouseEvent
& event
)
3595 wxWindow
*statbar
= consumer
->GetInputWindow();
3597 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
3598 if ( isOnGrip
!= m_isOnGrip
)
3600 m_isOnGrip
= isOnGrip
;
3603 m_cursorOld
= statbar
->GetCursor();
3604 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
3608 statbar
->SetCursor(m_cursorOld
);
3612 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
3615 #endif // wxUSE_STATUSBAR
3617 // ----------------------------------------------------------------------------
3618 // wxWin32FrameInputHandler
3619 // ----------------------------------------------------------------------------
3621 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
3624 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
3626 void Attach(wxInputConsumer
*consumer
);
3630 DECLARE_EVENT_TABLE()
3631 void OnSystemMenu(wxCommandEvent
&event
);
3632 void OnCloseFrame(wxCommandEvent
&event
);
3633 void OnClose(wxCloseEvent
&event
);
3635 wxWin32FrameInputHandler
*m_inputHnd
;
3636 wxTopLevelWindow
*m_wnd
;
3638 wxAcceleratorTable m_oldAccelTable
;
3642 wxWin32SystemMenuEvtHandler::
3643 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
)
3645 m_inputHnd
= handler
;
3649 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
3651 wxASSERT_MSG( m_wnd
== NULL
, wxT("can't attach the handler twice!") );
3653 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
3654 m_wnd
->PushEventHandler(this);
3657 // VS: This code relies on using generic implementation of
3658 // wxAcceleratorTable in wxUniv!
3659 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
3660 m_oldAccelTable
= table
;
3661 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
3662 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
3663 m_wnd
->SetAcceleratorTable(table
);
3667 void wxWin32SystemMenuEvtHandler::Detach()
3672 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
3674 m_wnd
->RemoveEventHandler(this);
3679 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
3680 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
3681 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
3682 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
3685 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
3688 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
3689 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
3693 m_inputHnd
->PopupSystemMenu(m_wnd
);
3694 #endif // wxUSE_MENUS
3697 m_wnd
->SetAcceleratorTable(table
);
3701 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
3703 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
3704 wxTOPLEVEL_BUTTON_CLOSE
);
3707 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
3714 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
3715 : wxStdInputHandler(handler
)
3717 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
3720 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
3722 if ( m_menuHandler
)
3724 m_menuHandler
->Detach();
3725 delete m_menuHandler
;
3729 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
3730 const wxMouseEvent
& event
)
3732 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
3734 wxTopLevelWindow
*tlw
=
3735 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
3737 long hit
= tlw
->HitTest(event
.GetPosition());
3739 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
3741 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
3742 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
3743 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
3746 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
3748 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
3749 (event
.RightDown() &&
3750 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
3751 hit
== wxHT_TOPLEVEL_ICON
)) )
3754 PopupSystemMenu(tlw
);
3755 #endif // wxUSE_MENUS
3761 return wxStdInputHandler::HandleMouse(consumer
, event
);
3766 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
) const
3770 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
3771 menu
.Append(wxID_RESTORE_FRAME
, _("&Restore"));
3772 menu
.Append(wxID_MOVE_FRAME
, _("&Move"));
3773 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
3774 menu
.Append(wxID_RESIZE_FRAME
, _("&Size"));
3775 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
3776 menu
.Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
3777 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
3778 menu
.Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
3779 menu
.AppendSeparator();
3780 menu
.Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
3782 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
3784 if ( window
->IsMaximized() )
3786 menu
.Enable(wxID_MAXIMIZE_FRAME
, false);
3787 menu
.Enable(wxID_MOVE_FRAME
, false);
3788 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
3789 menu
.Enable(wxID_RESIZE_FRAME
, false);
3792 menu
.Enable(wxID_RESTORE_FRAME
, false);
3795 window
->PopupMenu(&menu
, wxPoint(0, 0));
3798 #endif // wxUSE_MENUS
3800 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
3803 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
3805 // always detach if active frame changed:
3806 m_menuHandler
->Detach();
3810 m_menuHandler
->Attach(consumer
);
3814 return wxStdInputHandler::HandleActivation(consumer
, activated
);
3817 #endif // wxUSE_THEME_WIN32