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