]> git.saurik.com Git - wxWidgets.git/blame - src/univ/themes/win32.cpp
add Inflate(wxSize) overload
[wxWidgets.git] / src / univ / themes / win32.cpp
CommitLineData
00e086a7 1///////////////////////////////////////////////////////////////////////////////
3b3dc801 2// Name: src/univ/themes/win32.cpp
1e6feb95
VZ
3// Purpose: wxUniversal theme implementing Win32-like LNF
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 06.08.00
7// RCS-ID: $Id$
442b35b5 8// Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
65571936 9// Licence: wxWindows licence
1e6feb95
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
28 #include "wx/timer.h"
29 #include "wx/intl.h"
30 #include "wx/dc.h"
31 #include "wx/window.h"
32
33 #include "wx/dcmemory.h"
34
35 #include "wx/button.h"
51e298bb 36 #include "wx/bmpbuttn.h"
1e6feb95
VZ
37 #include "wx/listbox.h"
38 #include "wx/checklst.h"
8cb172b4 39 #include "wx/combobox.h"
1e6feb95
VZ
40 #include "wx/scrolbar.h"
41 #include "wx/slider.h"
42 #include "wx/textctrl.h"
3216dbf5 43 #include "wx/toolbar.h"
c2919ab3 44 #include "wx/statusbr.h"
b72a54d1
MB
45
46 #ifdef __WXMSW__
47 // for COLOR_* constants
48 #include "wx/msw/private.h"
49 #endif
3b3dc801 50 #include "wx/menu.h"
9eddec69 51 #include "wx/settings.h"
1832043f 52 #include "wx/toplevel.h"
155ecd4c 53 #include "wx/image.h"
1e6feb95
VZ
54#endif // WX_PRECOMP
55
56#include "wx/notebook.h"
57#include "wx/spinbutt.h"
536b70ac 58#include "wx/artprov.h"
43be3c33
JS
59#ifdef wxUSE_TOGGLEBTN
60#include "wx/tglbtn.h"
61#endif // wxUSE_TOGGLEBTN
1e6feb95
VZ
62
63#include "wx/univ/scrtimer.h"
147b8a4a 64#include "wx/univ/stdrend.h"
9467bdb7 65#include "wx/univ/inpcons.h"
1e6feb95
VZ
66#include "wx/univ/inphand.h"
67#include "wx/univ/colschem.h"
68#include "wx/univ/theme.h"
69
70// ----------------------------------------------------------------------------
71// constants
72// ----------------------------------------------------------------------------
73
74static const int BORDER_THICKNESS = 2;
75
76// the offset between the label and focus rect around it
77static const int FOCUS_RECT_OFFSET_X = 1;
78static const int FOCUS_RECT_OFFSET_Y = 1;
79
24a23c35
VS
80static const int FRAME_BORDER_THICKNESS = 3;
81static const int RESIZEABLE_FRAME_BORDER_THICKNESS = 4;
82static const int FRAME_TITLEBAR_HEIGHT = 18;
83static const int FRAME_BUTTON_WIDTH = 16;
84static const int FRAME_BUTTON_HEIGHT = 14;
85
71e03035
VZ
86static const size_t NUM_STATUSBAR_GRIP_BANDS = 3;
87static const size_t WIDTH_STATUSBAR_GRIP_BAND = 4;
88static const size_t STATUSBAR_GRIP_SIZE =
89 WIDTH_STATUSBAR_GRIP_BAND*NUM_STATUSBAR_GRIP_BANDS;
90
6766e5d1
JS
91static const wxCoord SLIDER_MARGIN = 6; // margin around slider
92static const wxCoord SLIDER_THUMB_LENGTH = 18;
93static const wxCoord SLIDER_TICK_LENGTH = 6;
94
1e6feb95
VZ
95// wxWin32Renderer: draw the GUI elements in Win32 style
96// ----------------------------------------------------------------------------
97
147b8a4a 98class wxWin32Renderer : public wxStdRenderer
1e6feb95
VZ
99{
100public:
24a23c35
VS
101 enum wxFrameButtonType
102 {
103 FrameButton_Close,
104 FrameButton_Minimize,
105 FrameButton_Maximize,
106 FrameButton_Restore,
107 FrameButton_Help,
108 FrameButton_Max
109 };
110
1e6feb95
VZ
111 // ctor
112 wxWin32Renderer(const wxColourScheme *scheme);
113
147b8a4a 114 // reimplement the renderer methods which are different for this theme
1e6feb95
VZ
115 virtual void DrawLabel(wxDC& dc,
116 const wxString& label,
117 const wxRect& rect,
118 int flags = 0,
119 int alignment = wxALIGN_LEFT | wxALIGN_TOP,
120 int indexAccel = -1,
121 wxRect *rectBounds = NULL);
122 virtual void DrawButtonLabel(wxDC& dc,
123 const wxString& label,
124 const wxBitmap& image,
125 const wxRect& rect,
126 int flags = 0,
127 int alignment = wxALIGN_LEFT | wxALIGN_TOP,
128 int indexAccel = -1,
129 wxRect *rectBounds = NULL);
1e6feb95
VZ
130 virtual void DrawButtonBorder(wxDC& dc,
131 const wxRect& rect,
132 int flags = 0,
147b8a4a 133 wxRect *rectIn = NULL);
0428ac8c 134
1e6feb95
VZ
135 virtual void DrawArrow(wxDC& dc,
136 wxDirection dir,
137 const wxRect& rect,
138 int flags = 0);
1e6feb95
VZ
139 virtual void DrawScrollbarThumb(wxDC& dc,
140 wxOrientation orient,
141 const wxRect& rect,
142 int flags = 0);
143 virtual void DrawScrollbarShaft(wxDC& dc,
144 wxOrientation orient,
145 const wxRect& rect,
146 int flags = 0);
147b8a4a 147
9a6384ca 148#if wxUSE_TOOLBAR
3216dbf5
VZ
149 virtual void DrawToolBarButton(wxDC& dc,
150 const wxString& label,
151 const wxBitmap& bitmap,
152 const wxRect& rect,
a8f4cabe 153 int flags = 0,
370efbe7
WS
154 long style = 0,
155 int tbarStyle = 0);
9a6384ca 156#endif // wxUSE_TOOLBAR
147b8a4a 157
c4036939 158#if wxUSE_NOTEBOOK
1e6feb95
VZ
159 virtual void DrawTab(wxDC& dc,
160 const wxRect& rect,
161 wxDirection dir,
162 const wxString& label,
163 const wxBitmap& bitmap = wxNullBitmap,
164 int flags = 0,
165 int indexAccel = -1);
c4036939 166#endif // wxUSE_NOTEBOOK
1e6feb95 167
9a6384ca 168#if wxUSE_SLIDER
1e6feb95
VZ
169 virtual void DrawSliderShaft(wxDC& dc,
170 const wxRect& rect,
6766e5d1 171 int lenThumb,
1e6feb95
VZ
172 wxOrientation orient,
173 int flags = 0,
6766e5d1 174 long style = 0,
1e6feb95
VZ
175 wxRect *rectShaft = NULL);
176 virtual void DrawSliderThumb(wxDC& dc,
177 const wxRect& rect,
178 wxOrientation orient,
6766e5d1
JS
179 int flags = 0,
180 long style = 0);
1e6feb95
VZ
181 virtual void DrawSliderTicks(wxDC& dc,
182 const wxRect& rect,
6766e5d1 183 int lenThumb,
1e6feb95
VZ
184 wxOrientation orient,
185 int start,
186 int end,
187 int step = 1,
6766e5d1
JS
188 int flags = 0,
189 long style = 0);
9a6384ca 190#endif // wxUSE_SLIDER
1e6feb95 191
9a6384ca 192#if wxUSE_MENUS
1e6feb95
VZ
193 virtual void DrawMenuBarItem(wxDC& dc,
194 const wxRect& rect,
195 const wxString& label,
196 int flags = 0,
197 int indexAccel = -1);
198 virtual void DrawMenuItem(wxDC& dc,
199 wxCoord y,
200 const wxMenuGeometryInfo& geometryInfo,
201 const wxString& label,
202 const wxString& accel,
203 const wxBitmap& bitmap = wxNullBitmap,
204 int flags = 0,
205 int indexAccel = -1);
206 virtual void DrawMenuSeparator(wxDC& dc,
207 wxCoord y,
208 const wxMenuGeometryInfo& geomInfo);
9a6384ca 209#endif // wxUSE_MENUS
71e03035 210
9a6384ca 211#if wxUSE_STATUSBAR
71e03035
VZ
212 virtual void DrawStatusField(wxDC& dc,
213 const wxRect& rect,
214 const wxString& label,
c2919ab3 215 int flags = 0, int style = 0);
9a6384ca 216#endif // wxUSE_STATUSBAR
71e03035 217
24a23c35
VS
218 // titlebars
219 virtual void DrawFrameTitleBar(wxDC& dc,
220 const wxRect& rect,
221 const wxString& title,
222 const wxIcon& icon,
223 int flags,
813edf09
VS
224 int specialButton = 0,
225 int specialButtonFlags = 0);
24a23c35
VS
226 virtual void DrawFrameBorder(wxDC& dc,
227 const wxRect& rect,
228 int flags);
229 virtual void DrawFrameBackground(wxDC& dc,
230 const wxRect& rect,
231 int flags);
232 virtual void DrawFrameTitle(wxDC& dc,
233 const wxRect& rect,
234 const wxString& title,
235 int flags);
236 virtual void DrawFrameIcon(wxDC& dc,
237 const wxRect& rect,
238 const wxIcon& icon,
239 int flags);
240 virtual void DrawFrameButton(wxDC& dc,
241 wxCoord x, wxCoord y,
242 int button,
243 int flags = 0);
244 virtual wxRect GetFrameClientArea(const wxRect& rect, int flags) const;
245 virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const;
e7dda1ff 246 virtual wxSize GetFrameMinSize(int flags) const;
24a23c35 247 virtual wxSize GetFrameIconSize() const;
813edf09 248 virtual int HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const;
24a23c35 249
1e6feb95 250 virtual void GetComboBitmaps(wxBitmap *bmpNormal,
1b465102 251 wxBitmap *bmpFocus,
1e6feb95
VZ
252 wxBitmap *bmpPressed,
253 wxBitmap *bmpDisabled);
254
255 virtual void AdjustSize(wxSize *size, const wxWindow *window);
1e6feb95
VZ
256 virtual bool AreScrollbarsInsideBorder() const;
257
258 virtual wxSize GetScrollbarArrowSize() const
259 { return m_sizeScrollbarArrow; }
9a6384ca 260
1e6feb95
VZ
261 virtual wxCoord GetListboxItemHeight(wxCoord fontHeight)
262 { return fontHeight + 2; }
263 virtual wxSize GetCheckBitmapSize() const
264 { return wxSize(13, 13); }
265 virtual wxSize GetRadioBitmapSize() const
266 { return wxSize(12, 12); }
267 virtual wxCoord GetCheckItemMargin() const
268 { return 0; }
269
3216dbf5
VZ
270 virtual wxSize GetToolBarButtonSize(wxCoord *separator) const
271 { if ( separator ) *separator = 5; return wxSize(16, 15); }
272 virtual wxSize GetToolBarMargin() const
34d26f42 273 { return wxSize(4, 4); }
3216dbf5 274
9a6384ca 275#if wxUSE_TEXTCTRL
1e6feb95 276 virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
3216dbf5 277 const wxRect& rect) const;
1e6feb95
VZ
278 virtual wxRect GetTextClientArea(const wxTextCtrl *text,
279 const wxRect& rect,
3216dbf5 280 wxCoord *extraSpaceBeyond) const;
9a6384ca 281#endif // wxUSE_TEXTCTRL
1e6feb95 282
c4036939 283#if wxUSE_NOTEBOOK
1e6feb95
VZ
284 virtual wxSize GetTabIndent() const { return wxSize(2, 2); }
285 virtual wxSize GetTabPadding() const { return wxSize(6, 5); }
c4036939 286#endif // wxUSE_NOTEBOOK
1e6feb95 287
9a6384ca
WS
288#if wxUSE_SLIDER
289
6766e5d1
JS
290 virtual wxCoord GetSliderDim() const { return SLIDER_THUMB_LENGTH + 2*BORDER_THICKNESS; }
291 virtual wxCoord GetSliderTickLen() const { return SLIDER_TICK_LENGTH; }
1e6feb95 292 virtual wxRect GetSliderShaftRect(const wxRect& rect,
6766e5d1
JS
293 int lenThumb,
294 wxOrientation orient,
295 long style = 0) const;
1e6feb95 296 virtual wxSize GetSliderThumbSize(const wxRect& rect,
6766e5d1 297 int lenThumb,
1e6feb95 298 wxOrientation orient) const;
9a6384ca
WS
299#endif // wxUSE_SLIDER
300
1e6feb95
VZ
301 virtual wxSize GetProgressBarStep() const { return wxSize(16, 32); }
302
9a6384ca 303#if wxUSE_MENUS
1e6feb95
VZ
304 virtual wxSize GetMenuBarItemSize(const wxSize& sizeText) const;
305 virtual wxMenuGeometryInfo *GetMenuGeometry(wxWindow *win,
306 const wxMenu& menu) const;
9a6384ca 307#endif // wxUSE_MENUS
71e03035 308
9a6384ca 309#if wxUSE_STATUSBAR
71e03035 310 virtual wxSize GetStatusBarBorders(wxCoord *borderBetweenFields) const;
9a6384ca 311#endif // wxUSE_STATUSBAR
71e03035 312
1e6feb95 313protected:
6229b92f 314 // overridden wxStdRenderer methods
147b8a4a
VZ
315 virtual void DrawFrameWithLabel(wxDC& dc,
316 const wxString& label,
317 const wxRect& rectFrame,
318 const wxRect& rectText,
319 int flags,
320 int alignment,
321 int indexAccel);
1e6feb95 322
6229b92f
VZ
323 virtual void DrawCheckItemBitmap(wxDC& dc,
324 const wxBitmap& bitmap,
325 const wxRect& rect,
326 int flags);
327
1e6feb95
VZ
328
329 // draw the border used for scrollbar arrows
a290fa5a 330 void DrawArrowBorder(wxDC& dc, wxRect *rect, bool isPressed = false);
1e6feb95
VZ
331
332 // public DrawArrow()s helper
333 void DrawArrow(wxDC& dc, const wxRect& rect,
0428ac8c 334 ArrowDirection arrowDir, ArrowStyle arrowStyle);
1e6feb95
VZ
335
336 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
337 void DrawArrowButton(wxDC& dc, const wxRect& rect,
0428ac8c
VZ
338 ArrowDirection arrowDir,
339 ArrowStyle arrowStyle);
1e6feb95 340
1e6feb95
VZ
341 // draw a normal or transposed line (useful for using the same code fo both
342 // horizontal and vertical widgets)
343 void DrawLine(wxDC& dc,
344 wxCoord x1, wxCoord y1,
345 wxCoord x2, wxCoord y2,
a290fa5a 346 bool transpose = false)
1e6feb95
VZ
347 {
348 if ( transpose )
349 dc.DrawLine(y1, x1, y2, x2);
350 else
351 dc.DrawLine(x1, y1, x2, y2);
352 }
353
354 // get the standard check/radio button bitmap
355 wxBitmap GetIndicator(IndicatorType indType, int flags);
6229b92f 356 virtual wxBitmap GetCheckBitmap(int flags)
1e6feb95 357 { return GetIndicator(IndicatorType_Check, flags); }
6229b92f 358 virtual wxBitmap GetRadioBitmap(int flags)
1e6feb95
VZ
359 { return GetIndicator(IndicatorType_Radio, flags); }
360
361private:
1e6feb95
VZ
362 // the sizing parameters (TODO make them changeable)
363 wxSize m_sizeScrollbarArrow;
364
24a23c35 365 wxFont m_titlebarFont;
71e03035 366
6229b92f 367 // the checked and unchecked bitmaps for DrawCheckItemBitmap()
e3400e2e
VZ
368 wxBitmap m_bmpCheckBitmaps[IndicatorStatus_Max];
369
370 // the bitmaps returned by GetIndicator()
371 wxBitmap m_bmpIndicators[IndicatorType_Max]
147b8a4a 372 [IndicatorState_MaxMenu]
e3400e2e
VZ
373 [IndicatorStatus_Max];
374
147b8a4a
VZ
375 // standard defaults for m_bmpCheckBitmaps and m_bmpIndicators
376 static const char **ms_xpmChecked[IndicatorStatus_Max];
377 static const char **ms_xpmIndicators[IndicatorType_Max]
378 [IndicatorState_MaxMenu]
379 [IndicatorStatus_Max];
380
24a23c35
VS
381 // titlebar icons:
382 wxBitmap m_bmpFrameButtons[FrameButton_Max];
1e6feb95
VZ
383
384 // first row is for the normal state, second - for the disabled
385 wxBitmap m_bmpArrows[Arrow_StateMax][Arrow_Max];
386};
387
388// ----------------------------------------------------------------------------
389// wxWin32InputHandler and derived classes: process the keyboard and mouse
390// messages according to Windows standards
391// ----------------------------------------------------------------------------
392
393class wxWin32InputHandler : public wxInputHandler
394{
395public:
9467bdb7 396 wxWin32InputHandler() { }
1e6feb95 397
67e49a98 398 virtual bool HandleKey(wxInputConsumer *control,
1e6feb95
VZ
399 const wxKeyEvent& event,
400 bool pressed);
67e49a98 401 virtual bool HandleMouse(wxInputConsumer *control,
1e6feb95 402 const wxMouseEvent& event);
1e6feb95
VZ
403};
404
9a6384ca 405#if wxUSE_SCROLLBAR
1e6feb95
VZ
406class wxWin32ScrollBarInputHandler : public wxStdScrollBarInputHandler
407{
408public:
9467bdb7 409 wxWin32ScrollBarInputHandler(wxRenderer *renderer,
1e6feb95
VZ
410 wxInputHandler *handler);
411
9467bdb7
VZ
412 virtual bool HandleMouse(wxInputConsumer *control,
413 const wxMouseEvent& event);
414 virtual bool HandleMouseMove(wxInputConsumer *control,
415 const wxMouseEvent& event);
1e6feb95
VZ
416
417 virtual bool OnScrollTimer(wxScrollBar *scrollbar,
418 const wxControlAction& action);
419
420protected:
61fef19b
VZ
421 virtual void Highlight(wxScrollBar * WXUNUSED(scrollbar),
422 bool WXUNUSED(doIt))
1e6feb95
VZ
423 {
424 // we don't highlight anything
425 }
426
427 // the first and last event which caused the thumb to move
428 wxMouseEvent m_eventStartDrag,
429 m_eventLastDrag;
430
431 // have we paused the scrolling because the mouse moved?
432 bool m_scrollPaused;
433
434 // we remember the interval of the timer to be able to restart it
435 int m_interval;
436};
9a6384ca 437#endif // wxUSE_SCROLLBAR
1e6feb95 438
9a6384ca 439#if wxUSE_CHECKBOX
9467bdb7 440class wxWin32CheckboxInputHandler : public wxStdInputHandler
1e6feb95
VZ
441{
442public:
443 wxWin32CheckboxInputHandler(wxInputHandler *handler)
9467bdb7 444 : wxStdInputHandler(handler) { }
1e6feb95 445
67e49a98 446 virtual bool HandleKey(wxInputConsumer *control,
1e6feb95
VZ
447 const wxKeyEvent& event,
448 bool pressed);
449};
9a6384ca 450#endif // wxUSE_CHECKBOX
1e6feb95 451
9a6384ca 452#if wxUSE_TEXTCTRL
9467bdb7 453class wxWin32TextCtrlInputHandler : public wxStdInputHandler
1e6feb95
VZ
454{
455public:
456 wxWin32TextCtrlInputHandler(wxInputHandler *handler)
9467bdb7 457 : wxStdInputHandler(handler) { }
1e6feb95 458
67e49a98 459 virtual bool HandleKey(wxInputConsumer *control,
1e6feb95
VZ
460 const wxKeyEvent& event,
461 bool pressed);
462};
9a6384ca 463#endif // wxUSE_TEXTCTRL
1e6feb95 464
71e03035
VZ
465class wxWin32StatusBarInputHandler : public wxStdInputHandler
466{
467public:
468 wxWin32StatusBarInputHandler(wxInputHandler *handler);
469
470 virtual bool HandleMouse(wxInputConsumer *consumer,
471 const wxMouseEvent& event);
472
473 virtual bool HandleMouseMove(wxInputConsumer *consumer,
474 const wxMouseEvent& event);
475
476protected:
477 // is the given point over the statusbar grip?
478 bool IsOnGrip(wxWindow *statbar, const wxPoint& pt) const;
479
480private:
481 // the cursor we had replaced with the resize one
482 wxCursor m_cursorOld;
483
484 // was the mouse over the grip last time we checked?
485 bool m_isOnGrip;
486};
487
8f71aafa
VS
488class wxWin32SystemMenuEvtHandler;
489
9467bdb7 490class wxWin32FrameInputHandler : public wxStdInputHandler
768f0c5a
VS
491{
492public:
2279b45a 493 wxWin32FrameInputHandler(wxInputHandler *handler);
d3c7fc99 494 virtual ~wxWin32FrameInputHandler();
768f0c5a
VS
495
496 virtual bool HandleMouse(wxInputConsumer *control,
497 const wxMouseEvent& event);
8f71aafa
VS
498
499 virtual bool HandleActivation(wxInputConsumer *consumer, bool activated);
00e086a7 500
9a6384ca 501#if wxUSE_MENUS
8f71aafa 502 void PopupSystemMenu(wxTopLevelWindow *window, const wxPoint& pos) const;
9a6384ca 503#endif // wxUSE_MENUS
8f71aafa
VS
504
505private:
506 // was the mouse over the grip last time we checked?
507 wxWin32SystemMenuEvtHandler *m_menuHandler;
768f0c5a
VS
508};
509
1e6feb95
VZ
510// ----------------------------------------------------------------------------
511// wxWin32ColourScheme: uses (default) Win32 colours
512// ----------------------------------------------------------------------------
513
514class wxWin32ColourScheme : public wxColourScheme
515{
516public:
517 virtual wxColour Get(StdColour col) const;
518 virtual wxColour GetBackground(wxWindow *win) const;
519};
520
536b70ac
VS
521// ----------------------------------------------------------------------------
522// wxWin32ArtProvider
523// ----------------------------------------------------------------------------
524
525class wxWin32ArtProvider : public wxArtProvider
526{
527protected:
528 virtual wxBitmap CreateBitmap(const wxArtID& id,
529 const wxArtClient& client,
530 const wxSize& size);
531};
532
1e6feb95
VZ
533// ----------------------------------------------------------------------------
534// wxWin32Theme
535// ----------------------------------------------------------------------------
536
d5d29b8a 537WX_DEFINE_ARRAY_PTR(wxInputHandler *, wxArrayHandlers);
1e6feb95
VZ
538
539class wxWin32Theme : public wxTheme
540{
541public:
542 wxWin32Theme();
543 virtual ~wxWin32Theme();
544
240889a1 545 virtual wxRenderer *GetRenderer();
536b70ac 546 virtual wxArtProvider *GetArtProvider();
9467bdb7
VZ
547 virtual wxInputHandler *GetInputHandler(const wxString& control,
548 wxInputConsumer *consumer);
1e6feb95
VZ
549 virtual wxColourScheme *GetColourScheme();
550
551private:
1e6feb95 552 wxWin32Renderer *m_renderer;
00e086a7 553
536b70ac 554 wxWin32ArtProvider *m_artProvider;
1e6feb95
VZ
555
556 // the names of the already created handlers and the handlers themselves
557 // (these arrays are synchronized)
558 wxSortedArrayString m_handlerNames;
559 wxArrayHandlers m_handlers;
560
1e6feb95
VZ
561 wxWin32ColourScheme *m_scheme;
562
563 WX_DECLARE_THEME(win32)
564};
565
566// ----------------------------------------------------------------------------
567// standard bitmaps
568// ----------------------------------------------------------------------------
569
24a23c35
VS
570// frame buttons bitmaps
571
572static const char *frame_button_close_xpm[] = {
573"12 10 2 1",
cc4bc3a0
VZ
574" c None",
575". c black",
24a23c35
VS
576" ",
577" .. .. ",
578" .. .. ",
579" .... ",
580" .. ",
581" .... ",
582" .. .. ",
583" .. .. ",
584" ",
585" "};
586
587static const char *frame_button_help_xpm[] = {
588"12 10 2 1",
cc4bc3a0
VZ
589" c None",
590". c #000000",
24a23c35
VS
591" .... ",
592" .. .. ",
593" .. .. ",
594" .. ",
595" .. ",
596" .. ",
597" ",
598" .. ",
599" .. ",
600" "};
601
602static const char *frame_button_maximize_xpm[] = {
603"12 10 2 1",
cc4bc3a0
VZ
604" c None",
605". c #000000",
24a23c35
VS
606" ......... ",
607" ......... ",
608" . . ",
609" . . ",
610" . . ",
611" . . ",
612" . . ",
613" . . ",
614" ......... ",
615" "};
616
617static const char *frame_button_minimize_xpm[] = {
618"12 10 2 1",
cc4bc3a0
VZ
619" c None",
620". c #000000",
24a23c35
VS
621" ",
622" ",
623" ",
624" ",
625" ",
626" ",
627" ",
628" ...... ",
629" ...... ",
630" "};
631
632static const char *frame_button_restore_xpm[] = {
633"12 10 2 1",
cc4bc3a0
VZ
634" c None",
635". c #000000",
24a23c35
VS
636" ...... ",
637" ...... ",
638" . . ",
639" ...... . ",
640" ...... . ",
641" . ... ",
642" . . ",
643" . . ",
644" ...... ",
645" "};
646
1e6feb95
VZ
647// menu bitmaps
648
649static const char *checked_menu_xpm[] = {
650/* columns rows colors chars-per-pixel */
651"9 9 2 1",
652"w c None",
653"b c black",
654/* pixels */
655"wwwwwwwww",
656"wwwwwwwbw",
657"wwwwwwbbw",
658"wbwwwbbbw",
659"wbbwbbbww",
660"wbbbbbwww",
661"wwbbbwwww",
662"wwwbwwwww",
663"wwwwwwwww"
664};
665
666static const char *selected_checked_menu_xpm[] = {
667/* columns rows colors chars-per-pixel */
668"9 9 2 1",
669"w c None",
670"b c white",
671/* pixels */
672"wwwwwwwww",
673"wwwwwwwbw",
674"wwwwwwbbw",
675"wbwwwbbbw",
676"wbbwbbbww",
677"wbbbbbwww",
678"wwbbbwwww",
679"wwwbwwwww",
680"wwwwwwwww"
681};
682
683static const char *disabled_checked_menu_xpm[] = {
684/* columns rows colors chars-per-pixel */
685"9 9 3 1",
686"w c None",
687"b c #7f7f7f",
688"W c #e0e0e0",
689/* pixels */
690"wwwwwwwww",
691"wwwwwwwbw",
692"wwwwwwbbW",
693"wbwwwbbbW",
694"wbbwbbbWW",
695"wbbbbbWWw",
696"wwbbbWWww",
697"wwwbWWwww",
698"wwwwWwwww"
699};
700
701static const char *selected_disabled_checked_menu_xpm[] = {
702/* columns rows colors chars-per-pixel */
703"9 9 2 1",
704"w c None",
705"b c #7f7f7f",
706/* pixels */
707"wwwwwwwww",
708"wwwwwwwbw",
709"wwwwwwbbw",
710"wbwwwbbbw",
711"wbbwbbbww",
712"wbbbbbwww",
713"wwbbbwwww",
714"wwwbwwwww",
715"wwwwwwwww"
716};
717
718// checkbox and radiobox bitmaps below
719
720static const char *checked_xpm[] = {
721/* columns rows colors chars-per-pixel */
722"13 13 5 1",
723"w c white",
724"b c black",
725"d c #7f7f7f",
726"g c #c0c0c0",
727"h c #e0e0e0",
728/* pixels */
729"ddddddddddddh",
730"dbbbbbbbbbbgh",
731"dbwwwwwwwwwgh",
732"dbwwwwwwwbwgh",
733"dbwwwwwwbbwgh",
734"dbwbwwwbbbwgh",
735"dbwbbwbbbwwgh",
736"dbwbbbbbwwwgh",
737"dbwwbbbwwwwgh",
738"dbwwwbwwwwwgh",
739"dbwwwwwwwwwgh",
740"dgggggggggggh",
741"hhhhhhhhhhhhh"
742};
743
744static const char *pressed_checked_xpm[] = {
745/* columns rows colors chars-per-pixel */
746"13 13 4 1",
747"b c black",
748"d c #7f7f7f",
749"g c #c0c0c0",
750"h c #e0e0e0",
751/* pixels */
752"ddddddddddddh",
753"dbbbbbbbbbbgh",
754"dbggggggggggh",
755"dbgggggggbggh",
756"dbggggggbbggh",
757"dbgbgggbbbggh",
758"dbgbbgbbbgggh",
759"dbgbbbbbggggh",
760"dbggbbbgggggh",
761"dbgggbggggggh",
762"dbggggggggggh",
763"dgggggggggggh",
764"hhhhhhhhhhhhh"
765};
766
767static const char *pressed_disabled_checked_xpm[] = {
768/* columns rows colors chars-per-pixel */
769"13 13 4 1",
770"b c black",
771"d c #7f7f7f",
772"g c #c0c0c0",
773"h c #e0e0e0",
774/* pixels */
775"ddddddddddddh",
776"dbbbbbbbbbbgh",
777"dbggggggggggh",
778"dbgggggggdggh",
779"dbggggggddggh",
780"dbgdgggdddggh",
781"dbgddgdddgggh",
782"dbgdddddggggh",
783"dbggdddgggggh",
784"dbgggdggggggh",
785"dbggggggggggh",
786"dgggggggggggh",
787"hhhhhhhhhhhhh"
788};
789
790static const char *checked_item_xpm[] = {
791/* columns rows colors chars-per-pixel */
792"13 13 3 1",
793"w c white",
794"b c black",
795"d c #808080",
796/* pixels */
797"wwwwwwwwwwwww",
798"wdddddddddddw",
799"wdwwwwwwwwwdw",
800"wdwwwwwwwbwdw",
801"wdwwwwwwbbwdw",
802"wdwbwwwbbbwdw",
803"wdwbbwbbbwwdw",
804"wdwbbbbbwwwdw",
805"wdwwbbbwwwwdw",
806"wdwwwbwwwwwdw",
807"wdwwwwwwwwwdw",
808"wdddddddddddw",
809"wwwwwwwwwwwww"
810};
811
812static const char *unchecked_xpm[] = {
813/* columns rows colors chars-per-pixel */
814"13 13 5 1",
815"w c white",
816"b c black",
817"d c #7f7f7f",
818"g c #c0c0c0",
819"h c #e0e0e0",
820/* pixels */
821"ddddddddddddh",
822"dbbbbbbbbbbgh",
823"dbwwwwwwwwwgh",
824"dbwwwwwwwwwgh",
825"dbwwwwwwwwwgh",
826"dbwwwwwwwwwgh",
827"dbwwwwwwwwwgh",
828"dbwwwwwwwwwgh",
829"dbwwwwwwwwwgh",
830"dbwwwwwwwwwgh",
831"dbwwwwwwwwwgh",
832"dgggggggggggh",
833"hhhhhhhhhhhhh"
834};
835
836static const char *pressed_unchecked_xpm[] = {
837/* columns rows colors chars-per-pixel */
838"13 13 4 1",
839"b c black",
840"d c #7f7f7f",
841"g c #c0c0c0",
842"h c #e0e0e0",
843/* pixels */
844"ddddddddddddh",
845"dbbbbbbbbbbgh",
846"dbggggggggggh",
847"dbggggggggggh",
848"dbggggggggggh",
849"dbggggggggggh",
850"dbggggggggggh",
851"dbggggggggggh",
852"dbggggggggggh",
853"dbggggggggggh",
854"dbggggggggggh",
855"dbggggggggggh",
856"hhhhhhhhhhhhh"
857};
858
859static const char *unchecked_item_xpm[] = {
860/* columns rows colors chars-per-pixel */
861"13 13 2 1",
862"w c white",
863"d c #808080",
864/* pixels */
865"wwwwwwwwwwwww",
866"wdddddddddddw",
867"wdwwwwwwwwwdw",
868"wdwwwwwwwwwdw",
869"wdwwwwwwwwwdw",
870"wdwwwwwwwwwdw",
871"wdwwwwwwwwwdw",
872"wdwwwwwwwwwdw",
873"wdwwwwwwwwwdw",
874"wdwwwwwwwwwdw",
875"wdwwwwwwwwwdw",
876"wdddddddddddw",
877"wwwwwwwwwwwww"
878};
879
415a0ff1
WS
880static const char *undetermined_xpm[] = {
881/* columns rows colors chars-per-pixel */
882"13 13 5 1",
883"A c #030303",
884"B c #838383",
885"C c #C3C3C3",
886"D c #FBFBFB",
887"E c #DBDBDB",
888/* pixels */
889"BBBBBBBBBBBBD",
890"BAAAAAAAAAAED",
891"BACDCDCDCDCED",
892"BADCDCDCDBDED",
893"BACDCDCDBBCED",
894"BADBDCEBBBDED",
895"BACBBDBBBDCED",
896"BADBBBBBDCDED",
897"BACDBBBDCDCED",
898"BADCDBDCDCDED",
899"BACDCDCDCDCED",
900"BEEEEEEEEEEED",
901"DDDDDDDDDDDDD"
902};
903
904static const char *pressed_undetermined_xpm[] = {
905/* columns rows colors chars-per-pixel */
906"13 13 5 1",
907"A c #040404",
908"B c #848484",
909"C c #C4C4C4",
910"D c #FCFCFC",
911"E c #DCDCDC",
912/* pixels */
913"BBBBBBBBBBBBD",
914"BAAAAAAAAAAED",
915"BACCCCCCCCCCD",
916"BACCCCCCCACED",
917"BACCCCCCAACED",
918"BACACCCAAACED",
919"BACAACAAACCED",
920"BACAAAAACCCED",
921"BACCAAACCCCCD",
922"BACCCACCCCCED",
923"BACCCCCCCCCED",
924"BEEEEEEEEEEED",
925"DDDDDDDDDDDDD"
926};
927
1e6feb95
VZ
928static const char *checked_radio_xpm[] = {
929/* columns rows colors chars-per-pixel */
930"12 12 6 1",
931" c None",
932"w c white",
933"b c black",
934"d c #7f7f7f",
935"g c #c0c0c0",
936"h c #e0e0e0",
937/* pixels */
938" dddd ",
939" ddbbbbdd ",
940" dbbwwwwbbh ",
941" dbwwwwwwgh ",
942"dbwwwbbwwwgh",
943"dbwwbbbbwwgh",
944"dbwwbbbbwwgh",
945"dbwwwbbwwwgh",
946" dbwwwwwwgh ",
947" dggwwwwggh ",
948" hhgggghh ",
949" hhhh "
950};
951
952static const char *pressed_checked_radio_xpm[] = {
953/* columns rows colors chars-per-pixel */
954"12 12 6 1",
955" c None",
956"w c white",
957"b c black",
958"d c #7f7f7f",
959"g c #c0c0c0",
960"h c #e0e0e0",
961/* pixels */
962" dddd ",
963" ddbbbbdd ",
964" dbbggggbbh ",
965" dbgggggggh ",
966"dbgggbbggggh",
967"dbggbbbbgggh",
968"dbggbbbbgggh",
969"dbgggbbggggh",
970" dbgggggggh ",
971" dggggggggh ",
972" hhgggghh ",
973" hhhh "
974};
975
976static const char *pressed_disabled_checked_radio_xpm[] = {
977/* columns rows colors chars-per-pixel */
978"12 12 6 1",
979" c None",
980"w c white",
981"b c black",
982"d c #7f7f7f",
983"g c #c0c0c0",
984"h c #e0e0e0",
985/* pixels */
986" dddd ",
987" ddbbbbdd ",
988" dbbggggbbh ",
989" dbgggggggh ",
990"dbgggddggggh",
991"dbggddddgggh",
992"dbggddddgggh",
993"dbgggddggggh",
994" dbgggggggh ",
995" dggggggggh ",
996" hhgggghh ",
997" hhhh ",
998};
999
1000static const char *unchecked_radio_xpm[] = {
1001/* columns rows colors chars-per-pixel */
1002"12 12 6 1",
1003" c None",
1004"w c white",
1005"b c black",
1006"d c #7f7f7f",
1007"g c #c0c0c0",
1008"h c #e0e0e0",
1009/* pixels */
1010" dddd ",
1011" ddbbbbdd ",
1012" dbbwwwwbbh ",
1013" dbwwwwwwgh ",
1014"dbwwwwwwwwgh",
1015"dbwwwwwwwwgh",
1016"dbwwwwwwwwgh",
1017"dbwwwwwwwwgh",
1018" dbwwwwwwgh ",
1019" dggwwwwggh ",
1020" hhgggghh ",
1021" hhhh "
1022};
1023
1024static const char *pressed_unchecked_radio_xpm[] = {
1025/* columns rows colors chars-per-pixel */
1026"12 12 6 1",
1027" c None",
1028"w c white",
1029"b c black",
1030"d c #7f7f7f",
1031"g c #c0c0c0",
1032"h c #e0e0e0",
1033/* pixels */
1034" dddd ",
1035" ddbbbbdd ",
1036" dbbggggbbh ",
1037" dbgggggggh ",
1038"dbgggggggggh",
1039"dbgggggggggh",
1040"dbgggggggggh",
1041"dbgggggggggh",
1042" dbgggggggh ",
1043" dggggggggh ",
1044" hhgggghh ",
1045" hhhh "
1046};
1047
147b8a4a
VZ
1048const char **wxWin32Renderer::ms_xpmIndicators[IndicatorType_Max]
1049 [IndicatorState_MaxMenu]
1050 [IndicatorStatus_Max] =
1e6feb95
VZ
1051{
1052 // checkboxes first
1053 {
1054 // normal state
415a0ff1 1055 { checked_xpm, unchecked_xpm, undetermined_xpm },
1e6feb95
VZ
1056
1057 // pressed state
415a0ff1 1058 { pressed_checked_xpm, pressed_unchecked_xpm, pressed_undetermined_xpm },
1e6feb95
VZ
1059
1060 // disabled state
415a0ff1 1061 { pressed_disabled_checked_xpm, pressed_unchecked_xpm, pressed_disabled_checked_xpm },
1e6feb95
VZ
1062 },
1063
1064 // radio
1065 {
1066 // normal state
415a0ff1 1067 { checked_radio_xpm, unchecked_radio_xpm, NULL },
1e6feb95
VZ
1068
1069 // pressed state
415a0ff1 1070 { pressed_checked_radio_xpm, pressed_unchecked_radio_xpm, NULL },
1e6feb95
VZ
1071
1072 // disabled state
415a0ff1 1073 { pressed_disabled_checked_radio_xpm, pressed_unchecked_radio_xpm, NULL },
1e6feb95
VZ
1074 },
1075
1076 // menu
1077 {
1078 // normal state
415a0ff1 1079 { checked_menu_xpm, NULL, NULL },
1e6feb95
VZ
1080
1081 // selected state
415a0ff1 1082 { selected_checked_menu_xpm, NULL, NULL },
1e6feb95
VZ
1083
1084 // disabled state
415a0ff1 1085 { disabled_checked_menu_xpm, NULL, NULL },
1e6feb95
VZ
1086
1087 // disabled selected state
415a0ff1 1088 { selected_disabled_checked_menu_xpm, NULL, NULL },
1e6feb95
VZ
1089 }
1090};
1091
147b8a4a 1092const char **wxWin32Renderer::ms_xpmChecked[IndicatorStatus_Max] =
e3400e2e
VZ
1093{
1094 checked_item_xpm,
1095 unchecked_item_xpm
1096};
1097
1e6feb95
VZ
1098// ============================================================================
1099// implementation
1100// ============================================================================
1101
1102WX_IMPLEMENT_THEME(wxWin32Theme, win32, wxTRANSLATE("Win32 theme"));
1103
1104// ----------------------------------------------------------------------------
1105// wxWin32Theme
1106// ----------------------------------------------------------------------------
1107
1108wxWin32Theme::wxWin32Theme()
1109{
240889a1
VS
1110 m_scheme = NULL;
1111 m_renderer = NULL;
9ef3ebfb 1112 m_artProvider = NULL;
1e6feb95
VZ
1113}
1114
1115wxWin32Theme::~wxWin32Theme()
1116{
1e6feb95
VZ
1117 delete m_renderer;
1118 delete m_scheme;
9ef3ebfb 1119 wxArtProvider::RemoveProvider(m_artProvider);
1e6feb95
VZ
1120}
1121
240889a1
VS
1122wxRenderer *wxWin32Theme::GetRenderer()
1123{
1124 if ( !m_renderer )
1125 {
1126 m_renderer = new wxWin32Renderer(GetColourScheme());
1127 }
1128
1129 return m_renderer;
1130}
1131
536b70ac
VS
1132wxArtProvider *wxWin32Theme::GetArtProvider()
1133{
1134 if ( !m_artProvider )
1135 {
1136 m_artProvider = new wxWin32ArtProvider;
1137 }
1138
1139 return m_artProvider;
1140}
1141
9467bdb7
VZ
1142wxInputHandler *
1143wxWin32Theme::GetInputHandler(const wxString& control,
1144 wxInputConsumer *consumer)
1e6feb95 1145{
9a6384ca 1146 wxInputHandler *handler = NULL;
1e6feb95
VZ
1147 int n = m_handlerNames.Index(control);
1148 if ( n == wxNOT_FOUND )
1149 {
9467bdb7
VZ
1150 static wxWin32InputHandler s_handlerDef;
1151
1152 wxInputHandler * const
1153 handlerStd = consumer->DoGetStdInputHandler(&s_handlerDef);
1154
1e6feb95 1155 // create a new handler
9467bdb7 1156 if ( control == wxINP_HANDLER_TOPLEVEL )
9a6384ca 1157 {
9467bdb7
VZ
1158 static wxWin32FrameInputHandler s_handler(handlerStd);
1159
1160 handler = &s_handler;
9a6384ca 1161 }
1e6feb95
VZ
1162#if wxUSE_CHECKBOX
1163 else if ( control == wxINP_HANDLER_CHECKBOX )
9467bdb7
VZ
1164 {
1165 static wxWin32CheckboxInputHandler s_handler(handlerStd);
1166
1167 handler = &s_handler;
1168 }
1e6feb95 1169#endif // wxUSE_CHECKBOX
9467bdb7
VZ
1170#if wxUSE_SCROLLBAR
1171 else if ( control == wxINP_HANDLER_SCROLLBAR )
1172 {
1173 static wxWin32ScrollBarInputHandler
1174 s_handler(GetRenderer(), handlerStd);
1175
1176 handler = &s_handler;
1177 }
1178#endif // wxUSE_SCROLLBAR
71e03035
VZ
1179#if wxUSE_STATUSBAR
1180 else if ( control == wxINP_HANDLER_STATUSBAR )
9467bdb7
VZ
1181 {
1182 static wxWin32StatusBarInputHandler s_handler(handlerStd);
1183
1184 handler = &s_handler;
1185 }
71e03035 1186#endif // wxUSE_STATUSBAR
9467bdb7
VZ
1187#if wxUSE_TEXTCTRL
1188 else if ( control == wxINP_HANDLER_TEXTCTRL )
1189 {
1190 static wxWin32TextCtrlInputHandler s_handler(handlerStd);
9a6384ca 1191
9467bdb7
VZ
1192 handler = &s_handler;
1193 }
1194#endif // wxUSE_TEXTCTRL
1195 else // no special handler for this control
1196 {
1197 handler = handlerStd;
1198 }
1e6feb95
VZ
1199
1200 n = m_handlerNames.Add(control);
1201 m_handlers.Insert(handler, n);
1202 }
1203 else // we already have it
1204 {
1205 handler = m_handlers[n];
1206 }
1207
1208 return handler;
1209}
1210
1211wxColourScheme *wxWin32Theme::GetColourScheme()
1212{
240889a1
VS
1213 if ( !m_scheme )
1214 {
1215 m_scheme = new wxWin32ColourScheme;
1216 }
1e6feb95
VZ
1217 return m_scheme;
1218}
1219
1220// ============================================================================
1221// wxWin32ColourScheme
1222// ============================================================================
1223
1224wxColour wxWin32ColourScheme::GetBackground(wxWindow *win) const
1225{
1226 wxColour col;
1227 if ( win->UseBgCol() )
1228 {
1229 // use the user specified colour
1230 col = win->GetBackgroundColour();
1231 }
1232
230205ae 1233 if ( !win->ShouldInheritColours() )
1e6feb95 1234 {
9a6384ca 1235#if wxUSE_TEXTCTRL
1e6feb95 1236 wxTextCtrl *text = wxDynamicCast(win, wxTextCtrl);
9a6384ca 1237#endif // wxUSE_TEXTCTRL
aeb3c1cb
JS
1238#if wxUSE_LISTBOX
1239 wxListBox* listBox = wxDynamicCast(win, wxListBox);
9a6384ca
WS
1240#endif // wxUSE_LISTBOX
1241
1242#if wxUSE_TEXTCTRL
aeb3c1cb
JS
1243 if ( text
1244#if wxUSE_LISTBOX
1245 || listBox
00e086a7 1246#endif
aeb3c1cb 1247 )
1e6feb95 1248 {
aeb3c1cb 1249 if ( !win->IsEnabled() ) // not IsEditable()
1e6feb95 1250 col = Get(CONTROL);
aeb3c1cb
JS
1251 else
1252 {
1253 if ( !col.Ok() )
1254 {
1255 // doesn't depend on the state
1256 col = Get(WINDOW);
1257 }
1258 }
1e6feb95 1259 }
9a6384ca 1260#endif // wxUSE_TEXTCTRL
00e086a7 1261
aeb3c1cb
JS
1262 if (!col.Ok())
1263 col = Get(CONTROL); // Most controls should be this colour, not WINDOW
1e6feb95
VZ
1264 }
1265 else
1266 {
1267 int flags = win->GetStateFlags();
1268
1269 // the colour set by the user should be used for the normal state
1270 // and for the states for which we don't have any specific colours
072a81ba 1271 if ( !col.Ok() || (flags & wxCONTROL_PRESSED) != 0 )
1e6feb95 1272 {
9a6384ca 1273#if wxUSE_SCROLLBAR
1e6feb95
VZ
1274 if ( wxDynamicCast(win, wxScrollBar) )
1275 col = Get(flags & wxCONTROL_PRESSED ? SCROLLBAR_PRESSED
1276 : SCROLLBAR);
1277 else
9a6384ca 1278#endif // wxUSE_SCROLLBAR
1e6feb95
VZ
1279 col = Get(CONTROL);
1280 }
1281 }
1282
1283 return col;
1284}
1285
1286wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const
1287{
1288 switch ( col )
1289 {
16bdba2c
VZ
1290 // use the system colours under Windows
1291#if defined(__WXMSW__)
1292 case WINDOW: return wxColour(GetSysColor(COLOR_WINDOW));
1293
1294 case CONTROL_PRESSED:
1295 case CONTROL_CURRENT:
1296 case CONTROL: return wxColour(GetSysColor(COLOR_BTNFACE));
1297
1298 case CONTROL_TEXT: return wxColour(GetSysColor(COLOR_BTNTEXT));
1299
5d3769f5
VZ
1300#if defined(COLOR_3DLIGHT)
1301 case SCROLLBAR: return wxColour(GetSysColor(COLOR_3DLIGHT));
1302#else
1303 case SCROLLBAR: return wxColour(0xe0e0e0);
1304#endif
1305 case SCROLLBAR_PRESSED: return wxColour(GetSysColor(COLOR_BTNTEXT));
16bdba2c
VZ
1306
1307 case HIGHLIGHT: return wxColour(GetSysColor(COLOR_HIGHLIGHT));
1308 case HIGHLIGHT_TEXT: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT));
1309
1310#if defined(COLOR_3DDKSHADOW)
1311 case SHADOW_DARK: return wxColour(GetSysColor(COLOR_3DDKSHADOW));
1312#else
a407ff6a 1313 case SHADOW_DARK: return wxColour(GetSysColor(COLOR_3DHADOW));
16bdba2c
VZ
1314#endif
1315
1316 case CONTROL_TEXT_DISABLED:
1317 case SHADOW_HIGHLIGHT: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT));
1318
1319 case SHADOW_IN: return wxColour(GetSysColor(COLOR_BTNFACE));
1320
1321 case CONTROL_TEXT_DISABLED_SHADOW:
1322 case SHADOW_OUT: return wxColour(GetSysColor(COLOR_BTNSHADOW));
71e03035 1323
24a23c35
VS
1324 case TITLEBAR: return wxColour(GetSysColor(COLOR_INACTIVECAPTION));
1325 case TITLEBAR_ACTIVE: return wxColour(GetSysColor(COLOR_ACTIVECAPTION));
6296744f
VS
1326 case TITLEBAR_TEXT: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT));
1327 case TITLEBAR_ACTIVE_TEXT: return wxColour(GetSysColor(COLOR_CAPTIONTEXT));
d1504049 1328
6296744f 1329 case DESKTOP: return wxColour(0x808000);
16bdba2c
VZ
1330#else // !__WXMSW__
1331 // use the standard Windows colours elsewhere
86313763
VZ
1332 case WINDOW: return *wxWHITE;
1333
1e6feb95
VZ
1334 case CONTROL_PRESSED:
1335 case CONTROL_CURRENT:
1336 case CONTROL: return wxColour(0xc0c0c0);
1337
1338 case CONTROL_TEXT: return *wxBLACK;
1339
1340 case SCROLLBAR: return wxColour(0xe0e0e0);
1341 case SCROLLBAR_PRESSED: return *wxBLACK;
1342
1343 case HIGHLIGHT: return wxColour(0x800000);
1344 case HIGHLIGHT_TEXT: return wxColour(0xffffff);
1345
1346 case SHADOW_DARK: return *wxBLACK;
1347
24a23c35
VS
1348 case CONTROL_TEXT_DISABLED:return wxColour(0xe0e0e0);
1349 case SHADOW_HIGHLIGHT: return wxColour(0xffffff);
1e6feb95
VZ
1350
1351 case SHADOW_IN: return wxColour(0xc0c0c0);
1352
1353 case CONTROL_TEXT_DISABLED_SHADOW:
1354 case SHADOW_OUT: return wxColour(0x7f7f7f);
24a23c35
VS
1355
1356 case TITLEBAR: return wxColour(0xaeaaae);
1357 case TITLEBAR_ACTIVE: return wxColour(0x820300);
6296744f
VS
1358 case TITLEBAR_TEXT: return wxColour(0xc0c0c0);
1359 case TITLEBAR_ACTIVE_TEXT:return *wxWHITE;
1360
1361 case DESKTOP: return wxColour(0x808000);
16bdba2c 1362#endif // __WXMSW__
1e6feb95 1363
a407ff6a
VZ
1364 case GAUGE: return Get(HIGHLIGHT);
1365
1e6feb95
VZ
1366 case MAX:
1367 default:
1368 wxFAIL_MSG(_T("invalid standard colour"));
1369 return *wxBLACK;
1370 }
1371}
1372
1373// ============================================================================
1374// wxWin32Renderer
1375// ============================================================================
1376
1377// ----------------------------------------------------------------------------
1378// construction
1379// ----------------------------------------------------------------------------
1380
1381wxWin32Renderer::wxWin32Renderer(const wxColourScheme *scheme)
147b8a4a 1382 : wxStdRenderer(scheme)
1e6feb95
VZ
1383{
1384 // init data
1e6feb95
VZ
1385 m_sizeScrollbarArrow = wxSize(16, 16);
1386
a756f210 1387 m_titlebarFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
24a23c35 1388 m_titlebarFont.SetWeight(wxFONTWEIGHT_BOLD);
1e6feb95
VZ
1389
1390 // init the arrow bitmaps
1391 static const size_t ARROW_WIDTH = 7;
1392 static const size_t ARROW_LENGTH = 4;
1393
1394 wxMask *mask;
1395 wxMemoryDC dcNormal,
1396 dcDisabled,
1397 dcInverse;
1398 for ( size_t n = 0; n < Arrow_Max; n++ )
1399 {
1400 bool isVertical = n > Arrow_Right;
1401 int w, h;
1402 if ( isVertical )
1403 {
1404 w = ARROW_WIDTH;
1405 h = ARROW_LENGTH;
1406 }
1407 else
1408 {
1409 h = ARROW_WIDTH;
1410 w = ARROW_LENGTH;
1411 }
1412
1413 // disabled arrow is larger because of the shadow
1414 m_bmpArrows[Arrow_Normal][n].Create(w, h);
1415 m_bmpArrows[Arrow_Disabled][n].Create(w + 1, h + 1);
1416
1417 dcNormal.SelectObject(m_bmpArrows[Arrow_Normal][n]);
1418 dcDisabled.SelectObject(m_bmpArrows[Arrow_Disabled][n]);
1419
1420 dcNormal.SetBackground(*wxWHITE_BRUSH);
1421 dcDisabled.SetBackground(*wxWHITE_BRUSH);
1422 dcNormal.Clear();
1423 dcDisabled.Clear();
1424
1425 dcNormal.SetPen(m_penBlack);
1426 dcDisabled.SetPen(m_penDarkGrey);
1427
1428 // calculate the position of the point of the arrow
1429 wxCoord x1, y1;
1430 if ( isVertical )
1431 {
1432 x1 = (ARROW_WIDTH - 1)/2;
1433 y1 = n == Arrow_Up ? 0 : ARROW_LENGTH - 1;
1434 }
1435 else // horizontal
1436 {
1437 x1 = n == Arrow_Left ? 0 : ARROW_LENGTH - 1;
1438 y1 = (ARROW_WIDTH - 1)/2;
1439 }
1440
1441 wxCoord x2 = x1,
1442 y2 = y1;
1443
1444 if ( isVertical )
1445 x2++;
1446 else
1447 y2++;
1448
1449 for ( size_t i = 0; i < ARROW_LENGTH; i++ )
1450 {
1451 dcNormal.DrawLine(x1, y1, x2, y2);
1452 dcDisabled.DrawLine(x1, y1, x2, y2);
1453
1454 if ( isVertical )
1455 {
1456 x1--;
1457 x2++;
1458
1459 if ( n == Arrow_Up )
1460 {
1461 y1++;
1462 y2++;
1463 }
1464 else // down arrow
1465 {
1466 y1--;
1467 y2--;
1468 }
1469 }
1470 else // left or right arrow
1471 {
1472 y1--;
1473 y2++;
1474
1475 if ( n == Arrow_Left )
1476 {
1477 x1++;
1478 x2++;
1479 }
1480 else
1481 {
1482 x1--;
1483 x2--;
1484 }
1485 }
1486 }
1487
1488 // draw the shadow for the disabled one
1489 dcDisabled.SetPen(m_penHighlight);
1490 switch ( n )
1491 {
1492 case Arrow_Left:
1493 y1 += 2;
1494 dcDisabled.DrawLine(x1, y1, x2, y2);
1495 break;
1496
1497 case Arrow_Right:
1498 x1 = ARROW_LENGTH - 1;
1499 y1 = (ARROW_WIDTH - 1)/2 + 1;
1500 x2 = 0;
1501 y2 = ARROW_WIDTH;
1502 dcDisabled.DrawLine(x1, y1, x2, y2);
1503 dcDisabled.DrawLine(++x1, y1, x2, ++y2);
1504 break;
1505
1506 case Arrow_Up:
1507 x1 += 2;
1508 dcDisabled.DrawLine(x1, y1, x2, y2);
1509 break;
1510
1511 case Arrow_Down:
1512 x1 = ARROW_WIDTH - 1;
1513 y1 = 1;
1514 x2 = (ARROW_WIDTH - 1)/2;
1515 y2 = ARROW_LENGTH;
1516 dcDisabled.DrawLine(x1, y1, x2, y2);
1517 dcDisabled.DrawLine(++x1, y1, x2, ++y2);
1518 break;
1519
1520 }
1521
d6922577 1522 // create the inverted bitmap but only for the right arrow as we only
1e6feb95
VZ
1523 // use it for the menus
1524 if ( n == Arrow_Right )
1525 {
d6922577
JS
1526 m_bmpArrows[Arrow_Inverted][n].Create(w, h);
1527 dcInverse.SelectObject(m_bmpArrows[Arrow_Inverted][n]);
1e6feb95
VZ
1528 dcInverse.Clear();
1529 dcInverse.Blit(0, 0, w, h,
1530 &dcNormal, 0, 0,
1531 wxXOR);
1532 dcInverse.SelectObject(wxNullBitmap);
1533
d6922577
JS
1534 mask = new wxMask(m_bmpArrows[Arrow_Inverted][n], *wxBLACK);
1535 m_bmpArrows[Arrow_Inverted][n].SetMask(mask);
1e6feb95 1536
d6922577
JS
1537 m_bmpArrows[Arrow_InvertedDisabled][n].Create(w, h);
1538 dcInverse.SelectObject(m_bmpArrows[Arrow_InvertedDisabled][n]);
1e6feb95
VZ
1539 dcInverse.Clear();
1540 dcInverse.Blit(0, 0, w, h,
1541 &dcDisabled, 0, 0,
1542 wxXOR);
1543 dcInverse.SelectObject(wxNullBitmap);
1544
d6922577
JS
1545 mask = new wxMask(m_bmpArrows[Arrow_InvertedDisabled][n], *wxBLACK);
1546 m_bmpArrows[Arrow_InvertedDisabled][n].SetMask(mask);
1e6feb95
VZ
1547 }
1548
1549 dcNormal.SelectObject(wxNullBitmap);
1550 dcDisabled.SelectObject(wxNullBitmap);
1551
1552 mask = new wxMask(m_bmpArrows[Arrow_Normal][n], *wxWHITE);
1553 m_bmpArrows[Arrow_Normal][n].SetMask(mask);
1554 mask = new wxMask(m_bmpArrows[Arrow_Disabled][n], *wxWHITE);
1555 m_bmpArrows[Arrow_Disabled][n].SetMask(mask);
1556
1557 m_bmpArrows[Arrow_Pressed][n] = m_bmpArrows[Arrow_Normal][n];
1558 }
71e03035 1559
24a23c35
VS
1560 // init the frame buttons bitmaps
1561 m_bmpFrameButtons[FrameButton_Close] = wxBitmap(frame_button_close_xpm);
1562 m_bmpFrameButtons[FrameButton_Minimize] = wxBitmap(frame_button_minimize_xpm);
1563 m_bmpFrameButtons[FrameButton_Maximize] = wxBitmap(frame_button_maximize_xpm);
1564 m_bmpFrameButtons[FrameButton_Restore] = wxBitmap(frame_button_restore_xpm);
1565 m_bmpFrameButtons[FrameButton_Help] = wxBitmap(frame_button_help_xpm);
1e6feb95
VZ
1566}
1567
1e6feb95
VZ
1568bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1569{
a290fa5a 1570 return true;
1e6feb95
VZ
1571}
1572
1e6feb95
VZ
1573// ----------------------------------------------------------------------------
1574// label
1575// ----------------------------------------------------------------------------
1576
1e6feb95
VZ
1577void wxWin32Renderer::DrawLabel(wxDC& dc,
1578 const wxString& label,
1579 const wxRect& rect,
1580 int flags,
1581 int alignment,
1582 int indexAccel,
1583 wxRect *rectBounds)
1e6feb95
VZ
1584{
1585 // the underscores are not drawn for focused controls in wxMSW
1586 if ( flags & wxCONTROL_FOCUSED )
1587 {
1588 indexAccel = -1;
1589 }
1590
1591 if ( flags & wxCONTROL_DISABLED )
1592 {
1593 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
1594 // currently only can happen for a menu item and it seems that Windows
1595 // doesn't draw the shadow in this case, so we don't do it neither
1596 if ( flags & wxCONTROL_SELECTED )
1597 {
1598 // just make the label text greyed out
147b8a4a
VZ
1599 dc.SetTextForeground(m_penDarkGrey.GetColour());
1600
1601 flags &= ~wxCONTROL_DISABLED;
1e6feb95
VZ
1602 }
1603 }
1604
147b8a4a
VZ
1605 wxStdRenderer::DrawLabel(dc, label, rect, flags, alignment,
1606 indexAccel, rectBounds);
1607}
1e6feb95 1608
147b8a4a
VZ
1609void wxWin32Renderer::DrawFrameWithLabel(wxDC& dc,
1610 const wxString& label,
1611 const wxRect& rectFrame,
1612 const wxRect& rectText,
1613 int flags,
1614 int alignment,
1615 int indexAccel)
1616{
1617 wxString label2;
1618 label2 << _T(' ') << label << _T(' ');
1619 if ( indexAccel != -1 )
1e6feb95 1620 {
147b8a4a
VZ
1621 // adjust it as we prepended a space
1622 indexAccel++;
1e6feb95
VZ
1623 }
1624
147b8a4a
VZ
1625 wxStdRenderer::DrawFrameWithLabel(dc, label2, rectFrame, rectText,
1626 flags, alignment, indexAccel);
1e6feb95
VZ
1627}
1628
1629void wxWin32Renderer::DrawButtonLabel(wxDC& dc,
1630 const wxString& label,
1631 const wxBitmap& image,
1632 const wxRect& rect,
1633 int flags,
1634 int alignment,
1635 int indexAccel,
1636 wxRect *rectBounds)
1637{
1638 // the underscores are not drawn for focused controls in wxMSW
1639 if ( flags & wxCONTROL_PRESSED )
1640 {
1641 indexAccel = -1;
1642 }
1643
147b8a4a
VZ
1644 wxStdRenderer::DrawButtonLabel(dc, label, image, rect, flags, alignment,
1645 indexAccel, rectBounds);
1646}
1e6feb95 1647
147b8a4a
VZ
1648void wxWin32Renderer::DrawButtonBorder(wxDC& dc,
1649 const wxRect& rectTotal,
1650 int flags,
1651 wxRect *rectIn)
1652{
1653 wxRect rect = rectTotal;
1e6feb95 1654
147b8a4a
VZ
1655 wxPen penOut(*wxBLACK);
1656 if ( flags & wxCONTROL_PRESSED )
1657 {
1658 // button pressed: draw a double border around it
1659 DrawRect(dc, &rect, penOut);
1660 DrawRect(dc, &rect, m_penDarkGrey);
1e6feb95 1661 }
147b8a4a 1662 else // button not pressed
1e6feb95 1663 {
147b8a4a 1664 if ( flags & (wxCONTROL_FOCUSED | wxCONTROL_ISDEFAULT) )
1e6feb95 1665 {
147b8a4a
VZ
1666 // button either default or focused (or both): add an extra border
1667 // around it
1668 DrawRect(dc, &rect, penOut);
1e6feb95
VZ
1669 }
1670
147b8a4a
VZ
1671 // now draw a normal button border
1672 DrawRaisedBorder(dc, &rect);
1e6feb95 1673 }
147b8a4a
VZ
1674
1675 if ( rectIn )
1676 *rectIn = rect;
1e6feb95
VZ
1677}
1678
1679// ----------------------------------------------------------------------------
1680// (check)listbox items
1681// ----------------------------------------------------------------------------
1682
6229b92f
VZ
1683void wxWin32Renderer::DrawCheckItemBitmap(wxDC& dc,
1684 const wxBitmap& bitmap,
1685 const wxRect& rect,
1686 int flags)
1e6feb95
VZ
1687{
1688 wxBitmap bmp;
1689 if ( bitmap.Ok() )
1690 {
1691 bmp = bitmap;
1692 }
1693 else // use default bitmap
1694 {
e3400e2e
VZ
1695 IndicatorStatus i = flags & wxCONTROL_CHECKED
1696 ? IndicatorStatus_Checked
1697 : IndicatorStatus_Unchecked;
1698
1699 if ( !m_bmpCheckBitmaps[i].Ok() )
1700 {
147b8a4a 1701 m_bmpCheckBitmaps[i] = wxBitmap(ms_xpmChecked[i]);
e3400e2e
VZ
1702 }
1703
1704 bmp = m_bmpCheckBitmaps[i];
1e6feb95
VZ
1705 }
1706
1707 dc.DrawBitmap(bmp, rect.x, rect.y + (rect.height - bmp.GetHeight()) / 2 - 1,
a290fa5a 1708 true /* use mask */);
1e6feb95
VZ
1709}
1710
1711// ----------------------------------------------------------------------------
1712// check/radio buttons
1713// ----------------------------------------------------------------------------
1714
1715wxBitmap wxWin32Renderer::GetIndicator(IndicatorType indType, int flags)
1716{
1717 IndicatorState indState;
147b8a4a
VZ
1718 IndicatorStatus indStatus;
1719 GetIndicatorsFromFlags(flags, indState, indStatus);
1e6feb95 1720
0428ac8c 1721 wxBitmap& bmp = m_bmpIndicators[indType][indState][indStatus];
e3400e2e 1722 if ( !bmp.Ok() )
54a96d02 1723 {
147b8a4a 1724 const char **xpm = ms_xpmIndicators[indType][indState][indStatus];
e3400e2e
VZ
1725 if ( xpm )
1726 {
1727 // create and cache it
1728 bmp = wxBitmap(xpm);
e3400e2e 1729 }
54a96d02 1730 }
e3400e2e
VZ
1731
1732 return bmp;
1e6feb95
VZ
1733}
1734
6229b92f
VZ
1735// ----------------------------------------------------------------------------
1736// toolbar stuff
1737// ----------------------------------------------------------------------------
1738
9a6384ca 1739#if wxUSE_TOOLBAR
3216dbf5
VZ
1740void wxWin32Renderer::DrawToolBarButton(wxDC& dc,
1741 const wxString& label,
1742 const wxBitmap& bitmap,
1743 const wxRect& rectOrig,
a8f4cabe 1744 int flags,
370efbe7
WS
1745 long style,
1746 int tbarStyle)
3216dbf5 1747{
a8f4cabe 1748 if (style == wxTOOL_STYLE_BUTTON)
3216dbf5
VZ
1749 {
1750 wxRect rect = rectOrig;
1751 rect.Deflate(BORDER_THICKNESS);
1752
1753 if ( flags & wxCONTROL_PRESSED )
1754 {
1755 DrawBorder(dc, wxBORDER_SUNKEN, rect, flags);
1756 }
1757 else if ( flags & wxCONTROL_CURRENT )
1758 {
1759 DrawBorder(dc, wxBORDER_RAISED, rect, flags);
1760 }
1761
370efbe7
WS
1762 if(tbarStyle & wxTB_TEXT)
1763 {
1764 if(tbarStyle & wxTB_HORIZONTAL)
1765 {
1766 dc.DrawLabel(label, bitmap, rect, wxALIGN_CENTRE);
1767 }
1768 else
1769 {
1770 dc.DrawLabel(label, bitmap, rect, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
1771 }
1772 }
1773 else
1774 {
1775 int xpoint = (rect.GetLeft() + rect.GetRight() + 1 - bitmap.GetWidth()) / 2;
1776 int ypoint = (rect.GetTop() + rect.GetBottom() + 1 - bitmap.GetHeight()) / 2;
1777 dc.DrawBitmap(bitmap, xpoint, ypoint);
1778 }
3216dbf5 1779 }
a8f4cabe 1780 else if (style == wxTOOL_STYLE_SEPARATOR)
3216dbf5 1781 {
2d3cddaf
VZ
1782 // leave a small gap aroudn the line, also account for the toolbar
1783 // border itself
1f7e5f7b
WS
1784 if(rectOrig.height > rectOrig.width)
1785 {
1786 // horizontal
1787 DrawVerticalLine(dc, rectOrig.x + rectOrig.width/2,
1788 rectOrig.y + 2*BORDER_THICKNESS,
1789 rectOrig.GetBottom() - BORDER_THICKNESS);
1790 }
1791 else
1792 {
1793 // vertical
1794 DrawHorizontalLine(dc, rectOrig.y + rectOrig.height/2,
1795 rectOrig.x + 2*BORDER_THICKNESS,
1796 rectOrig.GetRight() - BORDER_THICKNESS);
1797 }
3216dbf5 1798 }
a8f4cabe 1799 // don't draw wxTOOL_STYLE_CONTROL
3216dbf5 1800}
9a6384ca 1801#endif // wxUSE_TOOLBAR
3216dbf5 1802
1e6feb95
VZ
1803// ----------------------------------------------------------------------------
1804// notebook
1805// ----------------------------------------------------------------------------
1806
c4036939
VZ
1807#if wxUSE_NOTEBOOK
1808
1e6feb95
VZ
1809void wxWin32Renderer::DrawTab(wxDC& dc,
1810 const wxRect& rectOrig,
1811 wxDirection dir,
1812 const wxString& label,
1813 const wxBitmap& bitmap,
1814 int flags,
1815 int indexAccel)
1816{
00e086a7
WS
1817 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1818 #define REVERSE_FOR_VERTICAL(X,Y) \
1819 SELECT_FOR_VERTICAL(X,Y) \
1820 , \
1821 SELECT_FOR_VERTICAL(Y,X)
1822
1e6feb95
VZ
1823 wxRect rect = rectOrig;
1824
00e086a7
WS
1825 bool isVertical = ( dir == wxLEFT ) || ( dir == wxRIGHT );
1826
1e6feb95
VZ
1827 // the current tab is drawn indented (to the top for default case) and
1828 // bigger than the other ones
1829 const wxSize indent = GetTabIndent();
1830 if ( flags & wxCONTROL_SELECTED )
1831 {
7166a05d
WS
1832 rect.Inflate( SELECT_FOR_VERTICAL( indent.x , 0),
1833 SELECT_FOR_VERTICAL( 0, indent.y ));
1e6feb95
VZ
1834 switch ( dir )
1835 {
1836 default:
1837 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1838 // fall through
1839
1840 case wxTOP:
1e6feb95 1841 rect.y -= indent.y;
00e086a7 1842 // fall through
1e6feb95 1843 case wxBOTTOM:
1e6feb95
VZ
1844 rect.height += indent.y;
1845 break;
1846
1847 case wxLEFT:
00e086a7
WS
1848 rect.x -= indent.x;
1849 // fall through
1e6feb95 1850 case wxRIGHT:
00e086a7 1851 rect.width += indent.x;
1e6feb95
VZ
1852 break;
1853 }
1854 }
1855
1856 // draw the text, image and the focus around them (if necessary)
00e086a7
WS
1857 wxRect rectLabel( REVERSE_FOR_VERTICAL(rect.x,rect.y),
1858 REVERSE_FOR_VERTICAL(rect.width,rect.height)
1859 );
1e6feb95 1860 rectLabel.Deflate(1, 1);
00e086a7
WS
1861 if ( isVertical )
1862 {
1863 // draw it horizontally into memory and rotate for screen
1864 wxMemoryDC dcMem;
1865 wxBitmap bitmapRotated,
1866 bitmapMem( rectLabel.x + rectLabel.width,
1867 rectLabel.y + rectLabel.height );
1868 dcMem.SelectObject(bitmapMem);
1869 dcMem.SetBackground(dc.GetBackground());
1870 dcMem.SetFont(dc.GetFont());
1871 dcMem.SetTextForeground(dc.GetTextForeground());
1872 dcMem.Clear();
9a6384ca
WS
1873 bitmapRotated =
1874#if wxUSE_IMAGE
1875 wxBitmap( wxImage( bitmap.ConvertToImage() ).Rotate90(dir==wxLEFT) )
1876#else
1877 bitmap
1878#endif // wxUSE_IMAGE
1879 ;
00e086a7
WS
1880 DrawButtonLabel(dcMem, label, bitmapRotated, rectLabel,
1881 flags, wxALIGN_CENTRE, indexAccel);
1882 dcMem.SelectObject(wxNullBitmap);
1883 bitmapMem = bitmapMem.GetSubBitmap(rectLabel);
9a6384ca 1884#if wxUSE_IMAGE
00e086a7 1885 bitmapMem = wxBitmap(wxImage(bitmapMem.ConvertToImage()).Rotate90(dir==wxRIGHT));
9a6384ca 1886#endif // wxUSE_IMAGE
00e086a7
WS
1887 dc.DrawBitmap(bitmapMem, rectLabel.y, rectLabel.x, false);
1888 }
1889 else
1890 {
1891 DrawButtonLabel(dc, label, bitmap, rectLabel,
1892 flags, wxALIGN_CENTRE, indexAccel);
1893 }
1e6feb95
VZ
1894
1895 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
1896 static const wxCoord CUTOFF = 2; // radius of the rounded corner
00e086a7
WS
1897 wxCoord x = SELECT_FOR_VERTICAL(rect.x,rect.y),
1898 y = SELECT_FOR_VERTICAL(rect.y,rect.x),
1899 x2 = SELECT_FOR_VERTICAL(rect.GetRight(),rect.GetBottom()),
1900 y2 = SELECT_FOR_VERTICAL(rect.GetBottom(),rect.GetRight());
1e6feb95
VZ
1901
1902 // FIXME: all this code will break if the tab indent or the border width,
1903 // it is tied to the fact that both of them are equal to 2
1904 switch ( dir )
1905 {
1906 default:
00e086a7
WS
1907 // default is top
1908 case wxLEFT:
1909 // left orientation looks like top but IsVertical makes x and y reversed
1e6feb95 1910 case wxTOP:
00e086a7 1911 // top is not vertical so use coordinates in written order
1e6feb95 1912 dc.SetPen(m_penHighlight);
00e086a7
WS
1913 dc.DrawLine(REVERSE_FOR_VERTICAL(x, y2),
1914 REVERSE_FOR_VERTICAL(x, y + CUTOFF));
1915 dc.DrawLine(REVERSE_FOR_VERTICAL(x, y + CUTOFF),
1916 REVERSE_FOR_VERTICAL(x + CUTOFF, y));
1917 dc.DrawLine(REVERSE_FOR_VERTICAL(x + CUTOFF, y),
1918 REVERSE_FOR_VERTICAL(x2 - CUTOFF + 1, y));
1e6feb95
VZ
1919
1920 dc.SetPen(m_penBlack);
00e086a7
WS
1921 dc.DrawLine(REVERSE_FOR_VERTICAL(x2, y2),
1922 REVERSE_FOR_VERTICAL(x2, y + CUTOFF));
1923 dc.DrawLine(REVERSE_FOR_VERTICAL(x2, y + CUTOFF),
1924 REVERSE_FOR_VERTICAL(x2 - CUTOFF, y));
1e6feb95
VZ
1925
1926 dc.SetPen(m_penDarkGrey);
00e086a7
WS
1927 dc.DrawLine(REVERSE_FOR_VERTICAL(x2 - 1, y2),
1928 REVERSE_FOR_VERTICAL(x2 - 1, y + CUTOFF - 1));
1e6feb95
VZ
1929
1930 if ( flags & wxCONTROL_SELECTED )
1931 {
1932 dc.SetPen(m_penLightGrey);
1933
1934 // overwrite the part of the border below this tab
00e086a7
WS
1935 dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y2 + 1),
1936 REVERSE_FOR_VERTICAL(x2 - 1, y2 + 1));
1e6feb95
VZ
1937
1938 // and the shadow of the tab to the left of us
00e086a7
WS
1939 dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y + CUTOFF + 1),
1940 REVERSE_FOR_VERTICAL(x + 1, y2 + 1));
1e6feb95
VZ
1941 }
1942 break;
1943
00e086a7
WS
1944 case wxRIGHT:
1945 // right orientation looks like bottom but IsVertical makes x and y reversed
1e6feb95 1946 case wxBOTTOM:
00e086a7 1947 // bottom is not vertical so use coordinates in written order
1e6feb95
VZ
1948 dc.SetPen(m_penHighlight);
1949 // we need to continue one pixel further to overwrite the corner of
1950 // the border for the selected tab
00e086a7
WS
1951 dc.DrawLine(REVERSE_FOR_VERTICAL(x, y - (flags & wxCONTROL_SELECTED ? 1 : 0)),
1952 REVERSE_FOR_VERTICAL(x, y2 - CUTOFF));
1953 dc.DrawLine(REVERSE_FOR_VERTICAL(x, y2 - CUTOFF),
1954 REVERSE_FOR_VERTICAL(x + CUTOFF, y2));
1e6feb95
VZ
1955
1956 dc.SetPen(m_penBlack);
00e086a7
WS
1957 dc.DrawLine(REVERSE_FOR_VERTICAL(x + CUTOFF, y2),
1958 REVERSE_FOR_VERTICAL(x2 - CUTOFF + 1, y2));
1959 dc.DrawLine(REVERSE_FOR_VERTICAL(x2, y),
1960 REVERSE_FOR_VERTICAL(x2, y2 - CUTOFF));
1961 dc.DrawLine(REVERSE_FOR_VERTICAL(x2, y2 - CUTOFF),
1962 REVERSE_FOR_VERTICAL(x2 - CUTOFF, y2));
1e6feb95
VZ
1963
1964 dc.SetPen(m_penDarkGrey);
00e086a7
WS
1965 dc.DrawLine(REVERSE_FOR_VERTICAL(x + CUTOFF, y2 - 1),
1966 REVERSE_FOR_VERTICAL(x2 - CUTOFF + 1, y2 - 1));
1967 dc.DrawLine(REVERSE_FOR_VERTICAL(x2 - 1, y),
1968 REVERSE_FOR_VERTICAL(x2 - 1, y2 - CUTOFF + 1));
1e6feb95
VZ
1969
1970 if ( flags & wxCONTROL_SELECTED )
1971 {
1972 dc.SetPen(m_penLightGrey);
1973
1974 // overwrite the part of the (double!) border above this tab
00e086a7
WS
1975 dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y - 1),
1976 REVERSE_FOR_VERTICAL(x2 - 1, y - 1));
1977 dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y - 2),
1978 REVERSE_FOR_VERTICAL(x2 - 1, y - 2));
1e6feb95
VZ
1979
1980 // and the shadow of the tab to the left of us
00e086a7
WS
1981 dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y2 - CUTOFF),
1982 REVERSE_FOR_VERTICAL(x + 1, y - 1));
1e6feb95
VZ
1983 }
1984 break;
1e6feb95 1985 }
00e086a7
WS
1986
1987 #undef SELECT_FOR_VERTICAL
1988 #undef REVERSE_FOR_VERTICAL
1e6feb95
VZ
1989}
1990
c4036939
VZ
1991#endif // wxUSE_NOTEBOOK
1992
9a6384ca
WS
1993#if wxUSE_SLIDER
1994
1e6feb95
VZ
1995// ----------------------------------------------------------------------------
1996// slider
1997// ----------------------------------------------------------------------------
1998
61fef19b
VZ
1999wxSize
2000wxWin32Renderer::GetSliderThumbSize(const wxRect& WXUNUSED(rect),
2001 int lenThumb,
2002 wxOrientation orient) const
1e6feb95
VZ
2003{
2004 wxSize size;
6766e5d1
JS
2005 wxCoord width = wxMax (lenThumb, SLIDER_THUMB_LENGTH) / 2;
2006 wxCoord height = wxMax (lenThumb, SLIDER_THUMB_LENGTH);
1e6feb95 2007
00e086a7 2008 if (orient == wxHORIZONTAL)
1e6feb95 2009 {
6766e5d1
JS
2010 size.x = width;
2011 size.y = height;
1e6feb95 2012 }
6766e5d1
JS
2013 else
2014 { // == wxVERTICAL
2015 size.x = height;
2016 size.y = width;
1e6feb95
VZ
2017 }
2018
2019 return size;
2020}
2021
2022wxRect wxWin32Renderer::GetSliderShaftRect(const wxRect& rectOrig,
6766e5d1
JS
2023 int lenThumb,
2024 wxOrientation orient,
2025 long style) const
1e6feb95 2026{
6766e5d1
JS
2027 bool transpose = (orient == wxVERTICAL);
2028 bool left = ((style & wxSL_AUTOTICKS) != 0) &
2029 (((style & wxSL_TOP) != 0) & !transpose |
2030 ((style & wxSL_LEFT) != 0) & transpose |
2031 ((style & wxSL_BOTH) != 0));
2032 bool right = ((style & wxSL_AUTOTICKS) != 0) &
2033 (((style & wxSL_BOTTOM) != 0) & !transpose |
2034 ((style & wxSL_RIGHT) != 0) & transpose |
2035 ((style & wxSL_BOTH) != 0));
1e6feb95
VZ
2036
2037 wxRect rect = rectOrig;
2038
6766e5d1 2039 wxSize sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
1e6feb95 2040
6766e5d1
JS
2041 if (orient == wxHORIZONTAL) {
2042 rect.x += SLIDER_MARGIN;
00e086a7 2043 if (left & right)
6766e5d1
JS
2044 {
2045 rect.y += wxMax ((rect.height - 2*BORDER_THICKNESS) / 2, sizeThumb.y/2);
2046 }
00e086a7 2047 else if (left)
6766e5d1
JS
2048 {
2049 rect.y += wxMax ((rect.height - 2*BORDER_THICKNESS - sizeThumb.y/2), sizeThumb.y/2);
2050 }
2051 else
2052 {
2053 rect.y += sizeThumb.y/2;
2054 }
2055 rect.width -= 2*SLIDER_MARGIN;
2056 rect.height = 2*BORDER_THICKNESS;
1e6feb95 2057 }
6766e5d1
JS
2058 else
2059 { // == wxVERTICAL
2060 rect.y += SLIDER_MARGIN;
00e086a7 2061 if (left & right)
6766e5d1
JS
2062 {
2063 rect.x += wxMax ((rect.width - 2*BORDER_THICKNESS) / 2, sizeThumb.x/2);
2064 }
00e086a7 2065 else if (left)
6766e5d1
JS
2066 {
2067 rect.x += wxMax ((rect.width - 2*BORDER_THICKNESS - sizeThumb.x/2), sizeThumb.x/2);
2068 }
2069 else
2070 {
2071 rect.x += sizeThumb.x/2;
2072 }
1e6feb95 2073 rect.width = 2*BORDER_THICKNESS;
6766e5d1 2074 rect.height -= 2*SLIDER_MARGIN;
1e6feb95
VZ
2075 }
2076
2077 return rect;
2078}
2079
2080void wxWin32Renderer::DrawSliderShaft(wxDC& dc,
2081 const wxRect& rectOrig,
6766e5d1 2082 int lenThumb,
1e6feb95
VZ
2083 wxOrientation orient,
2084 int flags,
6766e5d1 2085 long style,
1e6feb95
VZ
2086 wxRect *rectShaft)
2087{
6766e5d1
JS
2088 /* show shaft geometry
2089
2090 shaft
2091 +-------------+
2092 | |
2093 | XXX | <-- x1
2094 | XXX |
2095 | XXX |
2096 | XXX |
2097 | XXX | <-- x2
2098 | |
2099 +-------------+
2100
2101 ^ ^
2102 | |
2103 y1 y2
2104 */
2105
2106 if (flags & wxCONTROL_FOCUSED) {
1e6feb95
VZ
2107 DrawFocusRect(dc, rectOrig);
2108 }
2109
6766e5d1 2110 wxRect rect = GetSliderShaftRect(rectOrig, lenThumb, orient, style);
1e6feb95 2111
6766e5d1 2112 if (rectShaft) *rectShaft = rect;
1e6feb95
VZ
2113
2114 DrawSunkenBorder(dc, &rect);
2115}
2116
2117void wxWin32Renderer::DrawSliderThumb(wxDC& dc,
2118 const wxRect& rect,
2119 wxOrientation orient,
6766e5d1
JS
2120 int flags,
2121 long style)
1e6feb95 2122{
6766e5d1
JS
2123 /* show thumb geometry
2124
2125 H <--- y1
2126 H H B
2127 H H B
2128 H H B <--- y3
2129 H D B
2130 H D B
2131 H D B
d6922577 2132 H D B where H is highlight colour
6766e5d1
JS
2133 H D B D dark grey
2134 H D B B black
2135 H D B
2136 H D B
2137 H D B <--- y4
2138 H D B
2139 H D B
2140 B <--- y2
2141
2142 ^ ^ ^
2143 | | |
2144 x1 x3 x2
1e6feb95
VZ
2145
2146 The interior of this shape is filled with the hatched brush if the thumb
2147 is pressed.
2148 */
2149
2150 DrawBackground(dc, wxNullColour, rect, flags);
2151
6766e5d1
JS
2152 bool transpose = (orient == wxVERTICAL);
2153 bool left = ((style & wxSL_AUTOTICKS) != 0) &
2154 (((style & wxSL_TOP) != 0) & !transpose |
2155 ((style & wxSL_LEFT) != 0) & transpose) &
2156 ((style & wxSL_BOTH) == 0);
2157 bool right = ((style & wxSL_AUTOTICKS) != 0) &
2158 (((style & wxSL_BOTTOM) != 0) & !transpose |
2159 ((style & wxSL_RIGHT) != 0) & transpose) &
2160 ((style & wxSL_BOTH) == 0);
2161
2162 wxCoord sizeArrow = (transpose ? rect.height : rect.width) / 2;
2163 wxCoord c = ((transpose ? rect.height : rect.width) - 2*sizeArrow);
2164
2165 wxCoord x1, x2, x3, y1, y2, y3, y4;
2166 x1 = (transpose ? rect.y : rect.x);
2167 x2 = (transpose ? rect.GetBottom() : rect.GetRight());
2168 x3 = (x1-1+c) + sizeArrow;
2169 y1 = (transpose ? rect.x : rect.y);
2170 y2 = (transpose ? rect.GetRight() : rect.GetBottom());
2171 y3 = (left ? (y1-1+c) + sizeArrow : y1);
2172 y4 = (right ? (y2+1-c) - sizeArrow : y2);
1e6feb95 2173
6766e5d1
JS
2174 dc.SetPen(m_penBlack);
2175 if (left) {
2176 DrawLine(dc, x3+1-c, y1, x2, y3, transpose);
2177 }
2178 DrawLine(dc, x2, y3, x2, y4, transpose);
00e086a7 2179 if (right)
1e6feb95 2180 {
6766e5d1 2181 DrawLine(dc, x3+1-c, y2, x2, y4, transpose);
1e6feb95
VZ
2182 }
2183 else
2184 {
6766e5d1 2185 DrawLine(dc, x1, y2, x2, y2, transpose);
1e6feb95
VZ
2186 }
2187
1e6feb95 2188 dc.SetPen(m_penDarkGrey);
6766e5d1
JS
2189 DrawLine(dc, x2-1, y3+1, x2-1, y4-1, transpose);
2190 if (right) {
2191 DrawLine(dc, x3+1-c, y2-1, x2-1, y4, transpose);
2192 }
2193 else
2194 {
2195 DrawLine(dc, x1+1, y2-1, x2-1, y2-1, transpose);
2196 }
1e6feb95 2197
6766e5d1 2198 dc.SetPen(m_penHighlight);
00e086a7 2199 if (left)
6766e5d1
JS
2200 {
2201 DrawLine(dc, x1, y3, x3, y1, transpose);
2202 DrawLine(dc, x3+1-c, y1+1, x2-1, y3, transpose);
2203 }
2204 else
2205 {
2206 DrawLine(dc, x1, y1, x2, y1, transpose);
2207 }
2208 DrawLine(dc, x1, y3, x1, y4, transpose);
00e086a7 2209 if (right)
1e6feb95 2210 {
6766e5d1
JS
2211 DrawLine(dc, x1, y4, x3+c, y2+c, transpose);
2212 }
2213
2214 if (flags & wxCONTROL_PRESSED) {
1e6feb95
VZ
2215 // TODO: MSW fills the entire area inside, not just the rect
2216 wxRect rectInt = rect;
00e086a7 2217 if ( transpose )
6766e5d1
JS
2218 {
2219 rectInt.SetLeft(y3);
2220 rectInt.SetRight(y4);
2221 }
1e6feb95 2222 else
6766e5d1
JS
2223 {
2224 rectInt.SetTop(y3);
2225 rectInt.SetBottom(y4);
2226 }
1e6feb95
VZ
2227 rectInt.Deflate(2);
2228
63f06c22 2229#if !defined(__WXMGL__)
1e6feb95
VZ
2230 static const char *stipple_xpm[] = {
2231 /* columns rows colors chars-per-pixel */
2232 "2 2 2 1",
2233 " c None",
2234 "w c white",
2235 /* pixels */
2236 "w ",
2237 " w",
2238 };
63f06c22
VS
2239#else
2240 // VS: MGL can only do 8x8 stipple brushes
2241 static const char *stipple_xpm[] = {
2242 /* columns rows colors chars-per-pixel */
2243 "8 8 2 1",
2244 " c None",
2245 "w c white",
2246 /* pixels */
2247 "w w w w ",
2248 " w w w w",
2249 "w w w w ",
2250 " w w w w",
2251 "w w w w ",
2252 " w w w w",
2253 "w w w w ",
2254 " w w w w",
2255 };
2256#endif
1e6feb95
VZ
2257 dc.SetBrush(wxBrush(stipple_xpm));
2258
2259 dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, SHADOW_HIGHLIGHT));
2260 dc.SetTextBackground(wxSCHEME_COLOUR(m_scheme, CONTROL));
2261 dc.SetPen(*wxTRANSPARENT_PEN);
2262 dc.DrawRectangle(rectInt);
2263 }
2264}
2265
2266void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
2267 const wxRect& rect,
6766e5d1 2268 int lenThumb,
1e6feb95
VZ
2269 wxOrientation orient,
2270 int start,
2271 int end,
2272 int step,
61fef19b 2273 int WXUNUSED(flags),
6766e5d1 2274 long style)
1e6feb95 2275{
6766e5d1
JS
2276 /* show ticks geometry
2277
2278 left right
2279 ticks shaft ticks
2280 ---- XX ---- <-- x1
2281 ---- XX ----
2282 ---- XX ----
2283 ---- XX ---- <-- x2
2284
2285 ^ ^ ^ ^
2286 | | | |
2287 y3 y1 y2 y4
2288 */
1e6feb95 2289
6766e5d1
JS
2290 // empty slider?
2291 if (end == start) return;
2292
2293 bool transpose = (orient == wxVERTICAL);
2294 bool left = ((style & wxSL_AUTOTICKS) != 0) &
2295 (((style & wxSL_TOP) != 0) & !transpose |
2296 ((style & wxSL_LEFT) != 0) & transpose |
2297 ((style & wxSL_BOTH) != 0));
2298 bool right = ((style & wxSL_AUTOTICKS) != 0) &
2299 (((style & wxSL_BOTTOM) != 0) & !transpose |
2300 ((style & wxSL_RIGHT) != 0) & transpose |
2301 ((style & wxSL_BOTH) != 0));
2302
2303 // default thumb size
2304 wxSize sizeThumb = GetSliderThumbSize (rect, 0, orient);
2305 wxCoord defaultLen = (transpose ? sizeThumb.x : sizeThumb.y);
2306
2307 // normal thumb size
2308 sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
2309 wxCoord widthThumb = (transpose ? sizeThumb.y : sizeThumb.x);
2310
2311 wxRect rectShaft = GetSliderShaftRect (rect, lenThumb, orient, style);
2312
2313 wxCoord x1, x2, y1, y2, y3, y4 , len;
2314 x1 = (transpose ? rectShaft.y : rectShaft.x) + widthThumb/2;
2315 x2 = (transpose ? rectShaft.GetBottom() : rectShaft.GetRight()) - widthThumb/2;
2316 y1 = (transpose ? rectShaft.x : rectShaft.y) - defaultLen/2;
2317 y2 = (transpose ? rectShaft.GetRight() : rectShaft.GetBottom()) + defaultLen/2;
2318 y3 = (transpose ? rect.x : rect.y);
2319 y4 = (transpose ? rect.GetRight() : rect.GetBottom());
2320 len = x2 - x1;
1e6feb95
VZ
2321
2322 dc.SetPen(m_penBlack);
2323
2324 int range = end - start;
6766e5d1 2325 for ( int n = 0; n < range; n += step ) {
1e6feb95
VZ
2326 wxCoord x = x1 + (len*n) / range;
2327
6766e5d1
JS
2328 if (left & (y1 > y3)) {
2329 DrawLine(dc, x, y1, x, y3, orient == wxVERTICAL);
2330 }
2331 if (right & (y4 > y2)) {
2332 DrawLine(dc, x, y2, x, y4, orient == wxVERTICAL);
2333 }
1e6feb95 2334 }
1e6feb95 2335 // always draw the line at the end position
6766e5d1
JS
2336 if (left & (y1 > y3)) {
2337 DrawLine(dc, x2, y1, x2, y3, orient == wxVERTICAL);
2338 }
2339 if (right & (y4 > y2)) {
2340 DrawLine(dc, x2, y2, x2, y4, orient == wxVERTICAL);
2341 }
1e6feb95
VZ
2342}
2343
9a6384ca
WS
2344#endif // wxUSE_SLIDER
2345
2346#if wxUSE_MENUS
2347
1e6feb95
VZ
2348// ----------------------------------------------------------------------------
2349// menu and menubar
2350// ----------------------------------------------------------------------------
2351
2352// wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2353class WXDLLEXPORT wxWin32MenuGeometryInfo : public wxMenuGeometryInfo
2354{
2355public:
2356 virtual wxSize GetSize() const { return m_size; }
2357
2358 wxCoord GetLabelOffset() const { return m_ofsLabel; }
2359 wxCoord GetAccelOffset() const { return m_ofsAccel; }
2360
2361 wxCoord GetItemHeight() const { return m_heightItem; }
2362
2363private:
2364 // the total size of the menu
2365 wxSize m_size;
2366
2367 // the offset of the start of the menu item label
2368 wxCoord m_ofsLabel;
2369
2370 // the offset of the start of the accel label
2371 wxCoord m_ofsAccel;
2372
2373 // the height of a normal (not separator) item
2374 wxCoord m_heightItem;
2375
71e03035
VZ
2376 friend wxMenuGeometryInfo *
2377 wxWin32Renderer::GetMenuGeometry(wxWindow *, const wxMenu&) const;
1e6feb95
VZ
2378};
2379
2380// FIXME: all constants are hardcoded but shouldn't be
2381static const wxCoord MENU_LEFT_MARGIN = 9;
2382static const wxCoord MENU_RIGHT_MARGIN = 18;
2383static const wxCoord MENU_VERT_MARGIN = 3;
2384
2385// the margin around bitmap/check marks (on each side)
2386static const wxCoord MENU_BMP_MARGIN = 2;
2387
2388// the margin between the labels and accel strings
2389static const wxCoord MENU_ACCEL_MARGIN = 8;
2390
2391// the separator height in pixels: in fact, strangely enough, the real height
2392// is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2393// account here
2394static const wxCoord MENU_SEPARATOR_HEIGHT = 3;
2395
2396// the size of the standard checkmark bitmap
2397static const wxCoord MENU_CHECK_SIZE = 9;
2398
2399void wxWin32Renderer::DrawMenuBarItem(wxDC& dc,
2400 const wxRect& rectOrig,
2401 const wxString& label,
2402 int flags,
2403 int indexAccel)
2404{
2405 wxRect rect = rectOrig;
2406 rect.height--;
2407
2408 wxDCTextColourChanger colChanger(dc);
2409
2410 if ( flags & wxCONTROL_SELECTED )
2411 {
2412 colChanger.Set(wxSCHEME_COLOUR(m_scheme, HIGHLIGHT_TEXT));
2413
147b8a4a
VZ
2414 const wxColour colBg = wxSCHEME_COLOUR(m_scheme, HIGHLIGHT);
2415 dc.SetBrush(colBg);
2416 dc.SetPen(colBg);
1e6feb95
VZ
2417 dc.DrawRectangle(rect);
2418 }
2419
2420 // don't draw the focus rect around menu bar items
2421 DrawLabel(dc, label, rect, flags & ~wxCONTROL_FOCUSED,
2422 wxALIGN_CENTRE, indexAccel);
2423}
2424
2425void wxWin32Renderer::DrawMenuItem(wxDC& dc,
2426 wxCoord y,
2427 const wxMenuGeometryInfo& gi,
2428 const wxString& label,
2429 const wxString& accel,
2430 const wxBitmap& bitmap,
2431 int flags,
2432 int indexAccel)
2433{
2434 const wxWin32MenuGeometryInfo& geometryInfo =
2435 (const wxWin32MenuGeometryInfo&)gi;
2436
2437 wxRect rect;
2438 rect.x = 0;
2439 rect.y = y;
2440 rect.width = geometryInfo.GetSize().x;
2441 rect.height = geometryInfo.GetItemHeight();
2442
2443 // draw the selected item specially
2444 wxDCTextColourChanger colChanger(dc);
2445 if ( flags & wxCONTROL_SELECTED )
2446 {
2447 colChanger.Set(wxSCHEME_COLOUR(m_scheme, HIGHLIGHT_TEXT));
2448
147b8a4a
VZ
2449 const wxColour colBg = wxSCHEME_COLOUR(m_scheme, HIGHLIGHT);
2450 dc.SetBrush(colBg);
2451 dc.SetPen(colBg);
1e6feb95
VZ
2452 dc.DrawRectangle(rect);
2453 }
2454
2455 // draw the bitmap: use the bitmap provided or the standard checkmark for
2456 // the checkable items
2457 wxBitmap bmp = bitmap;
2458 if ( !bmp.Ok() && (flags & wxCONTROL_CHECKED) )
2459 {
2460 bmp = GetIndicator(IndicatorType_Menu, flags);
2461 }
2462
2463 if ( bmp.Ok() )
2464 {
2465 rect.SetRight(geometryInfo.GetLabelOffset());
2466 wxControlRenderer::DrawBitmap(dc, bmp, rect);
2467 }
2468
2469 // draw the label
2470 rect.x = geometryInfo.GetLabelOffset();
2471 rect.SetRight(geometryInfo.GetAccelOffset());
2472
2473 DrawLabel(dc, label, rect, flags, wxALIGN_CENTRE_VERTICAL, indexAccel);
2474
2475 // draw the accel string
2476 rect.x = geometryInfo.GetAccelOffset();
2477 rect.SetRight(geometryInfo.GetSize().x);
2478
2479 // NB: no accel index here
2480 DrawLabel(dc, accel, rect, flags, wxALIGN_CENTRE_VERTICAL);
2481
2482 // draw the submenu indicator
2483 if ( flags & wxCONTROL_ISSUBMENU )
2484 {
2485 rect.x = geometryInfo.GetSize().x - MENU_RIGHT_MARGIN;
2486 rect.width = MENU_RIGHT_MARGIN;
2487
0428ac8c 2488 ArrowStyle arrowStyle;
1e6feb95 2489 if ( flags & wxCONTROL_DISABLED )
d6922577 2490 arrowStyle = flags & wxCONTROL_SELECTED ? Arrow_InvertedDisabled
1e6feb95
VZ
2491 : Arrow_Disabled;
2492 else if ( flags & wxCONTROL_SELECTED )
d6922577 2493 arrowStyle = Arrow_Inverted;
1e6feb95
VZ
2494 else
2495 arrowStyle = Arrow_Normal;
2496
2497 DrawArrow(dc, rect, Arrow_Right, arrowStyle);
2498 }
2499}
2500
2501void wxWin32Renderer::DrawMenuSeparator(wxDC& dc,
2502 wxCoord y,
2503 const wxMenuGeometryInfo& geomInfo)
2504{
2505 DrawHorizontalLine(dc, y + MENU_VERT_MARGIN, 0, geomInfo.GetSize().x);
2506}
2507
2508wxSize wxWin32Renderer::GetMenuBarItemSize(const wxSize& sizeText) const
2509{
2510 wxSize size = sizeText;
2511
2512 // FIXME: menubar height is configurable under Windows
2513 size.x += 12;
2514 size.y += 6;
2515
2516 return size;
2517}
2518
2519wxMenuGeometryInfo *wxWin32Renderer::GetMenuGeometry(wxWindow *win,
2520 const wxMenu& menu) const
2521{
2522 // prepare the dc: for now we draw all the items with the system font
2523 wxClientDC dc(win);
a756f210 2524 dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
1e6feb95
VZ
2525
2526 // the height of a normal item
2527 wxCoord heightText = dc.GetCharHeight();
2528
2529 // the total height
2530 wxCoord height = 0;
2531
2532 // the max length of label and accel strings: the menu width is the sum of
2533 // them, even if they're for different items (as the accels should be
2534 // aligned)
2535 //
2536 // the max length of the bitmap is never 0 as Windows always leaves enough
2537 // space for a check mark indicator
2538 wxCoord widthLabelMax = 0,
2539 widthAccelMax = 0,
2540 widthBmpMax = MENU_LEFT_MARGIN;
2541
ac32ba44 2542 for ( wxMenuItemList::compatibility_iterator node = menu.GetMenuItems().GetFirst();
1e6feb95
VZ
2543 node;
2544 node = node->GetNext() )
2545 {
2546 // height of this item
2547 wxCoord h;
2548
2549 wxMenuItem *item = node->GetData();
2550 if ( item->IsSeparator() )
2551 {
2552 h = MENU_SEPARATOR_HEIGHT;
2553 }
2554 else // not separator
2555 {
2556 h = heightText;
2557
2558 wxCoord widthLabel;
2559 dc.GetTextExtent(item->GetLabel(), &widthLabel, NULL);
2560 if ( widthLabel > widthLabelMax )
2561 {
2562 widthLabelMax = widthLabel;
2563 }
2564
2565 wxCoord widthAccel;
2566 dc.GetTextExtent(item->GetAccelString(), &widthAccel, NULL);
2567 if ( widthAccel > widthAccelMax )
2568 {
2569 widthAccelMax = widthAccel;
2570 }
2571
2572 const wxBitmap& bmp = item->GetBitmap();
2573 if ( bmp.Ok() )
2574 {
2575 wxCoord widthBmp = bmp.GetWidth();
2576 if ( widthBmp > widthBmpMax )
2577 widthBmpMax = widthBmp;
2578 }
2579 //else if ( item->IsCheckable() ): no need to check for this as
2580 // MENU_LEFT_MARGIN is big enough to show the check mark
2581 }
2582
2583 h += 2*MENU_VERT_MARGIN;
2584
2585 // remember the item position and height
2586 item->SetGeometry(height, h);
2587
2588 height += h;
2589 }
2590
2591 // bundle the metrics into a struct and return it
2592 wxWin32MenuGeometryInfo *gi = new wxWin32MenuGeometryInfo;
2593
2594 gi->m_ofsLabel = widthBmpMax + 2*MENU_BMP_MARGIN;
2595 gi->m_ofsAccel = gi->m_ofsLabel + widthLabelMax;
2596 if ( widthAccelMax > 0 )
2597 {
2598 // if we actually have any accesl, add a margin
2599 gi->m_ofsAccel += MENU_ACCEL_MARGIN;
2600 }
2601
2602 gi->m_heightItem = heightText + 2*MENU_VERT_MARGIN;
2603
2604 gi->m_size.x = gi->m_ofsAccel + widthAccelMax + MENU_RIGHT_MARGIN;
2605 gi->m_size.y = height;
2606
2607 return gi;
2608}
2609
9a6384ca
WS
2610#endif // wxUSE_MENUS
2611
2612#if wxUSE_STATUSBAR
2613
71e03035
VZ
2614// ----------------------------------------------------------------------------
2615// status bar
2616// ----------------------------------------------------------------------------
3379ed37 2617
71e03035
VZ
2618static const wxCoord STATBAR_BORDER_X = 2;
2619static const wxCoord STATBAR_BORDER_Y = 2;
3379ed37 2620
71e03035 2621wxSize wxWin32Renderer::GetStatusBarBorders(wxCoord *borderBetweenFields) const
3379ed37 2622{
71e03035
VZ
2623 if ( borderBetweenFields )
2624 *borderBetweenFields = 2;
3379ed37 2625
71e03035 2626 return wxSize(STATBAR_BORDER_X, STATBAR_BORDER_Y);
3379ed37
VZ
2627}
2628
71e03035
VZ
2629void wxWin32Renderer::DrawStatusField(wxDC& dc,
2630 const wxRect& rect,
2631 const wxString& label,
c2919ab3 2632 int flags, int style /*=0*/)
3379ed37 2633{
71e03035 2634 wxRect rectIn;
3379ed37 2635
71e03035
VZ
2636 if ( flags & wxCONTROL_ISDEFAULT )
2637 {
2638 // draw the size grip: it is a normal rect except that in the lower
2639 // right corner we have several bands which may be used for dragging
2640 // the status bar corner
2641 //
2642 // each band consists of 4 stripes: m_penHighlight, double
2643 // m_penDarkGrey and transparent one
2644 wxCoord x2 = rect.GetRight(),
2645 y2 = rect.GetBottom();
3379ed37 2646
71e03035 2647 // draw the upper left part of the rect normally
c2919ab3
VZ
2648 if (style != wxSB_FLAT)
2649 {
2650 if (style == wxSB_RAISED)
2651 dc.SetPen(m_penHighlight);
2652 else
2653 dc.SetPen(m_penDarkGrey);
2654 dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), y2);
2655 dc.DrawLine(rect.GetLeft() + 1, rect.GetTop(), x2, rect.GetTop());
2656 }
71e03035
VZ
2657
2658 // draw the grey stripes of the grip
2659 size_t n;
2660 wxCoord ofs = WIDTH_STATUSBAR_GRIP_BAND - 1;
2661 for ( n = 0; n < NUM_STATUSBAR_GRIP_BANDS; n++, ofs += WIDTH_STATUSBAR_GRIP_BAND )
2662 {
2663 dc.DrawLine(x2 - ofs + 1, y2 - 1, x2, y2 - ofs);
2664 dc.DrawLine(x2 - ofs, y2 - 1, x2, y2 - ofs - 1);
2665 }
2666
2667 // draw the white stripes
2668 dc.SetPen(m_penHighlight);
2669 ofs = WIDTH_STATUSBAR_GRIP_BAND + 1;
2670 for ( n = 0; n < NUM_STATUSBAR_GRIP_BANDS; n++, ofs += WIDTH_STATUSBAR_GRIP_BAND )
2671 {
2672 dc.DrawLine(x2 - ofs + 1, y2 - 1, x2, y2 - ofs);
2673 }
2674
2675 // draw the remaining rect boundaries
c2919ab3
VZ
2676 if (style != wxSB_FLAT)
2677 {
2678 if (style == wxSB_RAISED)
2679 dc.SetPen(m_penDarkGrey);
2680 else
2681 dc.SetPen(m_penHighlight);
2682 ofs -= WIDTH_STATUSBAR_GRIP_BAND;
2683 dc.DrawLine(x2, rect.GetTop(), x2, y2 - ofs + 1);
2684 dc.DrawLine(rect.GetLeft(), y2, x2 - ofs + 1, y2);
2685 }
71e03035
VZ
2686
2687 rectIn = rect;
2688 rectIn.Deflate(1);
2689
2690 rectIn.width -= STATUSBAR_GRIP_SIZE;
2691 }
2692 else // normal pane
2693 {
c2919ab3
VZ
2694 if (style == wxSB_RAISED)
2695 DrawBorder(dc, wxBORDER_RAISED, rect, flags, &rectIn);
2696 else if (style != wxSB_FLAT)
2697 DrawBorder(dc, wxBORDER_STATIC, rect, flags, &rectIn);
71e03035
VZ
2698 }
2699
2700 rectIn.Deflate(STATBAR_BORDER_X, STATBAR_BORDER_Y);
2701
2702 wxDCClipper clipper(dc, rectIn);
2703 DrawLabel(dc, label, rectIn, flags, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
2704}
3379ed37 2705
9a6384ca
WS
2706#endif // wxUSE_STATUSBAR
2707
1e6feb95
VZ
2708// ----------------------------------------------------------------------------
2709// combobox
2710// ----------------------------------------------------------------------------
2711
2712void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal,
61fef19b 2713 wxBitmap * WXUNUSED(bmpFocus),
1e6feb95
VZ
2714 wxBitmap *bmpPressed,
2715 wxBitmap *bmpDisabled)
2716{
2717 static const wxCoord widthCombo = 16;
2718 static const wxCoord heightCombo = 17;
2719
2720 wxMemoryDC dcMem;
2721
2722 if ( bmpNormal )
2723 {
2724 bmpNormal->Create(widthCombo, heightCombo);
2725 dcMem.SelectObject(*bmpNormal);
2726 DrawArrowButton(dcMem, wxRect(0, 0, widthCombo, heightCombo),
2727 Arrow_Down, Arrow_Normal);
2728 }
2729
2730 if ( bmpPressed )
2731 {
2732 bmpPressed->Create(widthCombo, heightCombo);
2733 dcMem.SelectObject(*bmpPressed);
2734 DrawArrowButton(dcMem, wxRect(0, 0, widthCombo, heightCombo),
2735 Arrow_Down, Arrow_Pressed);
2736 }
2737
2738 if ( bmpDisabled )
2739 {
2740 bmpDisabled->Create(widthCombo, heightCombo);
2741 dcMem.SelectObject(*bmpDisabled);
2742 DrawArrowButton(dcMem, wxRect(0, 0, widthCombo, heightCombo),
2743 Arrow_Down, Arrow_Disabled);
2744 }
2745}
2746
2747// ----------------------------------------------------------------------------
147b8a4a 2748// scrollbar
1e6feb95
VZ
2749// ----------------------------------------------------------------------------
2750
147b8a4a 2751void wxWin32Renderer::DrawArrowBorder(wxDC& dc, wxRect *rect, bool isPressed)
1e6feb95 2752{
147b8a4a
VZ
2753 if ( isPressed )
2754 {
2755 DrawRect(dc, rect, m_penDarkGrey);
1e6feb95 2756
147b8a4a
VZ
2757 // the arrow is usually drawn inside border of width 2 and is offset by
2758 // another pixel in both directions when it's pressed - as the border
2759 // in this case is more narrow as well, we have to adjust rect like
2760 // this:
2761 rect->Inflate(-1);
2762 rect->x++;
2763 rect->y++;
2764 }
2765 else // !pressed
2766 {
2767 DrawAntiSunkenBorder(dc, rect);
2768 }
1e6feb95
VZ
2769}
2770
1e6feb95
VZ
2771void wxWin32Renderer::DrawArrow(wxDC& dc,
2772 wxDirection dir,
2773 const wxRect& rect,
2774 int flags)
2775{
0428ac8c 2776 ArrowStyle arrowStyle;
1e6feb95
VZ
2777 if ( flags & wxCONTROL_PRESSED )
2778 {
2779 // can't be pressed and disabled
2780 arrowStyle = Arrow_Pressed;
2781 }
2782 else
2783 {
2784 arrowStyle = flags & wxCONTROL_DISABLED ? Arrow_Disabled : Arrow_Normal;
2785 }
2786
0428ac8c 2787 DrawArrowButton(dc, rect, GetArrowDirection(dir), arrowStyle);
1e6feb95
VZ
2788}
2789
2790void wxWin32Renderer::DrawArrow(wxDC& dc,
2791 const wxRect& rect,
0428ac8c
VZ
2792 ArrowDirection arrowDir,
2793 ArrowStyle arrowStyle)
1e6feb95
VZ
2794{
2795 const wxBitmap& bmp = m_bmpArrows[arrowStyle][arrowDir];
2796
2797 // under Windows the arrows always have the same size so just centre it in
2798 // the provided rectangle
2799 wxCoord x = rect.x + (rect.width - bmp.GetWidth()) / 2,
2800 y = rect.y + (rect.height - bmp.GetHeight()) / 2;
2801
2802 // Windows does it like this...
2803 if ( arrowDir == Arrow_Left )
2804 x--;
2805
2806 // draw it
a290fa5a 2807 dc.DrawBitmap(bmp, x, y, true /* use mask */);
1e6feb95
VZ
2808}
2809
2810void wxWin32Renderer::DrawArrowButton(wxDC& dc,
2811 const wxRect& rectAll,
0428ac8c
VZ
2812 ArrowDirection arrowDir,
2813 ArrowStyle arrowStyle)
1e6feb95
VZ
2814{
2815 wxRect rect = rectAll;
147b8a4a 2816 DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rect);
1e6feb95
VZ
2817 DrawArrowBorder(dc, &rect, arrowStyle == Arrow_Pressed);
2818 DrawArrow(dc, rect, arrowDir, arrowStyle);
2819}
2820
2821void wxWin32Renderer::DrawScrollbarThumb(wxDC& dc,
61fef19b 2822 wxOrientation WXUNUSED(orient),
1e6feb95 2823 const wxRect& rect,
61fef19b 2824 int WXUNUSED(flags))
1e6feb95
VZ
2825{
2826 // we don't use the flags, the thumb never changes appearance
2827 wxRect rectThumb = rect;
2828 DrawArrowBorder(dc, &rectThumb);
2829 DrawBackground(dc, wxNullColour, rectThumb);
2830}
2831
2832void wxWin32Renderer::DrawScrollbarShaft(wxDC& dc,
61fef19b 2833 wxOrientation WXUNUSED(orient),
1e6feb95
VZ
2834 const wxRect& rectBar,
2835 int flags)
2836{
2837 wxColourScheme::StdColour col = flags & wxCONTROL_PRESSED
2838 ? wxColourScheme::SCROLLBAR_PRESSED
2839 : wxColourScheme::SCROLLBAR;
147b8a4a 2840 DrawBackground(dc, m_scheme->Get(col), rectBar);
1e6feb95
VZ
2841}
2842
24a23c35
VS
2843// ----------------------------------------------------------------------------
2844// top level windows
2845// ----------------------------------------------------------------------------
2846
813edf09
VS
2847int wxWin32Renderer::HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const
2848{
2849 wxRect client = GetFrameClientArea(rect, flags);
71e03035 2850
22a35096 2851 if ( client.Contains(pt) )
813edf09 2852 return wxHT_TOPLEVEL_CLIENT_AREA;
71e03035 2853
813edf09
VS
2854 if ( flags & wxTOPLEVEL_TITLEBAR )
2855 {
2856 wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
2857
2858 if ( flags & wxTOPLEVEL_ICON )
2859 {
22a35096 2860 if ( wxRect(client.GetPosition(), GetFrameIconSize()).Contains(pt) )
813edf09
VS
2861 return wxHT_TOPLEVEL_ICON;
2862 }
71e03035 2863
813edf09
VS
2864 wxRect btnRect(client.GetRight() - 2 - FRAME_BUTTON_WIDTH,
2865 client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2,
2866 FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT);
71e03035 2867
813edf09
VS
2868 if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
2869 {
22a35096 2870 if ( btnRect.Contains(pt) )
813edf09
VS
2871 return wxHT_TOPLEVEL_BUTTON_CLOSE;
2872 btnRect.x -= FRAME_BUTTON_WIDTH + 2;
2873 }
2874 if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
2875 {
22a35096 2876 if ( btnRect.Contains(pt) )
813edf09
VS
2877 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE;
2878 btnRect.x -= FRAME_BUTTON_WIDTH;
2879 }
2880 if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
2881 {
22a35096 2882 if ( btnRect.Contains(pt) )
813edf09
VS
2883 return wxHT_TOPLEVEL_BUTTON_RESTORE;
2884 btnRect.x -= FRAME_BUTTON_WIDTH;
2885 }
2886 if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
2887 {
22a35096 2888 if ( btnRect.Contains(pt) )
813edf09
VS
2889 return wxHT_TOPLEVEL_BUTTON_ICONIZE;
2890 btnRect.x -= FRAME_BUTTON_WIDTH;
2891 }
2892 if ( flags & wxTOPLEVEL_BUTTON_HELP )
2893 {
22a35096 2894 if ( btnRect.Contains(pt) )
813edf09
VS
2895 return wxHT_TOPLEVEL_BUTTON_HELP;
2896 btnRect.x -= FRAME_BUTTON_WIDTH;
2897 }
2898
b22d16ad 2899 if ( pt.y >= client.y && pt.y < client.y + FRAME_TITLEBAR_HEIGHT )
813edf09
VS
2900 return wxHT_TOPLEVEL_TITLEBAR;
2901 }
2902
2903 if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
2904 {
2905 // we are certainly at one of borders, lets decide which one:
71e03035 2906
813edf09
VS
2907 int border = 0;
2908 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
b22d16ad 2909 if ( pt.x < client.x )
813edf09 2910 border |= wxHT_TOPLEVEL_BORDER_W;
b22d16ad 2911 else if ( pt.x >= client.width + client.x )
813edf09 2912 border |= wxHT_TOPLEVEL_BORDER_E;
b22d16ad 2913 if ( pt.y < client.y )
813edf09 2914 border |= wxHT_TOPLEVEL_BORDER_N;
b22d16ad 2915 else if ( pt.y >= client.height + client.y )
813edf09
VS
2916 border |= wxHT_TOPLEVEL_BORDER_S;
2917 return border;
2918 }
71e03035 2919
813edf09
VS
2920 return wxHT_NOWHERE;
2921}
2922
24a23c35
VS
2923void wxWin32Renderer::DrawFrameTitleBar(wxDC& dc,
2924 const wxRect& rect,
2925 const wxString& title,
2926 const wxIcon& icon,
2927 int flags,
813edf09
VS
2928 int specialButton,
2929 int specialButtonFlags)
24a23c35
VS
2930{
2931 if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
2932 {
2933 DrawFrameBorder(dc, rect, flags);
2934 }
2935 if ( flags & wxTOPLEVEL_TITLEBAR )
2936 {
2937 DrawFrameBackground(dc, rect, flags);
2938 if ( flags & wxTOPLEVEL_ICON )
2939 DrawFrameIcon(dc, rect, icon, flags);
2940 DrawFrameTitle(dc, rect, title, flags);
71e03035 2941
24a23c35
VS
2942 wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
2943 wxCoord x,y;
813edf09 2944 x = client.GetRight() - 2 - FRAME_BUTTON_WIDTH;
24a23c35 2945 y = client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2;
71e03035 2946
813edf09 2947 if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
24a23c35 2948 {
813edf09
VS
2949 DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_CLOSE,
2950 (specialButton == wxTOPLEVEL_BUTTON_CLOSE) ?
2951 specialButtonFlags : 0);
24a23c35
VS
2952 x -= FRAME_BUTTON_WIDTH + 2;
2953 }
813edf09 2954 if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
24a23c35 2955 {
813edf09
VS
2956 DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_MAXIMIZE,
2957 (specialButton == wxTOPLEVEL_BUTTON_MAXIMIZE) ?
2958 specialButtonFlags : 0);
24a23c35
VS
2959 x -= FRAME_BUTTON_WIDTH;
2960 }
813edf09 2961 if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
24a23c35 2962 {
813edf09
VS
2963 DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_RESTORE,
2964 (specialButton == wxTOPLEVEL_BUTTON_RESTORE) ?
2965 specialButtonFlags : 0);
24a23c35
VS
2966 x -= FRAME_BUTTON_WIDTH;
2967 }
813edf09 2968 if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
24a23c35 2969 {
813edf09
VS
2970 DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_ICONIZE,
2971 (specialButton == wxTOPLEVEL_BUTTON_ICONIZE) ?
2972 specialButtonFlags : 0);
24a23c35
VS
2973 x -= FRAME_BUTTON_WIDTH;
2974 }
813edf09 2975 if ( flags & wxTOPLEVEL_BUTTON_HELP )
24a23c35 2976 {
813edf09
VS
2977 DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_HELP,
2978 (specialButton == wxTOPLEVEL_BUTTON_HELP) ?
2979 specialButtonFlags : 0);
24a23c35
VS
2980 }
2981 }
2982}
2983
2984void wxWin32Renderer::DrawFrameBorder(wxDC& dc,
2985 const wxRect& rect,
2986 int flags)
2987{
2988 if ( !(flags & wxTOPLEVEL_BORDER) ) return;
71e03035 2989
24a23c35 2990 wxRect r(rect);
71e03035 2991
24a23c35
VS
2992 DrawShadedRect(dc, &r, m_penLightGrey, m_penBlack);
2993 DrawShadedRect(dc, &r, m_penHighlight, m_penDarkGrey);
2994 DrawShadedRect(dc, &r, m_penLightGrey, m_penLightGrey);
2995 if ( flags & wxTOPLEVEL_RESIZEABLE )
2996 DrawShadedRect(dc, &r, m_penLightGrey, m_penLightGrey);
2997}
2998
2999void wxWin32Renderer::DrawFrameBackground(wxDC& dc,
3000 const wxRect& rect,
3001 int flags)
3002{
3003 if ( !(flags & wxTOPLEVEL_TITLEBAR) ) return;
3004
71e03035 3005 wxColour col = (flags & wxTOPLEVEL_ACTIVE) ?
24a23c35
VS
3006 wxSCHEME_COLOUR(m_scheme, TITLEBAR_ACTIVE) :
3007 wxSCHEME_COLOUR(m_scheme, TITLEBAR);
3008
3009 wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
3010 r.height = FRAME_TITLEBAR_HEIGHT;
71e03035 3011
24a23c35
VS
3012 DrawBackground(dc, col, r);
3013}
3014
3015void wxWin32Renderer::DrawFrameTitle(wxDC& dc,
3016 const wxRect& rect,
3017 const wxString& title,
3018 int flags)
3019{
6296744f
VS
3020 wxColour col = (flags & wxTOPLEVEL_ACTIVE) ?
3021 wxSCHEME_COLOUR(m_scheme, TITLEBAR_ACTIVE_TEXT) :
3022 wxSCHEME_COLOUR(m_scheme, TITLEBAR_TEXT);
3023
24a23c35
VS
3024 wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
3025 r.height = FRAME_TITLEBAR_HEIGHT;
3026 if ( flags & wxTOPLEVEL_ICON )
e7dda1ff 3027 {
24a23c35 3028 r.x += FRAME_TITLEBAR_HEIGHT;
e7dda1ff
VS
3029 r.width -= FRAME_TITLEBAR_HEIGHT + 2;
3030 }
24a23c35 3031 else
e7dda1ff 3032 {
24a23c35 3033 r.x += 1;
e7dda1ff
VS
3034 r.width -= 3;
3035 }
3036
3037 if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
3038 r.width -= FRAME_BUTTON_WIDTH + 2;
3039 if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
3040 r.width -= FRAME_BUTTON_WIDTH;
3041 if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
3042 r.width -= FRAME_BUTTON_WIDTH;
3043 if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
3044 r.width -= FRAME_BUTTON_WIDTH;
3045 if ( flags & wxTOPLEVEL_BUTTON_HELP )
3046 r.width -= FRAME_BUTTON_WIDTH;
71e03035 3047
24a23c35 3048 dc.SetFont(m_titlebarFont);
6296744f 3049 dc.SetTextForeground(col);
d1504049 3050
e7dda1ff
VS
3051 wxCoord textW;
3052 dc.GetTextExtent(title, &textW, NULL);
3053 if ( textW > r.width )
3054 {
3055 // text is too big, let's shorten it and add "..." after it:
3056 size_t len = title.length();
3057 wxCoord WSoFar, letterW;
3058
3059 dc.GetTextExtent(wxT("..."), &WSoFar, NULL);
3060 if ( WSoFar > r.width )
3061 {
3062 // not enough space to draw anything
3063 return;
3064 }
3065
3066 wxString s;
3067 s.Alloc(len);
3068 for (size_t i = 0; i < len; i++)
3069 {
3070 dc.GetTextExtent(title[i], &letterW, NULL);
3071 if ( letterW + WSoFar > r.width )
3072 break;
3073 WSoFar += letterW;
3074 s << title[i];
3075 }
3076 s << wxT("...");
d1504049 3077 dc.DrawLabel(s, wxNullBitmap, r,
e7dda1ff
VS
3078 wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
3079 }
3080 else
d1504049 3081 dc.DrawLabel(title, wxNullBitmap, r,
e7dda1ff 3082 wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
24a23c35
VS
3083}
3084
3085void wxWin32Renderer::DrawFrameIcon(wxDC& dc,
3086 const wxRect& rect,
3087 const wxIcon& icon,
3088 int flags)
3089{
3deeefeb
VS
3090 if ( icon.Ok() )
3091 {
3092 wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
3093 dc.DrawIcon(icon, r.x, r.y);
3094 }
24a23c35
VS
3095}
3096
3097void wxWin32Renderer::DrawFrameButton(wxDC& dc,
3098 wxCoord x, wxCoord y,
3099 int button,
2e9f62da 3100 int flags)
24a23c35
VS
3101{
3102 wxRect r(x, y, FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT);
813edf09 3103
24a23c35
VS
3104 size_t idx = 0;
3105 switch (button)
3106 {
813edf09
VS
3107 case wxTOPLEVEL_BUTTON_CLOSE: idx = FrameButton_Close; break;
3108 case wxTOPLEVEL_BUTTON_MAXIMIZE: idx = FrameButton_Maximize; break;
3109 case wxTOPLEVEL_BUTTON_ICONIZE: idx = FrameButton_Minimize; break;
3110 case wxTOPLEVEL_BUTTON_RESTORE: idx = FrameButton_Restore; break;
3111 case wxTOPLEVEL_BUTTON_HELP: idx = FrameButton_Help; break;
24a23c35
VS
3112 default:
3113 wxFAIL_MSG(wxT("incorrect button specification"));
3114 }
71e03035
VZ
3115
3116 if ( flags & wxCONTROL_PRESSED )
813edf09
VS
3117 {
3118 DrawShadedRect(dc, &r, m_penBlack, m_penHighlight);
3119 DrawShadedRect(dc, &r, m_penDarkGrey, m_penLightGrey);
3120 DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r);
a290fa5a 3121 dc.DrawBitmap(m_bmpFrameButtons[idx], r.x+1, r.y+1, true);
813edf09
VS
3122 }
3123 else
3124 {
3125 DrawShadedRect(dc, &r, m_penHighlight, m_penBlack);
3126 DrawShadedRect(dc, &r, m_penLightGrey, m_penDarkGrey);
3127 DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r);
a290fa5a 3128 dc.DrawBitmap(m_bmpFrameButtons[idx], r.x, r.y, true);
813edf09 3129 }
24a23c35
VS
3130}
3131
3132
3133wxRect wxWin32Renderer::GetFrameClientArea(const wxRect& rect,
3134 int flags) const
3135{
3136 wxRect r(rect);
3137
3138 if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
3139 {
71e03035 3140 int border = (flags & wxTOPLEVEL_RESIZEABLE) ?
24a23c35
VS
3141 RESIZEABLE_FRAME_BORDER_THICKNESS :
3142 FRAME_BORDER_THICKNESS;
3143 r.Inflate(-border);
3144 }
3145 if ( flags & wxTOPLEVEL_TITLEBAR )
3146 {
3147 r.y += FRAME_TITLEBAR_HEIGHT;
3148 r.height -= FRAME_TITLEBAR_HEIGHT;
3149 }
3150
3151 return r;
3152}
3153
3154wxSize wxWin32Renderer::GetFrameTotalSize(const wxSize& clientSize,
3155 int flags) const
3156{
3157 wxSize s(clientSize);
3158
3159 if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
3160 {
71e03035 3161 int border = (flags & wxTOPLEVEL_RESIZEABLE) ?
24a23c35
VS
3162 RESIZEABLE_FRAME_BORDER_THICKNESS :
3163 FRAME_BORDER_THICKNESS;
3164 s.x += 2*border;
3165 s.y += 2*border;
3166 }
3167 if ( flags & wxTOPLEVEL_TITLEBAR )
3168 s.y += FRAME_TITLEBAR_HEIGHT;
3169
3170 return s;
3171}
3172
e7dda1ff
VS
3173wxSize wxWin32Renderer::GetFrameMinSize(int flags) const
3174{
8b5d5223 3175 wxSize s;
e7dda1ff
VS
3176
3177 if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
3178 {
3179 int border = (flags & wxTOPLEVEL_RESIZEABLE) ?
3180 RESIZEABLE_FRAME_BORDER_THICKNESS :
3181 FRAME_BORDER_THICKNESS;
3182 s.x += 2*border;
3183 s.y += 2*border;
3184 }
3185
3186 if ( flags & wxTOPLEVEL_TITLEBAR )
3187 {
3188 s.y += FRAME_TITLEBAR_HEIGHT;
3189
3190 if ( flags & wxTOPLEVEL_ICON )
3191 s.x += FRAME_TITLEBAR_HEIGHT + 2;
3192 if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
3193 s.x += FRAME_BUTTON_WIDTH + 2;
3194 if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
3195 s.x += FRAME_BUTTON_WIDTH;
3196 if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
3197 s.x += FRAME_BUTTON_WIDTH;
3198 if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
3199 s.x += FRAME_BUTTON_WIDTH;
3200 if ( flags & wxTOPLEVEL_BUTTON_HELP )
3201 s.x += FRAME_BUTTON_WIDTH;
3202 }
3203
3204 return s;
3205}
3206
24a23c35
VS
3207wxSize wxWin32Renderer::GetFrameIconSize() const
3208{
3209 return wxSize(16, 16);
3210}
3211
3212
63f06c22
VS
3213// ----------------------------------------------------------------------------
3214// standard icons
3215// ----------------------------------------------------------------------------
3216
13b22a67 3217/* Copyright (c) Julian Smart */
63f06c22 3218static char *error_xpm[]={
13b22a67
JS
3219/* columns rows colors chars-per-pixel */
3220"32 32 70 1",
3221"- c #BF0101",
3222"b c #361F1F",
3223"& c #C08484",
3224"X c #BF3333",
3225"# c #C08181",
3226"% c #C01111",
3227"d c #C51515",
3228"s c #551818",
3229"O c #C07E7E",
3230": c #C00E0E",
3231"u c #E28A8A",
3232"2 c #C81F1F",
3233"8 c #FFFFFF",
3234"p c #E59494",
3235"< c #BB0101",
3236"y c #DA6A6A",
3237"A c #4C4C4C",
3238"9 c #F7DFDF",
3239"@ c #BF5353",
3240"w c #FAE9E9",
3241"F c #272727",
3242"5 c #D24A4A",
3243". c #C06363",
3244"n c #BF8282",
3245"7 c #F2C9C9",
3246"t c #C09292",
3247"M c #3E3E3E",
3248"x c #4D4D4D",
3249"4 c #CA2A2A",
3250"h c #E79F9F",
3251"* c #C05454",
3252"D c #711212",
3253"V c #737373",
3254"$ c #BF3232",
3255"N c #900B0B",
3256"6 c #BD0303",
3257"3 c #DF7F7F",
3258"K c #6F1212",
3259"C c #BD0000",
3260"m c #950909",
3261"P c #8A8A8A",
3262"j c #D75F5F",
3263" c None",
3264"e c #F4D4D4",
3265"S c #BF2020",
3266"L c #747474",
3267"G c #842C2C",
3268"c c #ECB4B4",
3269"l c #2E2121",
3270"g c #BF7E7E",
3271"k c #9B0808",
3272"= c #BF0505",
3273"a c #B10303",
3274"q c #7E2020",
3275"1 c #642222",
3276"J c #676767",
3277"B c #322020",
3278"; c #C00303",
3279"i c #242424",
3280"o c #C00000",
3281"> c #BF1F1F",
3282", c #842B2B",
3283"f c #701212",
3284"0 c #BE0000",
3285"r c #960909",
3286"H c #686868",
3287"v c #BC0000",
3288"Z c #671414",
3289"+ c #C02020",
3290"z c #CD3535",
3291/* pixels */
3292" ",
3293" ",
3294" .XoooOO ",
3295" .+ooooooooo@# ",
3296" $oooooooooooo%& ",
3297" *=-ooooooooooooo;: ",
3298" *oooooooooooooooooo> ",
3299" =ooooooooooooooooooo, ",
3300" $-ooooooooooooooooooo<1 ",
3301" .oooooo2334ooo533oooooo6 ",
3302" +ooooooo789oo2883oooooo0q ",
3303" oooooooo2w83o78eoooooooor ",
3304" toooooooooy88u884oooooooori ",
3305" Xooooooooooe888poooooooooas ",
3306" ooooooooooo4889doooooooooof ",
3307" ooooooooooo588w2oooooooooofi ",
3308" oooooooooodw8887oooooooooofi ",
3309" goooooooooh8w588jooooooookli ",
3310" tooooooooz885op8wdooooooorix ",
3311" oooooood98cood98cooooooori ",
3312" @oooooop8w2ooo5885ooooovbi ",
3313" n%ooooooooooooooooooooomiM ",
3314" &;oooooooooooooooooooNBiV ",
3315" :ooooooooooooooooooCZiA ",
3316" nSooooooooooooooooCDiF ",
3317" nG<oooooooooooooNZiiH ",
3318" 160ooooooooovmBiFH ",
3319" nqrraoookrrbiiA ",
3320" nJisKKKliiiML ",
3321" nPiiix ",
3322" ",
3323" "
3324};
63f06c22 3325
13b22a67 3326/* Copyright (c) Julian Smart */
63f06c22 3327static char *info_xpm[]={
13b22a67
JS
3328/* columns rows colors chars-per-pixel */
3329"32 32 17 1",
3330"* c #A1A3FB",
3331"X c #FFFFFF",
3332"O c #191EF4",
3333"= c #777AF9",
3334": c #4D51F7",
3335" c None",
3336"- c #2328F5",
3337"+ c #4247F6",
3338"; c #C1C2FC",
3339". c #C0C0C0",
3340"& c #E0E1FE",
3341"% c #242424",
3342"> c #2D32F5",
3343"o c #CBCCFD",
3344"# c #0309F3",
3345"@ c #8C8FFA",
3346"$ c #EAEBFE",
3347/* pixels */
3348" ....... ",
3349" ...XXXXXXX... ",
3350" ..XXXXXXXXXXXXX.. ",
3351" .XXXXXXXXXXXXXXXXX. ",
3352" .XXXXXXXXoO+XXXXXXXX. ",
3353" .XXXXXXXXX@#OXXXXXXXXX. ",
3354" .XXXXXXXXXX$@oXXXXXXXXXX. ",
3355" .XXXXXXXXXXXXXXXXXXXXXXX.% ",
3356" .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
3357".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
3358".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
3359".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
3360" .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
3361" .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
3362" .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
3363" .XXXXXXXX*-##+XXXXXXXX.%%% ",
3364" .XXXXXXXXXXXXXXXXXXX.%%%% ",
3365" .XXXXXXXXXXXXXXXXX.%%%% ",
3366" ..XXXXXXXXXXXXX..%%%% ",
3367" %...XXXXXXXX..%%%%% ",
3368" %%%..XXXXXX.%%%%% ",
3369" %%%.XXXXX.%%% ",
3370" %.XXXX.%% ",
3371" .XXX.%% ",
3372" .XX.%% ",
3373" .X.%% ",
3374" ..%% ",
3375" .%% ",
3376" %% ",
3377" % ",
3378" ",
3379" "
3380};
63f06c22 3381
13b22a67 3382/* Copyright (c) Julian Smart */
63f06c22 3383static char *question_xpm[]={
13b22a67
JS
3384/* columns rows colors chars-per-pixel */
3385"32 32 16 1",
3386"O c #A3A3FF",
3387"X c #FFFFFF",
3388"% c #CACAFF",
3389"- c #4141FF",
3390"= c #6060FF",
3391"* c #2B2BFF",
3392"@ c #B5B5FF",
3393" c None",
3394"# c #1616FF",
3395"+ c #8181FF",
3396"$ c #0000FF",
3397". c #C0C0C0",
3398"; c #5555FF",
3399": c #242424",
3400"o c #E7E7FF",
3401"& c #7575FF",
3402/* pixels */
3403" ....... ",
3404" ...XXXXXXX... ",
3405" ..XXXXXXXXXXXXX.. ",
3406" .XXXXXXoO++@XXXXXX. ",
3407" .XXXXXXO#$$$$#%XXXXX. ",
3408" .XXXXXX@$$#&&#$#oXXXXX. ",
3409" .XXXXXXX*$$%XX%$$=XXXXXX. ",
3410" .XXXXXXX+-;XXXX$$-XXXXXX.: ",
3411" .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
3412".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
3413".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
3414".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
3415" .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
3416" .XXXXXXXXXXX--XXXXXXXXXX.::: ",
3417" .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
3418" .XXXXXXXXX-$$XXXXXXXXX.::: ",
3419" .XXXXXXXX-$$XXXXXXXX.:::: ",
3420" .XXXXXXXO++XXXXXXX.:::: ",
3421" ..XXXXXXXXXXXXX..:::: ",
3422" :...XXXXXXXX..::::: ",
3423" :::..XXXXXX.::::: ",
3424" :::.XXXXX.::: ",
3425" :.XXXX.:: ",
3426" .XXX.:: ",
3427" .XX.:: ",
3428" .X.:: ",
3429" ..:: ",
3430" .:: ",
3431" :: ",
3432" : ",
3433" ",
3434" "
3435};
63f06c22 3436
13b22a67 3437/* Copyright (c) Julian Smart */
63f06c22 3438static char *warning_xpm[]={
13b22a67
JS
3439/* columns rows colors chars-per-pixel */
3440"32 32 9 1",
3441"@ c Black",
3442"o c #A6A800",
3443"+ c #8A8C00",
3444"$ c #B8BA00",
3445" c None",
3446"O c #6E7000",
3447"X c #DCDF00",
3448". c #C00000",
3449"# c #373800",
3450/* pixels */
3451" ",
3452" ",
3453" ",
3454" . ",
3455" ... ",
3456" ... ",
3457" ..... ",
3458" ...X.. ",
3459" ..XXX.. ",
3460" ...XXX... ",
3461" ..XXXXX.. ",
3462" ..XXXXXX... ",
3463" ...XXoO+XX.. ",
3464" ..XXXO@#XXX.. ",
3465" ..XXXXO@#XXX... ",
3466" ...XXXXO@#XXXX.. ",
3467" ..XXXXXO@#XXXX... ",
3468" ...XXXXXo@OXXXXX.. ",
3469" ...XXXXXXo@OXXXXXX.. ",
3470" ..XXXXXXX$@OXXXXXX... ",
3471" ...XXXXXXXX@XXXXXXXX.. ",
3472" ...XXXXXXXXXXXXXXXXXX... ",
3473" ..XXXXXXXXXXOXXXXXXXXX.. ",
3474" ...XXXXXXXXXO@#XXXXXXXXX.. ",
3475" ..XXXXXXXXXXX#XXXXXXXXXX... ",
3476" ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3477" ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3478" .............................. ",
3479" .............................. ",
3480" ",
3481" ",
3482" "
3483};
3484
63f06c22 3485
536b70ac
VS
3486wxBitmap wxWin32ArtProvider::CreateBitmap(const wxArtID& id,
3487 const wxArtClient& WXUNUSED(client),
3488 const wxSize& WXUNUSED(size))
3489{
3490 if ( id == wxART_INFORMATION )
3491 return wxBitmap(info_xpm);
3492 if ( id == wxART_ERROR )
3493 return wxBitmap(error_xpm);
3494 if ( id == wxART_WARNING )
3495 return wxBitmap(warning_xpm);
3496 if ( id == wxART_QUESTION )
3497 return wxBitmap(question_xpm);
3498 return wxNullBitmap;
63f06c22
VS
3499}
3500
24a23c35 3501
9a6384ca
WS
3502#if wxUSE_TEXTCTRL
3503
1e6feb95
VZ
3504// ----------------------------------------------------------------------------
3505// text control geometry
3506// ----------------------------------------------------------------------------
3507
61fef19b 3508wxRect
6229b92f 3509wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
61fef19b 3510 const wxRect& rect) const
1e6feb95 3511{
6229b92f 3512 wxRect rectTotal = wxStdRenderer::GetTextTotalArea(text, rect);
1e6feb95 3513
6229b92f 3514 // this is strange but it's what Windows does
1e6feb95
VZ
3515 rectTotal.height++;
3516
3517 return rectTotal;
3518}
3519
61fef19b 3520wxRect
6229b92f 3521wxWin32Renderer::GetTextClientArea(const wxTextCtrl *text,
61fef19b
VZ
3522 const wxRect& rect,
3523 wxCoord *extraSpaceBeyond) const
1e6feb95
VZ
3524{
3525 wxRect rectText = rect;
3526
3527 // undo GetTextTotalArea()
3528 if ( rectText.height > 0 )
3529 rectText.height--;
3530
6229b92f 3531 return wxStdRenderer::GetTextClientArea(text, rect, extraSpaceBeyond);
1e6feb95
VZ
3532}
3533
9a6384ca
WS
3534#endif // wxUSE_TEXTCTRL
3535
1e6feb95
VZ
3536// ----------------------------------------------------------------------------
3537// size adjustments
3538// ----------------------------------------------------------------------------
3539
3540void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
3541{
3542#if wxUSE_SCROLLBAR
3543 if ( wxDynamicCast(window, wxScrollBar) )
3544 {
3545 // we only set the width of vert scrollbars and height of the
3546 // horizontal ones
3547 if ( window->GetWindowStyle() & wxSB_HORIZONTAL )
3548 size->y = m_sizeScrollbarArrow.y;
3549 else
3550 size->x = m_sizeScrollbarArrow.x;
3551
3552 // skip border width adjustments, they don't make sense for us
3553 return;
3554 }
9467bdb7 3555#endif // wxUSE_SCROLLBAR
1e6feb95 3556
06aa40d9
WS
3557#if wxUSE_BMPBUTTON
3558 if ( wxDynamicCast(window, wxBitmapButton) )
3559 {
3560 // do nothing
3561 } else
3562#endif // wxUSE_BMPBUTTON
43be3c33 3563#if wxUSE_BUTTON || wxUSE_TOGGLEBTN
9eddec69 3564 if ( 0
43be3c33 3565# if wxUSE_BUTTON
9eddec69 3566 || wxDynamicCast(window, wxButton)
43be3c33
JS
3567# endif // wxUSE_BUTTON
3568# if wxUSE_TOGGLEBTN
9eddec69 3569 || wxDynamicCast(window, wxToggleButton)
43be3c33
JS
3570# endif // wxUSE_TOGGLEBTN
3571 )
1e6feb95 3572 {
1b465102
VZ
3573 if ( !(window->GetWindowStyle() & wxBU_EXACTFIT) )
3574 {
3575 // TODO: don't harcode all this
3576 size->x += 3*window->GetCharWidth();
3577
3578 wxCoord heightBtn = (11*(window->GetCharHeight() + 8))/10;
3579 if ( size->y < heightBtn - 8 )
3580 size->y = heightBtn;
3581 else
3582 size->y += 9;
3583 }
1e6feb95 3584
6766e5d1
JS
3585 // for compatibility with other ports, the buttons default size is never
3586 // less than the standard one, but not when display not PDAs.
3587 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA)
3588 {
a290fa5a 3589 if ( !(window->GetWindowStyle() & wxBU_EXACTFIT) )
6766e5d1 3590 {
a290fa5a 3591 wxSize szDef = wxButton::GetDefaultSize();
6766e5d1
JS
3592 if ( size->x < szDef.x )
3593 size->x = szDef.x;
3594 }
3595 }
3596
1e6feb95
VZ
3597 // no border width adjustments for buttons
3598 return;
3599 }
43be3c33 3600#endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
1e6feb95
VZ
3601
3602 // take into account the border width
3603 wxRect rectBorder = GetBorderDimensions(window->GetBorder());
3604 size->x += rectBorder.x + rectBorder.width;
3605 size->y += rectBorder.y + rectBorder.height;
3606}
3607
3608// ============================================================================
3609// wxInputHandler
3610// ============================================================================
3611
3612// ----------------------------------------------------------------------------
3613// wxWin32InputHandler
3614// ----------------------------------------------------------------------------
3615
61fef19b
VZ
3616bool wxWin32InputHandler::HandleKey(wxInputConsumer * WXUNUSED(control),
3617 const wxKeyEvent& WXUNUSED(event),
3618 bool WXUNUSED(pressed))
1e6feb95 3619{
a290fa5a 3620 return false;
1e6feb95
VZ
3621}
3622
67e49a98 3623bool wxWin32InputHandler::HandleMouse(wxInputConsumer *control,
1e6feb95
VZ
3624 const wxMouseEvent& event)
3625{
211cc8dc 3626 // clicking on the control gives it focus
71e03035 3627 if ( event.ButtonDown() )
211cc8dc 3628 {
71e03035 3629 wxWindow *win = control->GetInputWindow();
d1504049 3630
9467bdb7
VZ
3631 if ( (wxWindow::FindFocus() != control->GetInputWindow()) &&
3632 win->AcceptsFocus() )
71e03035
VZ
3633 {
3634 win->SetFocus();
211cc8dc 3635
a290fa5a 3636 return true;
71e03035 3637 }
211cc8dc
VS
3638 }
3639
a290fa5a 3640 return false;
1e6feb95
VZ
3641}
3642
9a6384ca
WS
3643#if wxUSE_SCROLLBAR
3644
1e6feb95
VZ
3645// ----------------------------------------------------------------------------
3646// wxWin32ScrollBarInputHandler
3647// ----------------------------------------------------------------------------
3648
3649wxWin32ScrollBarInputHandler::
9467bdb7 3650wxWin32ScrollBarInputHandler(wxRenderer *renderer, wxInputHandler *handler)
1e6feb95
VZ
3651 : wxStdScrollBarInputHandler(renderer, handler)
3652{
a290fa5a 3653 m_scrollPaused = false;
1e6feb95
VZ
3654 m_interval = 0;
3655}
3656
3657bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar *scrollbar,
3658 const wxControlAction& action)
3659{
3660 // stop if went beyond the position of the original click (this can only
3661 // happen when we scroll by pages)
a290fa5a 3662 bool stop = false;
1e6feb95
VZ
3663 if ( action == wxACTION_SCROLL_PAGE_DOWN )
3664 {
3665 stop = m_renderer->HitTestScrollbar(scrollbar, m_ptStartScrolling)
3666 != wxHT_SCROLLBAR_BAR_2;
3667 }
3668 else if ( action == wxACTION_SCROLL_PAGE_UP )
3669 {
3670 stop = m_renderer->HitTestScrollbar(scrollbar, m_ptStartScrolling)
3671 != wxHT_SCROLLBAR_BAR_1;
3672 }
3673
3674 if ( stop )
3675 {
3676 StopScrolling(scrollbar);
3677
3678 scrollbar->Refresh();
3679
a290fa5a 3680 return false;
1e6feb95
VZ
3681 }
3682
3683 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar, action);
3684}
3685
67e49a98 3686bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer *control,
1e6feb95
VZ
3687 const wxMouseEvent& event)
3688{
3689 // remember the current state
3690 bool wasDraggingThumb = m_htLast == wxHT_SCROLLBAR_THUMB;
3691
3692 // do process the message
3693 bool rc = wxStdScrollBarInputHandler::HandleMouse(control, event);
3694
3695 // analyse the changes
3696 if ( !wasDraggingThumb && (m_htLast == wxHT_SCROLLBAR_THUMB) )
3697 {
3698 // we just started dragging the thumb, remember its initial position to
3699 // be able to restore it if the drag is cancelled later
affe4044 3700 m_eventStartDrag = event;
1e6feb95
VZ
3701 }
3702
3703 return rc;
3704}
3705
67e49a98 3706bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer *control,
1e6feb95
VZ
3707 const wxMouseEvent& event)
3708{
3709 // we don't highlight scrollbar elements, so there is no need to process
3710 // mouse move events normally - only do it while mouse is captured (i.e.
3711 // when we're dragging the thumb or pressing on something)
3712 if ( !m_winCapture )
a290fa5a 3713 return false;
1e6feb95
VZ
3714
3715 if ( event.Entering() )
3716 {
3717 // we're not interested in this at all
a290fa5a 3718 return false;
1e6feb95
VZ
3719 }
3720
67e49a98 3721 wxScrollBar *scrollbar = wxStaticCast(control->GetInputWindow(), wxScrollBar);
1e6feb95
VZ
3722 wxHitTest ht;
3723 if ( m_scrollPaused )
3724 {
3725 // check if the mouse returned to its original location
3726
3727 if ( event.Leaving() )
3728 {
3729 // it surely didn't
a290fa5a 3730 return false;
1e6feb95
VZ
3731 }
3732
3733 ht = m_renderer->HitTestScrollbar(scrollbar, event.GetPosition());
3734 if ( ht == m_htLast )
3735 {
3736 // yes it did, resume scrolling
a290fa5a 3737 m_scrollPaused = false;
1e6feb95
VZ
3738 if ( m_timerScroll )
3739 {
3740 // we were scrolling by line/page, restart timer
3741 m_timerScroll->Start(m_interval);
3742
a290fa5a 3743 Press(scrollbar, true);
1e6feb95
VZ
3744 }
3745 else // we were dragging the thumb
3746 {
3747 // restore its last location
3748 HandleThumbMove(scrollbar, m_eventLastDrag);
3749 }
3750
a290fa5a 3751 return true;
1e6feb95
VZ
3752 }
3753 }
3754 else // normal case, scrolling hasn't been paused
3755 {
3756 // if we're scrolling the scrollbar because the arrow or the shaft was
3757 // pressed, check that the mouse stays on the same scrollbar element
3758
a17a79ba
RR
3759#if 0
3760 // Always let thumb jump back if we leave the scrollbar
1e6feb95
VZ
3761 if ( event.Moving() )
3762 {
3763 ht = m_renderer->HitTestScrollbar(scrollbar, event.GetPosition());
3764 }
3765 else // event.Leaving()
3766 {
3767 ht = wxHT_NOWHERE;
3768 }
a17a79ba
RR
3769#else
3770 // Jump back only if we get far away from it
3771 wxPoint pos = event.GetPosition();
3772 if (scrollbar->HasFlag( wxVERTICAL ))
3773 {
4175e952 3774 if (pos.x > -40 && pos.x < scrollbar->GetSize().x+40)
a17a79ba
RR
3775 pos.x = 5;
3776 }
3777 else
3778 {
4175e952 3779 if (pos.y > -40 && pos.y < scrollbar->GetSize().y+40)
a17a79ba
RR
3780 pos.y = 5;
3781 }
3782 ht = m_renderer->HitTestScrollbar(scrollbar, pos );
3783#endif
1e6feb95
VZ
3784
3785 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3786 // is still ok - we only want to catch the case when the mouse leaves
3787 // the scrollbar here
3788 if ( m_htLast == wxHT_SCROLLBAR_THUMB && ht != wxHT_NOWHERE )
3789 {
3790 ht = wxHT_SCROLLBAR_THUMB;
3791 }
3792
3793 if ( ht != m_htLast )
3794 {
3795 // what were we doing? 2 possibilities: either an arrow/shaft was
3796 // pressed in which case we have a timer and so we just stop it or
3797 // we were dragging the thumb
3798 if ( m_timerScroll )
3799 {
3800 // pause scrolling
3801 m_interval = m_timerScroll->GetInterval();
3802 m_timerScroll->Stop();
a290fa5a 3803 m_scrollPaused = true;
1e6feb95
VZ
3804
3805 // unpress the arrow
a290fa5a 3806 Press(scrollbar, false);
1e6feb95
VZ
3807 }
3808 else // we were dragging the thumb
3809 {
3810 // remember the current thumb position to be able to restore it
3811 // if the mouse returns to it later
affe4044 3812 m_eventLastDrag = event;
1e6feb95
VZ
3813
3814 // and restore the original position (before dragging) of the
3815 // thumb for now
3816 HandleThumbMove(scrollbar, m_eventStartDrag);
3817 }
3818
a290fa5a 3819 return true;
1e6feb95
VZ
3820 }
3821 }
3822
9467bdb7 3823 return wxStdInputHandler::HandleMouseMove(control, event);
1e6feb95
VZ
3824}
3825
9a6384ca
WS
3826#endif // wxUSE_SCROLLBAR
3827
3828#if wxUSE_CHECKBOX
3829
1e6feb95
VZ
3830// ----------------------------------------------------------------------------
3831// wxWin32CheckboxInputHandler
3832// ----------------------------------------------------------------------------
3833
67e49a98 3834bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer *control,
1e6feb95
VZ
3835 const wxKeyEvent& event,
3836 bool pressed)
3837{
3838 if ( pressed )
3839 {
3840 wxControlAction action;
3841 int keycode = event.GetKeyCode();
3842 switch ( keycode )
3843 {
3844 case WXK_SPACE:
3845 action = wxACTION_CHECKBOX_TOGGLE;
3846 break;
3847
3848 case WXK_SUBTRACT:
3849 case WXK_NUMPAD_SUBTRACT:
3850 action = wxACTION_CHECKBOX_CHECK;
3851 break;
3852
3853 case WXK_ADD:
3854 case WXK_NUMPAD_ADD:
3855 case WXK_NUMPAD_EQUAL:
3856 action = wxACTION_CHECKBOX_CLEAR;
3857 break;
3858 }
3859
a290fa5a 3860 if ( !action.IsEmpty() )
1e6feb95
VZ
3861 {
3862 control->PerformAction(action);
3863
a290fa5a 3864 return true;
1e6feb95
VZ
3865 }
3866 }
3867
a290fa5a 3868 return false;
1e6feb95
VZ
3869}
3870
9a6384ca
WS
3871#endif // wxUSE_CHECKBOX
3872
3873#if wxUSE_TEXTCTRL
3874
1e6feb95
VZ
3875// ----------------------------------------------------------------------------
3876// wxWin32TextCtrlInputHandler
3877// ----------------------------------------------------------------------------
3878
67e49a98 3879bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer *control,
1e6feb95
VZ
3880 const wxKeyEvent& event,
3881 bool pressed)
3882{
3883 // handle only MSW-specific text bindings here, the others are handled in
3884 // the base class
3885 if ( pressed )
3886 {
3887 int keycode = event.GetKeyCode();
3888
3889 wxControlAction action;
3890 if ( keycode == WXK_DELETE && event.ShiftDown() )
3891 {
3892 action = wxACTION_TEXT_CUT;
3893 }
3894 else if ( keycode == WXK_INSERT )
3895 {
3896 if ( event.ControlDown() )
3897 action = wxACTION_TEXT_COPY;
3898 else if ( event.ShiftDown() )
3899 action = wxACTION_TEXT_PASTE;
3900 }
3901
3902 if ( action != wxACTION_NONE )
3903 {
3904 control->PerformAction(action);
3905
a290fa5a 3906 return true;
1e6feb95
VZ
3907 }
3908 }
3909
9467bdb7 3910 return wxStdInputHandler::HandleKey(control, event, pressed);
1e6feb95
VZ
3911}
3912
9a6384ca
WS
3913#endif // wxUSE_TEXTCTRL
3914
3915#if wxUSE_STATUSBAR
3916
71e03035
VZ
3917// ----------------------------------------------------------------------------
3918// wxWin32StatusBarInputHandler
3919// ----------------------------------------------------------------------------
3920
3921wxWin32StatusBarInputHandler::
3922wxWin32StatusBarInputHandler(wxInputHandler *handler)
3923 : wxStdInputHandler(handler)
3924{
a290fa5a 3925 m_isOnGrip = false;
71e03035
VZ
3926}
3927
3928bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow *statbar,
3929 const wxPoint& pt) const
3930{
3931 if ( statbar->HasFlag(wxST_SIZEGRIP) &&
d1504049 3932 statbar->GetParent()->HasFlag(wxRESIZE_BORDER) )
71e03035 3933 {
d1504049
VZ
3934 wxTopLevelWindow *
3935 parentTLW = wxDynamicCast(statbar->GetParent(), wxTopLevelWindow);
71e03035 3936
a290fa5a 3937 wxCHECK_MSG( parentTLW, false,
d1504049
VZ
3938 _T("the status bar should be a child of a TLW") );
3939
3940 // a maximized window can't be resized anyhow
3941 if ( !parentTLW->IsMaximized() )
3942 {
3943 // VZ: I think that the standard Windows behaviour is to only
3944 // show the resizing cursor when the mouse is on top of the
3945 // grip itself but apparently different Windows versions behave
3946 // differently (?) and it seems a better UI to allow resizing
3947 // the status bar even when the mouse is above the grip
3948 wxSize sizeSbar = statbar->GetSize();
3949
3950 int diff = sizeSbar.x - pt.x;
3951 return diff >= 0 && diff < (wxCoord)STATUSBAR_GRIP_SIZE;
3952 }
71e03035
VZ
3953 }
3954
a290fa5a 3955 return false;
71e03035
VZ
3956}
3957
3958bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer *consumer,
3959 const wxMouseEvent& event)
3960{
3961 if ( event.Button(1) )
3962 {
3963 if ( event.ButtonDown(1) )
3964 {
3965 wxWindow *statbar = consumer->GetInputWindow();
3966
3967 if ( IsOnGrip(statbar, event.GetPosition()) )
3968 {
3969 wxTopLevelWindow *tlw = wxDynamicCast(statbar->GetParent(),
3970 wxTopLevelWindow);
3971 if ( tlw )
3972 {
3973 tlw->PerformAction(wxACTION_TOPLEVEL_RESIZE,
3974 wxHT_TOPLEVEL_BORDER_SE);
3975
3976 statbar->SetCursor(m_cursorOld);
3977
a290fa5a 3978 return true;
71e03035
VZ
3979 }
3980 }
3981 }
3982 }
3983
3984 return wxStdInputHandler::HandleMouse(consumer, event);
3985}
3986
3987bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
3988 const wxMouseEvent& event)
3989{
3990 wxWindow *statbar = consumer->GetInputWindow();
3991
3992 bool isOnGrip = IsOnGrip(statbar, event.GetPosition());
3993 if ( isOnGrip != m_isOnGrip )
3994 {
3995 m_isOnGrip = isOnGrip;
3996 if ( isOnGrip )
3997 {
3998 m_cursorOld = statbar->GetCursor();
3999 statbar->SetCursor(wxCURSOR_SIZENWSE);
4000 }
4001 else
4002 {
4003 statbar->SetCursor(m_cursorOld);
4004 }
4005 }
4006
4007 return wxStdInputHandler::HandleMouseMove(consumer, event);
4008}
4009
9a6384ca
WS
4010#endif // wxUSE_STATUSBAR
4011
768f0c5a
VS
4012// ----------------------------------------------------------------------------
4013// wxWin32FrameInputHandler
4014// ----------------------------------------------------------------------------
4015
8f71aafa
VS
4016class wxWin32SystemMenuEvtHandler : public wxEvtHandler
4017{
4018public:
2279b45a 4019 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler);
00e086a7 4020
2279b45a
VS
4021 void Attach(wxInputConsumer *consumer);
4022 void Detach();
00e086a7 4023
8f71aafa
VS
4024private:
4025 DECLARE_EVENT_TABLE()
4026 void OnSystemMenu(wxCommandEvent &event);
4027 void OnCloseFrame(wxCommandEvent &event);
4028 void OnClose(wxCloseEvent &event);
00e086a7 4029
8f71aafa
VS
4030 wxWin32FrameInputHandler *m_inputHnd;
4031 wxTopLevelWindow *m_wnd;
0b4f47a3 4032#if wxUSE_ACCEL
8f71aafa 4033 wxAcceleratorTable m_oldAccelTable;
0b4f47a3 4034#endif
8f71aafa
VS
4035};
4036
9467bdb7
VZ
4037wxWin32SystemMenuEvtHandler::
4038wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler)
8f71aafa
VS
4039{
4040 m_inputHnd = handler;
2279b45a
VS
4041 m_wnd = NULL;
4042}
4043
4044void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer *consumer)
4045{
4046 wxASSERT_MSG( m_wnd == NULL, _T("can't attach the handler twice!") );
4047
8f71aafa
VS
4048 m_wnd = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
4049 m_wnd->PushEventHandler(this);
00e086a7 4050
0b4f47a3 4051#if wxUSE_ACCEL
00e086a7 4052 // VS: This code relies on using generic implementation of
8f71aafa
VS
4053 // wxAcceleratorTable in wxUniv!
4054 wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
4055 m_oldAccelTable = table;
4056 table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_SPACE, wxID_SYSTEM_MENU));
4057 table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_F4, wxID_CLOSE_FRAME));
4058 m_wnd->SetAcceleratorTable(table);
0b4f47a3 4059#endif
8f71aafa
VS
4060}
4061
2279b45a 4062void wxWin32SystemMenuEvtHandler::Detach()
8f71aafa
VS
4063{
4064 if ( m_wnd )
4065 {
0b4f47a3 4066#if wxUSE_ACCEL
8f71aafa 4067 m_wnd->SetAcceleratorTable(m_oldAccelTable);
0b4f47a3 4068#endif
00e086a7 4069 m_wnd->RemoveEventHandler(this);
2279b45a 4070 m_wnd = NULL;
8f71aafa
VS
4071 }
4072}
4073
4074BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler, wxEvtHandler)
4075 EVT_MENU(wxID_SYSTEM_MENU, wxWin32SystemMenuEvtHandler::OnSystemMenu)
4076 EVT_MENU(wxID_CLOSE_FRAME, wxWin32SystemMenuEvtHandler::OnCloseFrame)
4077 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose)
4078END_EVENT_TABLE()
4079
4080void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent &WXUNUSED(event))
4081{
4082 int border = ((m_wnd->GetWindowStyle() & wxRESIZE_BORDER) &&
4083 !m_wnd->IsMaximized()) ?
4084 RESIZEABLE_FRAME_BORDER_THICKNESS :
4085 FRAME_BORDER_THICKNESS;
4086 wxPoint pt = m_wnd->GetClientAreaOrigin();
4087 pt.x = -pt.x + border;
4088 pt.y = -pt.y + border + FRAME_TITLEBAR_HEIGHT;
4089
0b4f47a3 4090#if wxUSE_ACCEL
8f71aafa
VS
4091 wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
4092 m_wnd->SetAcceleratorTable(wxNullAcceleratorTable);
0b4f47a3
DS
4093#endif
4094
9a6384ca 4095#if wxUSE_MENUS
8f71aafa 4096 m_inputHnd->PopupSystemMenu(m_wnd, pt);
9a6384ca 4097#endif // wxUSE_MENUS
0b4f47a3
DS
4098
4099#if wxUSE_ACCEL
8f71aafa 4100 m_wnd->SetAcceleratorTable(table);
0b4f47a3 4101#endif
8f71aafa
VS
4102}
4103
4104void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent &WXUNUSED(event))
4105{
4106 m_wnd->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
4107 wxTOPLEVEL_BUTTON_CLOSE);
4108}
4109
4110void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent &event)
4111{
4112 m_wnd = NULL;
4113 event.Skip();
4114}
4115
4116
2279b45a 4117wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler *handler)
9467bdb7 4118 : wxStdInputHandler(handler)
8f71aafa 4119{
2279b45a
VS
4120 m_menuHandler = new wxWin32SystemMenuEvtHandler(this);
4121}
4122
4123wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4124{
4125 if ( m_menuHandler )
8f71aafa 4126 {
2279b45a
VS
4127 m_menuHandler->Detach();
4128 delete m_menuHandler;
4129 }
4130}
4131
4132bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer,
4133 const wxMouseEvent& event)
4134{
4135 if ( event.LeftDClick() || event.LeftDown() || event.RightDown() )
4136 {
4137 wxTopLevelWindow *tlw =
4138 wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
4139
4140 long hit = tlw->HitTest(event.GetPosition());
4141
4142 if ( event.LeftDClick() && hit == wxHT_TOPLEVEL_TITLEBAR )
8f71aafa 4143 {
2279b45a
VS
4144 tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
4145 tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4146 : wxTOPLEVEL_BUTTON_MAXIMIZE);
a290fa5a 4147 return true;
8f71aafa 4148 }
2279b45a 4149 else if ( tlw->GetWindowStyle() & wxSYSTEM_MENU )
8f71aafa 4150 {
2279b45a 4151 if ( (event.LeftDown() && hit == wxHT_TOPLEVEL_ICON) ||
00e086a7
WS
4152 (event.RightDown() &&
4153 (hit == wxHT_TOPLEVEL_TITLEBAR ||
2279b45a 4154 hit == wxHT_TOPLEVEL_ICON)) )
8f71aafa 4155 {
9a6384ca 4156#if wxUSE_MENUS
2279b45a 4157 PopupSystemMenu(tlw, event.GetPosition());
9a6384ca 4158#endif // wxUSE_MENUS
a290fa5a 4159 return true;
8f71aafa 4160 }
2279b45a
VS
4161 }
4162 }
4163
9467bdb7 4164 return wxStdInputHandler::HandleMouse(consumer, event);
2279b45a 4165}
8f71aafa 4166
9a6384ca
WS
4167#if wxUSE_MENUS
4168
00e086a7 4169void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow *window,
2279b45a
VS
4170 const wxPoint& pos) const
4171{
4172 wxMenu *menu = new wxMenu;
4173
4174 if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
4175 menu->Append(wxID_RESTORE_FRAME , _("&Restore"));
4176 menu->Append(wxID_MOVE_FRAME , _("&Move"));
4177 if ( window->GetWindowStyle() & wxRESIZE_BORDER )
4178 menu->Append(wxID_RESIZE_FRAME , _("&Size"));
4179 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME) )
4180 menu->Append(wxID_ICONIZE_FRAME , _("Mi&nimize"));
4181 if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
4182 menu->Append(wxID_MAXIMIZE_FRAME , _("Ma&ximize"));
4183 menu->AppendSeparator();
4184 menu->Append(wxID_CLOSE_FRAME, _("Close\tAlt-F4"));
00e086a7 4185
2279b45a
VS
4186 if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
4187 {
4188 if ( window->IsMaximized() )
4189 {
a290fa5a
WS
4190 menu->Enable(wxID_MAXIMIZE_FRAME, false);
4191 menu->Enable(wxID_MOVE_FRAME, false);
2279b45a 4192 if ( window->GetWindowStyle() & wxRESIZE_BORDER )
a290fa5a 4193 menu->Enable(wxID_RESIZE_FRAME, false);
2279b45a
VS
4194 }
4195 else
a290fa5a 4196 menu->Enable(wxID_RESTORE_FRAME, false);
2279b45a
VS
4197 }
4198
4199 window->PopupMenu(menu, pos);
4200 delete menu;
4201}
4202
9a6384ca
WS
4203#endif // wxUSE_MENUS
4204
00e086a7 4205bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer,
2279b45a
VS
4206 bool activated)
4207{
4208 if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU )
4209 {
4210 // always detach if active frame changed:
4211 m_menuHandler->Detach();
4212
4213 if ( activated )
4214 {
4215 m_menuHandler->Attach(consumer);
8f71aafa
VS
4216 }
4217 }
4218
9467bdb7 4219 return wxStdInputHandler::HandleActivation(consumer, activated);
8f71aafa 4220}