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
.IsOk() || (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
,
1684 if ( bitmap
.IsOk() )
1688 else // use default bitmap
1690 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
1691 ? IndicatorStatus_Checked
1692 : IndicatorStatus_Unchecked
;
1694 if ( !m_bmpCheckBitmaps
[i
].IsOk() )
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
.IsOk() && (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
) )
3146 Don't adjust the size for a scrollbar as its DoGetBestClientSize
3147 already has the correct size set. Any size changes here would get
3148 added to the best size, making the scrollbar larger.
3149 Also skip border width adjustments, they don't make sense for us.
3153 #endif // wxUSE_SCROLLBAR
3156 if ( wxDynamicCast(window
, wxBitmapButton
) )
3160 #endif // wxUSE_BMPBUTTON
3161 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
3164 || wxDynamicCast(window
, wxButton
)
3165 # endif // wxUSE_BUTTON
3166 # if wxUSE_TOGGLEBTN
3167 || wxDynamicCast(window
, wxToggleButton
)
3168 # endif // wxUSE_TOGGLEBTN
3171 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3173 // TODO: don't harcode all this
3174 size
->x
+= 3*window
->GetCharWidth();
3176 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3177 if ( size
->y
< heightBtn
- 8 )
3178 size
->y
= heightBtn
;
3183 // for compatibility with other ports, the buttons default size is never
3184 // less than the standard one, but not when display not PDAs.
3185 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
3187 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3189 wxSize szDef
= wxButton::GetDefaultSize();
3190 if ( size
->x
< szDef
.x
)
3195 // no border width adjustments for buttons
3198 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
3200 wxStdRenderer::AdjustSize(size
, window
);
3203 wxBitmap
wxWin32Renderer::GetFrameButtonBitmap(FrameButtonType type
)
3205 wxBitmap
& bmp
= m_bmpFrameButtons
[type
];
3208 bmp
= wxBitmap(ms_xpmFrameButtons
[type
]);
3214 // ============================================================================
3216 // ============================================================================
3218 // ----------------------------------------------------------------------------
3219 // wxWin32InputHandler
3220 // ----------------------------------------------------------------------------
3222 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3223 const wxKeyEvent
& WXUNUSED(event
),
3224 bool WXUNUSED(pressed
))
3229 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3230 const wxMouseEvent
& event
)
3232 // clicking on the control gives it focus
3233 if ( event
.ButtonDown() )
3235 wxWindow
* const win
= control
->GetInputWindow();
3237 if ( win
->CanAcceptFocus() && wxWindow::FindFocus() != win
)
3250 // ----------------------------------------------------------------------------
3251 // wxWin32ScrollBarInputHandler
3252 // ----------------------------------------------------------------------------
3254 wxWin32ScrollBarInputHandler::
3255 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
3256 : wxStdScrollBarInputHandler(renderer
, handler
)
3258 m_scrollPaused
= false;
3262 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3263 const wxControlAction
& action
)
3265 // stop if went beyond the position of the original click (this can only
3266 // happen when we scroll by pages)
3268 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3270 stop
= scrollbar
->HitTestBar(m_ptStartScrolling
) != wxHT_SCROLLBAR_BAR_2
;
3272 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3274 stop
= scrollbar
->HitTestBar(m_ptStartScrolling
) != wxHT_SCROLLBAR_BAR_1
;
3279 StopScrolling(scrollbar
);
3281 scrollbar
->Refresh();
3286 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3289 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3290 const wxMouseEvent
& event
)
3292 // remember the current state
3293 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3295 // do process the message
3296 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3298 // analyse the changes
3299 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3301 // we just started dragging the thumb, remember its initial position to
3302 // be able to restore it if the drag is cancelled later
3303 m_eventStartDrag
= event
;
3309 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3310 const wxMouseEvent
& event
)
3312 // we don't highlight scrollbar elements, so there is no need to process
3313 // mouse move events normally - only do it while mouse is captured (i.e.
3314 // when we're dragging the thumb or pressing on something)
3315 if ( !m_winCapture
)
3318 if ( event
.Entering() )
3320 // we're not interested in this at all
3324 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3326 if ( m_scrollPaused
)
3328 // check if the mouse returned to its original location
3330 if ( event
.Leaving() )
3336 ht
= scrollbar
->HitTestBar(event
.GetPosition());
3337 if ( ht
== m_htLast
)
3339 // yes it did, resume scrolling
3340 m_scrollPaused
= false;
3341 if ( m_timerScroll
)
3343 // we were scrolling by line/page, restart timer
3344 m_timerScroll
->Start(m_interval
);
3346 Press(scrollbar
, true);
3348 else // we were dragging the thumb
3350 // restore its last location
3351 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3357 else // normal case, scrolling hasn't been paused
3359 // if we're scrolling the scrollbar because the arrow or the shaft was
3360 // pressed, check that the mouse stays on the same scrollbar element
3363 // Always let thumb jump back if we leave the scrollbar
3364 if ( event
.Moving() )
3366 ht
= scrollbar
->HitTestBar(event
.GetPosition());
3368 else // event.Leaving()
3373 // Jump back only if we get far away from it
3374 wxPoint pos
= event
.GetPosition();
3375 if (scrollbar
->HasFlag( wxVERTICAL
))
3377 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
3382 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
3385 ht
= scrollbar
->HitTestBar(pos
);
3388 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3389 // is still ok - we only want to catch the case when the mouse leaves
3390 // the scrollbar here
3391 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3393 ht
= wxHT_SCROLLBAR_THUMB
;
3396 if ( ht
!= m_htLast
)
3398 // what were we doing? 2 possibilities: either an arrow/shaft was
3399 // pressed in which case we have a timer and so we just stop it or
3400 // we were dragging the thumb
3401 if ( m_timerScroll
)
3404 m_interval
= m_timerScroll
->GetInterval();
3405 m_timerScroll
->Stop();
3406 m_scrollPaused
= true;
3408 // unpress the arrow
3409 Press(scrollbar
, false);
3411 else // we were dragging the thumb
3413 // remember the current thumb position to be able to restore it
3414 // if the mouse returns to it later
3415 m_eventLastDrag
= event
;
3417 // and restore the original position (before dragging) of the
3419 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3426 return wxStdInputHandler::HandleMouseMove(control
, event
);
3429 #endif // wxUSE_SCROLLBAR
3433 // ----------------------------------------------------------------------------
3434 // wxWin32CheckboxInputHandler
3435 // ----------------------------------------------------------------------------
3437 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3438 const wxKeyEvent
& event
,
3443 wxControlAction action
;
3444 int keycode
= event
.GetKeyCode();
3448 action
= wxACTION_CHECKBOX_TOGGLE
;
3452 case WXK_NUMPAD_SUBTRACT
:
3453 action
= wxACTION_CHECKBOX_CHECK
;
3457 case WXK_NUMPAD_ADD
:
3458 case WXK_NUMPAD_EQUAL
:
3459 action
= wxACTION_CHECKBOX_CLEAR
;
3463 if ( !action
.IsEmpty() )
3465 control
->PerformAction(action
);
3474 #endif // wxUSE_CHECKBOX
3478 // ----------------------------------------------------------------------------
3479 // wxWin32TextCtrlInputHandler
3480 // ----------------------------------------------------------------------------
3482 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3483 const wxKeyEvent
& event
,
3486 // handle only MSW-specific text bindings here, the others are handled in
3490 int keycode
= event
.GetKeyCode();
3492 wxControlAction action
;
3493 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
3495 action
= wxACTION_TEXT_CUT
;
3497 else if ( keycode
== WXK_INSERT
)
3499 if ( event
.ControlDown() )
3500 action
= wxACTION_TEXT_COPY
;
3501 else if ( event
.ShiftDown() )
3502 action
= wxACTION_TEXT_PASTE
;
3505 if ( action
!= wxACTION_NONE
)
3507 control
->PerformAction(action
);
3513 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
3516 #endif // wxUSE_TEXTCTRL
3520 // ----------------------------------------------------------------------------
3521 // wxWin32StatusBarInputHandler
3522 // ----------------------------------------------------------------------------
3524 wxWin32StatusBarInputHandler::
3525 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
3526 : wxStdInputHandler(handler
)
3531 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
3532 const wxPoint
& pt
) const
3534 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
3535 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
3538 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
3540 wxCHECK_MSG( parentTLW
, false,
3541 wxT("the status bar should be a child of a TLW") );
3543 // a maximized window can't be resized anyhow
3544 if ( !parentTLW
->IsMaximized() )
3546 // VZ: I think that the standard Windows behaviour is to only
3547 // show the resizing cursor when the mouse is on top of the
3548 // grip itself but apparently different Windows versions behave
3549 // differently (?) and it seems a better UI to allow resizing
3550 // the status bar even when the mouse is above the grip
3551 wxSize sizeSbar
= statbar
->GetSize();
3553 int diff
= sizeSbar
.x
- pt
.x
;
3554 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
3561 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
3562 const wxMouseEvent
& event
)
3564 if ( event
.Button(1) )
3566 if ( event
.ButtonDown(1) )
3568 wxWindow
*statbar
= consumer
->GetInputWindow();
3570 if ( IsOnGrip(statbar
, event
.GetPosition()) )
3572 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
3576 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
3577 wxHT_TOPLEVEL_BORDER_SE
);
3579 statbar
->SetCursor(m_cursorOld
);
3587 return wxStdInputHandler::HandleMouse(consumer
, event
);
3590 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
3591 const wxMouseEvent
& event
)
3593 wxWindow
*statbar
= consumer
->GetInputWindow();
3595 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
3596 if ( isOnGrip
!= m_isOnGrip
)
3598 m_isOnGrip
= isOnGrip
;
3601 m_cursorOld
= statbar
->GetCursor();
3602 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
3606 statbar
->SetCursor(m_cursorOld
);
3610 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
3613 #endif // wxUSE_STATUSBAR
3615 // ----------------------------------------------------------------------------
3616 // wxWin32FrameInputHandler
3617 // ----------------------------------------------------------------------------
3619 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
3622 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
3624 void Attach(wxInputConsumer
*consumer
);
3628 DECLARE_EVENT_TABLE()
3629 void OnSystemMenu(wxCommandEvent
&event
);
3630 void OnCloseFrame(wxCommandEvent
&event
);
3631 void OnClose(wxCloseEvent
&event
);
3633 wxWin32FrameInputHandler
*m_inputHnd
;
3634 wxTopLevelWindow
*m_wnd
;
3636 wxAcceleratorTable m_oldAccelTable
;
3640 wxWin32SystemMenuEvtHandler::
3641 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
)
3643 m_inputHnd
= handler
;
3647 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
3649 wxASSERT_MSG( m_wnd
== NULL
, wxT("can't attach the handler twice!") );
3651 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
3652 m_wnd
->PushEventHandler(this);
3655 // VS: This code relies on using generic implementation of
3656 // wxAcceleratorTable in wxUniv!
3657 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
3658 m_oldAccelTable
= table
;
3659 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
3660 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
3661 m_wnd
->SetAcceleratorTable(table
);
3665 void wxWin32SystemMenuEvtHandler::Detach()
3670 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
3672 m_wnd
->RemoveEventHandler(this);
3677 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
3678 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
3679 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
3680 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
3683 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
3686 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
3687 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
3691 m_inputHnd
->PopupSystemMenu(m_wnd
);
3692 #endif // wxUSE_MENUS
3695 m_wnd
->SetAcceleratorTable(table
);
3699 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
3701 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
3702 wxTOPLEVEL_BUTTON_CLOSE
);
3705 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
3712 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
3713 : wxStdInputHandler(handler
)
3715 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
3718 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
3720 if ( m_menuHandler
)
3722 m_menuHandler
->Detach();
3723 delete m_menuHandler
;
3727 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
3728 const wxMouseEvent
& event
)
3730 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
3732 wxTopLevelWindow
*tlw
=
3733 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
3735 long hit
= tlw
->HitTest(event
.GetPosition());
3737 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
3739 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
3740 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
3741 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
3744 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
3746 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
3747 (event
.RightDown() &&
3748 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
3749 hit
== wxHT_TOPLEVEL_ICON
)) )
3752 PopupSystemMenu(tlw
);
3753 #endif // wxUSE_MENUS
3759 return wxStdInputHandler::HandleMouse(consumer
, event
);
3764 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
) const
3768 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
3769 menu
.Append(wxID_RESTORE_FRAME
, _("&Restore"));
3770 menu
.Append(wxID_MOVE_FRAME
, _("&Move"));
3771 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
3772 menu
.Append(wxID_RESIZE_FRAME
, _("&Size"));
3773 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
3774 menu
.Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
3775 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
3776 menu
.Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
3777 menu
.AppendSeparator();
3778 menu
.Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
3780 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
3782 if ( window
->IsMaximized() )
3784 menu
.Enable(wxID_MAXIMIZE_FRAME
, false);
3785 menu
.Enable(wxID_MOVE_FRAME
, false);
3786 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
3787 menu
.Enable(wxID_RESIZE_FRAME
, false);
3790 menu
.Enable(wxID_RESTORE_FRAME
, false);
3793 window
->PopupMenu(&menu
, wxPoint(0, 0));
3796 #endif // wxUSE_MENUS
3798 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
3801 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
3803 // always detach if active frame changed:
3804 m_menuHandler
->Detach();
3808 m_menuHandler
->Attach(consumer
);
3812 return wxStdInputHandler::HandleActivation(consumer
, activated
);
3815 #endif // wxUSE_THEME_WIN32