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