1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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/listbox.h"
44 #include "wx/toolbar.h"
45 #include "wx/statusbr.h"
48 // for COLOR_* constants
49 #include "wx/msw/private.h"
53 #include "wx/notebook.h"
54 #include "wx/spinbutt.h"
55 #include "wx/settings.h"
57 #include "wx/artprov.h"
58 #include "wx/toplevel.h"
61 #include "wx/univ/scrtimer.h"
62 #include "wx/univ/renderer.h"
63 #include "wx/univ/inphand.h"
64 #include "wx/univ/colschem.h"
65 #include "wx/univ/theme.h"
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 static const int BORDER_THICKNESS
= 2;
73 // the offset between the label and focus rect around it
74 static const int FOCUS_RECT_OFFSET_X
= 1;
75 static const int FOCUS_RECT_OFFSET_Y
= 1;
77 static const int FRAME_BORDER_THICKNESS
= 3;
78 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
79 static const int FRAME_TITLEBAR_HEIGHT
= 18;
80 static const int FRAME_BUTTON_WIDTH
= 16;
81 static const int FRAME_BUTTON_HEIGHT
= 14;
83 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
84 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
85 static const size_t STATUSBAR_GRIP_SIZE
=
86 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
88 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
89 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
90 static const wxCoord SLIDER_TICK_LENGTH
= 6;
102 IndicatorState_Normal
,
103 IndicatorState_Pressed
, // this one is for check/radioboxes
104 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
105 IndicatorState_Disabled
,
106 IndicatorState_SelectedDisabled
, // only for the menus
112 IndicatorStatus_Checked
,
113 IndicatorStatus_Unchecked
,
114 IndicatorStatus_Undeterminated
,
118 // wxWin32Renderer: draw the GUI elements in Win32 style
119 // ----------------------------------------------------------------------------
121 class wxWin32Renderer
: public wxRenderer
125 enum wxArrowDirection
140 Arrow_InvertedDisabled
,
144 enum wxFrameButtonType
147 FrameButton_Minimize
,
148 FrameButton_Maximize
,
155 wxWin32Renderer(const wxColourScheme
*scheme
);
157 // implement the base class pure virtuals
158 virtual void DrawBackground(wxDC
& dc
,
162 wxWindow
*window
= NULL
);
163 virtual void DrawLabel(wxDC
& dc
,
164 const wxString
& label
,
167 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
169 wxRect
*rectBounds
= NULL
);
170 virtual void DrawButtonLabel(wxDC
& dc
,
171 const wxString
& label
,
172 const wxBitmap
& image
,
175 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
177 wxRect
*rectBounds
= NULL
);
178 virtual void DrawBorder(wxDC
& dc
,
182 wxRect
*rectIn
= (wxRect
*)NULL
);
183 virtual void DrawHorizontalLine(wxDC
& dc
,
184 wxCoord y
, wxCoord x1
, wxCoord x2
);
185 virtual void DrawVerticalLine(wxDC
& dc
,
186 wxCoord x
, wxCoord y1
, wxCoord y2
);
187 virtual void DrawFrame(wxDC
& dc
,
188 const wxString
& label
,
191 int alignment
= wxALIGN_LEFT
,
192 int indexAccel
= -1);
193 virtual void DrawTextBorder(wxDC
& dc
,
197 wxRect
*rectIn
= (wxRect
*)NULL
);
198 virtual void DrawButtonBorder(wxDC
& dc
,
201 wxRect
*rectIn
= (wxRect
*)NULL
);
202 virtual void DrawArrow(wxDC
& dc
,
206 virtual void DrawScrollbarArrow(wxDC
& dc
,
210 { DrawArrow(dc
, dir
, rect
, flags
); }
211 virtual void DrawScrollbarThumb(wxDC
& dc
,
212 wxOrientation orient
,
215 virtual void DrawScrollbarShaft(wxDC
& dc
,
216 wxOrientation orient
,
219 virtual void DrawScrollCorner(wxDC
& dc
,
221 virtual void DrawItem(wxDC
& dc
,
222 const wxString
& label
,
225 virtual void DrawCheckItem(wxDC
& dc
,
226 const wxString
& label
,
227 const wxBitmap
& bitmap
,
230 virtual void DrawCheckButton(wxDC
& dc
,
231 const wxString
& label
,
232 const wxBitmap
& bitmap
,
235 wxAlignment align
= wxALIGN_LEFT
,
236 int indexAccel
= -1);
237 virtual void DrawRadioButton(wxDC
& dc
,
238 const wxString
& label
,
239 const wxBitmap
& bitmap
,
242 wxAlignment align
= wxALIGN_LEFT
,
243 int indexAccel
= -1);
244 virtual void DrawToolBarButton(wxDC
& dc
,
245 const wxString
& label
,
246 const wxBitmap
& bitmap
,
250 virtual void DrawTextLine(wxDC
& dc
,
251 const wxString
& text
,
256 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
257 virtual void DrawTab(wxDC
& dc
,
260 const wxString
& label
,
261 const wxBitmap
& bitmap
= wxNullBitmap
,
263 int indexAccel
= -1);
265 virtual void DrawSliderShaft(wxDC
& dc
,
268 wxOrientation orient
,
271 wxRect
*rectShaft
= NULL
);
272 virtual void DrawSliderThumb(wxDC
& dc
,
274 wxOrientation orient
,
277 virtual void DrawSliderTicks(wxDC
& dc
,
280 wxOrientation orient
,
287 virtual void DrawMenuBarItem(wxDC
& dc
,
289 const wxString
& label
,
291 int indexAccel
= -1);
292 virtual void DrawMenuItem(wxDC
& dc
,
294 const wxMenuGeometryInfo
& geometryInfo
,
295 const wxString
& label
,
296 const wxString
& accel
,
297 const wxBitmap
& bitmap
= wxNullBitmap
,
299 int indexAccel
= -1);
300 virtual void DrawMenuSeparator(wxDC
& dc
,
302 const wxMenuGeometryInfo
& geomInfo
);
304 virtual void DrawStatusField(wxDC
& dc
,
306 const wxString
& label
,
307 int flags
= 0, int style
= 0);
310 virtual void DrawFrameTitleBar(wxDC
& dc
,
312 const wxString
& title
,
315 int specialButton
= 0,
316 int specialButtonFlags
= 0);
317 virtual void DrawFrameBorder(wxDC
& dc
,
320 virtual void DrawFrameBackground(wxDC
& dc
,
323 virtual void DrawFrameTitle(wxDC
& dc
,
325 const wxString
& title
,
327 virtual void DrawFrameIcon(wxDC
& dc
,
331 virtual void DrawFrameButton(wxDC
& dc
,
332 wxCoord x
, wxCoord y
,
335 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
336 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
337 virtual wxSize
GetFrameMinSize(int flags
) const;
338 virtual wxSize
GetFrameIconSize() const;
339 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
341 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
343 wxBitmap
*bmpPressed
,
344 wxBitmap
*bmpDisabled
);
346 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
347 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
348 virtual bool AreScrollbarsInsideBorder() const;
350 virtual wxSize
GetScrollbarArrowSize() const
351 { return m_sizeScrollbarArrow
; }
352 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
353 wxScrollBar::Element elem
,
354 int thumbPos
= -1) const;
355 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
356 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
357 const wxPoint
& pt
) const;
358 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
360 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
361 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
362 { return fontHeight
+ 2; }
363 virtual wxSize
GetCheckBitmapSize() const
364 { return wxSize(13, 13); }
365 virtual wxSize
GetRadioBitmapSize() const
366 { return wxSize(12, 12); }
367 virtual wxCoord
GetCheckItemMargin() const
370 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
371 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
372 virtual wxSize
GetToolBarMargin() const
373 { return wxSize(4, 4); }
375 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
376 const wxRect
& rect
) const;
377 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
379 wxCoord
*extraSpaceBeyond
) const;
381 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
382 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
384 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
385 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
386 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
388 wxOrientation orient
,
389 long style
= 0) const;
390 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
392 wxOrientation orient
) const;
393 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
395 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
396 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
397 const wxMenu
& menu
) const;
399 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
402 // helper of DrawLabel() and DrawCheckOrRadioButton()
403 void DoDrawLabel(wxDC
& dc
,
404 const wxString
& label
,
407 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
409 wxRect
*rectBounds
= NULL
,
410 const wxPoint
& focusOffset
411 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
413 // common part of DrawLabel() and DrawItem()
414 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
416 // DrawLabel() and DrawButtonLabel() helper
417 void DrawLabelShadow(wxDC
& dc
,
418 const wxString
& label
,
423 // DrawButtonBorder() helper
424 void DoDrawBackground(wxDC
& dc
,
427 wxWindow
*window
= NULL
);
429 // DrawBorder() helpers: all of them shift and clip the DC after drawing
432 // just draw a rectangle with the given pen
433 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
435 // draw the lower left part of rectangle
436 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
438 // draw the rectange using the first brush for the left and top sides and
439 // the second one for the bottom and right ones
440 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
441 const wxPen
& pen1
, const wxPen
& pen2
);
443 // draw the normal 3D border
444 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
446 // draw the sunken 3D border
447 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
449 // draw the border used for scrollbar arrows
450 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
452 // public DrawArrow()s helper
453 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
454 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
456 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
457 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
458 wxArrowDirection arrowDir
,
459 wxArrowStyle arrowStyle
);
461 // DrawCheckButton/DrawRadioButton helper
462 void DrawCheckOrRadioButton(wxDC
& dc
,
463 const wxString
& label
,
464 const wxBitmap
& bitmap
,
469 wxCoord focusOffsetY
);
471 // draw a normal or transposed line (useful for using the same code fo both
472 // horizontal and vertical widgets)
473 void DrawLine(wxDC
& dc
,
474 wxCoord x1
, wxCoord y1
,
475 wxCoord x2
, wxCoord y2
,
476 bool transpose
= false)
479 dc
.DrawLine(y1
, x1
, y2
, x2
);
481 dc
.DrawLine(x1
, y1
, x2
, y2
);
484 // get the standard check/radio button bitmap
485 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
486 wxBitmap
GetCheckBitmap(int flags
)
487 { return GetIndicator(IndicatorType_Check
, flags
); }
488 wxBitmap
GetRadioBitmap(int flags
)
489 { return GetIndicator(IndicatorType_Radio
, flags
); }
492 const wxColourScheme
*m_scheme
;
494 // the sizing parameters (TODO make them changeable)
495 wxSize m_sizeScrollbarArrow
;
497 // GDI objects we use for drawing
498 wxColour m_colDarkGrey
,
506 wxFont m_titlebarFont
;
508 // the checked and unchecked bitmaps for DrawCheckItem()
509 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
511 // the bitmaps returned by GetIndicator()
512 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
514 [IndicatorStatus_Max
];
517 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
519 // first row is for the normal state, second - for the disabled
520 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
523 // ----------------------------------------------------------------------------
524 // wxWin32InputHandler and derived classes: process the keyboard and mouse
525 // messages according to Windows standards
526 // ----------------------------------------------------------------------------
528 class wxWin32InputHandler
: public wxInputHandler
531 wxWin32InputHandler(wxWin32Renderer
*renderer
);
533 virtual bool HandleKey(wxInputConsumer
*control
,
534 const wxKeyEvent
& event
,
536 virtual bool HandleMouse(wxInputConsumer
*control
,
537 const wxMouseEvent
& event
);
540 wxWin32Renderer
*m_renderer
;
543 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
546 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
547 wxInputHandler
*handler
);
549 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
550 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
552 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
553 const wxControlAction
& action
);
556 virtual bool IsAllowedButton(int button
) { return button
== 1; }
558 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
561 // we don't highlight anything
564 // the first and last event which caused the thumb to move
565 wxMouseEvent m_eventStartDrag
,
568 // have we paused the scrolling because the mouse moved?
571 // we remember the interval of the timer to be able to restart it
575 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
578 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
579 : wxStdCheckboxInputHandler(handler
) { }
581 virtual bool HandleKey(wxInputConsumer
*control
,
582 const wxKeyEvent
& event
,
586 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
589 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
590 : wxStdTextCtrlInputHandler(handler
) { }
592 virtual bool HandleKey(wxInputConsumer
*control
,
593 const wxKeyEvent
& event
,
597 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
600 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
602 virtual bool HandleMouse(wxInputConsumer
*consumer
,
603 const wxMouseEvent
& event
);
605 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
606 const wxMouseEvent
& event
);
609 // is the given point over the statusbar grip?
610 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
613 // the cursor we had replaced with the resize one
614 wxCursor m_cursorOld
;
616 // was the mouse over the grip last time we checked?
620 class wxWin32SystemMenuEvtHandler
;
622 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
625 wxWin32FrameInputHandler(wxInputHandler
*handler
);
626 ~wxWin32FrameInputHandler();
628 virtual bool HandleMouse(wxInputConsumer
*control
,
629 const wxMouseEvent
& event
);
631 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
633 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
636 // was the mouse over the grip last time we checked?
637 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
640 // ----------------------------------------------------------------------------
641 // wxWin32ColourScheme: uses (default) Win32 colours
642 // ----------------------------------------------------------------------------
644 class wxWin32ColourScheme
: public wxColourScheme
647 virtual wxColour
Get(StdColour col
) const;
648 virtual wxColour
GetBackground(wxWindow
*win
) const;
651 // ----------------------------------------------------------------------------
652 // wxWin32ArtProvider
653 // ----------------------------------------------------------------------------
655 class wxWin32ArtProvider
: public wxArtProvider
658 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
659 const wxArtClient
& client
,
663 // ----------------------------------------------------------------------------
665 // ----------------------------------------------------------------------------
667 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
669 class wxWin32Theme
: public wxTheme
673 virtual ~wxWin32Theme();
675 virtual wxRenderer
*GetRenderer();
676 virtual wxArtProvider
*GetArtProvider();
677 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
678 virtual wxColourScheme
*GetColourScheme();
681 // get the default input handler
682 wxInputHandler
*GetDefaultInputHandler();
684 wxWin32Renderer
*m_renderer
;
686 wxWin32ArtProvider
*m_artProvider
;
688 // the names of the already created handlers and the handlers themselves
689 // (these arrays are synchronized)
690 wxSortedArrayString m_handlerNames
;
691 wxArrayHandlers m_handlers
;
693 wxWin32InputHandler
*m_handlerDefault
;
695 wxWin32ColourScheme
*m_scheme
;
697 WX_DECLARE_THEME(win32
)
700 // ----------------------------------------------------------------------------
702 // ----------------------------------------------------------------------------
704 // frame buttons bitmaps
706 static const char *frame_button_close_xpm
[] = {
721 static const char *frame_button_help_xpm
[] = {
736 static const char *frame_button_maximize_xpm
[] = {
751 static const char *frame_button_minimize_xpm
[] = {
766 static const char *frame_button_restore_xpm
[] = {
783 static const char *checked_menu_xpm
[] = {
784 /* columns rows colors chars-per-pixel */
800 static const char *selected_checked_menu_xpm
[] = {
801 /* columns rows colors chars-per-pixel */
817 static const char *disabled_checked_menu_xpm
[] = {
818 /* columns rows colors chars-per-pixel */
835 static const char *selected_disabled_checked_menu_xpm
[] = {
836 /* columns rows colors chars-per-pixel */
852 // checkbox and radiobox bitmaps below
854 static const char *checked_xpm
[] = {
855 /* columns rows colors chars-per-pixel */
878 static const char *pressed_checked_xpm
[] = {
879 /* columns rows colors chars-per-pixel */
901 static const char *pressed_disabled_checked_xpm
[] = {
902 /* columns rows colors chars-per-pixel */
924 static const char *checked_item_xpm
[] = {
925 /* columns rows colors chars-per-pixel */
946 static const char *unchecked_xpm
[] = {
947 /* columns rows colors chars-per-pixel */
970 static const char *pressed_unchecked_xpm
[] = {
971 /* columns rows colors chars-per-pixel */
993 static const char *unchecked_item_xpm
[] = {
994 /* columns rows colors chars-per-pixel */
1014 static const char *undetermined_xpm
[] = {
1015 /* columns rows colors chars-per-pixel */
1038 static const char *pressed_undetermined_xpm
[] = {
1039 /* columns rows colors chars-per-pixel */
1062 static const char *checked_radio_xpm
[] = {
1063 /* columns rows colors chars-per-pixel */
1086 static const char *pressed_checked_radio_xpm
[] = {
1087 /* columns rows colors chars-per-pixel */
1110 static const char *pressed_disabled_checked_radio_xpm
[] = {
1111 /* columns rows colors chars-per-pixel */
1134 static const char *unchecked_radio_xpm
[] = {
1135 /* columns rows colors chars-per-pixel */
1158 static const char *pressed_unchecked_radio_xpm
[] = {
1159 /* columns rows colors chars-per-pixel */
1182 static const char **
1183 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1188 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1191 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1194 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1200 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1203 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1206 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1212 { checked_menu_xpm
, NULL
, NULL
},
1215 { selected_checked_menu_xpm
, NULL
, NULL
},
1218 { disabled_checked_menu_xpm
, NULL
, NULL
},
1220 // disabled selected state
1221 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1225 static const char **xpmChecked
[IndicatorStatus_Max
] =
1231 // ============================================================================
1233 // ============================================================================
1235 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1237 // ----------------------------------------------------------------------------
1239 // ----------------------------------------------------------------------------
1241 wxWin32Theme::wxWin32Theme()
1245 m_handlerDefault
= NULL
;
1246 m_artProvider
= NULL
;
1249 wxWin32Theme::~wxWin32Theme()
1251 size_t count
= m_handlers
.GetCount();
1252 for ( size_t n
= 0; n
< count
; n
++ )
1254 if ( m_handlers
[n
] != m_handlerDefault
)
1255 delete m_handlers
[n
];
1258 delete m_handlerDefault
;
1262 wxArtProvider::RemoveProvider(m_artProvider
);
1265 wxRenderer
*wxWin32Theme::GetRenderer()
1269 m_renderer
= new wxWin32Renderer(GetColourScheme());
1275 wxArtProvider
*wxWin32Theme::GetArtProvider()
1277 if ( !m_artProvider
)
1279 m_artProvider
= new wxWin32ArtProvider
;
1282 return m_artProvider
;
1285 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1287 if ( !m_handlerDefault
)
1289 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1292 return m_handlerDefault
;
1295 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1297 wxInputHandler
*handler
;
1298 int n
= m_handlerNames
.Index(control
);
1299 if ( n
== wxNOT_FOUND
)
1301 // create a new handler
1302 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1303 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1304 GetDefaultInputHandler());
1306 else if ( control
== wxINP_HANDLER_BUTTON
)
1307 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1308 #endif // wxUSE_BUTTON
1310 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1311 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1312 #endif // wxUSE_CHECKBOX
1314 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1315 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1316 #endif // wxUSE_COMBOBOX
1318 else if ( control
== wxINP_HANDLER_LISTBOX
)
1319 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1320 #endif // wxUSE_LISTBOX
1321 #if wxUSE_CHECKLISTBOX
1322 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1323 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1324 #endif // wxUSE_CHECKLISTBOX
1326 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1327 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1328 #endif // wxUSE_TEXTCTRL
1330 else if ( control
== wxINP_HANDLER_SLIDER
)
1331 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1332 #endif // wxUSE_SLIDER
1334 else if ( control
== wxINP_HANDLER_SPINBTN
)
1335 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1336 #endif // wxUSE_SPINBTN
1338 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1339 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1340 #endif // wxUSE_NOTEBOOK
1342 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1343 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1344 #endif // wxUSE_STATUSBAR
1346 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1347 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1348 #endif // wxUSE_TOOLBAR
1349 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1350 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1352 handler
= GetDefaultInputHandler();
1354 n
= m_handlerNames
.Add(control
);
1355 m_handlers
.Insert(handler
, n
);
1357 else // we already have it
1359 handler
= m_handlers
[n
];
1365 wxColourScheme
*wxWin32Theme::GetColourScheme()
1369 m_scheme
= new wxWin32ColourScheme
;
1374 // ============================================================================
1375 // wxWin32ColourScheme
1376 // ============================================================================
1378 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1381 if ( win
->UseBgCol() )
1383 // use the user specified colour
1384 col
= win
->GetBackgroundColour();
1387 if ( !win
->ShouldInheritColours() )
1389 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1391 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1399 if ( !win
->IsEnabled() ) // not IsEditable()
1405 // doesn't depend on the state
1412 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1416 int flags
= win
->GetStateFlags();
1418 // the colour set by the user should be used for the normal state
1419 // and for the states for which we don't have any specific colours
1420 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1422 if ( wxDynamicCast(win
, wxScrollBar
) )
1423 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1433 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1437 // use the system colours under Windows
1438 #if defined(__WXMSW__)
1439 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1441 case CONTROL_PRESSED
:
1442 case CONTROL_CURRENT
:
1443 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1445 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1447 #if defined(COLOR_3DLIGHT)
1448 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1450 case SCROLLBAR
: return wxColour(0xe0e0e0);
1452 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1454 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1455 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1457 #if defined(COLOR_3DDKSHADOW)
1458 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1460 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1463 case CONTROL_TEXT_DISABLED
:
1464 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1466 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1468 case CONTROL_TEXT_DISABLED_SHADOW
:
1469 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1471 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1472 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1473 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1474 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1476 case DESKTOP
: return wxColour(0x808000);
1478 // use the standard Windows colours elsewhere
1479 case WINDOW
: return *wxWHITE
;
1481 case CONTROL_PRESSED
:
1482 case CONTROL_CURRENT
:
1483 case CONTROL
: return wxColour(0xc0c0c0);
1485 case CONTROL_TEXT
: return *wxBLACK
;
1487 case SCROLLBAR
: return wxColour(0xe0e0e0);
1488 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1490 case HIGHLIGHT
: return wxColour(0x800000);
1491 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1493 case SHADOW_DARK
: return *wxBLACK
;
1495 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1496 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1498 case SHADOW_IN
: return wxColour(0xc0c0c0);
1500 case CONTROL_TEXT_DISABLED_SHADOW
:
1501 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1503 case TITLEBAR
: return wxColour(0xaeaaae);
1504 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1505 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1506 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1508 case DESKTOP
: return wxColour(0x808000);
1511 case GAUGE
: return Get(HIGHLIGHT
);
1515 wxFAIL_MSG(_T("invalid standard colour"));
1520 // ============================================================================
1522 // ============================================================================
1524 // ----------------------------------------------------------------------------
1526 // ----------------------------------------------------------------------------
1528 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1532 m_sizeScrollbarArrow
= wxSize(16, 16);
1534 // init colours and pens
1535 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1537 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1538 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1540 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1542 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1543 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1545 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1546 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1548 // init the arrow bitmaps
1549 static const size_t ARROW_WIDTH
= 7;
1550 static const size_t ARROW_LENGTH
= 4;
1553 wxMemoryDC dcNormal
,
1556 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1558 bool isVertical
= n
> Arrow_Right
;
1571 // disabled arrow is larger because of the shadow
1572 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1573 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1575 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1576 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1578 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1579 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1583 dcNormal
.SetPen(m_penBlack
);
1584 dcDisabled
.SetPen(m_penDarkGrey
);
1586 // calculate the position of the point of the arrow
1590 x1
= (ARROW_WIDTH
- 1)/2;
1591 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1595 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1596 y1
= (ARROW_WIDTH
- 1)/2;
1607 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1609 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1610 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1617 if ( n
== Arrow_Up
)
1628 else // left or right arrow
1633 if ( n
== Arrow_Left
)
1646 // draw the shadow for the disabled one
1647 dcDisabled
.SetPen(m_penHighlight
);
1652 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1656 x1
= ARROW_LENGTH
- 1;
1657 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1660 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1661 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1666 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1670 x1
= ARROW_WIDTH
- 1;
1672 x2
= (ARROW_WIDTH
- 1)/2;
1674 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1675 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1680 // create the inverted bitmap but only for the right arrow as we only
1681 // use it for the menus
1682 if ( n
== Arrow_Right
)
1684 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1685 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1687 dcInverse
.Blit(0, 0, w
, h
,
1690 dcInverse
.SelectObject(wxNullBitmap
);
1692 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1693 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1695 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1696 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1698 dcInverse
.Blit(0, 0, w
, h
,
1701 dcInverse
.SelectObject(wxNullBitmap
);
1703 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1704 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1707 dcNormal
.SelectObject(wxNullBitmap
);
1708 dcDisabled
.SelectObject(wxNullBitmap
);
1710 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1711 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1712 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1713 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1715 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1718 // init the frame buttons bitmaps
1719 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1720 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1721 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1722 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1723 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1726 // ----------------------------------------------------------------------------
1728 // ----------------------------------------------------------------------------
1731 The raised border in Win32 looks like this:
1733 IIIIIIIIIIIIIIIIIIIIIIB
1735 I GB I = white (HILIGHT)
1736 I GB H = light grey (LIGHT)
1737 I GB G = dark grey (SHADOI)
1738 I GB B = black (DKSHADOI)
1739 I GB I = hIghlight (COLOR_3DHILIGHT)
1741 IGGGGGGGGGGGGGGGGGGGGGB
1742 BBBBBBBBBBBBBBBBBBBBBBB
1744 The sunken border looks like this:
1746 GGGGGGGGGGGGGGGGGGGGGGI
1747 GBBBBBBBBBBBBBBBBBBBBHI
1754 GHHHHHHHHHHHHHHHHHHHHHI
1755 IIIIIIIIIIIIIIIIIIIIIII
1757 The static border (used for the controls which don't get focus) is like
1760 GGGGGGGGGGGGGGGGGGGGGGW
1768 WWWWWWWWWWWWWWWWWWWWWWW
1770 The most complicated is the double border:
1772 HHHHHHHHHHHHHHHHHHHHHHB
1773 HWWWWWWWWWWWWWWWWWWWWGB
1774 HWHHHHHHHHHHHHHHHHHHHGB
1779 HWHHHHHHHHHHHHHHHHHHHGB
1780 HGGGGGGGGGGGGGGGGGGGGGB
1781 BBBBBBBBBBBBBBBBBBBBBBB
1783 And the simple border is, well, simple:
1785 BBBBBBBBBBBBBBBBBBBBBBB
1794 BBBBBBBBBBBBBBBBBBBBBBB
1797 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1801 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1802 dc
.DrawRectangle(*rect
);
1808 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1810 // draw the bottom and right sides
1812 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1813 rect
->GetRight() + 1, rect
->GetBottom());
1814 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1815 rect
->GetRight(), rect
->GetBottom());
1821 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1822 const wxPen
& pen1
, const wxPen
& pen2
)
1824 // draw the rectangle
1826 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1827 rect
->GetLeft(), rect
->GetBottom());
1828 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1829 rect
->GetRight(), rect
->GetTop());
1831 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1832 rect
->GetRight(), rect
->GetBottom());
1833 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1834 rect
->GetRight() + 1, rect
->GetBottom());
1840 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1842 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1843 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1846 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1848 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1849 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1852 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1856 DrawRect(dc
, rect
, m_penDarkGrey
);
1858 // the arrow is usually drawn inside border of width 2 and is offset by
1859 // another pixel in both directions when it's pressed - as the border
1860 // in this case is more narrow as well, we have to adjust rect like
1868 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1869 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1873 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1875 const wxRect
& rectTotal
,
1876 int WXUNUSED(flags
),
1881 wxRect rect
= rectTotal
;
1885 case wxBORDER_SUNKEN
:
1886 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1888 DrawSunkenBorder(dc
, &rect
);
1892 case wxBORDER_STATIC
:
1893 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1896 case wxBORDER_RAISED
:
1897 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1899 DrawRaisedBorder(dc
, &rect
);
1903 case wxBORDER_DOUBLE
:
1904 DrawArrowBorder(dc
, &rect
);
1905 DrawRect(dc
, &rect
, m_penLightGrey
);
1908 case wxBORDER_SIMPLE
:
1909 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1911 DrawRect(dc
, &rect
, m_penBlack
);
1916 wxFAIL_MSG(_T("unknown border type"));
1919 case wxBORDER_DEFAULT
:
1928 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1933 case wxBORDER_RAISED
:
1934 case wxBORDER_SUNKEN
:
1935 width
= BORDER_THICKNESS
;
1938 case wxBORDER_SIMPLE
:
1939 case wxBORDER_STATIC
:
1943 case wxBORDER_DOUBLE
:
1949 // char *crash = NULL;
1951 wxFAIL_MSG(_T("unknown border type"));
1955 case wxBORDER_DEFAULT
:
1965 rect
.height
= width
;
1970 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1975 // ----------------------------------------------------------------------------
1977 // ----------------------------------------------------------------------------
1979 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1985 // text controls are not special under windows
1986 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1989 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1990 const wxRect
& rectTotal
,
1994 wxRect rect
= rectTotal
;
1996 if ( flags
& wxCONTROL_PRESSED
)
1998 // button pressed: draw a double border around it
1999 DrawRect(dc
, &rect
, m_penBlack
);
2000 DrawRect(dc
, &rect
, m_penDarkGrey
);
2004 // button not pressed
2006 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
2008 // button either default or focused (or both): add an extra border around it
2009 DrawRect(dc
, &rect
, m_penBlack
);
2012 // now draw a normal button
2013 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
2014 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
2023 // ----------------------------------------------------------------------------
2025 // ----------------------------------------------------------------------------
2027 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
2028 wxCoord y
, wxCoord x1
, wxCoord x2
)
2030 dc
.SetPen(m_penDarkGrey
);
2031 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2032 dc
.SetPen(m_penHighlight
);
2034 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2037 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
2038 wxCoord x
, wxCoord y1
, wxCoord y2
)
2040 dc
.SetPen(m_penDarkGrey
);
2041 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2042 dc
.SetPen(m_penHighlight
);
2044 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2047 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
2048 const wxString
& label
,
2054 wxCoord height
= 0; // of the label
2055 wxRect rectFrame
= rect
;
2056 if ( !label
.empty() )
2058 // the text should touch the top border of the rect, so the frame
2059 // itself should be lower
2060 dc
.GetTextExtent(label
, NULL
, &height
);
2061 rectFrame
.y
+= height
/ 2;
2062 rectFrame
.height
-= height
/ 2;
2064 // we have to draw each part of the frame individually as we can't
2065 // erase the background beyond the label as it might contain some
2066 // pixmap already, so drawing everything and then overwriting part of
2067 // the frame with label doesn't work
2069 // TODO: the +5 and space insertion should be customizable
2072 rectText
.x
= rectFrame
.x
+ 5;
2073 rectText
.y
= rect
.y
;
2074 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2075 rectText
.height
= height
;
2078 label2
<< _T(' ') << label
<< _T(' ');
2079 if ( indexAccel
!= -1 )
2081 // adjust it as we prepended a space
2086 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2088 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2092 // just draw the complete frame
2093 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2094 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2098 // ----------------------------------------------------------------------------
2100 // ----------------------------------------------------------------------------
2102 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2104 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2105 // pixels each while we really need dots here... PS_ALTERNATE might
2106 // work, but it is for NT 5 only
2108 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2110 // draw the pixels manually: note that to behave in the same manner as
2111 // DrawRect(), we must exclude the bottom and right borders from the
2113 wxCoord x1
= rect
.GetLeft(),
2115 x2
= rect
.GetRight(),
2116 y2
= rect
.GetBottom();
2118 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2120 // this seems to be closer than what Windows does than wxINVERT although
2121 // I'm still not sure if it's correct
2122 dc
.SetLogicalFunction(wxAND_REVERSE
);
2125 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2126 dc
.DrawPoint(z
, rect
.GetTop());
2128 wxCoord shift
= z
== x2
? 0 : 1;
2129 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2130 dc
.DrawPoint(x2
, z
);
2132 shift
= z
== y2
? 0 : 1;
2133 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2134 dc
.DrawPoint(z
, y2
);
2136 shift
= z
== x1
? 0 : 1;
2137 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2138 dc
.DrawPoint(x1
, z
);
2140 dc
.SetLogicalFunction(wxCOPY
);
2144 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2145 const wxString
& label
,
2150 // draw shadow of the text
2151 dc
.SetTextForeground(m_colHighlight
);
2152 wxRect rectShadow
= rect
;
2155 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2157 // make the text grey
2158 dc
.SetTextForeground(m_colDarkGrey
);
2161 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2162 const wxString
& label
,
2169 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2172 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2173 const wxString
& label
,
2179 const wxPoint
& focusOffset
)
2181 // the underscores are not drawn for focused controls in wxMSW
2182 if ( flags
& wxCONTROL_FOCUSED
)
2187 if ( flags
& wxCONTROL_DISABLED
)
2189 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2190 // currently only can happen for a menu item and it seems that Windows
2191 // doesn't draw the shadow in this case, so we don't do it neither
2192 if ( flags
& wxCONTROL_SELECTED
)
2194 // just make the label text greyed out
2195 dc
.SetTextForeground(m_colDarkGrey
);
2197 else // draw normal disabled label
2199 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2204 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2206 if ( flags
& wxCONTROL_DISABLED
)
2208 // restore the fg colour
2209 dc
.SetTextForeground(*wxBLACK
);
2212 if ( flags
& wxCONTROL_FOCUSED
)
2214 if ( focusOffset
.x
|| focusOffset
.y
)
2216 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2219 DrawFocusRect(dc
, rectLabel
);
2223 *rectBounds
= rectLabel
;
2226 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2227 const wxString
& label
,
2228 const wxBitmap
& image
,
2235 // the underscores are not drawn for focused controls in wxMSW
2236 if ( flags
& wxCONTROL_PRESSED
)
2241 wxRect rectLabel
= rect
;
2242 if ( !label
.empty() )
2244 // shift the label if a button is pressed
2245 if ( flags
& wxCONTROL_PRESSED
)
2251 if ( flags
& wxCONTROL_DISABLED
)
2253 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2256 // leave enough space for the focus rectangle
2257 if ( flags
& wxCONTROL_FOCUSED
)
2259 rectLabel
.Inflate(-2);
2263 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2265 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2267 if ( flags
& wxCONTROL_PRESSED
)
2269 // the focus rectangle is never pressed, so undo the shift done
2277 DrawFocusRect(dc
, rectLabel
);
2281 // ----------------------------------------------------------------------------
2282 // (check)listbox items
2283 // ----------------------------------------------------------------------------
2285 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2286 const wxString
& label
,
2290 wxDCTextColourChanger
colChanger(dc
);
2292 if ( flags
& wxCONTROL_SELECTED
)
2294 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2296 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2297 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2298 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2299 dc
.DrawRectangle(rect
);
2302 wxRect rectText
= rect
;
2304 rectText
.width
-= 2;
2305 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2307 if ( flags
& wxCONTROL_FOCUSED
)
2309 DrawFocusRect(dc
, rect
);
2313 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2314 const wxString
& label
,
2315 const wxBitmap
& bitmap
,
2324 else // use default bitmap
2326 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2327 ? IndicatorStatus_Checked
2328 : IndicatorStatus_Unchecked
;
2330 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2332 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2335 bmp
= m_bmpCheckBitmaps
[i
];
2338 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2339 true /* use mask */);
2341 wxRect rectLabel
= rect
;
2342 int bmpWidth
= bmp
.GetWidth();
2343 rectLabel
.x
+= bmpWidth
;
2344 rectLabel
.width
-= bmpWidth
;
2346 DrawItem(dc
, label
, rectLabel
, flags
);
2349 // ----------------------------------------------------------------------------
2350 // check/radio buttons
2351 // ----------------------------------------------------------------------------
2353 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2355 IndicatorState indState
;
2356 if ( flags
& wxCONTROL_SELECTED
)
2357 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2358 : IndicatorState_Selected
;
2359 else if ( flags
& wxCONTROL_DISABLED
)
2360 indState
= IndicatorState_Disabled
;
2361 else if ( flags
& wxCONTROL_PRESSED
)
2362 indState
= IndicatorState_Pressed
;
2364 indState
= IndicatorState_Normal
;
2366 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2367 ? IndicatorStatus_Checked
2368 : ( flags
& wxCONTROL_UNDETERMINED
2369 ? IndicatorStatus_Undeterminated
2370 : IndicatorStatus_Unchecked
);
2372 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2375 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2378 // create and cache it
2379 bmp
= wxBitmap(xpm
);
2380 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2387 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2388 const wxString
& label
,
2389 const wxBitmap
& bitmap
,
2394 wxCoord focusOffsetY
)
2396 // calculate the position of the bitmap and of the label
2397 wxCoord heightBmp
= bitmap
.GetHeight();
2399 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2402 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2403 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2405 // align label vertically with the bitmap - looks nicer like this
2406 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2408 // calc horz position
2409 if ( align
== wxALIGN_RIGHT
)
2411 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2412 rectLabel
.x
= rect
.x
+ 3;
2413 rectLabel
.SetRight(xBmp
);
2415 else // normal (checkbox to the left of the text) case
2418 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2419 rectLabel
.SetRight(rect
.GetRight());
2422 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2425 dc
, label
, rectLabel
,
2427 wxALIGN_LEFT
| wxALIGN_TOP
,
2429 NULL
, // we don't need bounding rect
2430 // use custom vert focus rect offset
2431 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2435 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2436 const wxString
& label
,
2437 const wxBitmap
& bitmap
,
2447 bmp
= GetRadioBitmap(flags
);
2449 DrawCheckOrRadioButton(dc
, label
,
2451 rect
, flags
, align
, indexAccel
,
2452 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2455 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2456 const wxString
& label
,
2457 const wxBitmap
& bitmap
,
2467 bmp
= GetCheckBitmap(flags
);
2469 DrawCheckOrRadioButton(dc
, label
,
2471 rect
, flags
, align
, indexAccel
,
2472 0); // no focus rect offset for checkboxes
2475 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2476 const wxString
& label
,
2477 const wxBitmap
& bitmap
,
2478 const wxRect
& rectOrig
,
2482 if (style
== wxTOOL_STYLE_BUTTON
)
2484 wxRect rect
= rectOrig
;
2485 rect
.Deflate(BORDER_THICKNESS
);
2487 if ( flags
& wxCONTROL_PRESSED
)
2489 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2491 else if ( flags
& wxCONTROL_CURRENT
)
2493 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2496 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2498 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2500 // leave a small gap aroudn the line, also account for the toolbar
2502 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2503 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2504 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2506 // don't draw wxTOOL_STYLE_CONTROL
2509 // ----------------------------------------------------------------------------
2511 // ----------------------------------------------------------------------------
2513 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2514 const wxString
& text
,
2520 // nothing special to do here
2521 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2525 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2526 const wxRect
& WXUNUSED(rect
))
2528 // we don't draw them
2531 // ----------------------------------------------------------------------------
2533 // ----------------------------------------------------------------------------
2535 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2536 const wxRect
& rectOrig
,
2538 const wxString
& label
,
2539 const wxBitmap
& bitmap
,
2543 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2544 #define REVERSE_FOR_VERTICAL(X,Y) \
2545 SELECT_FOR_VERTICAL(X,Y) \
2547 SELECT_FOR_VERTICAL(Y,X)
2549 wxRect rect
= rectOrig
;
2551 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2553 // the current tab is drawn indented (to the top for default case) and
2554 // bigger than the other ones
2555 const wxSize indent
= GetTabIndent();
2556 if ( flags
& wxCONTROL_SELECTED
)
2558 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
2559 SELECT_FOR_VERTICAL( 0, indent
.y
));
2563 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2570 rect
.height
+= indent
.y
;
2577 rect
.width
+= indent
.x
;
2582 // draw the text, image and the focus around them (if necessary)
2583 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2584 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2586 rectLabel
.Deflate(1, 1);
2589 // draw it horizontally into memory and rotate for screen
2591 wxBitmap bitmapRotated
,
2592 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2593 rectLabel
.y
+ rectLabel
.height
);
2594 dcMem
.SelectObject(bitmapMem
);
2595 dcMem
.SetBackground(dc
.GetBackground());
2596 dcMem
.SetFont(dc
.GetFont());
2597 dcMem
.SetTextForeground(dc
.GetTextForeground());
2599 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
2600 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2601 flags
, wxALIGN_CENTRE
, indexAccel
);
2602 dcMem
.SelectObject(wxNullBitmap
);
2603 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2604 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2605 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2609 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2610 flags
, wxALIGN_CENTRE
, indexAccel
);
2613 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2614 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2615 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2616 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2617 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2618 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2620 // FIXME: all this code will break if the tab indent or the border width,
2621 // it is tied to the fact that both of them are equal to 2
2627 // left orientation looks like top but IsVertical makes x and y reversed
2629 // top is not vertical so use coordinates in written order
2630 dc
.SetPen(m_penHighlight
);
2631 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2632 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2633 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2634 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2635 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2636 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2638 dc
.SetPen(m_penBlack
);
2639 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2640 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2641 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2642 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2644 dc
.SetPen(m_penDarkGrey
);
2645 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2646 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2648 if ( flags
& wxCONTROL_SELECTED
)
2650 dc
.SetPen(m_penLightGrey
);
2652 // overwrite the part of the border below this tab
2653 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2654 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2656 // and the shadow of the tab to the left of us
2657 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2658 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2663 // right orientation looks like bottom but IsVertical makes x and y reversed
2665 // bottom is not vertical so use coordinates in written order
2666 dc
.SetPen(m_penHighlight
);
2667 // we need to continue one pixel further to overwrite the corner of
2668 // the border for the selected tab
2669 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
2670 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2671 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2672 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2674 dc
.SetPen(m_penBlack
);
2675 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2676 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2677 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2678 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2679 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2680 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2682 dc
.SetPen(m_penDarkGrey
);
2683 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2684 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2685 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2686 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2688 if ( flags
& wxCONTROL_SELECTED
)
2690 dc
.SetPen(m_penLightGrey
);
2692 // overwrite the part of the (double!) border above this tab
2693 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2694 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2695 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2696 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2698 // and the shadow of the tab to the left of us
2699 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2700 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2705 #undef SELECT_FOR_VERTICAL
2706 #undef REVERSE_FOR_VERTICAL
2709 // ----------------------------------------------------------------------------
2711 // ----------------------------------------------------------------------------
2714 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2716 wxOrientation orient
) const
2719 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2720 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2722 if (orient
== wxHORIZONTAL
)
2736 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2738 wxOrientation orient
,
2741 bool transpose
= (orient
== wxVERTICAL
);
2742 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2743 (((style
& wxSL_TOP
) != 0) & !transpose
|
2744 ((style
& wxSL_LEFT
) != 0) & transpose
|
2745 ((style
& wxSL_BOTH
) != 0));
2746 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2747 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2748 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2749 ((style
& wxSL_BOTH
) != 0));
2751 wxRect rect
= rectOrig
;
2753 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2755 if (orient
== wxHORIZONTAL
) {
2756 rect
.x
+= SLIDER_MARGIN
;
2759 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2763 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2767 rect
.y
+= sizeThumb
.y
/2;
2769 rect
.width
-= 2*SLIDER_MARGIN
;
2770 rect
.height
= 2*BORDER_THICKNESS
;
2774 rect
.y
+= SLIDER_MARGIN
;
2777 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2781 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2785 rect
.x
+= sizeThumb
.x
/2;
2787 rect
.width
= 2*BORDER_THICKNESS
;
2788 rect
.height
-= 2*SLIDER_MARGIN
;
2794 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2795 const wxRect
& rectOrig
,
2797 wxOrientation orient
,
2802 /* show shaft geometry
2820 if (flags
& wxCONTROL_FOCUSED
) {
2821 DrawFocusRect(dc
, rectOrig
);
2824 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2826 if (rectShaft
) *rectShaft
= rect
;
2828 DrawSunkenBorder(dc
, &rect
);
2831 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2833 wxOrientation orient
,
2837 /* show thumb geometry
2846 H D B where H is highlight colour
2860 The interior of this shape is filled with the hatched brush if the thumb
2864 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2866 bool transpose
= (orient
== wxVERTICAL
);
2867 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2868 (((style
& wxSL_TOP
) != 0) & !transpose
|
2869 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2870 ((style
& wxSL_BOTH
) == 0);
2871 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2872 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2873 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2874 ((style
& wxSL_BOTH
) == 0);
2876 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2877 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2879 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2880 x1
= (transpose
? rect
.y
: rect
.x
);
2881 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2882 x3
= (x1
-1+c
) + sizeArrow
;
2883 y1
= (transpose
? rect
.x
: rect
.y
);
2884 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2885 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2886 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2888 dc
.SetPen(m_penBlack
);
2890 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2892 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2895 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2899 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2902 dc
.SetPen(m_penDarkGrey
);
2903 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2905 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2909 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2912 dc
.SetPen(m_penHighlight
);
2915 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2916 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2920 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2922 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2925 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2928 if (flags
& wxCONTROL_PRESSED
) {
2929 // TODO: MSW fills the entire area inside, not just the rect
2930 wxRect rectInt
= rect
;
2933 rectInt
.SetLeft(y3
);
2934 rectInt
.SetRight(y4
);
2939 rectInt
.SetBottom(y4
);
2943 #if !defined(__WXMGL__)
2944 static const char *stipple_xpm
[] = {
2945 /* columns rows colors chars-per-pixel */
2954 // VS: MGL can only do 8x8 stipple brushes
2955 static const char *stipple_xpm
[] = {
2956 /* columns rows colors chars-per-pixel */
2971 dc
.SetBrush(wxBrush(stipple_xpm
));
2973 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2974 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2975 dc
.SetPen(*wxTRANSPARENT_PEN
);
2976 dc
.DrawRectangle(rectInt
);
2980 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2983 wxOrientation orient
,
2987 int WXUNUSED(flags
),
2990 /* show ticks geometry
3005 if (end
== start
) return;
3007 bool transpose
= (orient
== wxVERTICAL
);
3008 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
3009 (((style
& wxSL_TOP
) != 0) & !transpose
|
3010 ((style
& wxSL_LEFT
) != 0) & transpose
|
3011 ((style
& wxSL_BOTH
) != 0));
3012 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
3013 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
3014 ((style
& wxSL_RIGHT
) != 0) & transpose
|
3015 ((style
& wxSL_BOTH
) != 0));
3017 // default thumb size
3018 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
3019 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
3021 // normal thumb size
3022 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
3023 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
3025 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
3027 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
3028 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
3029 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
3030 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
3031 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
3032 y3
= (transpose
? rect
.x
: rect
.y
);
3033 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
3036 dc
.SetPen(m_penBlack
);
3038 int range
= end
- start
;
3039 for ( int n
= 0; n
< range
; n
+= step
) {
3040 wxCoord x
= x1
+ (len
*n
) / range
;
3042 if (left
& (y1
> y3
)) {
3043 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
3045 if (right
& (y4
> y2
)) {
3046 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
3049 // always draw the line at the end position
3050 if (left
& (y1
> y3
)) {
3051 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3053 if (right
& (y4
> y2
)) {
3054 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3058 // ----------------------------------------------------------------------------
3060 // ----------------------------------------------------------------------------
3062 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3063 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3066 virtual wxSize
GetSize() const { return m_size
; }
3068 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3069 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3071 wxCoord
GetItemHeight() const { return m_heightItem
; }
3074 // the total size of the menu
3077 // the offset of the start of the menu item label
3080 // the offset of the start of the accel label
3083 // the height of a normal (not separator) item
3084 wxCoord m_heightItem
;
3086 friend wxMenuGeometryInfo
*
3087 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3090 // FIXME: all constants are hardcoded but shouldn't be
3091 static const wxCoord MENU_LEFT_MARGIN
= 9;
3092 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3093 static const wxCoord MENU_VERT_MARGIN
= 3;
3095 // the margin around bitmap/check marks (on each side)
3096 static const wxCoord MENU_BMP_MARGIN
= 2;
3098 // the margin between the labels and accel strings
3099 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3101 // the separator height in pixels: in fact, strangely enough, the real height
3102 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3104 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3106 // the size of the standard checkmark bitmap
3107 static const wxCoord MENU_CHECK_SIZE
= 9;
3109 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3110 const wxRect
& rectOrig
,
3111 const wxString
& label
,
3115 wxRect rect
= rectOrig
;
3118 wxDCTextColourChanger
colChanger(dc
);
3120 if ( flags
& wxCONTROL_SELECTED
)
3122 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3124 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3125 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3126 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3127 dc
.DrawRectangle(rect
);
3130 // don't draw the focus rect around menu bar items
3131 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3132 wxALIGN_CENTRE
, indexAccel
);
3135 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3137 const wxMenuGeometryInfo
& gi
,
3138 const wxString
& label
,
3139 const wxString
& accel
,
3140 const wxBitmap
& bitmap
,
3144 const wxWin32MenuGeometryInfo
& geometryInfo
=
3145 (const wxWin32MenuGeometryInfo
&)gi
;
3150 rect
.width
= geometryInfo
.GetSize().x
;
3151 rect
.height
= geometryInfo
.GetItemHeight();
3153 // draw the selected item specially
3154 wxDCTextColourChanger
colChanger(dc
);
3155 if ( flags
& wxCONTROL_SELECTED
)
3157 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3159 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3160 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3161 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3162 dc
.DrawRectangle(rect
);
3165 // draw the bitmap: use the bitmap provided or the standard checkmark for
3166 // the checkable items
3167 wxBitmap bmp
= bitmap
;
3168 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3170 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3175 rect
.SetRight(geometryInfo
.GetLabelOffset());
3176 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3180 rect
.x
= geometryInfo
.GetLabelOffset();
3181 rect
.SetRight(geometryInfo
.GetAccelOffset());
3183 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3185 // draw the accel string
3186 rect
.x
= geometryInfo
.GetAccelOffset();
3187 rect
.SetRight(geometryInfo
.GetSize().x
);
3189 // NB: no accel index here
3190 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3192 // draw the submenu indicator
3193 if ( flags
& wxCONTROL_ISSUBMENU
)
3195 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3196 rect
.width
= MENU_RIGHT_MARGIN
;
3198 wxArrowStyle arrowStyle
;
3199 if ( flags
& wxCONTROL_DISABLED
)
3200 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
3202 else if ( flags
& wxCONTROL_SELECTED
)
3203 arrowStyle
= Arrow_Inverted
;
3205 arrowStyle
= Arrow_Normal
;
3207 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3211 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3213 const wxMenuGeometryInfo
& geomInfo
)
3215 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3218 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3220 wxSize size
= sizeText
;
3222 // FIXME: menubar height is configurable under Windows
3229 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3230 const wxMenu
& menu
) const
3232 // prepare the dc: for now we draw all the items with the system font
3234 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3236 // the height of a normal item
3237 wxCoord heightText
= dc
.GetCharHeight();
3242 // the max length of label and accel strings: the menu width is the sum of
3243 // them, even if they're for different items (as the accels should be
3246 // the max length of the bitmap is never 0 as Windows always leaves enough
3247 // space for a check mark indicator
3248 wxCoord widthLabelMax
= 0,
3250 widthBmpMax
= MENU_LEFT_MARGIN
;
3252 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3254 node
= node
->GetNext() )
3256 // height of this item
3259 wxMenuItem
*item
= node
->GetData();
3260 if ( item
->IsSeparator() )
3262 h
= MENU_SEPARATOR_HEIGHT
;
3264 else // not separator
3269 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3270 if ( widthLabel
> widthLabelMax
)
3272 widthLabelMax
= widthLabel
;
3276 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3277 if ( widthAccel
> widthAccelMax
)
3279 widthAccelMax
= widthAccel
;
3282 const wxBitmap
& bmp
= item
->GetBitmap();
3285 wxCoord widthBmp
= bmp
.GetWidth();
3286 if ( widthBmp
> widthBmpMax
)
3287 widthBmpMax
= widthBmp
;
3289 //else if ( item->IsCheckable() ): no need to check for this as
3290 // MENU_LEFT_MARGIN is big enough to show the check mark
3293 h
+= 2*MENU_VERT_MARGIN
;
3295 // remember the item position and height
3296 item
->SetGeometry(height
, h
);
3301 // bundle the metrics into a struct and return it
3302 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3304 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3305 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3306 if ( widthAccelMax
> 0 )
3308 // if we actually have any accesl, add a margin
3309 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3312 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3314 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3315 gi
->m_size
.y
= height
;
3320 // ----------------------------------------------------------------------------
3322 // ----------------------------------------------------------------------------
3324 static const wxCoord STATBAR_BORDER_X
= 2;
3325 static const wxCoord STATBAR_BORDER_Y
= 2;
3327 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3329 if ( borderBetweenFields
)
3330 *borderBetweenFields
= 2;
3332 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3335 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3337 const wxString
& label
,
3338 int flags
, int style
/*=0*/)
3342 if ( flags
& wxCONTROL_ISDEFAULT
)
3344 // draw the size grip: it is a normal rect except that in the lower
3345 // right corner we have several bands which may be used for dragging
3346 // the status bar corner
3348 // each band consists of 4 stripes: m_penHighlight, double
3349 // m_penDarkGrey and transparent one
3350 wxCoord x2
= rect
.GetRight(),
3351 y2
= rect
.GetBottom();
3353 // draw the upper left part of the rect normally
3354 if (style
!= wxSB_FLAT
)
3356 if (style
== wxSB_RAISED
)
3357 dc
.SetPen(m_penHighlight
);
3359 dc
.SetPen(m_penDarkGrey
);
3360 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3361 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3364 // draw the grey stripes of the grip
3366 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3367 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3369 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3370 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3373 // draw the white stripes
3374 dc
.SetPen(m_penHighlight
);
3375 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3376 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3378 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3381 // draw the remaining rect boundaries
3382 if (style
!= wxSB_FLAT
)
3384 if (style
== wxSB_RAISED
)
3385 dc
.SetPen(m_penDarkGrey
);
3387 dc
.SetPen(m_penHighlight
);
3388 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3389 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3390 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3396 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3400 if (style
== wxSB_RAISED
)
3401 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3402 else if (style
!= wxSB_FLAT
)
3403 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3406 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3408 wxDCClipper
clipper(dc
, rectIn
);
3409 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3412 // ----------------------------------------------------------------------------
3414 // ----------------------------------------------------------------------------
3416 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3417 wxBitmap
* WXUNUSED(bmpFocus
),
3418 wxBitmap
*bmpPressed
,
3419 wxBitmap
*bmpDisabled
)
3421 static const wxCoord widthCombo
= 16;
3422 static const wxCoord heightCombo
= 17;
3428 bmpNormal
->Create(widthCombo
, heightCombo
);
3429 dcMem
.SelectObject(*bmpNormal
);
3430 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3431 Arrow_Down
, Arrow_Normal
);
3436 bmpPressed
->Create(widthCombo
, heightCombo
);
3437 dcMem
.SelectObject(*bmpPressed
);
3438 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3439 Arrow_Down
, Arrow_Pressed
);
3444 bmpDisabled
->Create(widthCombo
, heightCombo
);
3445 dcMem
.SelectObject(*bmpDisabled
);
3446 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3447 Arrow_Down
, Arrow_Disabled
);
3451 // ----------------------------------------------------------------------------
3453 // ----------------------------------------------------------------------------
3455 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3456 const wxColour
& col
,
3458 wxWindow
* WXUNUSED(window
))
3460 wxBrush
brush(col
, wxSOLID
);
3462 dc
.SetPen(*wxTRANSPARENT_PEN
);
3463 dc
.DrawRectangle(rect
);
3466 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3467 const wxColour
& col
,
3469 int WXUNUSED(flags
),
3472 // just fill it with the given or default bg colour
3473 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3474 DoDrawBackground(dc
, colBg
, rect
, window
);
3477 // ----------------------------------------------------------------------------
3479 // ----------------------------------------------------------------------------
3481 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3486 // get the bitmap for this arrow
3487 wxArrowDirection arrowDir
;
3490 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3491 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3492 case wxUP
: arrowDir
= Arrow_Up
; break;
3493 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3496 wxFAIL_MSG(_T("unknown arrow direction"));
3500 wxArrowStyle arrowStyle
;
3501 if ( flags
& wxCONTROL_PRESSED
)
3503 // can't be pressed and disabled
3504 arrowStyle
= Arrow_Pressed
;
3508 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3511 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3514 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3516 wxArrowDirection arrowDir
,
3517 wxArrowStyle arrowStyle
)
3519 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3521 // under Windows the arrows always have the same size so just centre it in
3522 // the provided rectangle
3523 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3524 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3526 // Windows does it like this...
3527 if ( arrowDir
== Arrow_Left
)
3531 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3534 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3535 const wxRect
& rectAll
,
3536 wxArrowDirection arrowDir
,
3537 wxArrowStyle arrowStyle
)
3539 wxRect rect
= rectAll
;
3540 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3541 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3542 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3545 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3546 wxOrientation
WXUNUSED(orient
),
3548 int WXUNUSED(flags
))
3550 // we don't use the flags, the thumb never changes appearance
3551 wxRect rectThumb
= rect
;
3552 DrawArrowBorder(dc
, &rectThumb
);
3553 DrawBackground(dc
, wxNullColour
, rectThumb
);
3556 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3557 wxOrientation
WXUNUSED(orient
),
3558 const wxRect
& rectBar
,
3561 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3562 ? wxColourScheme::SCROLLBAR_PRESSED
3563 : wxColourScheme::SCROLLBAR
;
3564 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3567 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3569 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3572 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3573 wxScrollBar::Element elem
,
3576 return StandardGetScrollbarRect(scrollbar
, elem
,
3577 thumbPos
, m_sizeScrollbarArrow
);
3580 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3582 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3585 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3586 const wxPoint
& pt
) const
3588 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3591 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3594 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3597 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3600 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3603 // ----------------------------------------------------------------------------
3604 // top level windows
3605 // ----------------------------------------------------------------------------
3607 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3609 wxRect client
= GetFrameClientArea(rect
, flags
);
3611 if ( client
.Inside(pt
) )
3612 return wxHT_TOPLEVEL_CLIENT_AREA
;
3614 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3616 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3618 if ( flags
& wxTOPLEVEL_ICON
)
3620 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3621 return wxHT_TOPLEVEL_ICON
;
3624 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3625 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3626 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3628 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3630 if ( btnRect
.Inside(pt
) )
3631 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3632 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3634 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3636 if ( btnRect
.Inside(pt
) )
3637 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3638 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3640 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3642 if ( btnRect
.Inside(pt
) )
3643 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3644 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3646 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3648 if ( btnRect
.Inside(pt
) )
3649 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3650 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3652 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3654 if ( btnRect
.Inside(pt
) )
3655 return wxHT_TOPLEVEL_BUTTON_HELP
;
3656 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3659 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3660 return wxHT_TOPLEVEL_TITLEBAR
;
3663 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3665 // we are certainly at one of borders, lets decide which one:
3668 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3669 if ( pt
.x
< client
.x
)
3670 border
|= wxHT_TOPLEVEL_BORDER_W
;
3671 else if ( pt
.x
>= client
.width
+ client
.x
)
3672 border
|= wxHT_TOPLEVEL_BORDER_E
;
3673 if ( pt
.y
< client
.y
)
3674 border
|= wxHT_TOPLEVEL_BORDER_N
;
3675 else if ( pt
.y
>= client
.height
+ client
.y
)
3676 border
|= wxHT_TOPLEVEL_BORDER_S
;
3680 return wxHT_NOWHERE
;
3683 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3685 const wxString
& title
,
3689 int specialButtonFlags
)
3691 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3693 DrawFrameBorder(dc
, rect
, flags
);
3695 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3697 DrawFrameBackground(dc
, rect
, flags
);
3698 if ( flags
& wxTOPLEVEL_ICON
)
3699 DrawFrameIcon(dc
, rect
, icon
, flags
);
3700 DrawFrameTitle(dc
, rect
, title
, flags
);
3702 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3704 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3705 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3707 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3709 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3710 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3711 specialButtonFlags
: 0);
3712 x
-= FRAME_BUTTON_WIDTH
+ 2;
3714 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3716 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3717 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3718 specialButtonFlags
: 0);
3719 x
-= FRAME_BUTTON_WIDTH
;
3721 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3723 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3724 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3725 specialButtonFlags
: 0);
3726 x
-= FRAME_BUTTON_WIDTH
;
3728 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3730 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3731 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3732 specialButtonFlags
: 0);
3733 x
-= FRAME_BUTTON_WIDTH
;
3735 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3737 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3738 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3739 specialButtonFlags
: 0);
3744 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3748 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3752 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3753 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3754 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3755 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3756 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3759 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3763 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3765 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3766 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3767 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3769 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3770 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3772 DrawBackground(dc
, col
, r
);
3775 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3777 const wxString
& title
,
3780 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3781 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3782 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3784 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3785 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3786 if ( flags
& wxTOPLEVEL_ICON
)
3788 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3789 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3797 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3798 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3799 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3800 r
.width
-= FRAME_BUTTON_WIDTH
;
3801 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3802 r
.width
-= FRAME_BUTTON_WIDTH
;
3803 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3804 r
.width
-= FRAME_BUTTON_WIDTH
;
3805 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3806 r
.width
-= FRAME_BUTTON_WIDTH
;
3808 dc
.SetFont(m_titlebarFont
);
3809 dc
.SetTextForeground(col
);
3812 dc
.GetTextExtent(title
, &textW
, NULL
);
3813 if ( textW
> r
.width
)
3815 // text is too big, let's shorten it and add "..." after it:
3816 size_t len
= title
.length();
3817 wxCoord WSoFar
, letterW
;
3819 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3820 if ( WSoFar
> r
.width
)
3822 // not enough space to draw anything
3828 for (size_t i
= 0; i
< len
; i
++)
3830 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3831 if ( letterW
+ WSoFar
> r
.width
)
3837 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3838 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3841 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3842 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3845 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3852 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3853 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3857 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3858 wxCoord x
, wxCoord y
,
3862 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3867 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3868 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3869 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3870 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3871 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3873 wxFAIL_MSG(wxT("incorrect button specification"));
3876 if ( flags
& wxCONTROL_PRESSED
)
3878 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3879 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3880 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3881 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3885 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3886 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3887 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3888 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3893 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3898 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3900 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3901 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3902 FRAME_BORDER_THICKNESS
;
3905 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3907 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3908 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3914 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3917 wxSize
s(clientSize
);
3919 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3921 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3922 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3923 FRAME_BORDER_THICKNESS
;
3927 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3928 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3933 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3937 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3939 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3940 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3941 FRAME_BORDER_THICKNESS
;
3946 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3948 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3950 if ( flags
& wxTOPLEVEL_ICON
)
3951 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3952 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3953 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3954 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3955 s
.x
+= FRAME_BUTTON_WIDTH
;
3956 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3957 s
.x
+= FRAME_BUTTON_WIDTH
;
3958 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3959 s
.x
+= FRAME_BUTTON_WIDTH
;
3960 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3961 s
.x
+= FRAME_BUTTON_WIDTH
;
3967 wxSize
wxWin32Renderer::GetFrameIconSize() const
3969 return wxSize(16, 16);
3973 // ----------------------------------------------------------------------------
3975 // ----------------------------------------------------------------------------
3977 /* Copyright (c) Julian Smart */
3978 static char *error_xpm
[]={
3979 /* columns rows colors chars-per-pixel */
4056 " $oooooooooooo%& ",
4057 " *=-ooooooooooooo;: ",
4058 " *oooooooooooooooooo> ",
4059 " =ooooooooooooooooooo, ",
4060 " $-ooooooooooooooooooo<1 ",
4061 " .oooooo2334ooo533oooooo6 ",
4062 " +ooooooo789oo2883oooooo0q ",
4063 " oooooooo2w83o78eoooooooor ",
4064 " toooooooooy88u884oooooooori ",
4065 " Xooooooooooe888poooooooooas ",
4066 " ooooooooooo4889doooooooooof ",
4067 " ooooooooooo588w2oooooooooofi ",
4068 " oooooooooodw8887oooooooooofi ",
4069 " goooooooooh8w588jooooooookli ",
4070 " tooooooooz885op8wdooooooorix ",
4071 " oooooood98cood98cooooooori ",
4072 " @oooooop8w2ooo5885ooooovbi ",
4073 " n%ooooooooooooooooooooomiM ",
4074 " &;oooooooooooooooooooNBiV ",
4075 " :ooooooooooooooooooCZiA ",
4076 " nSooooooooooooooooCDiF ",
4077 " nG<oooooooooooooNZiiH ",
4078 " 160ooooooooovmBiFH ",
4079 " nqrraoookrrbiiA ",
4086 /* Copyright (c) Julian Smart */
4087 static char *info_xpm
[]={
4088 /* columns rows colors chars-per-pixel */
4110 " ..XXXXXXXXXXXXX.. ",
4111 " .XXXXXXXXXXXXXXXXX. ",
4112 " .XXXXXXXXoO+XXXXXXXX. ",
4113 " .XXXXXXXXX@#OXXXXXXXXX. ",
4114 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
4115 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
4116 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
4117 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
4118 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
4119 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
4120 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4121 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4122 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
4123 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
4124 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
4125 " .XXXXXXXXXXXXXXXXX.%%%% ",
4126 " ..XXXXXXXXXXXXX..%%%% ",
4127 " %...XXXXXXXX..%%%%% ",
4128 " %%%..XXXXXX.%%%%% ",
4142 /* Copyright (c) Julian Smart */
4143 static char *question_xpm
[]={
4144 /* columns rows colors chars-per-pixel */
4165 " ..XXXXXXXXXXXXX.. ",
4166 " .XXXXXXoO++@XXXXXX. ",
4167 " .XXXXXXO#$$$$#%XXXXX. ",
4168 " .XXXXXX@$$#&&#$#oXXXXX. ",
4169 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
4170 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
4171 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
4172 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
4173 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
4174 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
4175 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
4176 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
4177 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
4178 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
4179 " .XXXXXXXX-$$XXXXXXXX.:::: ",
4180 " .XXXXXXXO++XXXXXXX.:::: ",
4181 " ..XXXXXXXXXXXXX..:::: ",
4182 " :...XXXXXXXX..::::: ",
4183 " :::..XXXXXX.::::: ",
4197 /* Copyright (c) Julian Smart */
4198 static char *warning_xpm
[]={
4199 /* columns rows colors chars-per-pixel */
4225 " ..XXXXO@#XXX... ",
4226 " ...XXXXO@#XXXX.. ",
4227 " ..XXXXXO@#XXXX... ",
4228 " ...XXXXXo@OXXXXX.. ",
4229 " ...XXXXXXo@OXXXXXX.. ",
4230 " ..XXXXXXX$@OXXXXXX... ",
4231 " ...XXXXXXXX@XXXXXXXX.. ",
4232 " ...XXXXXXXXXXXXXXXXXX... ",
4233 " ..XXXXXXXXXXOXXXXXXXXX.. ",
4234 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
4235 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
4236 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
4237 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
4238 " .............................. ",
4239 " .............................. ",
4246 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4247 const wxArtClient
& WXUNUSED(client
),
4248 const wxSize
& WXUNUSED(size
))
4250 if ( id
== wxART_INFORMATION
)
4251 return wxBitmap(info_xpm
);
4252 if ( id
== wxART_ERROR
)
4253 return wxBitmap(error_xpm
);
4254 if ( id
== wxART_WARNING
)
4255 return wxBitmap(warning_xpm
);
4256 if ( id
== wxART_QUESTION
)
4257 return wxBitmap(question_xpm
);
4258 return wxNullBitmap
;
4262 // ----------------------------------------------------------------------------
4263 // text control geometry
4264 // ----------------------------------------------------------------------------
4266 static inline int GetTextBorderWidth()
4272 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4273 const wxRect
& rect
) const
4275 wxRect rectTotal
= rect
;
4277 wxCoord widthBorder
= GetTextBorderWidth();
4278 rectTotal
.Inflate(widthBorder
);
4280 // this is what Windows does
4287 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4289 wxCoord
*extraSpaceBeyond
) const
4291 wxRect rectText
= rect
;
4293 // undo GetTextTotalArea()
4294 if ( rectText
.height
> 0 )
4297 wxCoord widthBorder
= GetTextBorderWidth();
4298 rectText
.Inflate(-widthBorder
);
4300 if ( extraSpaceBeyond
)
4301 *extraSpaceBeyond
= 0;
4306 // ----------------------------------------------------------------------------
4308 // ----------------------------------------------------------------------------
4310 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4313 if ( wxDynamicCast(window
, wxScrollBar
) )
4315 // we only set the width of vert scrollbars and height of the
4317 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4318 size
->y
= m_sizeScrollbarArrow
.y
;
4320 size
->x
= m_sizeScrollbarArrow
.x
;
4322 // skip border width adjustments, they don't make sense for us
4325 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4328 if ( wxDynamicCast(window
, wxBitmapButton
) )
4332 #endif // wxUSE_BMPBUTTON
4334 if ( wxDynamicCast(window
, wxButton
) )
4336 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4338 // TODO: don't harcode all this
4339 size
->x
+= 3*window
->GetCharWidth();
4341 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4342 if ( size
->y
< heightBtn
- 8 )
4343 size
->y
= heightBtn
;
4348 // for compatibility with other ports, the buttons default size is never
4349 // less than the standard one, but not when display not PDAs.
4350 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4352 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4354 wxSize szDef
= wxButton::GetDefaultSize();
4355 if ( size
->x
< szDef
.x
)
4360 // no border width adjustments for buttons
4363 #endif // wxUSE_BUTTON
4365 // take into account the border width
4366 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4367 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4368 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4371 // ============================================================================
4373 // ============================================================================
4375 // ----------------------------------------------------------------------------
4376 // wxWin32InputHandler
4377 // ----------------------------------------------------------------------------
4379 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4381 m_renderer
= renderer
;
4384 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4385 const wxKeyEvent
& WXUNUSED(event
),
4386 bool WXUNUSED(pressed
))
4391 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4392 const wxMouseEvent
& event
)
4394 // clicking on the control gives it focus
4395 if ( event
.ButtonDown() )
4397 wxWindow
*win
= control
->GetInputWindow();
4399 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4400 ( win
->AcceptsFocus() ) )
4411 // ----------------------------------------------------------------------------
4412 // wxWin32ScrollBarInputHandler
4413 // ----------------------------------------------------------------------------
4415 wxWin32ScrollBarInputHandler::
4416 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4417 wxInputHandler
*handler
)
4418 : wxStdScrollBarInputHandler(renderer
, handler
)
4420 m_scrollPaused
= false;
4424 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4425 const wxControlAction
& action
)
4427 // stop if went beyond the position of the original click (this can only
4428 // happen when we scroll by pages)
4430 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4432 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4433 != wxHT_SCROLLBAR_BAR_2
;
4435 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4437 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4438 != wxHT_SCROLLBAR_BAR_1
;
4443 StopScrolling(scrollbar
);
4445 scrollbar
->Refresh();
4450 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4453 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4454 const wxMouseEvent
& event
)
4456 // remember the current state
4457 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4459 // do process the message
4460 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4462 // analyse the changes
4463 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4465 // we just started dragging the thumb, remember its initial position to
4466 // be able to restore it if the drag is cancelled later
4467 m_eventStartDrag
= event
;
4473 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4474 const wxMouseEvent
& event
)
4476 // we don't highlight scrollbar elements, so there is no need to process
4477 // mouse move events normally - only do it while mouse is captured (i.e.
4478 // when we're dragging the thumb or pressing on something)
4479 if ( !m_winCapture
)
4482 if ( event
.Entering() )
4484 // we're not interested in this at all
4488 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4490 if ( m_scrollPaused
)
4492 // check if the mouse returned to its original location
4494 if ( event
.Leaving() )
4500 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4501 if ( ht
== m_htLast
)
4503 // yes it did, resume scrolling
4504 m_scrollPaused
= false;
4505 if ( m_timerScroll
)
4507 // we were scrolling by line/page, restart timer
4508 m_timerScroll
->Start(m_interval
);
4510 Press(scrollbar
, true);
4512 else // we were dragging the thumb
4514 // restore its last location
4515 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4521 else // normal case, scrolling hasn't been paused
4523 // if we're scrolling the scrollbar because the arrow or the shaft was
4524 // pressed, check that the mouse stays on the same scrollbar element
4527 // Always let thumb jump back if we leave the scrollbar
4528 if ( event
.Moving() )
4530 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4532 else // event.Leaving()
4537 // Jump back only if we get far away from it
4538 wxPoint pos
= event
.GetPosition();
4539 if (scrollbar
->HasFlag( wxVERTICAL
))
4541 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4546 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4549 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4552 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4553 // is still ok - we only want to catch the case when the mouse leaves
4554 // the scrollbar here
4555 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4557 ht
= wxHT_SCROLLBAR_THUMB
;
4560 if ( ht
!= m_htLast
)
4562 // what were we doing? 2 possibilities: either an arrow/shaft was
4563 // pressed in which case we have a timer and so we just stop it or
4564 // we were dragging the thumb
4565 if ( m_timerScroll
)
4568 m_interval
= m_timerScroll
->GetInterval();
4569 m_timerScroll
->Stop();
4570 m_scrollPaused
= true;
4572 // unpress the arrow
4573 Press(scrollbar
, false);
4575 else // we were dragging the thumb
4577 // remember the current thumb position to be able to restore it
4578 // if the mouse returns to it later
4579 m_eventLastDrag
= event
;
4581 // and restore the original position (before dragging) of the
4583 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4590 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4593 // ----------------------------------------------------------------------------
4594 // wxWin32CheckboxInputHandler
4595 // ----------------------------------------------------------------------------
4597 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4598 const wxKeyEvent
& event
,
4603 wxControlAction action
;
4604 int keycode
= event
.GetKeyCode();
4608 action
= wxACTION_CHECKBOX_TOGGLE
;
4612 case WXK_NUMPAD_SUBTRACT
:
4613 action
= wxACTION_CHECKBOX_CHECK
;
4617 case WXK_NUMPAD_ADD
:
4618 case WXK_NUMPAD_EQUAL
:
4619 action
= wxACTION_CHECKBOX_CLEAR
;
4623 if ( !action
.IsEmpty() )
4625 control
->PerformAction(action
);
4634 // ----------------------------------------------------------------------------
4635 // wxWin32TextCtrlInputHandler
4636 // ----------------------------------------------------------------------------
4638 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4639 const wxKeyEvent
& event
,
4642 // handle only MSW-specific text bindings here, the others are handled in
4646 int keycode
= event
.GetKeyCode();
4648 wxControlAction action
;
4649 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4651 action
= wxACTION_TEXT_CUT
;
4653 else if ( keycode
== WXK_INSERT
)
4655 if ( event
.ControlDown() )
4656 action
= wxACTION_TEXT_COPY
;
4657 else if ( event
.ShiftDown() )
4658 action
= wxACTION_TEXT_PASTE
;
4661 if ( action
!= wxACTION_NONE
)
4663 control
->PerformAction(action
);
4669 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4672 // ----------------------------------------------------------------------------
4673 // wxWin32StatusBarInputHandler
4674 // ----------------------------------------------------------------------------
4676 wxWin32StatusBarInputHandler::
4677 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4678 : wxStdInputHandler(handler
)
4683 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4684 const wxPoint
& pt
) const
4686 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4687 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4690 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4692 wxCHECK_MSG( parentTLW
, false,
4693 _T("the status bar should be a child of a TLW") );
4695 // a maximized window can't be resized anyhow
4696 if ( !parentTLW
->IsMaximized() )
4698 // VZ: I think that the standard Windows behaviour is to only
4699 // show the resizing cursor when the mouse is on top of the
4700 // grip itself but apparently different Windows versions behave
4701 // differently (?) and it seems a better UI to allow resizing
4702 // the status bar even when the mouse is above the grip
4703 wxSize sizeSbar
= statbar
->GetSize();
4705 int diff
= sizeSbar
.x
- pt
.x
;
4706 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4713 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4714 const wxMouseEvent
& event
)
4716 if ( event
.Button(1) )
4718 if ( event
.ButtonDown(1) )
4720 wxWindow
*statbar
= consumer
->GetInputWindow();
4722 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4724 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4728 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4729 wxHT_TOPLEVEL_BORDER_SE
);
4731 statbar
->SetCursor(m_cursorOld
);
4739 return wxStdInputHandler::HandleMouse(consumer
, event
);
4742 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4743 const wxMouseEvent
& event
)
4745 wxWindow
*statbar
= consumer
->GetInputWindow();
4747 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4748 if ( isOnGrip
!= m_isOnGrip
)
4750 m_isOnGrip
= isOnGrip
;
4753 m_cursorOld
= statbar
->GetCursor();
4754 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4758 statbar
->SetCursor(m_cursorOld
);
4762 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4765 // ----------------------------------------------------------------------------
4766 // wxWin32FrameInputHandler
4767 // ----------------------------------------------------------------------------
4769 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4772 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4774 void Attach(wxInputConsumer
*consumer
);
4778 DECLARE_EVENT_TABLE()
4779 void OnSystemMenu(wxCommandEvent
&event
);
4780 void OnCloseFrame(wxCommandEvent
&event
);
4781 void OnClose(wxCloseEvent
&event
);
4783 wxWin32FrameInputHandler
*m_inputHnd
;
4784 wxTopLevelWindow
*m_wnd
;
4786 wxAcceleratorTable m_oldAccelTable
;
4790 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4791 wxWin32FrameInputHandler
*handler
)
4793 m_inputHnd
= handler
;
4797 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4799 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4801 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4802 m_wnd
->PushEventHandler(this);
4805 // VS: This code relies on using generic implementation of
4806 // wxAcceleratorTable in wxUniv!
4807 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4808 m_oldAccelTable
= table
;
4809 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4810 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4811 m_wnd
->SetAcceleratorTable(table
);
4815 void wxWin32SystemMenuEvtHandler::Detach()
4820 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4822 m_wnd
->RemoveEventHandler(this);
4827 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4828 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4829 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4830 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4833 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4835 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4836 !m_wnd
->IsMaximized()) ?
4837 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4838 FRAME_BORDER_THICKNESS
;
4839 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4840 pt
.x
= -pt
.x
+ border
;
4841 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4844 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4845 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4848 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4851 m_wnd
->SetAcceleratorTable(table
);
4855 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4857 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4858 wxTOPLEVEL_BUTTON_CLOSE
);
4861 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4868 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4869 : wxStdFrameInputHandler(handler
)
4871 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4874 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4876 if ( m_menuHandler
)
4878 m_menuHandler
->Detach();
4879 delete m_menuHandler
;
4883 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4884 const wxMouseEvent
& event
)
4886 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4888 wxTopLevelWindow
*tlw
=
4889 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4891 long hit
= tlw
->HitTest(event
.GetPosition());
4893 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4895 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4896 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4897 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4900 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4902 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4903 (event
.RightDown() &&
4904 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4905 hit
== wxHT_TOPLEVEL_ICON
)) )
4907 PopupSystemMenu(tlw
, event
.GetPosition());
4913 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4916 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4917 const wxPoint
& pos
) const
4919 wxMenu
*menu
= new wxMenu
;
4921 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4922 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4923 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4924 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4925 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4926 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4927 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4928 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4929 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4930 menu
->AppendSeparator();
4931 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4933 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4935 if ( window
->IsMaximized() )
4937 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4938 menu
->Enable(wxID_MOVE_FRAME
, false);
4939 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4940 menu
->Enable(wxID_RESIZE_FRAME
, false);
4943 menu
->Enable(wxID_RESTORE_FRAME
, false);
4946 window
->PopupMenu(menu
, pos
);
4950 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4953 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4955 // always detach if active frame changed:
4956 m_menuHandler
->Detach();
4960 m_menuHandler
->Attach(consumer
);
4964 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);