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