]> git.saurik.com Git - wxWidgets.git/blame - src/univ/themes/win32.cpp
Ignore WXK_NONE events in wxStyledTextCtrl.
[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
63f06c22 2215#if !defined(__WXMGL__)
1e6feb95
VZ
2216 static const char *stipple_xpm[] = {
2217 /* columns rows colors chars-per-pixel */
2218 "2 2 2 1",
2219 " c None",
2220 "w c white",
2221 /* pixels */
2222 "w ",
2223 " w",
2224 };
63f06c22
VS
2225#else
2226 // VS: MGL can only do 8x8 stipple brushes
2227 static const char *stipple_xpm[] = {
2228 /* columns rows colors chars-per-pixel */
2229 "8 8 2 1",
2230 " c None",
2231 "w c white",
2232 /* pixels */
2233 "w w w w ",
2234 " w w w w",
2235 "w w w w ",
2236 " w w w w",
2237 "w w w w ",
2238 " w w w w",
2239 "w w w w ",
2240 " w w w w",
2241 };
2242#endif
1e6feb95
VZ
2243 dc.SetBrush(wxBrush(stipple_xpm));
2244
2245 dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, SHADOW_HIGHLIGHT));
2246 dc.SetTextBackground(wxSCHEME_COLOUR(m_scheme, CONTROL));
2247 dc.SetPen(*wxTRANSPARENT_PEN);
2248 dc.DrawRectangle(rectInt);
2249 }
2250}
2251
2252void wxWin32Renderer::DrawSliderTicks(wxDC& dc,
2253 const wxRect& rect,
6766e5d1 2254 int lenThumb,
1e6feb95
VZ
2255 wxOrientation orient,
2256 int start,
2257 int end,
2258 int step,
61fef19b 2259 int WXUNUSED(flags),
6766e5d1 2260 long style)
1e6feb95 2261{
6766e5d1
JS
2262 /* show ticks geometry
2263
2264 left right
2265 ticks shaft ticks
2266 ---- XX ---- <-- x1
2267 ---- XX ----
2268 ---- XX ----
2269 ---- XX ---- <-- x2
2270
2271 ^ ^ ^ ^
2272 | | | |
2273 y3 y1 y2 y4
2274 */
1e6feb95 2275
6766e5d1 2276 // empty slider?
4462f911
VZ
2277 if ( end == start )
2278 return;
2279
2280 bool left, right;
2281 GetSliderLabelsSides(orient, style, &left, &right);
2282
2283 bool isVertical = orient == wxVERTICAL;
6766e5d1
JS
2284
2285 // default thumb size
2286 wxSize sizeThumb = GetSliderThumbSize (rect, 0, orient);
4462f911 2287 wxCoord defaultLen = (isVertical ? sizeThumb.x : sizeThumb.y);
6766e5d1
JS
2288
2289 // normal thumb size
2290 sizeThumb = GetSliderThumbSize (rect, lenThumb, orient);
4462f911 2291 wxCoord widthThumb = (isVertical ? sizeThumb.y : sizeThumb.x);
6766e5d1
JS
2292
2293 wxRect rectShaft = GetSliderShaftRect (rect, lenThumb, orient, style);
2294
2295 wxCoord x1, x2, y1, y2, y3, y4 , len;
4462f911
VZ
2296 x1 = (isVertical ? rectShaft.y : rectShaft.x) + widthThumb/2;
2297 x2 = (isVertical ? rectShaft.GetBottom() : rectShaft.GetRight()) - widthThumb/2;
2298 y1 = (isVertical ? rectShaft.x : rectShaft.y) - defaultLen/2;
2299 y2 = (isVertical ? rectShaft.GetRight() : rectShaft.GetBottom()) + defaultLen/2;
2300 y3 = (isVertical ? rect.x : rect.y);
2301 y4 = (isVertical ? rect.GetRight() : rect.GetBottom());
6766e5d1 2302 len = x2 - x1;
1e6feb95
VZ
2303
2304 dc.SetPen(m_penBlack);
2305
2306 int range = end - start;
4462f911
VZ
2307 for ( int n = 0; n < range; n += step )
2308 {
1e6feb95
VZ
2309 wxCoord x = x1 + (len*n) / range;
2310
4462f911
VZ
2311 if (left & (y1 > y3))
2312 {
6766e5d1
JS
2313 DrawLine(dc, x, y1, x, y3, orient == wxVERTICAL);
2314 }
4462f911
VZ
2315 if (right & (y4 > y2))
2316 {
6766e5d1
JS
2317 DrawLine(dc, x, y2, x, y4, orient == wxVERTICAL);
2318 }
1e6feb95 2319 }
1e6feb95 2320 // always draw the line at the end position
4462f911
VZ
2321 if (left & (y1 > y3))
2322 {
6766e5d1
JS
2323 DrawLine(dc, x2, y1, x2, y3, orient == wxVERTICAL);
2324 }
4462f911
VZ
2325 if (right & (y4 > y2))
2326 {
6766e5d1
JS
2327 DrawLine(dc, x2, y2, x2, y4, orient == wxVERTICAL);
2328 }
1e6feb95
VZ
2329}
2330
9a6384ca
WS
2331#endif // wxUSE_SLIDER
2332
2333#if wxUSE_MENUS
2334
1e6feb95
VZ
2335// ----------------------------------------------------------------------------
2336// menu and menubar
2337// ----------------------------------------------------------------------------
2338
2339// wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2340class WXDLLEXPORT wxWin32MenuGeometryInfo : public wxMenuGeometryInfo
2341{
2342public:
2343 virtual wxSize GetSize() const { return m_size; }
2344
2345 wxCoord GetLabelOffset() const { return m_ofsLabel; }
2346 wxCoord GetAccelOffset() const { return m_ofsAccel; }
2347
2348 wxCoord GetItemHeight() const { return m_heightItem; }
2349
2350private:
2351 // the total size of the menu
2352 wxSize m_size;
2353
2354 // the offset of the start of the menu item label
2355 wxCoord m_ofsLabel;
2356
2357 // the offset of the start of the accel label
2358 wxCoord m_ofsAccel;
2359
2360 // the height of a normal (not separator) item
2361 wxCoord m_heightItem;
2362
71e03035
VZ
2363 friend wxMenuGeometryInfo *
2364 wxWin32Renderer::GetMenuGeometry(wxWindow *, const wxMenu&) const;
1e6feb95
VZ
2365};
2366
2367// FIXME: all constants are hardcoded but shouldn't be
2368static const wxCoord MENU_LEFT_MARGIN = 9;
2369static const wxCoord MENU_RIGHT_MARGIN = 18;
2370static const wxCoord MENU_VERT_MARGIN = 3;
2371
2372// the margin around bitmap/check marks (on each side)
2373static const wxCoord MENU_BMP_MARGIN = 2;
2374
2375// the margin between the labels and accel strings
2376static const wxCoord MENU_ACCEL_MARGIN = 8;
2377
2378// the separator height in pixels: in fact, strangely enough, the real height
2379// is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2380// account here
2381static const wxCoord MENU_SEPARATOR_HEIGHT = 3;
2382
2383// the size of the standard checkmark bitmap
2384static const wxCoord MENU_CHECK_SIZE = 9;
2385
2386void wxWin32Renderer::DrawMenuBarItem(wxDC& dc,
2387 const wxRect& rectOrig,
2388 const wxString& label,
2389 int flags,
2390 int indexAccel)
2391{
2392 wxRect rect = rectOrig;
2393 rect.height--;
2394
2395 wxDCTextColourChanger colChanger(dc);
2396
2397 if ( flags & wxCONTROL_SELECTED )
2398 {
2399 colChanger.Set(wxSCHEME_COLOUR(m_scheme, HIGHLIGHT_TEXT));
2400
147b8a4a
VZ
2401 const wxColour colBg = wxSCHEME_COLOUR(m_scheme, HIGHLIGHT);
2402 dc.SetBrush(colBg);
2403 dc.SetPen(colBg);
1e6feb95
VZ
2404 dc.DrawRectangle(rect);
2405 }
2406
2407 // don't draw the focus rect around menu bar items
2408 DrawLabel(dc, label, rect, flags & ~wxCONTROL_FOCUSED,
2409 wxALIGN_CENTRE, indexAccel);
2410}
2411
2412void wxWin32Renderer::DrawMenuItem(wxDC& dc,
2413 wxCoord y,
2414 const wxMenuGeometryInfo& gi,
2415 const wxString& label,
2416 const wxString& accel,
2417 const wxBitmap& bitmap,
2418 int flags,
2419 int indexAccel)
2420{
2421 const wxWin32MenuGeometryInfo& geometryInfo =
2422 (const wxWin32MenuGeometryInfo&)gi;
2423
2424 wxRect rect;
2425 rect.x = 0;
2426 rect.y = y;
2427 rect.width = geometryInfo.GetSize().x;
2428 rect.height = geometryInfo.GetItemHeight();
2429
2430 // draw the selected item specially
2431 wxDCTextColourChanger colChanger(dc);
2432 if ( flags & wxCONTROL_SELECTED )
2433 {
2434 colChanger.Set(wxSCHEME_COLOUR(m_scheme, HIGHLIGHT_TEXT));
2435
147b8a4a
VZ
2436 const wxColour colBg = wxSCHEME_COLOUR(m_scheme, HIGHLIGHT);
2437 dc.SetBrush(colBg);
2438 dc.SetPen(colBg);
1e6feb95
VZ
2439 dc.DrawRectangle(rect);
2440 }
2441
2442 // draw the bitmap: use the bitmap provided or the standard checkmark for
2443 // the checkable items
2444 wxBitmap bmp = bitmap;
a1b806b9 2445 if ( !bmp.IsOk() && (flags & wxCONTROL_CHECKED) )
1e6feb95
VZ
2446 {
2447 bmp = GetIndicator(IndicatorType_Menu, flags);
2448 }
2449
a1b806b9 2450 if ( bmp.IsOk() )
1e6feb95
VZ
2451 {
2452 rect.SetRight(geometryInfo.GetLabelOffset());
2453 wxControlRenderer::DrawBitmap(dc, bmp, rect);
2454 }
2455
2456 // draw the label
2457 rect.x = geometryInfo.GetLabelOffset();
2458 rect.SetRight(geometryInfo.GetAccelOffset());
2459
2460 DrawLabel(dc, label, rect, flags, wxALIGN_CENTRE_VERTICAL, indexAccel);
2461
2462 // draw the accel string
2463 rect.x = geometryInfo.GetAccelOffset();
2464 rect.SetRight(geometryInfo.GetSize().x);
2465
2466 // NB: no accel index here
2467 DrawLabel(dc, accel, rect, flags, wxALIGN_CENTRE_VERTICAL);
2468
2469 // draw the submenu indicator
2470 if ( flags & wxCONTROL_ISSUBMENU )
2471 {
2472 rect.x = geometryInfo.GetSize().x - MENU_RIGHT_MARGIN;
2473 rect.width = MENU_RIGHT_MARGIN;
2474
0428ac8c 2475 ArrowStyle arrowStyle;
1e6feb95 2476 if ( flags & wxCONTROL_DISABLED )
d6922577 2477 arrowStyle = flags & wxCONTROL_SELECTED ? Arrow_InvertedDisabled
1e6feb95
VZ
2478 : Arrow_Disabled;
2479 else if ( flags & wxCONTROL_SELECTED )
d6922577 2480 arrowStyle = Arrow_Inverted;
1e6feb95
VZ
2481 else
2482 arrowStyle = Arrow_Normal;
2483
2484 DrawArrow(dc, rect, Arrow_Right, arrowStyle);
2485 }
2486}
2487
2488void wxWin32Renderer::DrawMenuSeparator(wxDC& dc,
2489 wxCoord y,
2490 const wxMenuGeometryInfo& geomInfo)
2491{
2492 DrawHorizontalLine(dc, y + MENU_VERT_MARGIN, 0, geomInfo.GetSize().x);
2493}
2494
2495wxSize wxWin32Renderer::GetMenuBarItemSize(const wxSize& sizeText) const
2496{
2497 wxSize size = sizeText;
2498
2499 // FIXME: menubar height is configurable under Windows
2500 size.x += 12;
2501 size.y += 6;
2502
2503 return size;
2504}
2505
2506wxMenuGeometryInfo *wxWin32Renderer::GetMenuGeometry(wxWindow *win,
2507 const wxMenu& menu) const
2508{
2509 // prepare the dc: for now we draw all the items with the system font
2510 wxClientDC dc(win);
a756f210 2511 dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
1e6feb95
VZ
2512
2513 // the height of a normal item
2514 wxCoord heightText = dc.GetCharHeight();
2515
2516 // the total height
2517 wxCoord height = 0;
2518
2519 // the max length of label and accel strings: the menu width is the sum of
2520 // them, even if they're for different items (as the accels should be
2521 // aligned)
2522 //
2523 // the max length of the bitmap is never 0 as Windows always leaves enough
2524 // space for a check mark indicator
2525 wxCoord widthLabelMax = 0,
2526 widthAccelMax = 0,
2527 widthBmpMax = MENU_LEFT_MARGIN;
2528
ac32ba44 2529 for ( wxMenuItemList::compatibility_iterator node = menu.GetMenuItems().GetFirst();
1e6feb95
VZ
2530 node;
2531 node = node->GetNext() )
2532 {
2533 // height of this item
2534 wxCoord h;
2535
2536 wxMenuItem *item = node->GetData();
2537 if ( item->IsSeparator() )
2538 {
2539 h = MENU_SEPARATOR_HEIGHT;
2540 }
2541 else // not separator
2542 {
2543 h = heightText;
2544
2545 wxCoord widthLabel;
c267759c 2546 dc.GetTextExtent(item->GetItemLabelText(), &widthLabel, NULL);
1e6feb95
VZ
2547 if ( widthLabel > widthLabelMax )
2548 {
2549 widthLabelMax = widthLabel;
2550 }
2551
2552 wxCoord widthAccel;
2553 dc.GetTextExtent(item->GetAccelString(), &widthAccel, NULL);
2554 if ( widthAccel > widthAccelMax )
2555 {
2556 widthAccelMax = widthAccel;
2557 }
2558
2559 const wxBitmap& bmp = item->GetBitmap();
a1b806b9 2560 if ( bmp.IsOk() )
1e6feb95
VZ
2561 {
2562 wxCoord widthBmp = bmp.GetWidth();
2563 if ( widthBmp > widthBmpMax )
2564 widthBmpMax = widthBmp;
2565 }
2566 //else if ( item->IsCheckable() ): no need to check for this as
2567 // MENU_LEFT_MARGIN is big enough to show the check mark
2568 }
2569
2570 h += 2*MENU_VERT_MARGIN;
2571
2572 // remember the item position and height
2573 item->SetGeometry(height, h);
2574
2575 height += h;
2576 }
2577
2578 // bundle the metrics into a struct and return it
2579 wxWin32MenuGeometryInfo *gi = new wxWin32MenuGeometryInfo;
2580
2581 gi->m_ofsLabel = widthBmpMax + 2*MENU_BMP_MARGIN;
2582 gi->m_ofsAccel = gi->m_ofsLabel + widthLabelMax;
2583 if ( widthAccelMax > 0 )
2584 {
2585 // if we actually have any accesl, add a margin
2586 gi->m_ofsAccel += MENU_ACCEL_MARGIN;
2587 }
2588
2589 gi->m_heightItem = heightText + 2*MENU_VERT_MARGIN;
2590
2591 gi->m_size.x = gi->m_ofsAccel + widthAccelMax + MENU_RIGHT_MARGIN;
2592 gi->m_size.y = height;
2593
2594 return gi;
2595}
2596
9a6384ca
WS
2597#endif // wxUSE_MENUS
2598
2599#if wxUSE_STATUSBAR
2600
71e03035
VZ
2601// ----------------------------------------------------------------------------
2602// status bar
2603// ----------------------------------------------------------------------------
3379ed37 2604
71e03035
VZ
2605void wxWin32Renderer::DrawStatusField(wxDC& dc,
2606 const wxRect& rect,
2607 const wxString& label,
1cd9779f
VZ
2608 int flags,
2609 int style)
3379ed37 2610{
71e03035 2611 wxRect rectIn;
3379ed37 2612
1cd9779f 2613 if ( flags & wxCONTROL_SIZEGRIP )
71e03035
VZ
2614 {
2615 // draw the size grip: it is a normal rect except that in the lower
2616 // right corner we have several bands which may be used for dragging
2617 // the status bar corner
2618 //
2619 // each band consists of 4 stripes: m_penHighlight, double
2620 // m_penDarkGrey and transparent one
2621 wxCoord x2 = rect.GetRight(),
2622 y2 = rect.GetBottom();
3379ed37 2623
71e03035 2624 // draw the upper left part of the rect normally
c2919ab3
VZ
2625 if (style != wxSB_FLAT)
2626 {
2627 if (style == wxSB_RAISED)
2628 dc.SetPen(m_penHighlight);
2629 else
2630 dc.SetPen(m_penDarkGrey);
2631 dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), y2);
2632 dc.DrawLine(rect.GetLeft() + 1, rect.GetTop(), x2, rect.GetTop());
2633 }
71e03035
VZ
2634
2635 // draw the grey stripes of the grip
2636 size_t n;
2637 wxCoord ofs = WIDTH_STATUSBAR_GRIP_BAND - 1;
2638 for ( n = 0; n < NUM_STATUSBAR_GRIP_BANDS; n++, ofs += WIDTH_STATUSBAR_GRIP_BAND )
2639 {
2640 dc.DrawLine(x2 - ofs + 1, y2 - 1, x2, y2 - ofs);
2641 dc.DrawLine(x2 - ofs, y2 - 1, x2, y2 - ofs - 1);
2642 }
2643
2644 // draw the white stripes
2645 dc.SetPen(m_penHighlight);
2646 ofs = WIDTH_STATUSBAR_GRIP_BAND + 1;
2647 for ( n = 0; n < NUM_STATUSBAR_GRIP_BANDS; n++, ofs += WIDTH_STATUSBAR_GRIP_BAND )
2648 {
2649 dc.DrawLine(x2 - ofs + 1, y2 - 1, x2, y2 - ofs);
2650 }
2651
2652 // draw the remaining rect boundaries
c2919ab3
VZ
2653 if (style != wxSB_FLAT)
2654 {
2655 if (style == wxSB_RAISED)
2656 dc.SetPen(m_penDarkGrey);
2657 else
2658 dc.SetPen(m_penHighlight);
2659 ofs -= WIDTH_STATUSBAR_GRIP_BAND;
2660 dc.DrawLine(x2, rect.GetTop(), x2, y2 - ofs + 1);
2661 dc.DrawLine(rect.GetLeft(), y2, x2 - ofs + 1, y2);
2662 }
71e03035
VZ
2663
2664 rectIn = rect;
2665 rectIn.Deflate(1);
2666
2667 rectIn.width -= STATUSBAR_GRIP_SIZE;
71e03035 2668
1cd9779f
VZ
2669 // this will prevent the standard version from drawing any borders
2670 style = wxSB_FLAT;
2671 }
71e03035 2672
bfd5f909 2673 wxStdRenderer::DrawStatusField(dc, rect, label, flags, style);
71e03035 2674}
3379ed37 2675
9a6384ca
WS
2676#endif // wxUSE_STATUSBAR
2677
1e6feb95
VZ
2678// ----------------------------------------------------------------------------
2679// combobox
2680// ----------------------------------------------------------------------------
2681
2682void wxWin32Renderer::GetComboBitmaps(wxBitmap *bmpNormal,
61fef19b 2683 wxBitmap * WXUNUSED(bmpFocus),
1e6feb95
VZ
2684 wxBitmap *bmpPressed,
2685 wxBitmap *bmpDisabled)
2686{
2687 static const wxCoord widthCombo = 16;
2688 static const wxCoord heightCombo = 17;
2689
2690 wxMemoryDC dcMem;
2691
2692 if ( bmpNormal )
2693 {
2694 bmpNormal->Create(widthCombo, heightCombo);
2695 dcMem.SelectObject(*bmpNormal);
2696 DrawArrowButton(dcMem, wxRect(0, 0, widthCombo, heightCombo),
2697 Arrow_Down, Arrow_Normal);
2698 }
2699
2700 if ( bmpPressed )
2701 {
2702 bmpPressed->Create(widthCombo, heightCombo);
2703 dcMem.SelectObject(*bmpPressed);
2704 DrawArrowButton(dcMem, wxRect(0, 0, widthCombo, heightCombo),
2705 Arrow_Down, Arrow_Pressed);
2706 }
2707
2708 if ( bmpDisabled )
2709 {
2710 bmpDisabled->Create(widthCombo, heightCombo);
2711 dcMem.SelectObject(*bmpDisabled);
2712 DrawArrowButton(dcMem, wxRect(0, 0, widthCombo, heightCombo),
2713 Arrow_Down, Arrow_Disabled);
2714 }
2715}
2716
2717// ----------------------------------------------------------------------------
147b8a4a 2718// scrollbar
1e6feb95
VZ
2719// ----------------------------------------------------------------------------
2720
147b8a4a 2721void wxWin32Renderer::DrawArrowBorder(wxDC& dc, wxRect *rect, bool isPressed)
1e6feb95 2722{
147b8a4a
VZ
2723 if ( isPressed )
2724 {
2725 DrawRect(dc, rect, m_penDarkGrey);
1e6feb95 2726
147b8a4a
VZ
2727 // the arrow is usually drawn inside border of width 2 and is offset by
2728 // another pixel in both directions when it's pressed - as the border
2729 // in this case is more narrow as well, we have to adjust rect like
2730 // this:
2731 rect->Inflate(-1);
2732 rect->x++;
2733 rect->y++;
2734 }
2735 else // !pressed
2736 {
2737 DrawAntiSunkenBorder(dc, rect);
2738 }
1e6feb95
VZ
2739}
2740
1e6feb95
VZ
2741void wxWin32Renderer::DrawArrow(wxDC& dc,
2742 wxDirection dir,
2743 const wxRect& rect,
2744 int flags)
2745{
0428ac8c 2746 ArrowStyle arrowStyle;
1e6feb95
VZ
2747 if ( flags & wxCONTROL_PRESSED )
2748 {
2749 // can't be pressed and disabled
2750 arrowStyle = Arrow_Pressed;
2751 }
2752 else
2753 {
2754 arrowStyle = flags & wxCONTROL_DISABLED ? Arrow_Disabled : Arrow_Normal;
2755 }
2756
0428ac8c 2757 DrawArrowButton(dc, rect, GetArrowDirection(dir), arrowStyle);
1e6feb95
VZ
2758}
2759
2760void wxWin32Renderer::DrawArrow(wxDC& dc,
2761 const wxRect& rect,
0428ac8c
VZ
2762 ArrowDirection arrowDir,
2763 ArrowStyle arrowStyle)
1e6feb95
VZ
2764{
2765 const wxBitmap& bmp = m_bmpArrows[arrowStyle][arrowDir];
2766
2767 // under Windows the arrows always have the same size so just centre it in
2768 // the provided rectangle
2769 wxCoord x = rect.x + (rect.width - bmp.GetWidth()) / 2,
2770 y = rect.y + (rect.height - bmp.GetHeight()) / 2;
2771
2772 // Windows does it like this...
2773 if ( arrowDir == Arrow_Left )
2774 x--;
2775
2776 // draw it
a290fa5a 2777 dc.DrawBitmap(bmp, x, y, true /* use mask */);
1e6feb95
VZ
2778}
2779
2780void wxWin32Renderer::DrawArrowButton(wxDC& dc,
2781 const wxRect& rectAll,
0428ac8c
VZ
2782 ArrowDirection arrowDir,
2783 ArrowStyle arrowStyle)
1e6feb95
VZ
2784{
2785 wxRect rect = rectAll;
147b8a4a 2786 DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rect);
1e6feb95
VZ
2787 DrawArrowBorder(dc, &rect, arrowStyle == Arrow_Pressed);
2788 DrawArrow(dc, rect, arrowDir, arrowStyle);
2789}
2790
2791void wxWin32Renderer::DrawScrollbarThumb(wxDC& dc,
61fef19b 2792 wxOrientation WXUNUSED(orient),
1e6feb95 2793 const wxRect& rect,
61fef19b 2794 int WXUNUSED(flags))
1e6feb95
VZ
2795{
2796 // we don't use the flags, the thumb never changes appearance
2797 wxRect rectThumb = rect;
2798 DrawArrowBorder(dc, &rectThumb);
2799 DrawBackground(dc, wxNullColour, rectThumb);
2800}
2801
2802void wxWin32Renderer::DrawScrollbarShaft(wxDC& dc,
61fef19b 2803 wxOrientation WXUNUSED(orient),
1e6feb95
VZ
2804 const wxRect& rectBar,
2805 int flags)
2806{
2807 wxColourScheme::StdColour col = flags & wxCONTROL_PRESSED
2808 ? wxColourScheme::SCROLLBAR_PRESSED
2809 : wxColourScheme::SCROLLBAR;
147b8a4a 2810 DrawBackground(dc, m_scheme->Get(col), rectBar);
1e6feb95
VZ
2811}
2812
63f06c22
VS
2813// ----------------------------------------------------------------------------
2814// standard icons
2815// ----------------------------------------------------------------------------
2816
13b22a67 2817/* Copyright (c) Julian Smart */
579de297 2818static const char *error_xpm[]={
13b22a67
JS
2819/* columns rows colors chars-per-pixel */
2820"32 32 70 1",
2821"- c #BF0101",
2822"b c #361F1F",
2823"& c #C08484",
2824"X c #BF3333",
2825"# c #C08181",
2826"% c #C01111",
2827"d c #C51515",
2828"s c #551818",
2829"O c #C07E7E",
2830": c #C00E0E",
2831"u c #E28A8A",
2832"2 c #C81F1F",
2833"8 c #FFFFFF",
2834"p c #E59494",
2835"< c #BB0101",
2836"y c #DA6A6A",
2837"A c #4C4C4C",
2838"9 c #F7DFDF",
2839"@ c #BF5353",
2840"w c #FAE9E9",
2841"F c #272727",
2842"5 c #D24A4A",
2843". c #C06363",
2844"n c #BF8282",
2845"7 c #F2C9C9",
2846"t c #C09292",
2847"M c #3E3E3E",
2848"x c #4D4D4D",
2849"4 c #CA2A2A",
2850"h c #E79F9F",
2851"* c #C05454",
2852"D c #711212",
2853"V c #737373",
2854"$ c #BF3232",
2855"N c #900B0B",
2856"6 c #BD0303",
2857"3 c #DF7F7F",
2858"K c #6F1212",
2859"C c #BD0000",
2860"m c #950909",
2861"P c #8A8A8A",
2862"j c #D75F5F",
2863" c None",
2864"e c #F4D4D4",
2865"S c #BF2020",
2866"L c #747474",
2867"G c #842C2C",
2868"c c #ECB4B4",
2869"l c #2E2121",
2870"g c #BF7E7E",
2871"k c #9B0808",
2872"= c #BF0505",
2873"a c #B10303",
2874"q c #7E2020",
2875"1 c #642222",
2876"J c #676767",
2877"B c #322020",
2878"; c #C00303",
2879"i c #242424",
2880"o c #C00000",
2881"> c #BF1F1F",
2882", c #842B2B",
2883"f c #701212",
2884"0 c #BE0000",
2885"r c #960909",
2886"H c #686868",
2887"v c #BC0000",
2888"Z c #671414",
2889"+ c #C02020",
2890"z c #CD3535",
2891/* pixels */
2892" ",
2893" ",
2894" .XoooOO ",
2895" .+ooooooooo@# ",
2896" $oooooooooooo%& ",
2897" *=-ooooooooooooo;: ",
2898" *oooooooooooooooooo> ",
2899" =ooooooooooooooooooo, ",
2900" $-ooooooooooooooooooo<1 ",
2901" .oooooo2334ooo533oooooo6 ",
2902" +ooooooo789oo2883oooooo0q ",
2903" oooooooo2w83o78eoooooooor ",
2904" toooooooooy88u884oooooooori ",
2905" Xooooooooooe888poooooooooas ",
2906" ooooooooooo4889doooooooooof ",
2907" ooooooooooo588w2oooooooooofi ",
2908" oooooooooodw8887oooooooooofi ",
2909" goooooooooh8w588jooooooookli ",
2910" tooooooooz885op8wdooooooorix ",
2911" oooooood98cood98cooooooori ",
2912" @oooooop8w2ooo5885ooooovbi ",
2913" n%ooooooooooooooooooooomiM ",
2914" &;oooooooooooooooooooNBiV ",
2915" :ooooooooooooooooooCZiA ",
2916" nSooooooooooooooooCDiF ",
2917" nG<oooooooooooooNZiiH ",
2918" 160ooooooooovmBiFH ",
2919" nqrraoookrrbiiA ",
2920" nJisKKKliiiML ",
2921" nPiiix ",
2922" ",
2923" "
2924};
63f06c22 2925
13b22a67 2926/* Copyright (c) Julian Smart */
579de297 2927static const char *info_xpm[]={
13b22a67
JS
2928/* columns rows colors chars-per-pixel */
2929"32 32 17 1",
2930"* c #A1A3FB",
2931"X c #FFFFFF",
2932"O c #191EF4",
2933"= c #777AF9",
2934": c #4D51F7",
2935" c None",
2936"- c #2328F5",
2937"+ c #4247F6",
2938"; c #C1C2FC",
2939". c #C0C0C0",
2940"& c #E0E1FE",
2941"% c #242424",
2942"> c #2D32F5",
2943"o c #CBCCFD",
2944"# c #0309F3",
2945"@ c #8C8FFA",
2946"$ c #EAEBFE",
2947/* pixels */
2948" ....... ",
2949" ...XXXXXXX... ",
2950" ..XXXXXXXXXXXXX.. ",
2951" .XXXXXXXXXXXXXXXXX. ",
2952" .XXXXXXXXoO+XXXXXXXX. ",
2953" .XXXXXXXXX@#OXXXXXXXXX. ",
2954" .XXXXXXXXXX$@oXXXXXXXXXX. ",
2955" .XXXXXXXXXXXXXXXXXXXXXXX.% ",
2956" .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
2957".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
2958".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
2959".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
2960" .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
2961" .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
2962" .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
2963" .XXXXXXXX*-##+XXXXXXXX.%%% ",
2964" .XXXXXXXXXXXXXXXXXXX.%%%% ",
2965" .XXXXXXXXXXXXXXXXX.%%%% ",
2966" ..XXXXXXXXXXXXX..%%%% ",
2967" %...XXXXXXXX..%%%%% ",
2968" %%%..XXXXXX.%%%%% ",
2969" %%%.XXXXX.%%% ",
2970" %.XXXX.%% ",
2971" .XXX.%% ",
2972" .XX.%% ",
2973" .X.%% ",
2974" ..%% ",
2975" .%% ",
2976" %% ",
2977" % ",
2978" ",
2979" "
2980};
63f06c22 2981
13b22a67 2982/* Copyright (c) Julian Smart */
579de297 2983static const char *question_xpm[]={
13b22a67
JS
2984/* columns rows colors chars-per-pixel */
2985"32 32 16 1",
2986"O c #A3A3FF",
2987"X c #FFFFFF",
2988"% c #CACAFF",
2989"- c #4141FF",
2990"= c #6060FF",
2991"* c #2B2BFF",
2992"@ c #B5B5FF",
2993" c None",
2994"# c #1616FF",
2995"+ c #8181FF",
2996"$ c #0000FF",
2997". c #C0C0C0",
2998"; c #5555FF",
2999": c #242424",
3000"o c #E7E7FF",
3001"& c #7575FF",
3002/* pixels */
3003" ....... ",
3004" ...XXXXXXX... ",
3005" ..XXXXXXXXXXXXX.. ",
3006" .XXXXXXoO++@XXXXXX. ",
3007" .XXXXXXO#$$$$#%XXXXX. ",
3008" .XXXXXX@$$#&&#$#oXXXXX. ",
3009" .XXXXXXX*$$%XX%$$=XXXXXX. ",
3010" .XXXXXXX+-;XXXX$$-XXXXXX.: ",
3011" .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
3012".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
3013".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
3014".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
3015" .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
3016" .XXXXXXXXXXX--XXXXXXXXXX.::: ",
3017" .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
3018" .XXXXXXXXX-$$XXXXXXXXX.::: ",
3019" .XXXXXXXX-$$XXXXXXXX.:::: ",
3020" .XXXXXXXO++XXXXXXX.:::: ",
3021" ..XXXXXXXXXXXXX..:::: ",
3022" :...XXXXXXXX..::::: ",
3023" :::..XXXXXX.::::: ",
3024" :::.XXXXX.::: ",
3025" :.XXXX.:: ",
3026" .XXX.:: ",
3027" .XX.:: ",
3028" .X.:: ",
3029" ..:: ",
3030" .:: ",
3031" :: ",
3032" : ",
3033" ",
3034" "
3035};
63f06c22 3036
13b22a67 3037/* Copyright (c) Julian Smart */
579de297 3038static const char *warning_xpm[]={
13b22a67
JS
3039/* columns rows colors chars-per-pixel */
3040"32 32 9 1",
3041"@ c Black",
3042"o c #A6A800",
3043"+ c #8A8C00",
3044"$ c #B8BA00",
3045" c None",
3046"O c #6E7000",
3047"X c #DCDF00",
3048". c #C00000",
3049"# c #373800",
3050/* pixels */
3051" ",
3052" ",
3053" ",
3054" . ",
3055" ... ",
3056" ... ",
3057" ..... ",
3058" ...X.. ",
3059" ..XXX.. ",
3060" ...XXX... ",
3061" ..XXXXX.. ",
3062" ..XXXXXX... ",
3063" ...XXoO+XX.. ",
3064" ..XXXO@#XXX.. ",
3065" ..XXXXO@#XXX... ",
3066" ...XXXXO@#XXXX.. ",
3067" ..XXXXXO@#XXXX... ",
3068" ...XXXXXo@OXXXXX.. ",
3069" ...XXXXXXo@OXXXXXX.. ",
3070" ..XXXXXXX$@OXXXXXX... ",
3071" ...XXXXXXXX@XXXXXXXX.. ",
3072" ...XXXXXXXXXXXXXXXXXX... ",
3073" ..XXXXXXXXXXOXXXXXXXXX.. ",
3074" ...XXXXXXXXXO@#XXXXXXXXX.. ",
3075" ..XXXXXXXXXXX#XXXXXXXXXX... ",
3076" ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3077" ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3078" .............................. ",
3079" .............................. ",
3080" ",
3081" ",
3082" "
3083};
3084
63f06c22 3085
536b70ac
VS
3086wxBitmap wxWin32ArtProvider::CreateBitmap(const wxArtID& id,
3087 const wxArtClient& WXUNUSED(client),
3088 const wxSize& WXUNUSED(size))
3089{
3090 if ( id == wxART_INFORMATION )
3091 return wxBitmap(info_xpm);
3092 if ( id == wxART_ERROR )
3093 return wxBitmap(error_xpm);
3094 if ( id == wxART_WARNING )
3095 return wxBitmap(warning_xpm);
3096 if ( id == wxART_QUESTION )
3097 return wxBitmap(question_xpm);
3098 return wxNullBitmap;
63f06c22
VS
3099}
3100
24a23c35 3101
9a6384ca
WS
3102#if wxUSE_TEXTCTRL
3103
1e6feb95
VZ
3104// ----------------------------------------------------------------------------
3105// text control geometry
3106// ----------------------------------------------------------------------------
3107
61fef19b 3108wxRect
6229b92f 3109wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
61fef19b 3110 const wxRect& rect) const
1e6feb95 3111{
6229b92f 3112 wxRect rectTotal = wxStdRenderer::GetTextTotalArea(text, rect);
1e6feb95 3113
6229b92f 3114 // this is strange but it's what Windows does
1e6feb95
VZ
3115 rectTotal.height++;
3116
3117 return rectTotal;
3118}
3119
61fef19b 3120wxRect
6229b92f 3121wxWin32Renderer::GetTextClientArea(const wxTextCtrl *text,
61fef19b
VZ
3122 const wxRect& rect,
3123 wxCoord *extraSpaceBeyond) const
1e6feb95
VZ
3124{
3125 wxRect rectText = rect;
3126
3127 // undo GetTextTotalArea()
3128 if ( rectText.height > 0 )
3129 rectText.height--;
3130
6229b92f 3131 return wxStdRenderer::GetTextClientArea(text, rect, extraSpaceBeyond);
1e6feb95
VZ
3132}
3133
9a6384ca
WS
3134#endif // wxUSE_TEXTCTRL
3135
1e6feb95
VZ
3136// ----------------------------------------------------------------------------
3137// size adjustments
3138// ----------------------------------------------------------------------------
3139
3140void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
3141{
3142#if wxUSE_SCROLLBAR
3143 if ( wxDynamicCast(window, wxScrollBar) )
3144 {
82e17295
DS
3145 /*
3146 Don't adjust the size for a scrollbar as its DoGetBestClientSize
3147 already has the correct size set. Any size changes here would get
3148 added to the best size, making the scrollbar larger.
3149 Also skip border width adjustments, they don't make sense for us.
3150 */
1e6feb95
VZ
3151 return;
3152 }
9467bdb7 3153#endif // wxUSE_SCROLLBAR
1e6feb95 3154
06aa40d9
WS
3155#if wxUSE_BMPBUTTON
3156 if ( wxDynamicCast(window, wxBitmapButton) )
3157 {
3158 // do nothing
3159 } else
3160#endif // wxUSE_BMPBUTTON
43be3c33 3161#if wxUSE_BUTTON || wxUSE_TOGGLEBTN
9eddec69 3162 if ( 0
43be3c33 3163# if wxUSE_BUTTON
9eddec69 3164 || wxDynamicCast(window, wxButton)
43be3c33
JS
3165# endif // wxUSE_BUTTON
3166# if wxUSE_TOGGLEBTN
9eddec69 3167 || wxDynamicCast(window, wxToggleButton)
43be3c33
JS
3168# endif // wxUSE_TOGGLEBTN
3169 )
1e6feb95 3170 {
1b465102
VZ
3171 if ( !(window->GetWindowStyle() & wxBU_EXACTFIT) )
3172 {
3173 // TODO: don't harcode all this
3174 size->x += 3*window->GetCharWidth();
3175
3176 wxCoord heightBtn = (11*(window->GetCharHeight() + 8))/10;
3177 if ( size->y < heightBtn - 8 )
3178 size->y = heightBtn;
3179 else
3180 size->y += 9;
3181 }
1e6feb95 3182
6766e5d1
JS
3183 // for compatibility with other ports, the buttons default size is never
3184 // less than the standard one, but not when display not PDAs.
3185 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA)
3186 {
a290fa5a 3187 if ( !(window->GetWindowStyle() & wxBU_EXACTFIT) )
6766e5d1 3188 {
a290fa5a 3189 wxSize szDef = wxButton::GetDefaultSize();
6766e5d1
JS
3190 if ( size->x < szDef.x )
3191 size->x = szDef.x;
3192 }
3193 }
3194
1e6feb95
VZ
3195 // no border width adjustments for buttons
3196 return;
3197 }
43be3c33 3198#endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
1e6feb95 3199
1cd9779f 3200 wxStdRenderer::AdjustSize(size, window);
1e6feb95
VZ
3201}
3202
249803fb
VZ
3203wxBitmap wxWin32Renderer::GetFrameButtonBitmap(FrameButtonType type)
3204{
3205 wxBitmap& bmp = m_bmpFrameButtons[type];
a1b806b9 3206 if ( !bmp.IsOk() )
249803fb
VZ
3207 {
3208 bmp = wxBitmap(ms_xpmFrameButtons[type]);
3209 }
3210
3211 return bmp;
3212}
3213
1e6feb95
VZ
3214// ============================================================================
3215// wxInputHandler
3216// ============================================================================
3217
3218// ----------------------------------------------------------------------------
3219// wxWin32InputHandler
3220// ----------------------------------------------------------------------------
3221
61fef19b
VZ
3222bool wxWin32InputHandler::HandleKey(wxInputConsumer * WXUNUSED(control),
3223 const wxKeyEvent& WXUNUSED(event),
3224 bool WXUNUSED(pressed))
1e6feb95 3225{
a290fa5a 3226 return false;
1e6feb95
VZ
3227}
3228
67e49a98 3229bool wxWin32InputHandler::HandleMouse(wxInputConsumer *control,
1e6feb95
VZ
3230 const wxMouseEvent& event)
3231{
211cc8dc 3232 // clicking on the control gives it focus
71e03035 3233 if ( event.ButtonDown() )
211cc8dc 3234 {
ad02525d 3235 wxWindow * const win = control->GetInputWindow();
d1504049 3236
ad02525d 3237 if ( win->CanAcceptFocus() && wxWindow::FindFocus() != win )
71e03035
VZ
3238 {
3239 win->SetFocus();
211cc8dc 3240
a290fa5a 3241 return true;
71e03035 3242 }
211cc8dc
VS
3243 }
3244
a290fa5a 3245 return false;
1e6feb95
VZ
3246}
3247
9a6384ca
WS
3248#if wxUSE_SCROLLBAR
3249
1e6feb95
VZ
3250// ----------------------------------------------------------------------------
3251// wxWin32ScrollBarInputHandler
3252// ----------------------------------------------------------------------------
3253
3254wxWin32ScrollBarInputHandler::
9467bdb7 3255wxWin32ScrollBarInputHandler(wxRenderer *renderer, wxInputHandler *handler)
1e6feb95
VZ
3256 : wxStdScrollBarInputHandler(renderer, handler)
3257{
a290fa5a 3258 m_scrollPaused = false;
1e6feb95
VZ
3259 m_interval = 0;
3260}
3261
3262bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar *scrollbar,
3263 const wxControlAction& action)
3264{
3265 // stop if went beyond the position of the original click (this can only
3266 // happen when we scroll by pages)
a290fa5a 3267 bool stop = false;
1e6feb95
VZ
3268 if ( action == wxACTION_SCROLL_PAGE_DOWN )
3269 {
56195504 3270 stop = scrollbar->HitTestBar(m_ptStartScrolling) != wxHT_SCROLLBAR_BAR_2;
1e6feb95
VZ
3271 }
3272 else if ( action == wxACTION_SCROLL_PAGE_UP )
3273 {
56195504 3274 stop = scrollbar->HitTestBar(m_ptStartScrolling) != wxHT_SCROLLBAR_BAR_1;
1e6feb95
VZ
3275 }
3276
3277 if ( stop )
3278 {
3279 StopScrolling(scrollbar);
3280
3281 scrollbar->Refresh();
3282
a290fa5a 3283 return false;
1e6feb95
VZ
3284 }
3285
3286 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar, action);
3287}
3288
67e49a98 3289bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer *control,
1e6feb95
VZ
3290 const wxMouseEvent& event)
3291{
3292 // remember the current state
3293 bool wasDraggingThumb = m_htLast == wxHT_SCROLLBAR_THUMB;
3294
3295 // do process the message
3296 bool rc = wxStdScrollBarInputHandler::HandleMouse(control, event);
3297
3298 // analyse the changes
3299 if ( !wasDraggingThumb && (m_htLast == wxHT_SCROLLBAR_THUMB) )
3300 {
3301 // we just started dragging the thumb, remember its initial position to
3302 // be able to restore it if the drag is cancelled later
affe4044 3303 m_eventStartDrag = event;
1e6feb95
VZ
3304 }
3305
3306 return rc;
3307}
3308
67e49a98 3309bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer *control,
1e6feb95
VZ
3310 const wxMouseEvent& event)
3311{
3312 // we don't highlight scrollbar elements, so there is no need to process
3313 // mouse move events normally - only do it while mouse is captured (i.e.
3314 // when we're dragging the thumb or pressing on something)
3315 if ( !m_winCapture )
a290fa5a 3316 return false;
1e6feb95
VZ
3317
3318 if ( event.Entering() )
3319 {
3320 // we're not interested in this at all
a290fa5a 3321 return false;
1e6feb95
VZ
3322 }
3323
67e49a98 3324 wxScrollBar *scrollbar = wxStaticCast(control->GetInputWindow(), wxScrollBar);
1e6feb95
VZ
3325 wxHitTest ht;
3326 if ( m_scrollPaused )
3327 {
3328 // check if the mouse returned to its original location
3329
3330 if ( event.Leaving() )
3331 {
3332 // it surely didn't
a290fa5a 3333 return false;
1e6feb95
VZ
3334 }
3335
56195504 3336 ht = scrollbar->HitTestBar(event.GetPosition());
1e6feb95
VZ
3337 if ( ht == m_htLast )
3338 {
3339 // yes it did, resume scrolling
a290fa5a 3340 m_scrollPaused = false;
1e6feb95
VZ
3341 if ( m_timerScroll )
3342 {
3343 // we were scrolling by line/page, restart timer
3344 m_timerScroll->Start(m_interval);
3345
a290fa5a 3346 Press(scrollbar, true);
1e6feb95
VZ
3347 }
3348 else // we were dragging the thumb
3349 {
3350 // restore its last location
3351 HandleThumbMove(scrollbar, m_eventLastDrag);
3352 }
3353
a290fa5a 3354 return true;
1e6feb95
VZ
3355 }
3356 }
3357 else // normal case, scrolling hasn't been paused
3358 {
3359 // if we're scrolling the scrollbar because the arrow or the shaft was
3360 // pressed, check that the mouse stays on the same scrollbar element
3361
a17a79ba
RR
3362#if 0
3363 // Always let thumb jump back if we leave the scrollbar
1e6feb95
VZ
3364 if ( event.Moving() )
3365 {
56195504 3366 ht = scrollbar->HitTestBar(event.GetPosition());
1e6feb95
VZ
3367 }
3368 else // event.Leaving()
3369 {
3370 ht = wxHT_NOWHERE;
3371 }
a17a79ba
RR
3372#else
3373 // Jump back only if we get far away from it
3374 wxPoint pos = event.GetPosition();
3375 if (scrollbar->HasFlag( wxVERTICAL ))
3376 {
4175e952 3377 if (pos.x > -40 && pos.x < scrollbar->GetSize().x+40)
a17a79ba
RR
3378 pos.x = 5;
3379 }
3380 else
3381 {
4175e952 3382 if (pos.y > -40 && pos.y < scrollbar->GetSize().y+40)
a17a79ba
RR
3383 pos.y = 5;
3384 }
56195504 3385 ht = scrollbar->HitTestBar(pos);
a17a79ba 3386#endif
1e6feb95
VZ
3387
3388 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3389 // is still ok - we only want to catch the case when the mouse leaves
3390 // the scrollbar here
3391 if ( m_htLast == wxHT_SCROLLBAR_THUMB && ht != wxHT_NOWHERE )
3392 {
3393 ht = wxHT_SCROLLBAR_THUMB;
3394 }
3395
3396 if ( ht != m_htLast )
3397 {
3398 // what were we doing? 2 possibilities: either an arrow/shaft was
3399 // pressed in which case we have a timer and so we just stop it or
3400 // we were dragging the thumb
3401 if ( m_timerScroll )
3402 {
3403 // pause scrolling
3404 m_interval = m_timerScroll->GetInterval();
3405 m_timerScroll->Stop();
a290fa5a 3406 m_scrollPaused = true;
1e6feb95
VZ
3407
3408 // unpress the arrow
a290fa5a 3409 Press(scrollbar, false);
1e6feb95
VZ
3410 }
3411 else // we were dragging the thumb
3412 {
3413 // remember the current thumb position to be able to restore it
3414 // if the mouse returns to it later
affe4044 3415 m_eventLastDrag = event;
1e6feb95
VZ
3416
3417 // and restore the original position (before dragging) of the
3418 // thumb for now
3419 HandleThumbMove(scrollbar, m_eventStartDrag);
3420 }
3421
a290fa5a 3422 return true;
1e6feb95
VZ
3423 }
3424 }
3425
9467bdb7 3426 return wxStdInputHandler::HandleMouseMove(control, event);
1e6feb95
VZ
3427}
3428
9a6384ca
WS
3429#endif // wxUSE_SCROLLBAR
3430
3431#if wxUSE_CHECKBOX
3432
1e6feb95
VZ
3433// ----------------------------------------------------------------------------
3434// wxWin32CheckboxInputHandler
3435// ----------------------------------------------------------------------------
3436
67e49a98 3437bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer *control,
1e6feb95
VZ
3438 const wxKeyEvent& event,
3439 bool pressed)
3440{
3441 if ( pressed )
3442 {
3443 wxControlAction action;
3444 int keycode = event.GetKeyCode();
3445 switch ( keycode )
3446 {
3447 case WXK_SPACE:
3448 action = wxACTION_CHECKBOX_TOGGLE;
3449 break;
3450
3451 case WXK_SUBTRACT:
3452 case WXK_NUMPAD_SUBTRACT:
3453 action = wxACTION_CHECKBOX_CHECK;
3454 break;
3455
3456 case WXK_ADD:
3457 case WXK_NUMPAD_ADD:
3458 case WXK_NUMPAD_EQUAL:
3459 action = wxACTION_CHECKBOX_CLEAR;
3460 break;
3461 }
3462
a290fa5a 3463 if ( !action.IsEmpty() )
1e6feb95
VZ
3464 {
3465 control->PerformAction(action);
3466
a290fa5a 3467 return true;
1e6feb95
VZ
3468 }
3469 }
3470
a290fa5a 3471 return false;
1e6feb95
VZ
3472}
3473
9a6384ca
WS
3474#endif // wxUSE_CHECKBOX
3475
3476#if wxUSE_TEXTCTRL
3477
1e6feb95
VZ
3478// ----------------------------------------------------------------------------
3479// wxWin32TextCtrlInputHandler
3480// ----------------------------------------------------------------------------
3481
67e49a98 3482bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer *control,
1e6feb95
VZ
3483 const wxKeyEvent& event,
3484 bool pressed)
3485{
3486 // handle only MSW-specific text bindings here, the others are handled in
3487 // the base class
3488 if ( pressed )
3489 {
3490 int keycode = event.GetKeyCode();
3491
3492 wxControlAction action;
3493 if ( keycode == WXK_DELETE && event.ShiftDown() )
3494 {
3495 action = wxACTION_TEXT_CUT;
3496 }
3497 else if ( keycode == WXK_INSERT )
3498 {
3499 if ( event.ControlDown() )
3500 action = wxACTION_TEXT_COPY;
3501 else if ( event.ShiftDown() )
3502 action = wxACTION_TEXT_PASTE;
3503 }
3504
3505 if ( action != wxACTION_NONE )
3506 {
3507 control->PerformAction(action);
3508
a290fa5a 3509 return true;
1e6feb95
VZ
3510 }
3511 }
3512
9467bdb7 3513 return wxStdInputHandler::HandleKey(control, event, pressed);
1e6feb95
VZ
3514}
3515
9a6384ca
WS
3516#endif // wxUSE_TEXTCTRL
3517
3518#if wxUSE_STATUSBAR
3519
71e03035
VZ
3520// ----------------------------------------------------------------------------
3521// wxWin32StatusBarInputHandler
3522// ----------------------------------------------------------------------------
3523
3524wxWin32StatusBarInputHandler::
3525wxWin32StatusBarInputHandler(wxInputHandler *handler)
3526 : wxStdInputHandler(handler)
3527{
a290fa5a 3528 m_isOnGrip = false;
71e03035
VZ
3529}
3530
3531bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow *statbar,
3532 const wxPoint& pt) const
3533{
3534 if ( statbar->HasFlag(wxST_SIZEGRIP) &&
d1504049 3535 statbar->GetParent()->HasFlag(wxRESIZE_BORDER) )
71e03035 3536 {
d1504049
VZ
3537 wxTopLevelWindow *
3538 parentTLW = wxDynamicCast(statbar->GetParent(), wxTopLevelWindow);
71e03035 3539
a290fa5a 3540 wxCHECK_MSG( parentTLW, false,
9a83f860 3541 wxT("the status bar should be a child of a TLW") );
d1504049
VZ
3542
3543 // a maximized window can't be resized anyhow
3544 if ( !parentTLW->IsMaximized() )
3545 {
3546 // VZ: I think that the standard Windows behaviour is to only
3547 // show the resizing cursor when the mouse is on top of the
3548 // grip itself but apparently different Windows versions behave
3549 // differently (?) and it seems a better UI to allow resizing
3550 // the status bar even when the mouse is above the grip
3551 wxSize sizeSbar = statbar->GetSize();
3552
3553 int diff = sizeSbar.x - pt.x;
3554 return diff >= 0 && diff < (wxCoord)STATUSBAR_GRIP_SIZE;
3555 }
71e03035
VZ
3556 }
3557
a290fa5a 3558 return false;
71e03035
VZ
3559}
3560
3561bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer *consumer,
3562 const wxMouseEvent& event)
3563{
3564 if ( event.Button(1) )
3565 {
3566 if ( event.ButtonDown(1) )
3567 {
3568 wxWindow *statbar = consumer->GetInputWindow();
3569
3570 if ( IsOnGrip(statbar, event.GetPosition()) )
3571 {
3572 wxTopLevelWindow *tlw = wxDynamicCast(statbar->GetParent(),
3573 wxTopLevelWindow);
3574 if ( tlw )
3575 {
3576 tlw->PerformAction(wxACTION_TOPLEVEL_RESIZE,
3577 wxHT_TOPLEVEL_BORDER_SE);
3578
3579 statbar->SetCursor(m_cursorOld);
3580
a290fa5a 3581 return true;
71e03035
VZ
3582 }
3583 }
3584 }
3585 }
3586
3587 return wxStdInputHandler::HandleMouse(consumer, event);
3588}
3589
3590bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
3591 const wxMouseEvent& event)
3592{
3593 wxWindow *statbar = consumer->GetInputWindow();
3594
3595 bool isOnGrip = IsOnGrip(statbar, event.GetPosition());
3596 if ( isOnGrip != m_isOnGrip )
3597 {
3598 m_isOnGrip = isOnGrip;
3599 if ( isOnGrip )
3600 {
3601 m_cursorOld = statbar->GetCursor();
3602 statbar->SetCursor(wxCURSOR_SIZENWSE);
3603 }
3604 else
3605 {
3606 statbar->SetCursor(m_cursorOld);
3607 }
3608 }
3609
3610 return wxStdInputHandler::HandleMouseMove(consumer, event);
3611}
3612
9a6384ca
WS
3613#endif // wxUSE_STATUSBAR
3614
768f0c5a
VS
3615// ----------------------------------------------------------------------------
3616// wxWin32FrameInputHandler
3617// ----------------------------------------------------------------------------
3618
8f71aafa
VS
3619class wxWin32SystemMenuEvtHandler : public wxEvtHandler
3620{
3621public:
2279b45a 3622 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler);
00e086a7 3623
2279b45a
VS
3624 void Attach(wxInputConsumer *consumer);
3625 void Detach();
00e086a7 3626
8f71aafa
VS
3627private:
3628 DECLARE_EVENT_TABLE()
3629 void OnSystemMenu(wxCommandEvent &event);
3630 void OnCloseFrame(wxCommandEvent &event);
3631 void OnClose(wxCloseEvent &event);
00e086a7 3632
8f71aafa
VS
3633 wxWin32FrameInputHandler *m_inputHnd;
3634 wxTopLevelWindow *m_wnd;
0b4f47a3 3635#if wxUSE_ACCEL
8f71aafa 3636 wxAcceleratorTable m_oldAccelTable;
0b4f47a3 3637#endif
8f71aafa
VS
3638};
3639
9467bdb7
VZ
3640wxWin32SystemMenuEvtHandler::
3641wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler)
8f71aafa
VS
3642{
3643 m_inputHnd = handler;
2279b45a
VS
3644 m_wnd = NULL;
3645}
3646
3647void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer *consumer)
3648{
9a83f860 3649 wxASSERT_MSG( m_wnd == NULL, wxT("can't attach the handler twice!") );
2279b45a 3650
8f71aafa
VS
3651 m_wnd = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
3652 m_wnd->PushEventHandler(this);
00e086a7 3653
0b4f47a3 3654#if wxUSE_ACCEL
00e086a7 3655 // VS: This code relies on using generic implementation of
8f71aafa
VS
3656 // wxAcceleratorTable in wxUniv!
3657 wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
3658 m_oldAccelTable = table;
3659 table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_SPACE, wxID_SYSTEM_MENU));
3660 table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_F4, wxID_CLOSE_FRAME));
3661 m_wnd->SetAcceleratorTable(table);
0b4f47a3 3662#endif
8f71aafa
VS
3663}
3664
2279b45a 3665void wxWin32SystemMenuEvtHandler::Detach()
8f71aafa
VS
3666{
3667 if ( m_wnd )
3668 {
0b4f47a3 3669#if wxUSE_ACCEL
8f71aafa 3670 m_wnd->SetAcceleratorTable(m_oldAccelTable);
0b4f47a3 3671#endif
00e086a7 3672 m_wnd->RemoveEventHandler(this);
2279b45a 3673 m_wnd = NULL;
8f71aafa
VS
3674 }
3675}
3676
3677BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler, wxEvtHandler)
3678 EVT_MENU(wxID_SYSTEM_MENU, wxWin32SystemMenuEvtHandler::OnSystemMenu)
3679 EVT_MENU(wxID_CLOSE_FRAME, wxWin32SystemMenuEvtHandler::OnCloseFrame)
3680 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose)
3681END_EVENT_TABLE()
3682
3683void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent &WXUNUSED(event))
3684{
0b4f47a3 3685#if wxUSE_ACCEL
8f71aafa
VS
3686 wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
3687 m_wnd->SetAcceleratorTable(wxNullAcceleratorTable);
0b4f47a3
DS
3688#endif
3689
9a6384ca 3690#if wxUSE_MENUS
249803fb 3691 m_inputHnd->PopupSystemMenu(m_wnd);
9a6384ca 3692#endif // wxUSE_MENUS
0b4f47a3
DS
3693
3694#if wxUSE_ACCEL
8f71aafa 3695 m_wnd->SetAcceleratorTable(table);
0b4f47a3 3696#endif
8f71aafa
VS
3697}
3698
3699void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent &WXUNUSED(event))
3700{
3701 m_wnd->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
3702 wxTOPLEVEL_BUTTON_CLOSE);
3703}
3704
3705void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent &event)
3706{
3707 m_wnd = NULL;
3708 event.Skip();
3709}
3710
3711
2279b45a 3712wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler *handler)
9467bdb7 3713 : wxStdInputHandler(handler)
8f71aafa 3714{
2279b45a
VS
3715 m_menuHandler = new wxWin32SystemMenuEvtHandler(this);
3716}
3717
3718wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
3719{
3720 if ( m_menuHandler )
8f71aafa 3721 {
2279b45a
VS
3722 m_menuHandler->Detach();
3723 delete m_menuHandler;
3724 }
3725}
3726
3727bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer,
3728 const wxMouseEvent& event)
3729{
3730 if ( event.LeftDClick() || event.LeftDown() || event.RightDown() )
3731 {
3732 wxTopLevelWindow *tlw =
3733 wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
3734
3735 long hit = tlw->HitTest(event.GetPosition());
3736
3737 if ( event.LeftDClick() && hit == wxHT_TOPLEVEL_TITLEBAR )
8f71aafa 3738 {
2279b45a
VS
3739 tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
3740 tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
3741 : wxTOPLEVEL_BUTTON_MAXIMIZE);
a290fa5a 3742 return true;
8f71aafa 3743 }
2279b45a 3744 else if ( tlw->GetWindowStyle() & wxSYSTEM_MENU )
8f71aafa 3745 {
2279b45a 3746 if ( (event.LeftDown() && hit == wxHT_TOPLEVEL_ICON) ||
00e086a7
WS
3747 (event.RightDown() &&
3748 (hit == wxHT_TOPLEVEL_TITLEBAR ||
2279b45a 3749 hit == wxHT_TOPLEVEL_ICON)) )
8f71aafa 3750 {
9a6384ca 3751#if wxUSE_MENUS
249803fb 3752 PopupSystemMenu(tlw);
9a6384ca 3753#endif // wxUSE_MENUS
a290fa5a 3754 return true;
8f71aafa 3755 }
2279b45a
VS
3756 }
3757 }
3758
9467bdb7 3759 return wxStdInputHandler::HandleMouse(consumer, event);
2279b45a 3760}
8f71aafa 3761
9a6384ca
WS
3762#if wxUSE_MENUS
3763
249803fb 3764void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow *window) const
2279b45a 3765{
249803fb 3766 wxMenu menu;
2279b45a
VS
3767
3768 if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
249803fb
VZ
3769 menu.Append(wxID_RESTORE_FRAME , _("&Restore"));
3770 menu.Append(wxID_MOVE_FRAME , _("&Move"));
2279b45a 3771 if ( window->GetWindowStyle() & wxRESIZE_BORDER )
249803fb 3772 menu.Append(wxID_RESIZE_FRAME , _("&Size"));
2279b45a 3773 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME) )
249803fb 3774 menu.Append(wxID_ICONIZE_FRAME , _("Mi&nimize"));
2279b45a 3775 if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
249803fb
VZ
3776 menu.Append(wxID_MAXIMIZE_FRAME , _("Ma&ximize"));
3777 menu.AppendSeparator();
b82f92a8 3778 menu.Append(wxID_CLOSE_FRAME, _("&Close") + _T("\t") + _("Alt+") + _T("F4"));
00e086a7 3779
2279b45a
VS
3780 if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
3781 {
3782 if ( window->IsMaximized() )
3783 {
249803fb
VZ
3784 menu.Enable(wxID_MAXIMIZE_FRAME, false);
3785 menu.Enable(wxID_MOVE_FRAME, false);
2279b45a 3786 if ( window->GetWindowStyle() & wxRESIZE_BORDER )
249803fb 3787 menu.Enable(wxID_RESIZE_FRAME, false);
2279b45a
VS
3788 }
3789 else
249803fb 3790 menu.Enable(wxID_RESTORE_FRAME, false);
2279b45a
VS
3791 }
3792
249803fb 3793 window->PopupMenu(&menu, wxPoint(0, 0));
2279b45a
VS
3794}
3795
9a6384ca
WS
3796#endif // wxUSE_MENUS
3797
00e086a7 3798bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer,
2279b45a
VS
3799 bool activated)
3800{
3801 if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU )
3802 {
3803 // always detach if active frame changed:
3804 m_menuHandler->Detach();
3805
3806 if ( activated )
3807 {
3808 m_menuHandler->Attach(consumer);
8f71aafa
VS
3809 }
3810 }
3811
9467bdb7 3812 return wxStdInputHandler::HandleActivation(consumer, activated);
8f71aafa 3813}
4353a8df 3814
e7637222 3815#endif // wxUSE_THEME_WIN32