1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/themes/win32.cpp
3 // Purpose: wxUniversal theme implementing Win32-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
31 #include "wx/window.h"
33 #include "wx/dcmemory.h"
35 #include "wx/button.h"
36 #include "wx/bmpbuttn.h"
37 #include "wx/listbox.h"
38 #include "wx/checklst.h"
39 #include "wx/combobox.h"
40 #include "wx/scrolbar.h"
41 #include "wx/slider.h"
42 #include "wx/textctrl.h"
43 #include "wx/toolbar.h"
44 #include "wx/statusbr.h"
47 // for COLOR_* constants
48 #include "wx/msw/private.h"
51 #include "wx/settings.h"
52 #include "wx/toplevel.h"
56 #include "wx/notebook.h"
57 #include "wx/spinbutt.h"
58 #include "wx/artprov.h"
59 #ifdef wxUSE_TOGGLEBTN
60 #include "wx/tglbtn.h"
61 #endif // wxUSE_TOGGLEBTN
63 #include "wx/univ/scrtimer.h"
64 #include "wx/univ/renderer.h"
65 #include "wx/univ/inpcons.h"
66 #include "wx/univ/inphand.h"
67 #include "wx/univ/colschem.h"
68 #include "wx/univ/theme.h"
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 static const int BORDER_THICKNESS
= 2;
76 // the offset between the label and focus rect around it
77 static const int FOCUS_RECT_OFFSET_X
= 1;
78 static const int FOCUS_RECT_OFFSET_Y
= 1;
80 static const int FRAME_BORDER_THICKNESS
= 3;
81 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
82 static const int FRAME_TITLEBAR_HEIGHT
= 18;
83 static const int FRAME_BUTTON_WIDTH
= 16;
84 static const int FRAME_BUTTON_HEIGHT
= 14;
86 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
87 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
88 static const size_t STATUSBAR_GRIP_SIZE
=
89 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
91 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
92 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
93 static const wxCoord SLIDER_TICK_LENGTH
= 6;
105 IndicatorState_Normal
,
106 IndicatorState_Pressed
, // this one is for check/radioboxes
107 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
108 IndicatorState_Disabled
,
109 IndicatorState_SelectedDisabled
, // only for the menus
115 IndicatorStatus_Checked
,
116 IndicatorStatus_Unchecked
,
117 IndicatorStatus_Undeterminated
,
121 // wxWin32Renderer: draw the GUI elements in Win32 style
122 // ----------------------------------------------------------------------------
124 class wxWin32Renderer
: public wxRenderer
128 enum wxArrowDirection
143 Arrow_InvertedDisabled
,
147 enum wxFrameButtonType
150 FrameButton_Minimize
,
151 FrameButton_Maximize
,
158 wxWin32Renderer(const wxColourScheme
*scheme
);
160 // implement the base class pure virtuals
161 virtual void DrawBackground(wxDC
& dc
,
165 wxWindow
*window
= NULL
);
166 virtual void DrawLabel(wxDC
& dc
,
167 const wxString
& label
,
170 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
172 wxRect
*rectBounds
= NULL
);
173 virtual void DrawButtonLabel(wxDC
& dc
,
174 const wxString
& label
,
175 const wxBitmap
& image
,
178 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
180 wxRect
*rectBounds
= NULL
);
181 virtual void DrawBorder(wxDC
& dc
,
185 wxRect
*rectIn
= (wxRect
*)NULL
);
186 virtual void DrawHorizontalLine(wxDC
& dc
,
187 wxCoord y
, wxCoord x1
, wxCoord x2
);
188 virtual void DrawVerticalLine(wxDC
& dc
,
189 wxCoord x
, wxCoord y1
, wxCoord y2
);
190 virtual void DrawFrame(wxDC
& dc
,
191 const wxString
& label
,
194 int alignment
= wxALIGN_LEFT
,
195 int indexAccel
= -1);
196 virtual void DrawTextBorder(wxDC
& dc
,
200 wxRect
*rectIn
= (wxRect
*)NULL
);
201 virtual void DrawButtonBorder(wxDC
& dc
,
204 wxRect
*rectIn
= (wxRect
*)NULL
);
205 virtual void DrawArrow(wxDC
& dc
,
209 virtual void DrawScrollbarArrow(wxDC
& dc
,
213 { DrawArrow(dc
, dir
, rect
, flags
); }
214 virtual void DrawScrollbarThumb(wxDC
& dc
,
215 wxOrientation orient
,
218 virtual void DrawScrollbarShaft(wxDC
& dc
,
219 wxOrientation orient
,
222 virtual void DrawScrollCorner(wxDC
& dc
,
224 virtual void DrawItem(wxDC
& dc
,
225 const wxString
& label
,
228 virtual void DrawCheckItem(wxDC
& dc
,
229 const wxString
& label
,
230 const wxBitmap
& bitmap
,
233 virtual void DrawCheckButton(wxDC
& dc
,
234 const wxString
& label
,
235 const wxBitmap
& bitmap
,
238 wxAlignment align
= wxALIGN_LEFT
,
239 int indexAccel
= -1);
240 virtual void DrawRadioButton(wxDC
& dc
,
241 const wxString
& label
,
242 const wxBitmap
& bitmap
,
245 wxAlignment align
= wxALIGN_LEFT
,
246 int indexAccel
= -1);
248 virtual void DrawToolBarButton(wxDC
& dc
,
249 const wxString
& label
,
250 const wxBitmap
& bitmap
,
255 #endif // wxUSE_TOOLBAR
256 virtual void DrawTextLine(wxDC
& dc
,
257 const wxString
& text
,
262 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
263 virtual void DrawTab(wxDC
& dc
,
266 const wxString
& label
,
267 const wxBitmap
& bitmap
= wxNullBitmap
,
269 int indexAccel
= -1);
272 virtual void DrawSliderShaft(wxDC
& dc
,
275 wxOrientation orient
,
278 wxRect
*rectShaft
= NULL
);
279 virtual void DrawSliderThumb(wxDC
& dc
,
281 wxOrientation orient
,
284 virtual void DrawSliderTicks(wxDC
& dc
,
287 wxOrientation orient
,
293 #endif // wxUSE_SLIDER
296 virtual void DrawMenuBarItem(wxDC
& dc
,
298 const wxString
& label
,
300 int indexAccel
= -1);
301 virtual void DrawMenuItem(wxDC
& dc
,
303 const wxMenuGeometryInfo
& geometryInfo
,
304 const wxString
& label
,
305 const wxString
& accel
,
306 const wxBitmap
& bitmap
= wxNullBitmap
,
308 int indexAccel
= -1);
309 virtual void DrawMenuSeparator(wxDC
& dc
,
311 const wxMenuGeometryInfo
& geomInfo
);
312 #endif // wxUSE_MENUS
315 virtual void DrawStatusField(wxDC
& dc
,
317 const wxString
& label
,
318 int flags
= 0, int style
= 0);
319 #endif // wxUSE_STATUSBAR
322 virtual void DrawFrameTitleBar(wxDC
& dc
,
324 const wxString
& title
,
327 int specialButton
= 0,
328 int specialButtonFlags
= 0);
329 virtual void DrawFrameBorder(wxDC
& dc
,
332 virtual void DrawFrameBackground(wxDC
& dc
,
335 virtual void DrawFrameTitle(wxDC
& dc
,
337 const wxString
& title
,
339 virtual void DrawFrameIcon(wxDC
& dc
,
343 virtual void DrawFrameButton(wxDC
& dc
,
344 wxCoord x
, wxCoord y
,
347 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
348 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
349 virtual wxSize
GetFrameMinSize(int flags
) const;
350 virtual wxSize
GetFrameIconSize() const;
351 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
353 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
355 wxBitmap
*bmpPressed
,
356 wxBitmap
*bmpDisabled
);
358 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
359 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
360 virtual bool AreScrollbarsInsideBorder() const;
362 virtual wxSize
GetScrollbarArrowSize() const
363 { return m_sizeScrollbarArrow
; }
366 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
367 wxScrollBar::Element elem
,
368 int thumbPos
= -1) const;
369 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
370 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
371 const wxPoint
& pt
) const;
372 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
374 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
375 #endif // wxUSE_SCROLLBAR
377 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
378 { return fontHeight
+ 2; }
379 virtual wxSize
GetCheckBitmapSize() const
380 { return wxSize(13, 13); }
381 virtual wxSize
GetRadioBitmapSize() const
382 { return wxSize(12, 12); }
383 virtual wxCoord
GetCheckItemMargin() const
386 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
387 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
388 virtual wxSize
GetToolBarMargin() const
389 { return wxSize(4, 4); }
392 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
393 const wxRect
& rect
) const;
394 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
396 wxCoord
*extraSpaceBeyond
) const;
397 #endif // wxUSE_TEXTCTRL
399 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
400 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
404 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
405 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
406 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
408 wxOrientation orient
,
409 long style
= 0) const;
410 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
412 wxOrientation orient
) const;
413 #endif // wxUSE_SLIDER
415 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
418 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
419 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
420 const wxMenu
& menu
) const;
421 #endif // wxUSE_MENUS
424 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
425 #endif // wxUSE_STATUSBAR
428 // helper of DrawLabel() and DrawCheckOrRadioButton()
429 void DoDrawLabel(wxDC
& dc
,
430 const wxString
& label
,
433 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
435 wxRect
*rectBounds
= NULL
,
436 const wxPoint
& focusOffset
437 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
439 // common part of DrawLabel() and DrawItem()
440 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
442 // DrawLabel() and DrawButtonLabel() helper
443 void DrawLabelShadow(wxDC
& dc
,
444 const wxString
& label
,
449 // DrawButtonBorder() helper
450 void DoDrawBackground(wxDC
& dc
,
453 wxWindow
*window
= NULL
);
455 // DrawBorder() helpers: all of them shift and clip the DC after drawing
458 // just draw a rectangle with the given pen
459 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
461 // draw the lower left part of rectangle
462 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
464 // draw the rectange using the first brush for the left and top sides and
465 // the second one for the bottom and right ones
466 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
467 const wxPen
& pen1
, const wxPen
& pen2
);
469 // draw the normal 3D border
470 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
472 // draw the sunken 3D border
473 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
475 // draw the border used for scrollbar arrows
476 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
478 // public DrawArrow()s helper
479 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
480 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
482 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
483 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
484 wxArrowDirection arrowDir
,
485 wxArrowStyle arrowStyle
);
487 // DrawCheckButton/DrawRadioButton helper
488 void DrawCheckOrRadioButton(wxDC
& dc
,
489 const wxString
& label
,
490 const wxBitmap
& bitmap
,
495 wxCoord focusOffsetY
);
497 // draw a normal or transposed line (useful for using the same code fo both
498 // horizontal and vertical widgets)
499 void DrawLine(wxDC
& dc
,
500 wxCoord x1
, wxCoord y1
,
501 wxCoord x2
, wxCoord y2
,
502 bool transpose
= false)
505 dc
.DrawLine(y1
, x1
, y2
, x2
);
507 dc
.DrawLine(x1
, y1
, x2
, y2
);
510 // get the standard check/radio button bitmap
511 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
512 wxBitmap
GetCheckBitmap(int flags
)
513 { return GetIndicator(IndicatorType_Check
, flags
); }
514 wxBitmap
GetRadioBitmap(int flags
)
515 { return GetIndicator(IndicatorType_Radio
, flags
); }
518 const wxColourScheme
*m_scheme
;
520 // the sizing parameters (TODO make them changeable)
521 wxSize m_sizeScrollbarArrow
;
523 // GDI objects we use for drawing
524 wxColour m_colDarkGrey
,
532 wxFont m_titlebarFont
;
534 // the checked and unchecked bitmaps for DrawCheckItem()
535 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
537 // the bitmaps returned by GetIndicator()
538 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
540 [IndicatorStatus_Max
];
543 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
545 // first row is for the normal state, second - for the disabled
546 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
549 // ----------------------------------------------------------------------------
550 // wxWin32InputHandler and derived classes: process the keyboard and mouse
551 // messages according to Windows standards
552 // ----------------------------------------------------------------------------
554 class wxWin32InputHandler
: public wxInputHandler
557 wxWin32InputHandler() { }
559 virtual bool HandleKey(wxInputConsumer
*control
,
560 const wxKeyEvent
& event
,
562 virtual bool HandleMouse(wxInputConsumer
*control
,
563 const wxMouseEvent
& event
);
567 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
570 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
,
571 wxInputHandler
*handler
);
573 virtual bool HandleMouse(wxInputConsumer
*control
,
574 const wxMouseEvent
& event
);
575 virtual bool HandleMouseMove(wxInputConsumer
*control
,
576 const wxMouseEvent
& event
);
578 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
579 const wxControlAction
& action
);
582 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
585 // we don't highlight anything
588 // the first and last event which caused the thumb to move
589 wxMouseEvent m_eventStartDrag
,
592 // have we paused the scrolling because the mouse moved?
595 // we remember the interval of the timer to be able to restart it
598 #endif // wxUSE_SCROLLBAR
601 class wxWin32CheckboxInputHandler
: public wxStdInputHandler
604 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
605 : wxStdInputHandler(handler
) { }
607 virtual bool HandleKey(wxInputConsumer
*control
,
608 const wxKeyEvent
& event
,
611 #endif // wxUSE_CHECKBOX
614 class wxWin32TextCtrlInputHandler
: public wxStdInputHandler
617 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
618 : wxStdInputHandler(handler
) { }
620 virtual bool HandleKey(wxInputConsumer
*control
,
621 const wxKeyEvent
& event
,
624 #endif // wxUSE_TEXTCTRL
626 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
629 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
631 virtual bool HandleMouse(wxInputConsumer
*consumer
,
632 const wxMouseEvent
& event
);
634 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
635 const wxMouseEvent
& event
);
638 // is the given point over the statusbar grip?
639 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
642 // the cursor we had replaced with the resize one
643 wxCursor m_cursorOld
;
645 // was the mouse over the grip last time we checked?
649 class wxWin32SystemMenuEvtHandler
;
651 class wxWin32FrameInputHandler
: public wxStdInputHandler
654 wxWin32FrameInputHandler(wxInputHandler
*handler
);
655 virtual ~wxWin32FrameInputHandler();
657 virtual bool HandleMouse(wxInputConsumer
*control
,
658 const wxMouseEvent
& event
);
660 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
663 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
664 #endif // wxUSE_MENUS
667 // was the mouse over the grip last time we checked?
668 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
671 // ----------------------------------------------------------------------------
672 // wxWin32ColourScheme: uses (default) Win32 colours
673 // ----------------------------------------------------------------------------
675 class wxWin32ColourScheme
: public wxColourScheme
678 virtual wxColour
Get(StdColour col
) const;
679 virtual wxColour
GetBackground(wxWindow
*win
) const;
682 // ----------------------------------------------------------------------------
683 // wxWin32ArtProvider
684 // ----------------------------------------------------------------------------
686 class wxWin32ArtProvider
: public wxArtProvider
689 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
690 const wxArtClient
& client
,
694 // ----------------------------------------------------------------------------
696 // ----------------------------------------------------------------------------
698 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
700 class wxWin32Theme
: public wxTheme
704 virtual ~wxWin32Theme();
706 virtual wxRenderer
*GetRenderer();
707 virtual wxArtProvider
*GetArtProvider();
708 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
709 wxInputConsumer
*consumer
);
710 virtual wxColourScheme
*GetColourScheme();
713 wxWin32Renderer
*m_renderer
;
715 wxWin32ArtProvider
*m_artProvider
;
717 // the names of the already created handlers and the handlers themselves
718 // (these arrays are synchronized)
719 wxSortedArrayString m_handlerNames
;
720 wxArrayHandlers m_handlers
;
722 wxWin32ColourScheme
*m_scheme
;
724 WX_DECLARE_THEME(win32
)
727 // ----------------------------------------------------------------------------
729 // ----------------------------------------------------------------------------
731 // frame buttons bitmaps
733 static const char *frame_button_close_xpm
[] = {
748 static const char *frame_button_help_xpm
[] = {
763 static const char *frame_button_maximize_xpm
[] = {
778 static const char *frame_button_minimize_xpm
[] = {
793 static const char *frame_button_restore_xpm
[] = {
810 static const char *checked_menu_xpm
[] = {
811 /* columns rows colors chars-per-pixel */
827 static const char *selected_checked_menu_xpm
[] = {
828 /* columns rows colors chars-per-pixel */
844 static const char *disabled_checked_menu_xpm
[] = {
845 /* columns rows colors chars-per-pixel */
862 static const char *selected_disabled_checked_menu_xpm
[] = {
863 /* columns rows colors chars-per-pixel */
879 // checkbox and radiobox bitmaps below
881 static const char *checked_xpm
[] = {
882 /* columns rows colors chars-per-pixel */
905 static const char *pressed_checked_xpm
[] = {
906 /* columns rows colors chars-per-pixel */
928 static const char *pressed_disabled_checked_xpm
[] = {
929 /* columns rows colors chars-per-pixel */
951 static const char *checked_item_xpm
[] = {
952 /* columns rows colors chars-per-pixel */
973 static const char *unchecked_xpm
[] = {
974 /* columns rows colors chars-per-pixel */
997 static const char *pressed_unchecked_xpm
[] = {
998 /* columns rows colors chars-per-pixel */
1020 static const char *unchecked_item_xpm
[] = {
1021 /* columns rows colors chars-per-pixel */
1041 static const char *undetermined_xpm
[] = {
1042 /* columns rows colors chars-per-pixel */
1065 static const char *pressed_undetermined_xpm
[] = {
1066 /* columns rows colors chars-per-pixel */
1089 static const char *checked_radio_xpm
[] = {
1090 /* columns rows colors chars-per-pixel */
1113 static const char *pressed_checked_radio_xpm
[] = {
1114 /* columns rows colors chars-per-pixel */
1137 static const char *pressed_disabled_checked_radio_xpm
[] = {
1138 /* columns rows colors chars-per-pixel */
1161 static const char *unchecked_radio_xpm
[] = {
1162 /* columns rows colors chars-per-pixel */
1185 static const char *pressed_unchecked_radio_xpm
[] = {
1186 /* columns rows colors chars-per-pixel */
1209 static const char **
1210 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1215 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1218 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1221 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1227 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1230 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1233 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1239 { checked_menu_xpm
, NULL
, NULL
},
1242 { selected_checked_menu_xpm
, NULL
, NULL
},
1245 { disabled_checked_menu_xpm
, NULL
, NULL
},
1247 // disabled selected state
1248 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1252 static const char **xpmChecked
[IndicatorStatus_Max
] =
1258 // ============================================================================
1260 // ============================================================================
1262 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1264 // ----------------------------------------------------------------------------
1266 // ----------------------------------------------------------------------------
1268 wxWin32Theme::wxWin32Theme()
1272 m_artProvider
= NULL
;
1275 wxWin32Theme::~wxWin32Theme()
1279 wxArtProvider::RemoveProvider(m_artProvider
);
1282 wxRenderer
*wxWin32Theme::GetRenderer()
1286 m_renderer
= new wxWin32Renderer(GetColourScheme());
1292 wxArtProvider
*wxWin32Theme::GetArtProvider()
1294 if ( !m_artProvider
)
1296 m_artProvider
= new wxWin32ArtProvider
;
1299 return m_artProvider
;
1303 wxWin32Theme::GetInputHandler(const wxString
& control
,
1304 wxInputConsumer
*consumer
)
1306 wxInputHandler
*handler
= NULL
;
1307 int n
= m_handlerNames
.Index(control
);
1308 if ( n
== wxNOT_FOUND
)
1310 static wxWin32InputHandler s_handlerDef
;
1312 wxInputHandler
* const
1313 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
1315 // create a new handler
1316 if ( control
== wxINP_HANDLER_TOPLEVEL
)
1318 static wxWin32FrameInputHandler
s_handler(handlerStd
);
1320 handler
= &s_handler
;
1323 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1325 static wxWin32CheckboxInputHandler
s_handler(handlerStd
);
1327 handler
= &s_handler
;
1329 #endif // wxUSE_CHECKBOX
1331 else if ( control
== wxINP_HANDLER_SCROLLBAR
)
1333 static wxWin32ScrollBarInputHandler
1334 s_handler(GetRenderer(), handlerStd
);
1336 handler
= &s_handler
;
1338 #endif // wxUSE_SCROLLBAR
1340 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1342 static wxWin32StatusBarInputHandler
s_handler(handlerStd
);
1344 handler
= &s_handler
;
1346 #endif // wxUSE_STATUSBAR
1348 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1350 static wxWin32TextCtrlInputHandler
s_handler(handlerStd
);
1352 handler
= &s_handler
;
1354 #endif // wxUSE_TEXTCTRL
1355 else // no special handler for this control
1357 handler
= handlerStd
;
1360 n
= m_handlerNames
.Add(control
);
1361 m_handlers
.Insert(handler
, n
);
1363 else // we already have it
1365 handler
= m_handlers
[n
];
1371 wxColourScheme
*wxWin32Theme::GetColourScheme()
1375 m_scheme
= new wxWin32ColourScheme
;
1380 // ============================================================================
1381 // wxWin32ColourScheme
1382 // ============================================================================
1384 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1387 if ( win
->UseBgCol() )
1389 // use the user specified colour
1390 col
= win
->GetBackgroundColour();
1393 if ( !win
->ShouldInheritColours() )
1396 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1397 #endif // wxUSE_TEXTCTRL
1399 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1400 #endif // wxUSE_LISTBOX
1409 if ( !win
->IsEnabled() ) // not IsEditable()
1415 // doesn't depend on the state
1420 #endif // wxUSE_TEXTCTRL
1423 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1427 int flags
= win
->GetStateFlags();
1429 // the colour set by the user should be used for the normal state
1430 // and for the states for which we don't have any specific colours
1431 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1434 if ( wxDynamicCast(win
, wxScrollBar
) )
1435 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1438 #endif // wxUSE_SCROLLBAR
1446 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1450 // use the system colours under Windows
1451 #if defined(__WXMSW__)
1452 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1454 case CONTROL_PRESSED
:
1455 case CONTROL_CURRENT
:
1456 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1458 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1460 #if defined(COLOR_3DLIGHT)
1461 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1463 case SCROLLBAR
: return wxColour(0xe0e0e0);
1465 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1467 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1468 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1470 #if defined(COLOR_3DDKSHADOW)
1471 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1473 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1476 case CONTROL_TEXT_DISABLED
:
1477 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1479 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1481 case CONTROL_TEXT_DISABLED_SHADOW
:
1482 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1484 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1485 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1486 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1487 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1489 case DESKTOP
: return wxColour(0x808000);
1491 // use the standard Windows colours elsewhere
1492 case WINDOW
: return *wxWHITE
;
1494 case CONTROL_PRESSED
:
1495 case CONTROL_CURRENT
:
1496 case CONTROL
: return wxColour(0xc0c0c0);
1498 case CONTROL_TEXT
: return *wxBLACK
;
1500 case SCROLLBAR
: return wxColour(0xe0e0e0);
1501 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1503 case HIGHLIGHT
: return wxColour(0x800000);
1504 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1506 case SHADOW_DARK
: return *wxBLACK
;
1508 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1509 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1511 case SHADOW_IN
: return wxColour(0xc0c0c0);
1513 case CONTROL_TEXT_DISABLED_SHADOW
:
1514 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1516 case TITLEBAR
: return wxColour(0xaeaaae);
1517 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1518 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1519 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1521 case DESKTOP
: return wxColour(0x808000);
1524 case GAUGE
: return Get(HIGHLIGHT
);
1528 wxFAIL_MSG(_T("invalid standard colour"));
1533 // ============================================================================
1535 // ============================================================================
1537 // ----------------------------------------------------------------------------
1539 // ----------------------------------------------------------------------------
1541 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1545 m_sizeScrollbarArrow
= wxSize(16, 16);
1547 // init colours and pens
1548 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1550 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1551 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1553 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1555 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1556 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1558 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1559 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1561 // init the arrow bitmaps
1562 static const size_t ARROW_WIDTH
= 7;
1563 static const size_t ARROW_LENGTH
= 4;
1566 wxMemoryDC dcNormal
,
1569 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1571 bool isVertical
= n
> Arrow_Right
;
1584 // disabled arrow is larger because of the shadow
1585 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1586 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1588 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1589 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1591 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1592 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1596 dcNormal
.SetPen(m_penBlack
);
1597 dcDisabled
.SetPen(m_penDarkGrey
);
1599 // calculate the position of the point of the arrow
1603 x1
= (ARROW_WIDTH
- 1)/2;
1604 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1608 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1609 y1
= (ARROW_WIDTH
- 1)/2;
1620 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1622 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1623 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1630 if ( n
== Arrow_Up
)
1641 else // left or right arrow
1646 if ( n
== Arrow_Left
)
1659 // draw the shadow for the disabled one
1660 dcDisabled
.SetPen(m_penHighlight
);
1665 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1669 x1
= ARROW_LENGTH
- 1;
1670 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1673 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1674 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1679 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1683 x1
= ARROW_WIDTH
- 1;
1685 x2
= (ARROW_WIDTH
- 1)/2;
1687 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1688 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1693 // create the inverted bitmap but only for the right arrow as we only
1694 // use it for the menus
1695 if ( n
== Arrow_Right
)
1697 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1698 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1700 dcInverse
.Blit(0, 0, w
, h
,
1703 dcInverse
.SelectObject(wxNullBitmap
);
1705 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1706 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1708 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1709 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1711 dcInverse
.Blit(0, 0, w
, h
,
1714 dcInverse
.SelectObject(wxNullBitmap
);
1716 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1717 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1720 dcNormal
.SelectObject(wxNullBitmap
);
1721 dcDisabled
.SelectObject(wxNullBitmap
);
1723 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1724 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1725 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1726 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1728 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1731 // init the frame buttons bitmaps
1732 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1733 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1734 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1735 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1736 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1739 // ----------------------------------------------------------------------------
1741 // ----------------------------------------------------------------------------
1744 The raised border in Win32 looks like this:
1746 IIIIIIIIIIIIIIIIIIIIIIB
1748 I GB I = white (HILIGHT)
1749 I GB H = light grey (LIGHT)
1750 I GB G = dark grey (SHADOI)
1751 I GB B = black (DKSHADOI)
1752 I GB I = hIghlight (COLOR_3DHILIGHT)
1754 IGGGGGGGGGGGGGGGGGGGGGB
1755 BBBBBBBBBBBBBBBBBBBBBBB
1757 The sunken border looks like this:
1759 GGGGGGGGGGGGGGGGGGGGGGI
1760 GBBBBBBBBBBBBBBBBBBBBHI
1767 GHHHHHHHHHHHHHHHHHHHHHI
1768 IIIIIIIIIIIIIIIIIIIIIII
1770 The static border (used for the controls which don't get focus) is like
1773 GGGGGGGGGGGGGGGGGGGGGGW
1781 WWWWWWWWWWWWWWWWWWWWWWW
1783 The most complicated is the double border:
1785 HHHHHHHHHHHHHHHHHHHHHHB
1786 HWWWWWWWWWWWWWWWWWWWWGB
1787 HWHHHHHHHHHHHHHHHHHHHGB
1792 HWHHHHHHHHHHHHHHHHHHHGB
1793 HGGGGGGGGGGGGGGGGGGGGGB
1794 BBBBBBBBBBBBBBBBBBBBBBB
1796 And the simple border is, well, simple:
1798 BBBBBBBBBBBBBBBBBBBBBBB
1807 BBBBBBBBBBBBBBBBBBBBBBB
1810 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1814 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1815 dc
.DrawRectangle(*rect
);
1821 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1823 // draw the bottom and right sides
1825 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1826 rect
->GetRight() + 1, rect
->GetBottom());
1827 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1828 rect
->GetRight(), rect
->GetBottom());
1834 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1835 const wxPen
& pen1
, const wxPen
& pen2
)
1837 // draw the rectangle
1839 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1840 rect
->GetLeft(), rect
->GetBottom());
1841 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1842 rect
->GetRight(), rect
->GetTop());
1844 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1845 rect
->GetRight(), rect
->GetBottom());
1846 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1847 rect
->GetRight() + 1, rect
->GetBottom());
1853 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1855 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1856 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1859 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1861 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1862 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1865 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1869 DrawRect(dc
, rect
, m_penDarkGrey
);
1871 // the arrow is usually drawn inside border of width 2 and is offset by
1872 // another pixel in both directions when it's pressed - as the border
1873 // in this case is more narrow as well, we have to adjust rect like
1881 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1882 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1886 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1888 const wxRect
& rectTotal
,
1889 int WXUNUSED(flags
),
1894 wxRect rect
= rectTotal
;
1898 case wxBORDER_SUNKEN
:
1899 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1901 DrawSunkenBorder(dc
, &rect
);
1905 case wxBORDER_STATIC
:
1906 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1909 case wxBORDER_RAISED
:
1910 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1912 DrawRaisedBorder(dc
, &rect
);
1916 case wxBORDER_DOUBLE
:
1917 DrawArrowBorder(dc
, &rect
);
1918 DrawRect(dc
, &rect
, m_penLightGrey
);
1921 case wxBORDER_SIMPLE
:
1922 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1924 DrawRect(dc
, &rect
, m_penBlack
);
1929 wxFAIL_MSG(_T("unknown border type"));
1932 case wxBORDER_DEFAULT
:
1941 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1946 case wxBORDER_RAISED
:
1947 case wxBORDER_SUNKEN
:
1948 width
= BORDER_THICKNESS
;
1951 case wxBORDER_SIMPLE
:
1952 case wxBORDER_STATIC
:
1956 case wxBORDER_DOUBLE
:
1962 // char *crash = NULL;
1964 wxFAIL_MSG(_T("unknown border type"));
1968 case wxBORDER_DEFAULT
:
1978 rect
.height
= width
;
1983 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1988 // ----------------------------------------------------------------------------
1990 // ----------------------------------------------------------------------------
1992 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1998 // text controls are not special under windows
1999 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
2002 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
2003 const wxRect
& rectTotal
,
2007 wxRect rect
= rectTotal
;
2009 if ( flags
& wxCONTROL_PRESSED
)
2011 // button pressed: draw a double border around it
2012 DrawRect(dc
, &rect
, m_penBlack
);
2013 DrawRect(dc
, &rect
, m_penDarkGrey
);
2017 // button not pressed
2019 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
2021 // button either default or focused (or both): add an extra border around it
2022 DrawRect(dc
, &rect
, m_penBlack
);
2025 // now draw a normal button
2026 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
2027 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
2036 // ----------------------------------------------------------------------------
2038 // ----------------------------------------------------------------------------
2040 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
2041 wxCoord y
, wxCoord x1
, wxCoord x2
)
2043 dc
.SetPen(m_penDarkGrey
);
2044 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2045 dc
.SetPen(m_penHighlight
);
2047 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2050 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
2051 wxCoord x
, wxCoord y1
, wxCoord y2
)
2053 dc
.SetPen(m_penDarkGrey
);
2054 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2055 dc
.SetPen(m_penHighlight
);
2057 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2060 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
2061 const wxString
& label
,
2067 wxCoord height
= 0; // of the label
2068 wxRect rectFrame
= rect
;
2069 if ( !label
.empty() )
2071 // the text should touch the top border of the rect, so the frame
2072 // itself should be lower
2073 dc
.GetTextExtent(label
, NULL
, &height
);
2074 rectFrame
.y
+= height
/ 2;
2075 rectFrame
.height
-= height
/ 2;
2077 // we have to draw each part of the frame individually as we can't
2078 // erase the background beyond the label as it might contain some
2079 // pixmap already, so drawing everything and then overwriting part of
2080 // the frame with label doesn't work
2082 // TODO: the +5 and space insertion should be customizable
2085 rectText
.x
= rectFrame
.x
+ 5;
2086 rectText
.y
= rect
.y
;
2087 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2088 rectText
.height
= height
;
2091 label2
<< _T(' ') << label
<< _T(' ');
2092 if ( indexAccel
!= -1 )
2094 // adjust it as we prepended a space
2099 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2101 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2105 // just draw the complete frame
2106 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2107 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2111 // ----------------------------------------------------------------------------
2113 // ----------------------------------------------------------------------------
2115 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2117 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2118 // pixels each while we really need dots here... PS_ALTERNATE might
2119 // work, but it is for NT 5 only
2121 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2123 // draw the pixels manually: note that to behave in the same manner as
2124 // DrawRect(), we must exclude the bottom and right borders from the
2126 wxCoord x1
= rect
.GetLeft(),
2128 x2
= rect
.GetRight(),
2129 y2
= rect
.GetBottom();
2131 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2133 // this seems to be closer than what Windows does than wxINVERT although
2134 // I'm still not sure if it's correct
2135 dc
.SetLogicalFunction(wxAND_REVERSE
);
2138 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2139 dc
.DrawPoint(z
, rect
.GetTop());
2141 wxCoord shift
= z
== x2
? 0 : 1;
2142 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2143 dc
.DrawPoint(x2
, z
);
2145 shift
= z
== y2
? 0 : 1;
2146 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2147 dc
.DrawPoint(z
, y2
);
2149 shift
= z
== x1
? 0 : 1;
2150 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2151 dc
.DrawPoint(x1
, z
);
2153 dc
.SetLogicalFunction(wxCOPY
);
2157 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2158 const wxString
& label
,
2163 // draw shadow of the text
2164 dc
.SetTextForeground(m_colHighlight
);
2165 wxRect rectShadow
= rect
;
2168 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2170 // make the text grey
2171 dc
.SetTextForeground(m_colDarkGrey
);
2174 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2175 const wxString
& label
,
2182 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2185 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2186 const wxString
& label
,
2192 const wxPoint
& focusOffset
)
2194 // the underscores are not drawn for focused controls in wxMSW
2195 if ( flags
& wxCONTROL_FOCUSED
)
2200 if ( flags
& wxCONTROL_DISABLED
)
2202 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2203 // currently only can happen for a menu item and it seems that Windows
2204 // doesn't draw the shadow in this case, so we don't do it neither
2205 if ( flags
& wxCONTROL_SELECTED
)
2207 // just make the label text greyed out
2208 dc
.SetTextForeground(m_colDarkGrey
);
2210 else // draw normal disabled label
2212 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2217 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2219 if ( flags
& wxCONTROL_DISABLED
)
2221 // restore the fg colour
2222 dc
.SetTextForeground(*wxBLACK
);
2225 if ( flags
& wxCONTROL_FOCUSED
)
2227 if ( focusOffset
.x
|| focusOffset
.y
)
2229 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2232 DrawFocusRect(dc
, rectLabel
);
2236 *rectBounds
= rectLabel
;
2239 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2240 const wxString
& label
,
2241 const wxBitmap
& image
,
2248 // the underscores are not drawn for focused controls in wxMSW
2249 if ( flags
& wxCONTROL_PRESSED
)
2254 wxRect rectLabel
= rect
;
2255 if ( !label
.empty() )
2257 // shift the label if a button is pressed
2258 if ( flags
& wxCONTROL_PRESSED
)
2264 if ( flags
& wxCONTROL_DISABLED
)
2266 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2269 // leave enough space for the focus rectangle
2270 if ( flags
& wxCONTROL_FOCUSED
)
2272 rectLabel
.Inflate(-2);
2276 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2278 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2280 if ( flags
& wxCONTROL_PRESSED
)
2282 // the focus rectangle is never pressed, so undo the shift done
2290 DrawFocusRect(dc
, rectLabel
);
2294 // ----------------------------------------------------------------------------
2295 // (check)listbox items
2296 // ----------------------------------------------------------------------------
2298 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2299 const wxString
& label
,
2303 wxDCTextColourChanger
colChanger(dc
);
2305 if ( flags
& wxCONTROL_SELECTED
)
2307 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2309 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2310 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2311 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2312 dc
.DrawRectangle(rect
);
2315 wxRect rectText
= rect
;
2317 rectText
.width
-= 2;
2318 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2320 if ( flags
& wxCONTROL_FOCUSED
)
2322 DrawFocusRect(dc
, rect
);
2326 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2327 const wxString
& label
,
2328 const wxBitmap
& bitmap
,
2337 else // use default bitmap
2339 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2340 ? IndicatorStatus_Checked
2341 : IndicatorStatus_Unchecked
;
2343 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2345 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2348 bmp
= m_bmpCheckBitmaps
[i
];
2351 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2352 true /* use mask */);
2354 wxRect rectLabel
= rect
;
2355 int bmpWidth
= bmp
.GetWidth();
2356 rectLabel
.x
+= bmpWidth
;
2357 rectLabel
.width
-= bmpWidth
;
2359 DrawItem(dc
, label
, rectLabel
, flags
);
2362 // ----------------------------------------------------------------------------
2363 // check/radio buttons
2364 // ----------------------------------------------------------------------------
2366 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2368 IndicatorState indState
;
2369 if ( flags
& wxCONTROL_SELECTED
)
2370 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2371 : IndicatorState_Selected
;
2372 else if ( flags
& wxCONTROL_DISABLED
)
2373 indState
= IndicatorState_Disabled
;
2374 else if ( flags
& wxCONTROL_PRESSED
)
2375 indState
= IndicatorState_Pressed
;
2377 indState
= IndicatorState_Normal
;
2379 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2380 ? IndicatorStatus_Checked
2381 : ( flags
& wxCONTROL_UNDETERMINED
2382 ? IndicatorStatus_Undeterminated
2383 : IndicatorStatus_Unchecked
);
2385 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2388 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2391 // create and cache it
2392 bmp
= wxBitmap(xpm
);
2393 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2400 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2401 const wxString
& label
,
2402 const wxBitmap
& bitmap
,
2407 wxCoord focusOffsetY
)
2409 // calculate the position of the bitmap and of the label
2410 wxCoord heightBmp
= bitmap
.GetHeight();
2412 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2415 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2416 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2418 // align label vertically with the bitmap - looks nicer like this
2419 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2421 // calc horz position
2422 if ( align
== wxALIGN_RIGHT
)
2424 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2425 rectLabel
.x
= rect
.x
+ 3;
2426 rectLabel
.SetRight(xBmp
);
2428 else // normal (checkbox to the left of the text) case
2431 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2432 rectLabel
.SetRight(rect
.GetRight());
2435 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2438 dc
, label
, rectLabel
,
2440 wxALIGN_LEFT
| wxALIGN_TOP
,
2442 NULL
, // we don't need bounding rect
2443 // use custom vert focus rect offset
2444 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2448 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2449 const wxString
& label
,
2450 const wxBitmap
& bitmap
,
2460 bmp
= GetRadioBitmap(flags
);
2462 DrawCheckOrRadioButton(dc
, label
,
2464 rect
, flags
, align
, indexAccel
,
2465 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2468 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2469 const wxString
& label
,
2470 const wxBitmap
& bitmap
,
2480 bmp
= GetCheckBitmap(flags
);
2482 DrawCheckOrRadioButton(dc
, label
,
2484 rect
, flags
, align
, indexAccel
,
2485 0); // no focus rect offset for checkboxes
2489 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2490 const wxString
& label
,
2491 const wxBitmap
& bitmap
,
2492 const wxRect
& rectOrig
,
2497 if (style
== wxTOOL_STYLE_BUTTON
)
2499 wxRect rect
= rectOrig
;
2500 rect
.Deflate(BORDER_THICKNESS
);
2502 if ( flags
& wxCONTROL_PRESSED
)
2504 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2506 else if ( flags
& wxCONTROL_CURRENT
)
2508 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2511 if(tbarStyle
& wxTB_TEXT
)
2513 if(tbarStyle
& wxTB_HORIZONTAL
)
2515 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2519 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
2524 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
2525 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
2526 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
2529 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2531 // leave a small gap aroudn the line, also account for the toolbar
2533 if(rectOrig
.height
> rectOrig
.width
)
2536 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2537 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2538 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2543 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
2544 rectOrig
.x
+ 2*BORDER_THICKNESS
,
2545 rectOrig
.GetRight() - BORDER_THICKNESS
);
2548 // don't draw wxTOOL_STYLE_CONTROL
2550 #endif // wxUSE_TOOLBAR
2552 // ----------------------------------------------------------------------------
2554 // ----------------------------------------------------------------------------
2556 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2557 const wxString
& text
,
2563 // nothing special to do here
2564 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2568 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2569 const wxRect
& WXUNUSED(rect
))
2571 // we don't draw them
2574 // ----------------------------------------------------------------------------
2576 // ----------------------------------------------------------------------------
2578 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2579 const wxRect
& rectOrig
,
2581 const wxString
& label
,
2582 const wxBitmap
& bitmap
,
2586 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2587 #define REVERSE_FOR_VERTICAL(X,Y) \
2588 SELECT_FOR_VERTICAL(X,Y) \
2590 SELECT_FOR_VERTICAL(Y,X)
2592 wxRect rect
= rectOrig
;
2594 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2596 // the current tab is drawn indented (to the top for default case) and
2597 // bigger than the other ones
2598 const wxSize indent
= GetTabIndent();
2599 if ( flags
& wxCONTROL_SELECTED
)
2601 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
2602 SELECT_FOR_VERTICAL( 0, indent
.y
));
2606 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2613 rect
.height
+= indent
.y
;
2620 rect
.width
+= indent
.x
;
2625 // draw the text, image and the focus around them (if necessary)
2626 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2627 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2629 rectLabel
.Deflate(1, 1);
2632 // draw it horizontally into memory and rotate for screen
2634 wxBitmap bitmapRotated
,
2635 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2636 rectLabel
.y
+ rectLabel
.height
);
2637 dcMem
.SelectObject(bitmapMem
);
2638 dcMem
.SetBackground(dc
.GetBackground());
2639 dcMem
.SetFont(dc
.GetFont());
2640 dcMem
.SetTextForeground(dc
.GetTextForeground());
2644 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
2647 #endif // wxUSE_IMAGE
2649 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2650 flags
, wxALIGN_CENTRE
, indexAccel
);
2651 dcMem
.SelectObject(wxNullBitmap
);
2652 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2654 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2655 #endif // wxUSE_IMAGE
2656 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2660 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2661 flags
, wxALIGN_CENTRE
, indexAccel
);
2664 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2665 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2666 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2667 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2668 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2669 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2671 // FIXME: all this code will break if the tab indent or the border width,
2672 // it is tied to the fact that both of them are equal to 2
2678 // left orientation looks like top but IsVertical makes x and y reversed
2680 // top is not vertical so use coordinates in written order
2681 dc
.SetPen(m_penHighlight
);
2682 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2683 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2684 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2685 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2686 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2687 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2689 dc
.SetPen(m_penBlack
);
2690 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2691 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2692 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2693 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2695 dc
.SetPen(m_penDarkGrey
);
2696 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2697 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2699 if ( flags
& wxCONTROL_SELECTED
)
2701 dc
.SetPen(m_penLightGrey
);
2703 // overwrite the part of the border below this tab
2704 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2705 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2707 // and the shadow of the tab to the left of us
2708 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2709 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2714 // right orientation looks like bottom but IsVertical makes x and y reversed
2716 // bottom is not vertical so use coordinates in written order
2717 dc
.SetPen(m_penHighlight
);
2718 // we need to continue one pixel further to overwrite the corner of
2719 // the border for the selected tab
2720 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
2721 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2722 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2723 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2725 dc
.SetPen(m_penBlack
);
2726 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2727 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2728 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2729 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2730 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2731 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2733 dc
.SetPen(m_penDarkGrey
);
2734 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2735 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2736 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2737 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2739 if ( flags
& wxCONTROL_SELECTED
)
2741 dc
.SetPen(m_penLightGrey
);
2743 // overwrite the part of the (double!) border above this tab
2744 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2745 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2746 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2747 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2749 // and the shadow of the tab to the left of us
2750 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2751 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2756 #undef SELECT_FOR_VERTICAL
2757 #undef REVERSE_FOR_VERTICAL
2762 // ----------------------------------------------------------------------------
2764 // ----------------------------------------------------------------------------
2767 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2769 wxOrientation orient
) const
2772 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2773 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2775 if (orient
== wxHORIZONTAL
)
2789 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2791 wxOrientation orient
,
2794 bool transpose
= (orient
== wxVERTICAL
);
2795 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2796 (((style
& wxSL_TOP
) != 0) & !transpose
|
2797 ((style
& wxSL_LEFT
) != 0) & transpose
|
2798 ((style
& wxSL_BOTH
) != 0));
2799 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2800 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2801 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2802 ((style
& wxSL_BOTH
) != 0));
2804 wxRect rect
= rectOrig
;
2806 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2808 if (orient
== wxHORIZONTAL
) {
2809 rect
.x
+= SLIDER_MARGIN
;
2812 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2816 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2820 rect
.y
+= sizeThumb
.y
/2;
2822 rect
.width
-= 2*SLIDER_MARGIN
;
2823 rect
.height
= 2*BORDER_THICKNESS
;
2827 rect
.y
+= SLIDER_MARGIN
;
2830 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2834 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2838 rect
.x
+= sizeThumb
.x
/2;
2840 rect
.width
= 2*BORDER_THICKNESS
;
2841 rect
.height
-= 2*SLIDER_MARGIN
;
2847 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2848 const wxRect
& rectOrig
,
2850 wxOrientation orient
,
2855 /* show shaft geometry
2873 if (flags
& wxCONTROL_FOCUSED
) {
2874 DrawFocusRect(dc
, rectOrig
);
2877 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2879 if (rectShaft
) *rectShaft
= rect
;
2881 DrawSunkenBorder(dc
, &rect
);
2884 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2886 wxOrientation orient
,
2890 /* show thumb geometry
2899 H D B where H is highlight colour
2913 The interior of this shape is filled with the hatched brush if the thumb
2917 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2919 bool transpose
= (orient
== wxVERTICAL
);
2920 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2921 (((style
& wxSL_TOP
) != 0) & !transpose
|
2922 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2923 ((style
& wxSL_BOTH
) == 0);
2924 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2925 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2926 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2927 ((style
& wxSL_BOTH
) == 0);
2929 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2930 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2932 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2933 x1
= (transpose
? rect
.y
: rect
.x
);
2934 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2935 x3
= (x1
-1+c
) + sizeArrow
;
2936 y1
= (transpose
? rect
.x
: rect
.y
);
2937 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2938 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2939 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2941 dc
.SetPen(m_penBlack
);
2943 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2945 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2948 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2952 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2955 dc
.SetPen(m_penDarkGrey
);
2956 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2958 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2962 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2965 dc
.SetPen(m_penHighlight
);
2968 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2969 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2973 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2975 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2978 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2981 if (flags
& wxCONTROL_PRESSED
) {
2982 // TODO: MSW fills the entire area inside, not just the rect
2983 wxRect rectInt
= rect
;
2986 rectInt
.SetLeft(y3
);
2987 rectInt
.SetRight(y4
);
2992 rectInt
.SetBottom(y4
);
2996 #if !defined(__WXMGL__)
2997 static const char *stipple_xpm
[] = {
2998 /* columns rows colors chars-per-pixel */
3007 // VS: MGL can only do 8x8 stipple brushes
3008 static const char *stipple_xpm
[] = {
3009 /* columns rows colors chars-per-pixel */
3024 dc
.SetBrush(wxBrush(stipple_xpm
));
3026 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
3027 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
3028 dc
.SetPen(*wxTRANSPARENT_PEN
);
3029 dc
.DrawRectangle(rectInt
);
3033 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
3036 wxOrientation orient
,
3040 int WXUNUSED(flags
),
3043 /* show ticks geometry
3058 if (end
== start
) return;
3060 bool transpose
= (orient
== wxVERTICAL
);
3061 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
3062 (((style
& wxSL_TOP
) != 0) & !transpose
|
3063 ((style
& wxSL_LEFT
) != 0) & transpose
|
3064 ((style
& wxSL_BOTH
) != 0));
3065 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
3066 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
3067 ((style
& wxSL_RIGHT
) != 0) & transpose
|
3068 ((style
& wxSL_BOTH
) != 0));
3070 // default thumb size
3071 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
3072 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
3074 // normal thumb size
3075 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
3076 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
3078 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
3080 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
3081 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
3082 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
3083 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
3084 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
3085 y3
= (transpose
? rect
.x
: rect
.y
);
3086 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
3089 dc
.SetPen(m_penBlack
);
3091 int range
= end
- start
;
3092 for ( int n
= 0; n
< range
; n
+= step
) {
3093 wxCoord x
= x1
+ (len
*n
) / range
;
3095 if (left
& (y1
> y3
)) {
3096 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
3098 if (right
& (y4
> y2
)) {
3099 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
3102 // always draw the line at the end position
3103 if (left
& (y1
> y3
)) {
3104 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3106 if (right
& (y4
> y2
)) {
3107 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3111 #endif // wxUSE_SLIDER
3115 // ----------------------------------------------------------------------------
3117 // ----------------------------------------------------------------------------
3119 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3120 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3123 virtual wxSize
GetSize() const { return m_size
; }
3125 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3126 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3128 wxCoord
GetItemHeight() const { return m_heightItem
; }
3131 // the total size of the menu
3134 // the offset of the start of the menu item label
3137 // the offset of the start of the accel label
3140 // the height of a normal (not separator) item
3141 wxCoord m_heightItem
;
3143 friend wxMenuGeometryInfo
*
3144 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3147 // FIXME: all constants are hardcoded but shouldn't be
3148 static const wxCoord MENU_LEFT_MARGIN
= 9;
3149 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3150 static const wxCoord MENU_VERT_MARGIN
= 3;
3152 // the margin around bitmap/check marks (on each side)
3153 static const wxCoord MENU_BMP_MARGIN
= 2;
3155 // the margin between the labels and accel strings
3156 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3158 // the separator height in pixels: in fact, strangely enough, the real height
3159 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3161 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3163 // the size of the standard checkmark bitmap
3164 static const wxCoord MENU_CHECK_SIZE
= 9;
3166 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3167 const wxRect
& rectOrig
,
3168 const wxString
& label
,
3172 wxRect rect
= rectOrig
;
3175 wxDCTextColourChanger
colChanger(dc
);
3177 if ( flags
& wxCONTROL_SELECTED
)
3179 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3181 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3182 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3183 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3184 dc
.DrawRectangle(rect
);
3187 // don't draw the focus rect around menu bar items
3188 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3189 wxALIGN_CENTRE
, indexAccel
);
3192 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3194 const wxMenuGeometryInfo
& gi
,
3195 const wxString
& label
,
3196 const wxString
& accel
,
3197 const wxBitmap
& bitmap
,
3201 const wxWin32MenuGeometryInfo
& geometryInfo
=
3202 (const wxWin32MenuGeometryInfo
&)gi
;
3207 rect
.width
= geometryInfo
.GetSize().x
;
3208 rect
.height
= geometryInfo
.GetItemHeight();
3210 // draw the selected item specially
3211 wxDCTextColourChanger
colChanger(dc
);
3212 if ( flags
& wxCONTROL_SELECTED
)
3214 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3216 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3217 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3218 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3219 dc
.DrawRectangle(rect
);
3222 // draw the bitmap: use the bitmap provided or the standard checkmark for
3223 // the checkable items
3224 wxBitmap bmp
= bitmap
;
3225 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3227 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3232 rect
.SetRight(geometryInfo
.GetLabelOffset());
3233 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3237 rect
.x
= geometryInfo
.GetLabelOffset();
3238 rect
.SetRight(geometryInfo
.GetAccelOffset());
3240 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3242 // draw the accel string
3243 rect
.x
= geometryInfo
.GetAccelOffset();
3244 rect
.SetRight(geometryInfo
.GetSize().x
);
3246 // NB: no accel index here
3247 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3249 // draw the submenu indicator
3250 if ( flags
& wxCONTROL_ISSUBMENU
)
3252 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3253 rect
.width
= MENU_RIGHT_MARGIN
;
3255 wxArrowStyle arrowStyle
;
3256 if ( flags
& wxCONTROL_DISABLED
)
3257 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
3259 else if ( flags
& wxCONTROL_SELECTED
)
3260 arrowStyle
= Arrow_Inverted
;
3262 arrowStyle
= Arrow_Normal
;
3264 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3268 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3270 const wxMenuGeometryInfo
& geomInfo
)
3272 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3275 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3277 wxSize size
= sizeText
;
3279 // FIXME: menubar height is configurable under Windows
3286 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3287 const wxMenu
& menu
) const
3289 // prepare the dc: for now we draw all the items with the system font
3291 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3293 // the height of a normal item
3294 wxCoord heightText
= dc
.GetCharHeight();
3299 // the max length of label and accel strings: the menu width is the sum of
3300 // them, even if they're for different items (as the accels should be
3303 // the max length of the bitmap is never 0 as Windows always leaves enough
3304 // space for a check mark indicator
3305 wxCoord widthLabelMax
= 0,
3307 widthBmpMax
= MENU_LEFT_MARGIN
;
3309 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3311 node
= node
->GetNext() )
3313 // height of this item
3316 wxMenuItem
*item
= node
->GetData();
3317 if ( item
->IsSeparator() )
3319 h
= MENU_SEPARATOR_HEIGHT
;
3321 else // not separator
3326 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3327 if ( widthLabel
> widthLabelMax
)
3329 widthLabelMax
= widthLabel
;
3333 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3334 if ( widthAccel
> widthAccelMax
)
3336 widthAccelMax
= widthAccel
;
3339 const wxBitmap
& bmp
= item
->GetBitmap();
3342 wxCoord widthBmp
= bmp
.GetWidth();
3343 if ( widthBmp
> widthBmpMax
)
3344 widthBmpMax
= widthBmp
;
3346 //else if ( item->IsCheckable() ): no need to check for this as
3347 // MENU_LEFT_MARGIN is big enough to show the check mark
3350 h
+= 2*MENU_VERT_MARGIN
;
3352 // remember the item position and height
3353 item
->SetGeometry(height
, h
);
3358 // bundle the metrics into a struct and return it
3359 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3361 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3362 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3363 if ( widthAccelMax
> 0 )
3365 // if we actually have any accesl, add a margin
3366 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3369 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3371 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3372 gi
->m_size
.y
= height
;
3377 #endif // wxUSE_MENUS
3381 // ----------------------------------------------------------------------------
3383 // ----------------------------------------------------------------------------
3385 static const wxCoord STATBAR_BORDER_X
= 2;
3386 static const wxCoord STATBAR_BORDER_Y
= 2;
3388 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3390 if ( borderBetweenFields
)
3391 *borderBetweenFields
= 2;
3393 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3396 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3398 const wxString
& label
,
3399 int flags
, int style
/*=0*/)
3403 if ( flags
& wxCONTROL_ISDEFAULT
)
3405 // draw the size grip: it is a normal rect except that in the lower
3406 // right corner we have several bands which may be used for dragging
3407 // the status bar corner
3409 // each band consists of 4 stripes: m_penHighlight, double
3410 // m_penDarkGrey and transparent one
3411 wxCoord x2
= rect
.GetRight(),
3412 y2
= rect
.GetBottom();
3414 // draw the upper left part of the rect normally
3415 if (style
!= wxSB_FLAT
)
3417 if (style
== wxSB_RAISED
)
3418 dc
.SetPen(m_penHighlight
);
3420 dc
.SetPen(m_penDarkGrey
);
3421 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3422 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3425 // draw the grey stripes of the grip
3427 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3428 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3430 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3431 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3434 // draw the white stripes
3435 dc
.SetPen(m_penHighlight
);
3436 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3437 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3439 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3442 // draw the remaining rect boundaries
3443 if (style
!= wxSB_FLAT
)
3445 if (style
== wxSB_RAISED
)
3446 dc
.SetPen(m_penDarkGrey
);
3448 dc
.SetPen(m_penHighlight
);
3449 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3450 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3451 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3457 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3461 if (style
== wxSB_RAISED
)
3462 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3463 else if (style
!= wxSB_FLAT
)
3464 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3467 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3469 wxDCClipper
clipper(dc
, rectIn
);
3470 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3473 #endif // wxUSE_STATUSBAR
3475 // ----------------------------------------------------------------------------
3477 // ----------------------------------------------------------------------------
3479 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3480 wxBitmap
* WXUNUSED(bmpFocus
),
3481 wxBitmap
*bmpPressed
,
3482 wxBitmap
*bmpDisabled
)
3484 static const wxCoord widthCombo
= 16;
3485 static const wxCoord heightCombo
= 17;
3491 bmpNormal
->Create(widthCombo
, heightCombo
);
3492 dcMem
.SelectObject(*bmpNormal
);
3493 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3494 Arrow_Down
, Arrow_Normal
);
3499 bmpPressed
->Create(widthCombo
, heightCombo
);
3500 dcMem
.SelectObject(*bmpPressed
);
3501 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3502 Arrow_Down
, Arrow_Pressed
);
3507 bmpDisabled
->Create(widthCombo
, heightCombo
);
3508 dcMem
.SelectObject(*bmpDisabled
);
3509 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3510 Arrow_Down
, Arrow_Disabled
);
3514 // ----------------------------------------------------------------------------
3516 // ----------------------------------------------------------------------------
3518 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3519 const wxColour
& col
,
3521 wxWindow
* WXUNUSED(window
))
3523 wxBrush
brush(col
, wxSOLID
);
3525 dc
.SetPen(*wxTRANSPARENT_PEN
);
3526 dc
.DrawRectangle(rect
);
3529 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3530 const wxColour
& col
,
3532 int WXUNUSED(flags
),
3535 // just fill it with the given or default bg colour
3536 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3537 DoDrawBackground(dc
, colBg
, rect
, window
);
3540 // ----------------------------------------------------------------------------
3542 // ----------------------------------------------------------------------------
3544 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3549 // get the bitmap for this arrow
3550 wxArrowDirection arrowDir
;
3553 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3554 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3555 case wxUP
: arrowDir
= Arrow_Up
; break;
3556 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3559 wxFAIL_MSG(_T("unknown arrow direction"));
3563 wxArrowStyle arrowStyle
;
3564 if ( flags
& wxCONTROL_PRESSED
)
3566 // can't be pressed and disabled
3567 arrowStyle
= Arrow_Pressed
;
3571 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3574 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3577 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3579 wxArrowDirection arrowDir
,
3580 wxArrowStyle arrowStyle
)
3582 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3584 // under Windows the arrows always have the same size so just centre it in
3585 // the provided rectangle
3586 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3587 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3589 // Windows does it like this...
3590 if ( arrowDir
== Arrow_Left
)
3594 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3597 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3598 const wxRect
& rectAll
,
3599 wxArrowDirection arrowDir
,
3600 wxArrowStyle arrowStyle
)
3602 wxRect rect
= rectAll
;
3603 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3604 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3605 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3608 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3609 wxOrientation
WXUNUSED(orient
),
3611 int WXUNUSED(flags
))
3613 // we don't use the flags, the thumb never changes appearance
3614 wxRect rectThumb
= rect
;
3615 DrawArrowBorder(dc
, &rectThumb
);
3616 DrawBackground(dc
, wxNullColour
, rectThumb
);
3619 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3620 wxOrientation
WXUNUSED(orient
),
3621 const wxRect
& rectBar
,
3624 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3625 ? wxColourScheme::SCROLLBAR_PRESSED
3626 : wxColourScheme::SCROLLBAR
;
3627 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3630 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3632 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3637 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3638 wxScrollBar::Element elem
,
3641 return StandardGetScrollbarRect(scrollbar
, elem
,
3642 thumbPos
, m_sizeScrollbarArrow
);
3645 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3647 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3650 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3651 const wxPoint
& pt
) const
3653 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3656 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3659 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3662 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3665 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3668 #endif // wxUSE_SCROLLBAR
3670 // ----------------------------------------------------------------------------
3671 // top level windows
3672 // ----------------------------------------------------------------------------
3674 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3676 wxRect client
= GetFrameClientArea(rect
, flags
);
3678 if ( client
.Contains(pt
) )
3679 return wxHT_TOPLEVEL_CLIENT_AREA
;
3681 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3683 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3685 if ( flags
& wxTOPLEVEL_ICON
)
3687 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Contains(pt
) )
3688 return wxHT_TOPLEVEL_ICON
;
3691 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3692 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3693 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3695 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3697 if ( btnRect
.Contains(pt
) )
3698 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3699 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3701 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3703 if ( btnRect
.Contains(pt
) )
3704 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3705 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3707 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3709 if ( btnRect
.Contains(pt
) )
3710 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3711 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3713 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3715 if ( btnRect
.Contains(pt
) )
3716 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3717 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3719 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3721 if ( btnRect
.Contains(pt
) )
3722 return wxHT_TOPLEVEL_BUTTON_HELP
;
3723 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3726 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3727 return wxHT_TOPLEVEL_TITLEBAR
;
3730 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3732 // we are certainly at one of borders, lets decide which one:
3735 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3736 if ( pt
.x
< client
.x
)
3737 border
|= wxHT_TOPLEVEL_BORDER_W
;
3738 else if ( pt
.x
>= client
.width
+ client
.x
)
3739 border
|= wxHT_TOPLEVEL_BORDER_E
;
3740 if ( pt
.y
< client
.y
)
3741 border
|= wxHT_TOPLEVEL_BORDER_N
;
3742 else if ( pt
.y
>= client
.height
+ client
.y
)
3743 border
|= wxHT_TOPLEVEL_BORDER_S
;
3747 return wxHT_NOWHERE
;
3750 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3752 const wxString
& title
,
3756 int specialButtonFlags
)
3758 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3760 DrawFrameBorder(dc
, rect
, flags
);
3762 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3764 DrawFrameBackground(dc
, rect
, flags
);
3765 if ( flags
& wxTOPLEVEL_ICON
)
3766 DrawFrameIcon(dc
, rect
, icon
, flags
);
3767 DrawFrameTitle(dc
, rect
, title
, flags
);
3769 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3771 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3772 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3774 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3776 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3777 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3778 specialButtonFlags
: 0);
3779 x
-= FRAME_BUTTON_WIDTH
+ 2;
3781 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3783 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3784 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3785 specialButtonFlags
: 0);
3786 x
-= FRAME_BUTTON_WIDTH
;
3788 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3790 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3791 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3792 specialButtonFlags
: 0);
3793 x
-= FRAME_BUTTON_WIDTH
;
3795 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3797 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3798 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3799 specialButtonFlags
: 0);
3800 x
-= FRAME_BUTTON_WIDTH
;
3802 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3804 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3805 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3806 specialButtonFlags
: 0);
3811 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3815 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3819 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3820 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3821 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3822 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3823 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3826 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3830 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3832 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3833 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3834 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3836 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3837 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3839 DrawBackground(dc
, col
, r
);
3842 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3844 const wxString
& title
,
3847 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3848 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3849 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3851 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3852 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3853 if ( flags
& wxTOPLEVEL_ICON
)
3855 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3856 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3864 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3865 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3866 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3867 r
.width
-= FRAME_BUTTON_WIDTH
;
3868 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3869 r
.width
-= FRAME_BUTTON_WIDTH
;
3870 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3871 r
.width
-= FRAME_BUTTON_WIDTH
;
3872 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3873 r
.width
-= FRAME_BUTTON_WIDTH
;
3875 dc
.SetFont(m_titlebarFont
);
3876 dc
.SetTextForeground(col
);
3879 dc
.GetTextExtent(title
, &textW
, NULL
);
3880 if ( textW
> r
.width
)
3882 // text is too big, let's shorten it and add "..." after it:
3883 size_t len
= title
.length();
3884 wxCoord WSoFar
, letterW
;
3886 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3887 if ( WSoFar
> r
.width
)
3889 // not enough space to draw anything
3895 for (size_t i
= 0; i
< len
; i
++)
3897 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3898 if ( letterW
+ WSoFar
> r
.width
)
3904 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3905 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3908 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3909 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3912 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3919 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3920 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3924 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3925 wxCoord x
, wxCoord y
,
3929 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3934 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3935 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3936 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3937 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3938 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3940 wxFAIL_MSG(wxT("incorrect button specification"));
3943 if ( flags
& wxCONTROL_PRESSED
)
3945 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3946 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3947 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3948 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3952 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3953 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3954 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3955 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3960 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3965 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3967 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3968 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3969 FRAME_BORDER_THICKNESS
;
3972 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3974 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3975 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3981 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3984 wxSize
s(clientSize
);
3986 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3988 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3989 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3990 FRAME_BORDER_THICKNESS
;
3994 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3995 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
4000 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
4004 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
4006 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
4007 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4008 FRAME_BORDER_THICKNESS
;
4013 if ( flags
& wxTOPLEVEL_TITLEBAR
)
4015 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
4017 if ( flags
& wxTOPLEVEL_ICON
)
4018 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
4019 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
4020 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
4021 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
4022 s
.x
+= FRAME_BUTTON_WIDTH
;
4023 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
4024 s
.x
+= FRAME_BUTTON_WIDTH
;
4025 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
4026 s
.x
+= FRAME_BUTTON_WIDTH
;
4027 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
4028 s
.x
+= FRAME_BUTTON_WIDTH
;
4034 wxSize
wxWin32Renderer::GetFrameIconSize() const
4036 return wxSize(16, 16);
4040 // ----------------------------------------------------------------------------
4042 // ----------------------------------------------------------------------------
4044 /* Copyright (c) Julian Smart */
4045 static char *error_xpm
[]={
4046 /* columns rows colors chars-per-pixel */
4123 " $oooooooooooo%& ",
4124 " *=-ooooooooooooo;: ",
4125 " *oooooooooooooooooo> ",
4126 " =ooooooooooooooooooo, ",
4127 " $-ooooooooooooooooooo<1 ",
4128 " .oooooo2334ooo533oooooo6 ",
4129 " +ooooooo789oo2883oooooo0q ",
4130 " oooooooo2w83o78eoooooooor ",
4131 " toooooooooy88u884oooooooori ",
4132 " Xooooooooooe888poooooooooas ",
4133 " ooooooooooo4889doooooooooof ",
4134 " ooooooooooo588w2oooooooooofi ",
4135 " oooooooooodw8887oooooooooofi ",
4136 " goooooooooh8w588jooooooookli ",
4137 " tooooooooz885op8wdooooooorix ",
4138 " oooooood98cood98cooooooori ",
4139 " @oooooop8w2ooo5885ooooovbi ",
4140 " n%ooooooooooooooooooooomiM ",
4141 " &;oooooooooooooooooooNBiV ",
4142 " :ooooooooooooooooooCZiA ",
4143 " nSooooooooooooooooCDiF ",
4144 " nG<oooooooooooooNZiiH ",
4145 " 160ooooooooovmBiFH ",
4146 " nqrraoookrrbiiA ",
4153 /* Copyright (c) Julian Smart */
4154 static char *info_xpm
[]={
4155 /* columns rows colors chars-per-pixel */
4177 " ..XXXXXXXXXXXXX.. ",
4178 " .XXXXXXXXXXXXXXXXX. ",
4179 " .XXXXXXXXoO+XXXXXXXX. ",
4180 " .XXXXXXXXX@#OXXXXXXXXX. ",
4181 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
4182 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
4183 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
4184 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
4185 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
4186 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
4187 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4188 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4189 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
4190 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
4191 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
4192 " .XXXXXXXXXXXXXXXXX.%%%% ",
4193 " ..XXXXXXXXXXXXX..%%%% ",
4194 " %...XXXXXXXX..%%%%% ",
4195 " %%%..XXXXXX.%%%%% ",
4209 /* Copyright (c) Julian Smart */
4210 static char *question_xpm
[]={
4211 /* columns rows colors chars-per-pixel */
4232 " ..XXXXXXXXXXXXX.. ",
4233 " .XXXXXXoO++@XXXXXX. ",
4234 " .XXXXXXO#$$$$#%XXXXX. ",
4235 " .XXXXXX@$$#&&#$#oXXXXX. ",
4236 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
4237 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
4238 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
4239 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
4240 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
4241 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
4242 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
4243 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
4244 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
4245 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
4246 " .XXXXXXXX-$$XXXXXXXX.:::: ",
4247 " .XXXXXXXO++XXXXXXX.:::: ",
4248 " ..XXXXXXXXXXXXX..:::: ",
4249 " :...XXXXXXXX..::::: ",
4250 " :::..XXXXXX.::::: ",
4264 /* Copyright (c) Julian Smart */
4265 static char *warning_xpm
[]={
4266 /* columns rows colors chars-per-pixel */
4292 " ..XXXXO@#XXX... ",
4293 " ...XXXXO@#XXXX.. ",
4294 " ..XXXXXO@#XXXX... ",
4295 " ...XXXXXo@OXXXXX.. ",
4296 " ...XXXXXXo@OXXXXXX.. ",
4297 " ..XXXXXXX$@OXXXXXX... ",
4298 " ...XXXXXXXX@XXXXXXXX.. ",
4299 " ...XXXXXXXXXXXXXXXXXX... ",
4300 " ..XXXXXXXXXXOXXXXXXXXX.. ",
4301 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
4302 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
4303 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
4304 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
4305 " .............................. ",
4306 " .............................. ",
4313 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4314 const wxArtClient
& WXUNUSED(client
),
4315 const wxSize
& WXUNUSED(size
))
4317 if ( id
== wxART_INFORMATION
)
4318 return wxBitmap(info_xpm
);
4319 if ( id
== wxART_ERROR
)
4320 return wxBitmap(error_xpm
);
4321 if ( id
== wxART_WARNING
)
4322 return wxBitmap(warning_xpm
);
4323 if ( id
== wxART_QUESTION
)
4324 return wxBitmap(question_xpm
);
4325 return wxNullBitmap
;
4331 // ----------------------------------------------------------------------------
4332 // text control geometry
4333 // ----------------------------------------------------------------------------
4335 static inline int GetTextBorderWidth()
4341 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4342 const wxRect
& rect
) const
4344 wxRect rectTotal
= rect
;
4346 wxCoord widthBorder
= GetTextBorderWidth();
4347 rectTotal
.Inflate(widthBorder
);
4349 // this is what Windows does
4356 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4358 wxCoord
*extraSpaceBeyond
) const
4360 wxRect rectText
= rect
;
4362 // undo GetTextTotalArea()
4363 if ( rectText
.height
> 0 )
4366 wxCoord widthBorder
= GetTextBorderWidth();
4367 rectText
.Inflate(-widthBorder
);
4369 if ( extraSpaceBeyond
)
4370 *extraSpaceBeyond
= 0;
4375 #endif // wxUSE_TEXTCTRL
4377 // ----------------------------------------------------------------------------
4379 // ----------------------------------------------------------------------------
4381 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4384 if ( wxDynamicCast(window
, wxScrollBar
) )
4386 // we only set the width of vert scrollbars and height of the
4388 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4389 size
->y
= m_sizeScrollbarArrow
.y
;
4391 size
->x
= m_sizeScrollbarArrow
.x
;
4393 // skip border width adjustments, they don't make sense for us
4396 #endif // wxUSE_SCROLLBAR
4399 if ( wxDynamicCast(window
, wxBitmapButton
) )
4403 #endif // wxUSE_BMPBUTTON
4404 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
4407 || wxDynamicCast(window
, wxButton
)
4408 # endif // wxUSE_BUTTON
4409 # if wxUSE_TOGGLEBTN
4410 || wxDynamicCast(window
, wxToggleButton
)
4411 # endif // wxUSE_TOGGLEBTN
4414 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4416 // TODO: don't harcode all this
4417 size
->x
+= 3*window
->GetCharWidth();
4419 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4420 if ( size
->y
< heightBtn
- 8 )
4421 size
->y
= heightBtn
;
4426 // for compatibility with other ports, the buttons default size is never
4427 // less than the standard one, but not when display not PDAs.
4428 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4430 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4432 wxSize szDef
= wxButton::GetDefaultSize();
4433 if ( size
->x
< szDef
.x
)
4438 // no border width adjustments for buttons
4441 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
4443 // take into account the border width
4444 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4445 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4446 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4449 // ============================================================================
4451 // ============================================================================
4453 // ----------------------------------------------------------------------------
4454 // wxWin32InputHandler
4455 // ----------------------------------------------------------------------------
4457 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4458 const wxKeyEvent
& WXUNUSED(event
),
4459 bool WXUNUSED(pressed
))
4464 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4465 const wxMouseEvent
& event
)
4467 // clicking on the control gives it focus
4468 if ( event
.ButtonDown() )
4470 wxWindow
*win
= control
->GetInputWindow();
4472 if ( (wxWindow::FindFocus() != control
->GetInputWindow()) &&
4473 win
->AcceptsFocus() )
4486 // ----------------------------------------------------------------------------
4487 // wxWin32ScrollBarInputHandler
4488 // ----------------------------------------------------------------------------
4490 wxWin32ScrollBarInputHandler::
4491 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
4492 : wxStdScrollBarInputHandler(renderer
, handler
)
4494 m_scrollPaused
= false;
4498 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4499 const wxControlAction
& action
)
4501 // stop if went beyond the position of the original click (this can only
4502 // happen when we scroll by pages)
4504 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4506 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4507 != wxHT_SCROLLBAR_BAR_2
;
4509 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4511 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4512 != wxHT_SCROLLBAR_BAR_1
;
4517 StopScrolling(scrollbar
);
4519 scrollbar
->Refresh();
4524 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4527 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4528 const wxMouseEvent
& event
)
4530 // remember the current state
4531 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4533 // do process the message
4534 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4536 // analyse the changes
4537 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4539 // we just started dragging the thumb, remember its initial position to
4540 // be able to restore it if the drag is cancelled later
4541 m_eventStartDrag
= event
;
4547 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4548 const wxMouseEvent
& event
)
4550 // we don't highlight scrollbar elements, so there is no need to process
4551 // mouse move events normally - only do it while mouse is captured (i.e.
4552 // when we're dragging the thumb or pressing on something)
4553 if ( !m_winCapture
)
4556 if ( event
.Entering() )
4558 // we're not interested in this at all
4562 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4564 if ( m_scrollPaused
)
4566 // check if the mouse returned to its original location
4568 if ( event
.Leaving() )
4574 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4575 if ( ht
== m_htLast
)
4577 // yes it did, resume scrolling
4578 m_scrollPaused
= false;
4579 if ( m_timerScroll
)
4581 // we were scrolling by line/page, restart timer
4582 m_timerScroll
->Start(m_interval
);
4584 Press(scrollbar
, true);
4586 else // we were dragging the thumb
4588 // restore its last location
4589 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4595 else // normal case, scrolling hasn't been paused
4597 // if we're scrolling the scrollbar because the arrow or the shaft was
4598 // pressed, check that the mouse stays on the same scrollbar element
4601 // Always let thumb jump back if we leave the scrollbar
4602 if ( event
.Moving() )
4604 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4606 else // event.Leaving()
4611 // Jump back only if we get far away from it
4612 wxPoint pos
= event
.GetPosition();
4613 if (scrollbar
->HasFlag( wxVERTICAL
))
4615 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4620 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4623 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4626 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4627 // is still ok - we only want to catch the case when the mouse leaves
4628 // the scrollbar here
4629 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4631 ht
= wxHT_SCROLLBAR_THUMB
;
4634 if ( ht
!= m_htLast
)
4636 // what were we doing? 2 possibilities: either an arrow/shaft was
4637 // pressed in which case we have a timer and so we just stop it or
4638 // we were dragging the thumb
4639 if ( m_timerScroll
)
4642 m_interval
= m_timerScroll
->GetInterval();
4643 m_timerScroll
->Stop();
4644 m_scrollPaused
= true;
4646 // unpress the arrow
4647 Press(scrollbar
, false);
4649 else // we were dragging the thumb
4651 // remember the current thumb position to be able to restore it
4652 // if the mouse returns to it later
4653 m_eventLastDrag
= event
;
4655 // and restore the original position (before dragging) of the
4657 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4664 return wxStdInputHandler::HandleMouseMove(control
, event
);
4667 #endif // wxUSE_SCROLLBAR
4671 // ----------------------------------------------------------------------------
4672 // wxWin32CheckboxInputHandler
4673 // ----------------------------------------------------------------------------
4675 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4676 const wxKeyEvent
& event
,
4681 wxControlAction action
;
4682 int keycode
= event
.GetKeyCode();
4686 action
= wxACTION_CHECKBOX_TOGGLE
;
4690 case WXK_NUMPAD_SUBTRACT
:
4691 action
= wxACTION_CHECKBOX_CHECK
;
4695 case WXK_NUMPAD_ADD
:
4696 case WXK_NUMPAD_EQUAL
:
4697 action
= wxACTION_CHECKBOX_CLEAR
;
4701 if ( !action
.IsEmpty() )
4703 control
->PerformAction(action
);
4712 #endif // wxUSE_CHECKBOX
4716 // ----------------------------------------------------------------------------
4717 // wxWin32TextCtrlInputHandler
4718 // ----------------------------------------------------------------------------
4720 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4721 const wxKeyEvent
& event
,
4724 // handle only MSW-specific text bindings here, the others are handled in
4728 int keycode
= event
.GetKeyCode();
4730 wxControlAction action
;
4731 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4733 action
= wxACTION_TEXT_CUT
;
4735 else if ( keycode
== WXK_INSERT
)
4737 if ( event
.ControlDown() )
4738 action
= wxACTION_TEXT_COPY
;
4739 else if ( event
.ShiftDown() )
4740 action
= wxACTION_TEXT_PASTE
;
4743 if ( action
!= wxACTION_NONE
)
4745 control
->PerformAction(action
);
4751 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
4754 #endif // wxUSE_TEXTCTRL
4758 // ----------------------------------------------------------------------------
4759 // wxWin32StatusBarInputHandler
4760 // ----------------------------------------------------------------------------
4762 wxWin32StatusBarInputHandler::
4763 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4764 : wxStdInputHandler(handler
)
4769 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4770 const wxPoint
& pt
) const
4772 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4773 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4776 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4778 wxCHECK_MSG( parentTLW
, false,
4779 _T("the status bar should be a child of a TLW") );
4781 // a maximized window can't be resized anyhow
4782 if ( !parentTLW
->IsMaximized() )
4784 // VZ: I think that the standard Windows behaviour is to only
4785 // show the resizing cursor when the mouse is on top of the
4786 // grip itself but apparently different Windows versions behave
4787 // differently (?) and it seems a better UI to allow resizing
4788 // the status bar even when the mouse is above the grip
4789 wxSize sizeSbar
= statbar
->GetSize();
4791 int diff
= sizeSbar
.x
- pt
.x
;
4792 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4799 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4800 const wxMouseEvent
& event
)
4802 if ( event
.Button(1) )
4804 if ( event
.ButtonDown(1) )
4806 wxWindow
*statbar
= consumer
->GetInputWindow();
4808 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4810 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4814 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4815 wxHT_TOPLEVEL_BORDER_SE
);
4817 statbar
->SetCursor(m_cursorOld
);
4825 return wxStdInputHandler::HandleMouse(consumer
, event
);
4828 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4829 const wxMouseEvent
& event
)
4831 wxWindow
*statbar
= consumer
->GetInputWindow();
4833 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4834 if ( isOnGrip
!= m_isOnGrip
)
4836 m_isOnGrip
= isOnGrip
;
4839 m_cursorOld
= statbar
->GetCursor();
4840 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4844 statbar
->SetCursor(m_cursorOld
);
4848 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4851 #endif // wxUSE_STATUSBAR
4853 // ----------------------------------------------------------------------------
4854 // wxWin32FrameInputHandler
4855 // ----------------------------------------------------------------------------
4857 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4860 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4862 void Attach(wxInputConsumer
*consumer
);
4866 DECLARE_EVENT_TABLE()
4867 void OnSystemMenu(wxCommandEvent
&event
);
4868 void OnCloseFrame(wxCommandEvent
&event
);
4869 void OnClose(wxCloseEvent
&event
);
4871 wxWin32FrameInputHandler
*m_inputHnd
;
4872 wxTopLevelWindow
*m_wnd
;
4874 wxAcceleratorTable m_oldAccelTable
;
4878 wxWin32SystemMenuEvtHandler::
4879 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
)
4881 m_inputHnd
= handler
;
4885 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4887 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4889 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4890 m_wnd
->PushEventHandler(this);
4893 // VS: This code relies on using generic implementation of
4894 // wxAcceleratorTable in wxUniv!
4895 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4896 m_oldAccelTable
= table
;
4897 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4898 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4899 m_wnd
->SetAcceleratorTable(table
);
4903 void wxWin32SystemMenuEvtHandler::Detach()
4908 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4910 m_wnd
->RemoveEventHandler(this);
4915 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4916 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4917 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4918 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4921 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4923 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4924 !m_wnd
->IsMaximized()) ?
4925 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4926 FRAME_BORDER_THICKNESS
;
4927 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4928 pt
.x
= -pt
.x
+ border
;
4929 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4932 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4933 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4937 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4938 #endif // wxUSE_MENUS
4941 m_wnd
->SetAcceleratorTable(table
);
4945 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4947 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4948 wxTOPLEVEL_BUTTON_CLOSE
);
4951 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4958 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4959 : wxStdInputHandler(handler
)
4961 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4964 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4966 if ( m_menuHandler
)
4968 m_menuHandler
->Detach();
4969 delete m_menuHandler
;
4973 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4974 const wxMouseEvent
& event
)
4976 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4978 wxTopLevelWindow
*tlw
=
4979 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4981 long hit
= tlw
->HitTest(event
.GetPosition());
4983 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4985 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4986 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4987 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4990 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4992 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4993 (event
.RightDown() &&
4994 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4995 hit
== wxHT_TOPLEVEL_ICON
)) )
4998 PopupSystemMenu(tlw
, event
.GetPosition());
4999 #endif // wxUSE_MENUS
5005 return wxStdInputHandler::HandleMouse(consumer
, event
);
5010 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
5011 const wxPoint
& pos
) const
5013 wxMenu
*menu
= new wxMenu
;
5015 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
5016 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
5017 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
5018 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
5019 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
5020 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
5021 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
5022 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
5023 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
5024 menu
->AppendSeparator();
5025 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
5027 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
5029 if ( window
->IsMaximized() )
5031 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
5032 menu
->Enable(wxID_MOVE_FRAME
, false);
5033 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
5034 menu
->Enable(wxID_RESIZE_FRAME
, false);
5037 menu
->Enable(wxID_RESTORE_FRAME
, false);
5040 window
->PopupMenu(menu
, pos
);
5044 #endif // wxUSE_MENUS
5046 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
5049 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
5051 // always detach if active frame changed:
5052 m_menuHandler
->Detach();
5056 m_menuHandler
->Attach(consumer
);
5060 return wxStdInputHandler::HandleActivation(consumer
, activated
);