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