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