1 // Name: univ/themes/win32.cpp
2 // Purpose: wxUniversal theme implementing Win32-like LNF
3 // Author: Vadim Zeitlin
7 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
30 #include "wx/window.h"
32 #include "wx/dcmemory.h"
34 #include "wx/button.h"
35 #include "wx/listbox.h"
36 #include "wx/checklst.h"
37 #include "wx/combobox.h"
38 #include "wx/scrolbar.h"
39 #include "wx/slider.h"
40 #include "wx/textctrl.h"
41 #include "wx/toolbar.h"
44 // for COLOR_* constants
45 #include "wx/msw/private.h"
49 #include "wx/notebook.h"
50 #include "wx/spinbutt.h"
51 #include "wx/settings.h"
53 #include "wx/artprov.h"
54 #include "wx/toplevel.h"
56 #include "wx/univ/scrtimer.h"
57 #include "wx/univ/renderer.h"
58 #include "wx/univ/inphand.h"
59 #include "wx/univ/colschem.h"
60 #include "wx/univ/theme.h"
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 static const int BORDER_THICKNESS
= 2;
68 // the offset between the label and focus rect around it
69 static const int FOCUS_RECT_OFFSET_X
= 1;
70 static const int FOCUS_RECT_OFFSET_Y
= 1;
72 static const int FRAME_BORDER_THICKNESS
= 3;
73 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
74 static const int FRAME_TITLEBAR_HEIGHT
= 18;
75 static const int FRAME_BUTTON_WIDTH
= 16;
76 static const int FRAME_BUTTON_HEIGHT
= 14;
78 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
79 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
80 static const size_t STATUSBAR_GRIP_SIZE
=
81 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
83 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
84 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
85 static const wxCoord SLIDER_TICK_LENGTH
= 6;
97 IndicatorState_Normal
,
98 IndicatorState_Pressed
, // this one is for check/radioboxes
99 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
100 IndicatorState_Disabled
,
101 IndicatorState_SelectedDisabled
, // only for the menus
107 IndicatorStatus_Checked
,
108 IndicatorStatus_Unchecked
,
112 // wxWin32Renderer: draw the GUI elements in Win32 style
113 // ----------------------------------------------------------------------------
115 class wxWin32Renderer
: public wxRenderer
119 enum wxArrowDirection
134 Arrow_InversedDisabled
,
138 enum wxFrameButtonType
141 FrameButton_Minimize
,
142 FrameButton_Maximize
,
149 wxWin32Renderer(const wxColourScheme
*scheme
);
151 // implement the base class pure virtuals
152 virtual void DrawBackground(wxDC
& dc
,
156 wxWindow
*window
= NULL
);
157 virtual void DrawLabel(wxDC
& dc
,
158 const wxString
& label
,
161 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
163 wxRect
*rectBounds
= NULL
);
164 virtual void DrawButtonLabel(wxDC
& dc
,
165 const wxString
& label
,
166 const wxBitmap
& image
,
169 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
171 wxRect
*rectBounds
= NULL
);
172 virtual void DrawBorder(wxDC
& dc
,
176 wxRect
*rectIn
= (wxRect
*)NULL
);
177 virtual void DrawHorizontalLine(wxDC
& dc
,
178 wxCoord y
, wxCoord x1
, wxCoord x2
);
179 virtual void DrawVerticalLine(wxDC
& dc
,
180 wxCoord x
, wxCoord y1
, wxCoord y2
);
181 virtual void DrawFrame(wxDC
& dc
,
182 const wxString
& label
,
185 int alignment
= wxALIGN_LEFT
,
186 int indexAccel
= -1);
187 virtual void DrawTextBorder(wxDC
& dc
,
191 wxRect
*rectIn
= (wxRect
*)NULL
);
192 virtual void DrawButtonBorder(wxDC
& dc
,
195 wxRect
*rectIn
= (wxRect
*)NULL
);
196 virtual void DrawArrow(wxDC
& dc
,
200 virtual void DrawScrollbarArrow(wxDC
& dc
,
204 { DrawArrow(dc
, dir
, rect
, flags
); }
205 virtual void DrawScrollbarThumb(wxDC
& dc
,
206 wxOrientation orient
,
209 virtual void DrawScrollbarShaft(wxDC
& dc
,
210 wxOrientation orient
,
213 virtual void DrawScrollCorner(wxDC
& dc
,
215 virtual void DrawItem(wxDC
& dc
,
216 const wxString
& label
,
219 virtual void DrawCheckItem(wxDC
& dc
,
220 const wxString
& label
,
221 const wxBitmap
& bitmap
,
224 virtual void DrawCheckButton(wxDC
& dc
,
225 const wxString
& label
,
226 const wxBitmap
& bitmap
,
229 wxAlignment align
= wxALIGN_LEFT
,
230 int indexAccel
= -1);
231 virtual void DrawRadioButton(wxDC
& dc
,
232 const wxString
& label
,
233 const wxBitmap
& bitmap
,
236 wxAlignment align
= wxALIGN_LEFT
,
237 int indexAccel
= -1);
238 virtual void DrawToolBarButton(wxDC
& dc
,
239 const wxString
& label
,
240 const wxBitmap
& bitmap
,
244 virtual void DrawTextLine(wxDC
& dc
,
245 const wxString
& text
,
250 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
251 virtual void DrawTab(wxDC
& dc
,
254 const wxString
& label
,
255 const wxBitmap
& bitmap
= wxNullBitmap
,
257 int indexAccel
= -1);
259 virtual void DrawSliderShaft(wxDC
& dc
,
262 wxOrientation orient
,
265 wxRect
*rectShaft
= NULL
);
266 virtual void DrawSliderThumb(wxDC
& dc
,
268 wxOrientation orient
,
271 virtual void DrawSliderTicks(wxDC
& dc
,
274 wxOrientation orient
,
281 virtual void DrawMenuBarItem(wxDC
& dc
,
283 const wxString
& label
,
285 int indexAccel
= -1);
286 virtual void DrawMenuItem(wxDC
& dc
,
288 const wxMenuGeometryInfo
& geometryInfo
,
289 const wxString
& label
,
290 const wxString
& accel
,
291 const wxBitmap
& bitmap
= wxNullBitmap
,
293 int indexAccel
= -1);
294 virtual void DrawMenuSeparator(wxDC
& dc
,
296 const wxMenuGeometryInfo
& geomInfo
);
298 virtual void DrawStatusField(wxDC
& dc
,
300 const wxString
& label
,
304 virtual void DrawFrameTitleBar(wxDC
& dc
,
306 const wxString
& title
,
309 int specialButton
= 0,
310 int specialButtonFlags
= 0);
311 virtual void DrawFrameBorder(wxDC
& dc
,
314 virtual void DrawFrameBackground(wxDC
& dc
,
317 virtual void DrawFrameTitle(wxDC
& dc
,
319 const wxString
& title
,
321 virtual void DrawFrameIcon(wxDC
& dc
,
325 virtual void DrawFrameButton(wxDC
& dc
,
326 wxCoord x
, wxCoord y
,
329 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
330 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
331 virtual wxSize
GetFrameMinSize(int flags
) const;
332 virtual wxSize
GetFrameIconSize() const;
333 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
335 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
337 wxBitmap
*bmpPressed
,
338 wxBitmap
*bmpDisabled
);
340 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
341 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
342 virtual bool AreScrollbarsInsideBorder() const;
344 virtual wxSize
GetScrollbarArrowSize() const
345 { return m_sizeScrollbarArrow
; }
346 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
347 wxScrollBar::Element elem
,
348 int thumbPos
= -1) const;
349 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
350 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
351 const wxPoint
& pt
) const;
352 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
354 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
355 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
356 { return fontHeight
+ 2; }
357 virtual wxSize
GetCheckBitmapSize() const
358 { return wxSize(13, 13); }
359 virtual wxSize
GetRadioBitmapSize() const
360 { return wxSize(12, 12); }
361 virtual wxCoord
GetCheckItemMargin() const
364 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
365 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
366 virtual wxSize
GetToolBarMargin() const
367 { return wxSize(4, 4); }
369 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
370 const wxRect
& rect
) const;
371 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
373 wxCoord
*extraSpaceBeyond
) const;
375 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
376 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
378 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
379 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
380 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
382 wxOrientation orient
,
383 long style
= 0) const;
384 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
386 wxOrientation orient
) const;
387 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
389 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
390 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
391 const wxMenu
& menu
) const;
393 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
396 // helper of DrawLabel() and DrawCheckOrRadioButton()
397 void DoDrawLabel(wxDC
& dc
,
398 const wxString
& label
,
401 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
403 wxRect
*rectBounds
= NULL
,
404 const wxPoint
& focusOffset
405 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
407 // common part of DrawLabel() and DrawItem()
408 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
410 // DrawLabel() and DrawButtonLabel() helper
411 void DrawLabelShadow(wxDC
& dc
,
412 const wxString
& label
,
417 // DrawButtonBorder() helper
418 void DoDrawBackground(wxDC
& dc
,
421 wxWindow
*window
= NULL
);
423 // DrawBorder() helpers: all of them shift and clip the DC after drawing
426 // just draw a rectangle with the given pen
427 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
429 // draw the lower left part of rectangle
430 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
432 // draw the rectange using the first brush for the left and top sides and
433 // the second one for the bottom and right ones
434 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
435 const wxPen
& pen1
, const wxPen
& pen2
);
437 // draw the normal 3D border
438 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
440 // draw the sunken 3D border
441 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
443 // draw the border used for scrollbar arrows
444 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
446 // public DrawArrow()s helper
447 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
448 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
450 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
451 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
452 wxArrowDirection arrowDir
,
453 wxArrowStyle arrowStyle
);
455 // DrawCheckButton/DrawRadioButton helper
456 void DrawCheckOrRadioButton(wxDC
& dc
,
457 const wxString
& label
,
458 const wxBitmap
& bitmap
,
463 wxCoord focusOffsetY
);
465 // draw a normal or transposed line (useful for using the same code fo both
466 // horizontal and vertical widgets)
467 void DrawLine(wxDC
& dc
,
468 wxCoord x1
, wxCoord y1
,
469 wxCoord x2
, wxCoord y2
,
470 bool transpose
= FALSE
)
473 dc
.DrawLine(y1
, x1
, y2
, x2
);
475 dc
.DrawLine(x1
, y1
, x2
, y2
);
478 // get the standard check/radio button bitmap
479 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
480 wxBitmap
GetCheckBitmap(int flags
)
481 { return GetIndicator(IndicatorType_Check
, flags
); }
482 wxBitmap
GetRadioBitmap(int flags
)
483 { return GetIndicator(IndicatorType_Radio
, flags
); }
486 const wxColourScheme
*m_scheme
;
488 // the sizing parameters (TODO make them changeable)
489 wxSize m_sizeScrollbarArrow
;
491 // GDI objects we use for drawing
492 wxColour m_colDarkGrey
,
500 wxFont m_titlebarFont
;
502 // the checked and unchecked bitmaps for DrawCheckItem()
503 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
505 // the bitmaps returned by GetIndicator()
506 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
508 [IndicatorStatus_Max
];
511 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
513 // first row is for the normal state, second - for the disabled
514 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
517 // ----------------------------------------------------------------------------
518 // wxWin32InputHandler and derived classes: process the keyboard and mouse
519 // messages according to Windows standards
520 // ----------------------------------------------------------------------------
522 class wxWin32InputHandler
: public wxInputHandler
525 wxWin32InputHandler(wxWin32Renderer
*renderer
);
527 virtual bool HandleKey(wxInputConsumer
*control
,
528 const wxKeyEvent
& event
,
530 virtual bool HandleMouse(wxInputConsumer
*control
,
531 const wxMouseEvent
& event
);
534 wxWin32Renderer
*m_renderer
;
537 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
540 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
541 wxInputHandler
*handler
);
543 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
544 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
546 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
547 const wxControlAction
& action
);
550 virtual bool IsAllowedButton(int button
) { return button
== 1; }
552 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
554 // we don't highlight anything
557 // the first and last event which caused the thumb to move
558 wxMouseEvent m_eventStartDrag
,
561 // have we paused the scrolling because the mouse moved?
564 // we remember the interval of the timer to be able to restart it
568 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
571 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
572 : wxStdCheckboxInputHandler(handler
) { }
574 virtual bool HandleKey(wxInputConsumer
*control
,
575 const wxKeyEvent
& event
,
579 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
582 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
583 : wxStdTextCtrlInputHandler(handler
) { }
585 virtual bool HandleKey(wxInputConsumer
*control
,
586 const wxKeyEvent
& event
,
590 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
593 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
595 virtual bool HandleMouse(wxInputConsumer
*consumer
,
596 const wxMouseEvent
& event
);
598 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
599 const wxMouseEvent
& event
);
602 // is the given point over the statusbar grip?
603 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
606 // the cursor we had replaced with the resize one
607 wxCursor m_cursorOld
;
609 // was the mouse over the grip last time we checked?
613 class wxWin32SystemMenuEvtHandler
;
615 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
618 wxWin32FrameInputHandler(wxInputHandler
*handler
);
619 ~wxWin32FrameInputHandler();
621 virtual bool HandleMouse(wxInputConsumer
*control
,
622 const wxMouseEvent
& event
);
624 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
626 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
629 // was the mouse over the grip last time we checked?
630 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
633 // ----------------------------------------------------------------------------
634 // wxWin32ColourScheme: uses (default) Win32 colours
635 // ----------------------------------------------------------------------------
637 class wxWin32ColourScheme
: public wxColourScheme
640 virtual wxColour
Get(StdColour col
) const;
641 virtual wxColour
GetBackground(wxWindow
*win
) const;
644 // ----------------------------------------------------------------------------
645 // wxWin32ArtProvider
646 // ----------------------------------------------------------------------------
648 class wxWin32ArtProvider
: public wxArtProvider
651 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
652 const wxArtClient
& client
,
656 // ----------------------------------------------------------------------------
658 // ----------------------------------------------------------------------------
660 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
662 class wxWin32Theme
: public wxTheme
666 virtual ~wxWin32Theme();
668 virtual wxRenderer
*GetRenderer();
669 virtual wxArtProvider
*GetArtProvider();
670 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
671 virtual wxColourScheme
*GetColourScheme();
674 // get the default input handler
675 wxInputHandler
*GetDefaultInputHandler();
677 wxWin32Renderer
*m_renderer
;
679 wxWin32ArtProvider
*m_artProvider
;
681 // the names of the already created handlers and the handlers themselves
682 // (these arrays are synchronized)
683 wxSortedArrayString m_handlerNames
;
684 wxArrayHandlers m_handlers
;
686 wxWin32InputHandler
*m_handlerDefault
;
688 wxWin32ColourScheme
*m_scheme
;
690 WX_DECLARE_THEME(win32
)
693 // ----------------------------------------------------------------------------
695 // ----------------------------------------------------------------------------
697 // frame buttons bitmaps
699 static const char *frame_button_close_xpm
[] = {
714 static const char *frame_button_help_xpm
[] = {
729 static const char *frame_button_maximize_xpm
[] = {
744 static const char *frame_button_minimize_xpm
[] = {
759 static const char *frame_button_restore_xpm
[] = {
776 static const char *checked_menu_xpm
[] = {
777 /* columns rows colors chars-per-pixel */
793 static const char *selected_checked_menu_xpm
[] = {
794 /* columns rows colors chars-per-pixel */
810 static const char *disabled_checked_menu_xpm
[] = {
811 /* columns rows colors chars-per-pixel */
828 static const char *selected_disabled_checked_menu_xpm
[] = {
829 /* columns rows colors chars-per-pixel */
845 // checkbox and radiobox bitmaps below
847 static const char *checked_xpm
[] = {
848 /* columns rows colors chars-per-pixel */
871 static const char *pressed_checked_xpm
[] = {
872 /* columns rows colors chars-per-pixel */
894 static const char *pressed_disabled_checked_xpm
[] = {
895 /* columns rows colors chars-per-pixel */
917 static const char *checked_item_xpm
[] = {
918 /* columns rows colors chars-per-pixel */
939 static const char *unchecked_xpm
[] = {
940 /* columns rows colors chars-per-pixel */
963 static const char *pressed_unchecked_xpm
[] = {
964 /* columns rows colors chars-per-pixel */
986 static const char *unchecked_item_xpm
[] = {
987 /* columns rows colors chars-per-pixel */
1007 static const char *checked_radio_xpm
[] = {
1008 /* columns rows colors chars-per-pixel */
1031 static const char *pressed_checked_radio_xpm
[] = {
1032 /* columns rows colors chars-per-pixel */
1055 static const char *pressed_disabled_checked_radio_xpm
[] = {
1056 /* columns rows colors chars-per-pixel */
1079 static const char *unchecked_radio_xpm
[] = {
1080 /* columns rows colors chars-per-pixel */
1103 static const char *pressed_unchecked_radio_xpm
[] = {
1104 /* columns rows colors chars-per-pixel */
1127 static const char **
1128 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1133 { checked_xpm
, unchecked_xpm
},
1136 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1139 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1145 { checked_radio_xpm
, unchecked_radio_xpm
},
1148 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1151 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1157 { checked_menu_xpm
, NULL
},
1160 { selected_checked_menu_xpm
, NULL
},
1163 { disabled_checked_menu_xpm
, NULL
},
1165 // disabled selected state
1166 { selected_disabled_checked_menu_xpm
, NULL
},
1170 static const char **xpmChecked
[IndicatorStatus_Max
] =
1176 // ============================================================================
1178 // ============================================================================
1180 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1182 // ----------------------------------------------------------------------------
1184 // ----------------------------------------------------------------------------
1186 wxWin32Theme::wxWin32Theme()
1190 m_handlerDefault
= NULL
;
1191 m_artProvider
= NULL
;
1194 wxWin32Theme::~wxWin32Theme()
1196 size_t count
= m_handlers
.GetCount();
1197 for ( size_t n
= 0; n
< count
; n
++ )
1199 if ( m_handlers
[n
] != m_handlerDefault
)
1200 delete m_handlers
[n
];
1203 delete m_handlerDefault
;
1207 wxArtProvider::RemoveProvider(m_artProvider
);
1210 wxRenderer
*wxWin32Theme::GetRenderer()
1214 m_renderer
= new wxWin32Renderer(GetColourScheme());
1220 wxArtProvider
*wxWin32Theme::GetArtProvider()
1222 if ( !m_artProvider
)
1224 m_artProvider
= new wxWin32ArtProvider
;
1227 return m_artProvider
;
1230 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1232 if ( !m_handlerDefault
)
1234 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1237 return m_handlerDefault
;
1240 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1242 wxInputHandler
*handler
;
1243 int n
= m_handlerNames
.Index(control
);
1244 if ( n
== wxNOT_FOUND
)
1246 // create a new handler
1247 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1248 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1249 GetDefaultInputHandler());
1251 else if ( control
== wxINP_HANDLER_BUTTON
)
1252 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1253 #endif // wxUSE_BUTTON
1255 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1256 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1257 #endif // wxUSE_CHECKBOX
1259 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1260 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1261 #endif // wxUSE_COMBOBOX
1263 else if ( control
== wxINP_HANDLER_LISTBOX
)
1264 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1265 #endif // wxUSE_LISTBOX
1266 #if wxUSE_CHECKLISTBOX
1267 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1268 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1269 #endif // wxUSE_CHECKLISTBOX
1271 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1272 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1273 #endif // wxUSE_TEXTCTRL
1275 else if ( control
== wxINP_HANDLER_SLIDER
)
1276 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1277 #endif // wxUSE_SLIDER
1279 else if ( control
== wxINP_HANDLER_SPINBTN
)
1280 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1281 #endif // wxUSE_SPINBTN
1283 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1284 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1285 #endif // wxUSE_NOTEBOOK
1287 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1288 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1289 #endif // wxUSE_STATUSBAR
1291 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1292 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1293 #endif // wxUSE_TOOLBAR
1294 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1295 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1297 handler
= GetDefaultInputHandler();
1299 n
= m_handlerNames
.Add(control
);
1300 m_handlers
.Insert(handler
, n
);
1302 else // we already have it
1304 handler
= m_handlers
[n
];
1310 wxColourScheme
*wxWin32Theme::GetColourScheme()
1314 m_scheme
= new wxWin32ColourScheme
;
1319 // ============================================================================
1320 // wxWin32ColourScheme
1321 // ============================================================================
1323 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1326 if ( win
->UseBgCol() )
1328 // use the user specified colour
1329 col
= win
->GetBackgroundColour();
1332 if ( win
->IsContainerWindow() )
1334 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1337 if ( !text
->IsEnabled() ) // not IsEditable()
1339 //else: execute code below
1344 // doesn't depend on the state
1350 int flags
= win
->GetStateFlags();
1352 // the colour set by the user should be used for the normal state
1353 // and for the states for which we don't have any specific colours
1354 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1356 if ( wxDynamicCast(win
, wxScrollBar
) )
1357 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1367 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1371 // use the system colours under Windows
1372 #if defined(__WXMSW__)
1373 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1375 case CONTROL_PRESSED
:
1376 case CONTROL_CURRENT
:
1377 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1379 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1381 #if defined(COLOR_3DLIGHT)
1382 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1384 case SCROLLBAR
: return wxColour(0xe0e0e0);
1386 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1388 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1389 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1391 #if defined(COLOR_3DDKSHADOW)
1392 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1394 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1397 case CONTROL_TEXT_DISABLED
:
1398 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1400 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1402 case CONTROL_TEXT_DISABLED_SHADOW
:
1403 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1405 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1406 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1407 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1408 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1410 case DESKTOP
: return wxColour(0x808000);
1412 // use the standard Windows colours elsewhere
1413 case WINDOW
: return *wxWHITE
;
1415 case CONTROL_PRESSED
:
1416 case CONTROL_CURRENT
:
1417 case CONTROL
: return wxColour(0xc0c0c0);
1419 case CONTROL_TEXT
: return *wxBLACK
;
1421 case SCROLLBAR
: return wxColour(0xe0e0e0);
1422 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1424 case HIGHLIGHT
: return wxColour(0x800000);
1425 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1427 case SHADOW_DARK
: return *wxBLACK
;
1429 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1430 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1432 case SHADOW_IN
: return wxColour(0xc0c0c0);
1434 case CONTROL_TEXT_DISABLED_SHADOW
:
1435 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1437 case TITLEBAR
: return wxColour(0xaeaaae);
1438 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1439 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1440 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1442 case DESKTOP
: return wxColour(0x808000);
1445 case GAUGE
: return Get(HIGHLIGHT
);
1449 wxFAIL_MSG(_T("invalid standard colour"));
1454 // ============================================================================
1456 // ============================================================================
1458 // ----------------------------------------------------------------------------
1460 // ----------------------------------------------------------------------------
1462 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1466 m_sizeScrollbarArrow
= wxSize(16, 16);
1468 // init colours and pens
1469 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1471 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1472 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1474 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1476 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1477 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1479 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1480 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1482 // init the arrow bitmaps
1483 static const size_t ARROW_WIDTH
= 7;
1484 static const size_t ARROW_LENGTH
= 4;
1487 wxMemoryDC dcNormal
,
1490 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1492 bool isVertical
= n
> Arrow_Right
;
1505 // disabled arrow is larger because of the shadow
1506 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1507 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1509 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1510 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1512 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1513 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1517 dcNormal
.SetPen(m_penBlack
);
1518 dcDisabled
.SetPen(m_penDarkGrey
);
1520 // calculate the position of the point of the arrow
1524 x1
= (ARROW_WIDTH
- 1)/2;
1525 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1529 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1530 y1
= (ARROW_WIDTH
- 1)/2;
1541 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1543 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1544 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1551 if ( n
== Arrow_Up
)
1562 else // left or right arrow
1567 if ( n
== Arrow_Left
)
1580 // draw the shadow for the disabled one
1581 dcDisabled
.SetPen(m_penHighlight
);
1586 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1590 x1
= ARROW_LENGTH
- 1;
1591 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1594 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1595 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1600 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1604 x1
= ARROW_WIDTH
- 1;
1606 x2
= (ARROW_WIDTH
- 1)/2;
1608 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1609 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1614 // create the inversed bitmap but only for the right arrow as we only
1615 // use it for the menus
1616 if ( n
== Arrow_Right
)
1618 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1619 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1621 dcInverse
.Blit(0, 0, w
, h
,
1624 dcInverse
.SelectObject(wxNullBitmap
);
1626 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1627 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1629 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1630 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1632 dcInverse
.Blit(0, 0, w
, h
,
1635 dcInverse
.SelectObject(wxNullBitmap
);
1637 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1638 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1641 dcNormal
.SelectObject(wxNullBitmap
);
1642 dcDisabled
.SelectObject(wxNullBitmap
);
1644 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1645 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1646 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1647 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1649 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1652 // init the frame buttons bitmaps
1653 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1654 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1655 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1656 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1657 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1660 // ----------------------------------------------------------------------------
1662 // ----------------------------------------------------------------------------
1665 The raised border in Win32 looks like this:
1667 IIIIIIIIIIIIIIIIIIIIIIB
1669 I GB I = white (HILIGHT)
1670 I GB H = light grey (LIGHT)
1671 I GB G = dark grey (SHADOI)
1672 I GB B = black (DKSHADOI)
1673 I GB I = hIghlight (COLOR_3DHILIGHT)
1675 IGGGGGGGGGGGGGGGGGGGGGB
1676 BBBBBBBBBBBBBBBBBBBBBBB
1678 The sunken border looks like this:
1680 GGGGGGGGGGGGGGGGGGGGGGI
1681 GBBBBBBBBBBBBBBBBBBBBHI
1688 GHHHHHHHHHHHHHHHHHHHHHI
1689 IIIIIIIIIIIIIIIIIIIIIII
1691 The static border (used for the controls which don't get focus) is like
1694 GGGGGGGGGGGGGGGGGGGGGGW
1702 WWWWWWWWWWWWWWWWWWWWWWW
1704 The most complicated is the double border:
1706 HHHHHHHHHHHHHHHHHHHHHHB
1707 HWWWWWWWWWWWWWWWWWWWWGB
1708 HWHHHHHHHHHHHHHHHHHHHGB
1713 HWHHHHHHHHHHHHHHHHHHHGB
1714 HGGGGGGGGGGGGGGGGGGGGGB
1715 BBBBBBBBBBBBBBBBBBBBBBB
1717 And the simple border is, well, simple:
1719 BBBBBBBBBBBBBBBBBBBBBBB
1728 BBBBBBBBBBBBBBBBBBBBBBB
1731 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1735 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1736 dc
.DrawRectangle(*rect
);
1742 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1744 // draw the bottom and right sides
1746 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1747 rect
->GetRight() + 1, rect
->GetBottom());
1748 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1749 rect
->GetRight(), rect
->GetBottom());
1755 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1756 const wxPen
& pen1
, const wxPen
& pen2
)
1758 // draw the rectangle
1760 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1761 rect
->GetLeft(), rect
->GetBottom());
1762 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1763 rect
->GetRight(), rect
->GetTop());
1765 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1766 rect
->GetRight(), rect
->GetBottom());
1767 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1768 rect
->GetRight() + 1, rect
->GetBottom());
1774 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1776 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1777 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1780 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1782 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1783 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1786 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1790 DrawRect(dc
, rect
, m_penDarkGrey
);
1792 // the arrow is usually drawn inside border of width 2 and is offset by
1793 // another pixel in both directions when it's pressed - as the border
1794 // in this case is more narrow as well, we have to adjust rect like
1802 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1803 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1807 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1809 const wxRect
& rectTotal
,
1810 int WXUNUSED(flags
),
1815 wxRect rect
= rectTotal
;
1819 case wxBORDER_SUNKEN
:
1820 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1822 DrawSunkenBorder(dc
, &rect
);
1826 case wxBORDER_STATIC
:
1827 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1830 case wxBORDER_RAISED
:
1831 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1833 DrawRaisedBorder(dc
, &rect
);
1837 case wxBORDER_DOUBLE
:
1838 DrawArrowBorder(dc
, &rect
);
1839 DrawRect(dc
, &rect
, m_penLightGrey
);
1842 case wxBORDER_SIMPLE
:
1843 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1845 DrawRect(dc
, &rect
, m_penBlack
);
1850 wxFAIL_MSG(_T("unknown border type"));
1853 case wxBORDER_DEFAULT
:
1862 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1867 case wxBORDER_RAISED
:
1868 case wxBORDER_SUNKEN
:
1869 width
= BORDER_THICKNESS
;
1872 case wxBORDER_SIMPLE
:
1873 case wxBORDER_STATIC
:
1877 case wxBORDER_DOUBLE
:
1883 // char *crash = NULL;
1885 wxFAIL_MSG(_T("unknown border type"));
1889 case wxBORDER_DEFAULT
:
1899 rect
.height
= width
;
1904 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1909 // ----------------------------------------------------------------------------
1911 // ----------------------------------------------------------------------------
1913 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1919 // text controls are not special under windows
1920 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1923 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1924 const wxRect
& rectTotal
,
1928 wxRect rect
= rectTotal
;
1930 if ( flags
& wxCONTROL_PRESSED
)
1932 // button pressed: draw a double border around it
1933 DrawRect(dc
, &rect
, m_penBlack
);
1934 DrawRect(dc
, &rect
, m_penDarkGrey
);
1938 // button not pressed
1940 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1942 // button either default or focused (or both): add an extra border around it
1943 DrawRect(dc
, &rect
, m_penBlack
);
1946 // now draw a normal button
1947 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1948 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1957 // ----------------------------------------------------------------------------
1959 // ----------------------------------------------------------------------------
1961 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1962 wxCoord y
, wxCoord x1
, wxCoord x2
)
1964 dc
.SetPen(m_penDarkGrey
);
1965 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1966 dc
.SetPen(m_penHighlight
);
1968 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1971 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1972 wxCoord x
, wxCoord y1
, wxCoord y2
)
1974 dc
.SetPen(m_penDarkGrey
);
1975 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1976 dc
.SetPen(m_penHighlight
);
1978 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1981 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1982 const wxString
& label
,
1988 wxCoord height
= 0; // of the label
1989 wxRect rectFrame
= rect
;
1990 if ( !label
.empty() )
1992 // the text should touch the top border of the rect, so the frame
1993 // itself should be lower
1994 dc
.GetTextExtent(label
, NULL
, &height
);
1995 rectFrame
.y
+= height
/ 2;
1996 rectFrame
.height
-= height
/ 2;
1998 // we have to draw each part of the frame individually as we can't
1999 // erase the background beyond the label as it might contain some
2000 // pixmap already, so drawing everything and then overwriting part of
2001 // the frame with label doesn't work
2003 // TODO: the +5 and space insertion should be customizable
2006 rectText
.x
= rectFrame
.x
+ 5;
2007 rectText
.y
= rect
.y
;
2008 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2009 rectText
.height
= height
;
2012 label2
<< _T(' ') << label
<< _T(' ');
2013 if ( indexAccel
!= -1 )
2015 // adjust it as we prepended a space
2020 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2022 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2026 // just draw the complete frame
2027 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2028 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2032 // ----------------------------------------------------------------------------
2034 // ----------------------------------------------------------------------------
2036 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2038 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2039 // pixels each while we really need dots here... PS_ALTERNATE might
2040 // work, but it is for NT 5 only
2042 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2044 // draw the pixels manually: note that to behave in the same manner as
2045 // DrawRect(), we must exclude the bottom and right borders from the
2047 wxCoord x1
= rect
.GetLeft(),
2049 x2
= rect
.GetRight(),
2050 y2
= rect
.GetBottom();
2052 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2054 // this seems to be closer than what Windows does than wxINVERT although
2055 // I'm still not sure if it's correct
2056 dc
.SetLogicalFunction(wxAND_REVERSE
);
2059 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2060 dc
.DrawPoint(z
, rect
.GetTop());
2062 wxCoord shift
= z
== x2
? 0 : 1;
2063 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2064 dc
.DrawPoint(x2
, z
);
2066 shift
= z
== y2
? 0 : 1;
2067 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2068 dc
.DrawPoint(z
, y2
);
2070 shift
= z
== x1
? 0 : 1;
2071 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2072 dc
.DrawPoint(x1
, z
);
2074 dc
.SetLogicalFunction(wxCOPY
);
2078 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2079 const wxString
& label
,
2084 // draw shadow of the text
2085 dc
.SetTextForeground(m_colHighlight
);
2086 wxRect rectShadow
= rect
;
2089 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2091 // make the text grey
2092 dc
.SetTextForeground(m_colDarkGrey
);
2095 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2096 const wxString
& label
,
2103 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2106 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2107 const wxString
& label
,
2113 const wxPoint
& focusOffset
)
2115 // the underscores are not drawn for focused controls in wxMSW
2116 if ( flags
& wxCONTROL_FOCUSED
)
2121 if ( flags
& wxCONTROL_DISABLED
)
2123 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2124 // currently only can happen for a menu item and it seems that Windows
2125 // doesn't draw the shadow in this case, so we don't do it neither
2126 if ( flags
& wxCONTROL_SELECTED
)
2128 // just make the label text greyed out
2129 dc
.SetTextForeground(m_colDarkGrey
);
2131 else // draw normal disabled label
2133 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2138 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2140 if ( flags
& wxCONTROL_DISABLED
)
2142 // restore the fg colour
2143 dc
.SetTextForeground(*wxBLACK
);
2146 if ( flags
& wxCONTROL_FOCUSED
)
2148 if ( focusOffset
.x
|| focusOffset
.y
)
2150 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2153 DrawFocusRect(dc
, rectLabel
);
2157 *rectBounds
= rectLabel
;
2160 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2161 const wxString
& label
,
2162 const wxBitmap
& image
,
2169 // the underscores are not drawn for focused controls in wxMSW
2170 if ( flags
& wxCONTROL_PRESSED
)
2175 wxRect rectLabel
= rect
;
2176 if ( !label
.empty() )
2178 // shift the label if a button is pressed
2179 if ( flags
& wxCONTROL_PRESSED
)
2185 if ( flags
& wxCONTROL_DISABLED
)
2187 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2190 // leave enough space for the focus rectangle
2191 if ( flags
& wxCONTROL_FOCUSED
)
2193 rectLabel
.Inflate(-2);
2197 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2199 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2201 if ( flags
& wxCONTROL_PRESSED
)
2203 // the focus rectangle is never pressed, so undo the shift done
2211 DrawFocusRect(dc
, rectLabel
);
2215 // ----------------------------------------------------------------------------
2216 // (check)listbox items
2217 // ----------------------------------------------------------------------------
2219 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2220 const wxString
& label
,
2224 wxDCTextColourChanger
colChanger(dc
);
2226 if ( flags
& wxCONTROL_SELECTED
)
2228 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2230 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2231 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2232 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2233 dc
.DrawRectangle(rect
);
2236 wxRect rectText
= rect
;
2238 rectText
.width
-= 2;
2239 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2241 if ( flags
& wxCONTROL_FOCUSED
)
2243 DrawFocusRect(dc
, rect
);
2247 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2248 const wxString
& label
,
2249 const wxBitmap
& bitmap
,
2258 else // use default bitmap
2260 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2261 ? IndicatorStatus_Checked
2262 : IndicatorStatus_Unchecked
;
2264 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2266 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2269 bmp
= m_bmpCheckBitmaps
[i
];
2272 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2273 TRUE
/* use mask */);
2275 wxRect rectLabel
= rect
;
2276 int bmpWidth
= bmp
.GetWidth();
2277 rectLabel
.x
+= bmpWidth
;
2278 rectLabel
.width
-= bmpWidth
;
2280 DrawItem(dc
, label
, rectLabel
, flags
);
2283 // ----------------------------------------------------------------------------
2284 // check/radio buttons
2285 // ----------------------------------------------------------------------------
2287 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2289 IndicatorState indState
;
2290 if ( flags
& wxCONTROL_SELECTED
)
2291 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2292 : IndicatorState_Selected
;
2293 else if ( flags
& wxCONTROL_DISABLED
)
2294 indState
= IndicatorState_Disabled
;
2295 else if ( flags
& wxCONTROL_PRESSED
)
2296 indState
= IndicatorState_Pressed
;
2298 indState
= IndicatorState_Normal
;
2300 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2301 ? IndicatorStatus_Checked
2302 : IndicatorStatus_Unchecked
;
2304 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2307 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2310 // create and cache it
2311 bmp
= wxBitmap(xpm
);
2312 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2319 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2320 const wxString
& label
,
2321 const wxBitmap
& bitmap
,
2326 wxCoord focusOffsetY
)
2328 // calculate the position of the bitmap and of the label
2329 wxCoord heightBmp
= bitmap
.GetHeight();
2331 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2334 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2335 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2337 // align label vertically with the bitmap - looks nicer like this
2338 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2340 // calc horz position
2341 if ( align
== wxALIGN_RIGHT
)
2343 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2344 rectLabel
.x
= rect
.x
+ 3;
2345 rectLabel
.SetRight(xBmp
);
2347 else // normal (checkbox to the left of the text) case
2350 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2351 rectLabel
.SetRight(rect
.GetRight());
2354 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2357 dc
, label
, rectLabel
,
2359 wxALIGN_LEFT
| wxALIGN_TOP
,
2361 NULL
, // we don't need bounding rect
2362 // use custom vert focus rect offset
2363 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2367 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2368 const wxString
& label
,
2369 const wxBitmap
& bitmap
,
2379 bmp
= GetRadioBitmap(flags
);
2381 DrawCheckOrRadioButton(dc
, label
,
2383 rect
, flags
, align
, indexAccel
,
2384 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2387 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2388 const wxString
& label
,
2389 const wxBitmap
& bitmap
,
2399 bmp
= GetCheckBitmap(flags
);
2401 DrawCheckOrRadioButton(dc
, label
,
2403 rect
, flags
, align
, indexAccel
,
2404 0); // no focus rect offset for checkboxes
2407 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2408 const wxString
& label
,
2409 const wxBitmap
& bitmap
,
2410 const wxRect
& rectOrig
,
2414 if (style
== wxTOOL_STYLE_BUTTON
)
2416 wxRect rect
= rectOrig
;
2417 rect
.Deflate(BORDER_THICKNESS
);
2419 if ( flags
& wxCONTROL_PRESSED
)
2421 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2423 else if ( flags
& wxCONTROL_CURRENT
)
2425 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2428 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2430 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2432 // leave a small gap aroudn the line, also account for the toolbar
2434 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2435 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2436 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2438 // don't draw wxTOOL_STYLE_CONTROL
2441 // ----------------------------------------------------------------------------
2443 // ----------------------------------------------------------------------------
2445 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2446 const wxString
& text
,
2452 // nothing special to do here
2453 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2456 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2458 // we don't draw them
2461 // ----------------------------------------------------------------------------
2463 // ----------------------------------------------------------------------------
2465 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2466 const wxRect
& rectOrig
,
2468 const wxString
& label
,
2469 const wxBitmap
& bitmap
,
2473 wxRect rect
= rectOrig
;
2475 // the current tab is drawn indented (to the top for default case) and
2476 // bigger than the other ones
2477 const wxSize indent
= GetTabIndent();
2478 if ( flags
& wxCONTROL_SELECTED
)
2483 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2487 rect
.Inflate(indent
.x
, 0);
2489 rect
.height
+= indent
.y
;
2493 rect
.Inflate(indent
.x
, 0);
2494 rect
.height
+= indent
.y
;
2499 wxFAIL_MSG(_T("TODO"));
2504 // draw the text, image and the focus around them (if necessary)
2505 wxRect rectLabel
= rect
;
2506 rectLabel
.Deflate(1, 1);
2507 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2508 flags
, wxALIGN_CENTRE
, indexAccel
);
2510 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2511 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2514 x2
= rect
.GetRight(),
2515 y2
= rect
.GetBottom();
2517 // FIXME: all this code will break if the tab indent or the border width,
2518 // it is tied to the fact that both of them are equal to 2
2523 dc
.SetPen(m_penHighlight
);
2524 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2525 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2526 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2528 dc
.SetPen(m_penBlack
);
2529 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2530 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2532 dc
.SetPen(m_penDarkGrey
);
2533 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2535 if ( flags
& wxCONTROL_SELECTED
)
2537 dc
.SetPen(m_penLightGrey
);
2539 // overwrite the part of the border below this tab
2540 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2542 // and the shadow of the tab to the left of us
2543 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2548 dc
.SetPen(m_penHighlight
);
2549 // we need to continue one pixel further to overwrite the corner of
2550 // the border for the selected tab
2551 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2553 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2555 dc
.SetPen(m_penBlack
);
2556 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2557 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2558 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2560 dc
.SetPen(m_penDarkGrey
);
2561 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2562 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2564 if ( flags
& wxCONTROL_SELECTED
)
2566 dc
.SetPen(m_penLightGrey
);
2568 // overwrite the part of the (double!) border above this tab
2569 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2570 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2572 // and the shadow of the tab to the left of us
2573 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2579 wxFAIL_MSG(_T("TODO"));
2583 // ----------------------------------------------------------------------------
2585 // ----------------------------------------------------------------------------
2587 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2589 wxOrientation orient
) const
2592 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2593 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2595 if (orient
== wxHORIZONTAL
)
2609 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2611 wxOrientation orient
,
2614 bool transpose
= (orient
== wxVERTICAL
);
2615 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2616 (((style
& wxSL_TOP
) != 0) & !transpose
|
2617 ((style
& wxSL_LEFT
) != 0) & transpose
|
2618 ((style
& wxSL_BOTH
) != 0));
2619 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2620 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2621 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2622 ((style
& wxSL_BOTH
) != 0));
2624 wxRect rect
= rectOrig
;
2626 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2628 if (orient
== wxHORIZONTAL
) {
2629 rect
.x
+= SLIDER_MARGIN
;
2632 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2636 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2640 rect
.y
+= sizeThumb
.y
/2;
2642 rect
.width
-= 2*SLIDER_MARGIN
;
2643 rect
.height
= 2*BORDER_THICKNESS
;
2647 rect
.y
+= SLIDER_MARGIN
;
2650 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2654 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2658 rect
.x
+= sizeThumb
.x
/2;
2660 rect
.width
= 2*BORDER_THICKNESS
;
2661 rect
.height
-= 2*SLIDER_MARGIN
;
2667 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2668 const wxRect
& rectOrig
,
2670 wxOrientation orient
,
2675 /* show shaft geometry
2693 if (flags
& wxCONTROL_FOCUSED
) {
2694 DrawFocusRect(dc
, rectOrig
);
2697 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2699 if (rectShaft
) *rectShaft
= rect
;
2701 DrawSunkenBorder(dc
, &rect
);
2704 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2706 wxOrientation orient
,
2710 /* show thumb geometry
2719 H D B where H is hightlight colour
2733 The interior of this shape is filled with the hatched brush if the thumb
2737 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2739 bool transpose
= (orient
== wxVERTICAL
);
2740 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2741 (((style
& wxSL_TOP
) != 0) & !transpose
|
2742 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2743 ((style
& wxSL_BOTH
) == 0);
2744 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2745 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2746 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2747 ((style
& wxSL_BOTH
) == 0);
2749 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2750 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2752 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2753 x1
= (transpose
? rect
.y
: rect
.x
);
2754 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2755 x3
= (x1
-1+c
) + sizeArrow
;
2756 y1
= (transpose
? rect
.x
: rect
.y
);
2757 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2758 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2759 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2761 dc
.SetPen(m_penBlack
);
2763 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2765 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2768 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2772 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2775 dc
.SetPen(m_penDarkGrey
);
2776 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2778 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2782 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2785 dc
.SetPen(m_penHighlight
);
2788 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2789 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2793 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2795 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2798 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2801 if (flags
& wxCONTROL_PRESSED
) {
2802 // TODO: MSW fills the entire area inside, not just the rect
2803 wxRect rectInt
= rect
;
2806 rectInt
.SetLeft(y3
);
2807 rectInt
.SetRight(y4
);
2812 rectInt
.SetBottom(y4
);
2816 #if !defined(__WXMGL__)
2817 static const char *stipple_xpm
[] = {
2818 /* columns rows colors chars-per-pixel */
2827 // VS: MGL can only do 8x8 stipple brushes
2828 static const char *stipple_xpm
[] = {
2829 /* columns rows colors chars-per-pixel */
2844 dc
.SetBrush(wxBrush(stipple_xpm
));
2846 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2847 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2848 dc
.SetPen(*wxTRANSPARENT_PEN
);
2849 dc
.DrawRectangle(rectInt
);
2853 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2856 wxOrientation orient
,
2863 /* show ticks geometry
2878 if (end
== start
) return;
2880 bool transpose
= (orient
== wxVERTICAL
);
2881 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2882 (((style
& wxSL_TOP
) != 0) & !transpose
|
2883 ((style
& wxSL_LEFT
) != 0) & transpose
|
2884 ((style
& wxSL_BOTH
) != 0));
2885 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2886 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2887 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2888 ((style
& wxSL_BOTH
) != 0));
2890 // default thumb size
2891 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2892 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
2894 // normal thumb size
2895 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2896 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
2898 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2900 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2901 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2902 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2903 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2904 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2905 y3
= (transpose
? rect
.x
: rect
.y
);
2906 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2909 dc
.SetPen(m_penBlack
);
2911 int range
= end
- start
;
2912 for ( int n
= 0; n
< range
; n
+= step
) {
2913 wxCoord x
= x1
+ (len
*n
) / range
;
2915 if (left
& (y1
> y3
)) {
2916 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2918 if (right
& (y4
> y2
)) {
2919 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2922 // always draw the line at the end position
2923 if (left
& (y1
> y3
)) {
2924 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2926 if (right
& (y4
> y2
)) {
2927 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2931 // ----------------------------------------------------------------------------
2933 // ----------------------------------------------------------------------------
2935 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2936 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2939 virtual wxSize
GetSize() const { return m_size
; }
2941 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2942 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2944 wxCoord
GetItemHeight() const { return m_heightItem
; }
2947 // the total size of the menu
2950 // the offset of the start of the menu item label
2953 // the offset of the start of the accel label
2956 // the height of a normal (not separator) item
2957 wxCoord m_heightItem
;
2959 friend wxMenuGeometryInfo
*
2960 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2963 // FIXME: all constants are hardcoded but shouldn't be
2964 static const wxCoord MENU_LEFT_MARGIN
= 9;
2965 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2966 static const wxCoord MENU_VERT_MARGIN
= 3;
2968 // the margin around bitmap/check marks (on each side)
2969 static const wxCoord MENU_BMP_MARGIN
= 2;
2971 // the margin between the labels and accel strings
2972 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2974 // the separator height in pixels: in fact, strangely enough, the real height
2975 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2977 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2979 // the size of the standard checkmark bitmap
2980 static const wxCoord MENU_CHECK_SIZE
= 9;
2982 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2983 const wxRect
& rectOrig
,
2984 const wxString
& label
,
2988 wxRect rect
= rectOrig
;
2991 wxDCTextColourChanger
colChanger(dc
);
2993 if ( flags
& wxCONTROL_SELECTED
)
2995 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2997 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2998 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2999 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3000 dc
.DrawRectangle(rect
);
3003 // don't draw the focus rect around menu bar items
3004 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3005 wxALIGN_CENTRE
, indexAccel
);
3008 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3010 const wxMenuGeometryInfo
& gi
,
3011 const wxString
& label
,
3012 const wxString
& accel
,
3013 const wxBitmap
& bitmap
,
3017 const wxWin32MenuGeometryInfo
& geometryInfo
=
3018 (const wxWin32MenuGeometryInfo
&)gi
;
3023 rect
.width
= geometryInfo
.GetSize().x
;
3024 rect
.height
= geometryInfo
.GetItemHeight();
3026 // draw the selected item specially
3027 wxDCTextColourChanger
colChanger(dc
);
3028 if ( flags
& wxCONTROL_SELECTED
)
3030 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3032 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3033 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3034 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3035 dc
.DrawRectangle(rect
);
3038 // draw the bitmap: use the bitmap provided or the standard checkmark for
3039 // the checkable items
3040 wxBitmap bmp
= bitmap
;
3041 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3043 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3048 rect
.SetRight(geometryInfo
.GetLabelOffset());
3049 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3053 rect
.x
= geometryInfo
.GetLabelOffset();
3054 rect
.SetRight(geometryInfo
.GetAccelOffset());
3056 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3058 // draw the accel string
3059 rect
.x
= geometryInfo
.GetAccelOffset();
3060 rect
.SetRight(geometryInfo
.GetSize().x
);
3062 // NB: no accel index here
3063 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3065 // draw the submenu indicator
3066 if ( flags
& wxCONTROL_ISSUBMENU
)
3068 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3069 rect
.width
= MENU_RIGHT_MARGIN
;
3071 wxArrowStyle arrowStyle
;
3072 if ( flags
& wxCONTROL_DISABLED
)
3073 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
3075 else if ( flags
& wxCONTROL_SELECTED
)
3076 arrowStyle
= Arrow_Inversed
;
3078 arrowStyle
= Arrow_Normal
;
3080 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3084 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3086 const wxMenuGeometryInfo
& geomInfo
)
3088 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3091 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3093 wxSize size
= sizeText
;
3095 // FIXME: menubar height is configurable under Windows
3102 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3103 const wxMenu
& menu
) const
3105 // prepare the dc: for now we draw all the items with the system font
3107 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3109 // the height of a normal item
3110 wxCoord heightText
= dc
.GetCharHeight();
3115 // the max length of label and accel strings: the menu width is the sum of
3116 // them, even if they're for different items (as the accels should be
3119 // the max length of the bitmap is never 0 as Windows always leaves enough
3120 // space for a check mark indicator
3121 wxCoord widthLabelMax
= 0,
3123 widthBmpMax
= MENU_LEFT_MARGIN
;
3125 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3127 node
= node
->GetNext() )
3129 // height of this item
3132 wxMenuItem
*item
= node
->GetData();
3133 if ( item
->IsSeparator() )
3135 h
= MENU_SEPARATOR_HEIGHT
;
3137 else // not separator
3142 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3143 if ( widthLabel
> widthLabelMax
)
3145 widthLabelMax
= widthLabel
;
3149 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3150 if ( widthAccel
> widthAccelMax
)
3152 widthAccelMax
= widthAccel
;
3155 const wxBitmap
& bmp
= item
->GetBitmap();
3158 wxCoord widthBmp
= bmp
.GetWidth();
3159 if ( widthBmp
> widthBmpMax
)
3160 widthBmpMax
= widthBmp
;
3162 //else if ( item->IsCheckable() ): no need to check for this as
3163 // MENU_LEFT_MARGIN is big enough to show the check mark
3166 h
+= 2*MENU_VERT_MARGIN
;
3168 // remember the item position and height
3169 item
->SetGeometry(height
, h
);
3174 // bundle the metrics into a struct and return it
3175 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3177 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3178 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3179 if ( widthAccelMax
> 0 )
3181 // if we actually have any accesl, add a margin
3182 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3185 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3187 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3188 gi
->m_size
.y
= height
;
3193 // ----------------------------------------------------------------------------
3195 // ----------------------------------------------------------------------------
3197 static const wxCoord STATBAR_BORDER_X
= 2;
3198 static const wxCoord STATBAR_BORDER_Y
= 2;
3200 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3202 if ( borderBetweenFields
)
3203 *borderBetweenFields
= 2;
3205 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3208 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3210 const wxString
& label
,
3215 if ( flags
& wxCONTROL_ISDEFAULT
)
3217 // draw the size grip: it is a normal rect except that in the lower
3218 // right corner we have several bands which may be used for dragging
3219 // the status bar corner
3221 // each band consists of 4 stripes: m_penHighlight, double
3222 // m_penDarkGrey and transparent one
3223 wxCoord x2
= rect
.GetRight(),
3224 y2
= rect
.GetBottom();
3226 // draw the upper left part of the rect normally
3227 dc
.SetPen(m_penDarkGrey
);
3228 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3229 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3231 // draw the grey stripes of the grip
3233 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3234 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3236 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3237 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3240 // draw the white stripes
3241 dc
.SetPen(m_penHighlight
);
3242 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3243 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3245 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3248 // draw the remaining rect boundaries
3249 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3250 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3251 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3256 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3260 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3263 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3265 wxDCClipper
clipper(dc
, rectIn
);
3266 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3269 // ----------------------------------------------------------------------------
3271 // ----------------------------------------------------------------------------
3273 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3275 wxBitmap
*bmpPressed
,
3276 wxBitmap
*bmpDisabled
)
3278 static const wxCoord widthCombo
= 16;
3279 static const wxCoord heightCombo
= 17;
3285 bmpNormal
->Create(widthCombo
, heightCombo
);
3286 dcMem
.SelectObject(*bmpNormal
);
3287 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3288 Arrow_Down
, Arrow_Normal
);
3293 bmpPressed
->Create(widthCombo
, heightCombo
);
3294 dcMem
.SelectObject(*bmpPressed
);
3295 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3296 Arrow_Down
, Arrow_Pressed
);
3301 bmpDisabled
->Create(widthCombo
, heightCombo
);
3302 dcMem
.SelectObject(*bmpDisabled
);
3303 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3304 Arrow_Down
, Arrow_Disabled
);
3308 // ----------------------------------------------------------------------------
3310 // ----------------------------------------------------------------------------
3312 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3313 const wxColour
& col
,
3317 wxBrush
brush(col
, wxSOLID
);
3319 dc
.SetPen(*wxTRANSPARENT_PEN
);
3320 dc
.DrawRectangle(rect
);
3323 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3324 const wxColour
& col
,
3329 // just fill it with the given or default bg colour
3330 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3331 DoDrawBackground(dc
, colBg
, rect
, window
);
3334 // ----------------------------------------------------------------------------
3336 // ----------------------------------------------------------------------------
3338 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3343 // get the bitmap for this arrow
3344 wxArrowDirection arrowDir
;
3347 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3348 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3349 case wxUP
: arrowDir
= Arrow_Up
; break;
3350 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3353 wxFAIL_MSG(_T("unknown arrow direction"));
3357 wxArrowStyle arrowStyle
;
3358 if ( flags
& wxCONTROL_PRESSED
)
3360 // can't be pressed and disabled
3361 arrowStyle
= Arrow_Pressed
;
3365 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3368 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3371 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3373 wxArrowDirection arrowDir
,
3374 wxArrowStyle arrowStyle
)
3376 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3378 // under Windows the arrows always have the same size so just centre it in
3379 // the provided rectangle
3380 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3381 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3383 // Windows does it like this...
3384 if ( arrowDir
== Arrow_Left
)
3388 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3391 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3392 const wxRect
& rectAll
,
3393 wxArrowDirection arrowDir
,
3394 wxArrowStyle arrowStyle
)
3396 wxRect rect
= rectAll
;
3397 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3398 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3399 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3402 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3403 wxOrientation orient
,
3407 // we don't use the flags, the thumb never changes appearance
3408 wxRect rectThumb
= rect
;
3409 DrawArrowBorder(dc
, &rectThumb
);
3410 DrawBackground(dc
, wxNullColour
, rectThumb
);
3413 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3414 wxOrientation orient
,
3415 const wxRect
& rectBar
,
3418 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3419 ? wxColourScheme::SCROLLBAR_PRESSED
3420 : wxColourScheme::SCROLLBAR
;
3421 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3424 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3426 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3429 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3430 wxScrollBar::Element elem
,
3433 return StandardGetScrollbarRect(scrollbar
, elem
,
3434 thumbPos
, m_sizeScrollbarArrow
);
3437 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3439 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3442 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3443 const wxPoint
& pt
) const
3445 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3448 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3451 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3454 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3457 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3460 // ----------------------------------------------------------------------------
3461 // top level windows
3462 // ----------------------------------------------------------------------------
3464 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3466 wxRect client
= GetFrameClientArea(rect
, flags
);
3468 if ( client
.Inside(pt
) )
3469 return wxHT_TOPLEVEL_CLIENT_AREA
;
3471 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3473 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3475 if ( flags
& wxTOPLEVEL_ICON
)
3477 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3478 return wxHT_TOPLEVEL_ICON
;
3481 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3482 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3483 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3485 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3487 if ( btnRect
.Inside(pt
) )
3488 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3489 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3491 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3493 if ( btnRect
.Inside(pt
) )
3494 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3495 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3497 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3499 if ( btnRect
.Inside(pt
) )
3500 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3501 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3503 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3505 if ( btnRect
.Inside(pt
) )
3506 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3507 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3509 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3511 if ( btnRect
.Inside(pt
) )
3512 return wxHT_TOPLEVEL_BUTTON_HELP
;
3513 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3516 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3517 return wxHT_TOPLEVEL_TITLEBAR
;
3520 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3522 // we are certainly at one of borders, lets decide which one:
3525 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3526 if ( pt
.x
< client
.x
)
3527 border
|= wxHT_TOPLEVEL_BORDER_W
;
3528 else if ( pt
.x
>= client
.width
+ client
.x
)
3529 border
|= wxHT_TOPLEVEL_BORDER_E
;
3530 if ( pt
.y
< client
.y
)
3531 border
|= wxHT_TOPLEVEL_BORDER_N
;
3532 else if ( pt
.y
>= client
.height
+ client
.y
)
3533 border
|= wxHT_TOPLEVEL_BORDER_S
;
3537 return wxHT_NOWHERE
;
3540 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3542 const wxString
& title
,
3546 int specialButtonFlags
)
3548 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3550 DrawFrameBorder(dc
, rect
, flags
);
3552 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3554 DrawFrameBackground(dc
, rect
, flags
);
3555 if ( flags
& wxTOPLEVEL_ICON
)
3556 DrawFrameIcon(dc
, rect
, icon
, flags
);
3557 DrawFrameTitle(dc
, rect
, title
, flags
);
3559 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3561 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3562 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3564 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3566 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3567 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3568 specialButtonFlags
: 0);
3569 x
-= FRAME_BUTTON_WIDTH
+ 2;
3571 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3573 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3574 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3575 specialButtonFlags
: 0);
3576 x
-= FRAME_BUTTON_WIDTH
;
3578 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3580 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3581 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3582 specialButtonFlags
: 0);
3583 x
-= FRAME_BUTTON_WIDTH
;
3585 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3587 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3588 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3589 specialButtonFlags
: 0);
3590 x
-= FRAME_BUTTON_WIDTH
;
3592 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3594 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3595 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3596 specialButtonFlags
: 0);
3597 x
-= FRAME_BUTTON_WIDTH
;
3602 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3606 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3610 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3611 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3612 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3613 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3614 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3617 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3621 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3623 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3624 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3625 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3627 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3628 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3630 DrawBackground(dc
, col
, r
);
3633 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3635 const wxString
& title
,
3638 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3639 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3640 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3642 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3643 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3644 if ( flags
& wxTOPLEVEL_ICON
)
3646 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3647 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3655 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3656 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3657 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3658 r
.width
-= FRAME_BUTTON_WIDTH
;
3659 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3660 r
.width
-= FRAME_BUTTON_WIDTH
;
3661 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3662 r
.width
-= FRAME_BUTTON_WIDTH
;
3663 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3664 r
.width
-= FRAME_BUTTON_WIDTH
;
3666 dc
.SetFont(m_titlebarFont
);
3667 dc
.SetTextForeground(col
);
3670 dc
.GetTextExtent(title
, &textW
, NULL
);
3671 if ( textW
> r
.width
)
3673 // text is too big, let's shorten it and add "..." after it:
3674 size_t len
= title
.length();
3675 wxCoord WSoFar
, letterW
;
3677 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3678 if ( WSoFar
> r
.width
)
3680 // not enough space to draw anything
3686 for (size_t i
= 0; i
< len
; i
++)
3688 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3689 if ( letterW
+ WSoFar
> r
.width
)
3695 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3696 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3699 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3700 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3703 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3710 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3711 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3715 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3716 wxCoord x
, wxCoord y
,
3720 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3725 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3726 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3727 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3728 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3729 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3731 wxFAIL_MSG(wxT("incorrect button specification"));
3734 if ( flags
& wxCONTROL_PRESSED
)
3736 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3737 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3738 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3739 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3743 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3744 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3745 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3746 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3751 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3756 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3758 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3759 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3760 FRAME_BORDER_THICKNESS
;
3763 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3765 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3766 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3772 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3775 wxSize
s(clientSize
);
3777 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3779 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3780 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3781 FRAME_BORDER_THICKNESS
;
3785 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3786 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3791 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3795 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3797 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3798 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3799 FRAME_BORDER_THICKNESS
;
3804 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3806 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3808 if ( flags
& wxTOPLEVEL_ICON
)
3809 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3810 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3811 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3812 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3813 s
.x
+= FRAME_BUTTON_WIDTH
;
3814 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3815 s
.x
+= FRAME_BUTTON_WIDTH
;
3816 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3817 s
.x
+= FRAME_BUTTON_WIDTH
;
3818 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3819 s
.x
+= FRAME_BUTTON_WIDTH
;
3825 wxSize
wxWin32Renderer::GetFrameIconSize() const
3827 return wxSize(16, 16);
3831 // ----------------------------------------------------------------------------
3833 // ----------------------------------------------------------------------------
3835 static char *error_xpm
[]={
3842 "...........########.............",
3843 "........###aaaaaaaa###..........",
3844 ".......#aaaaaaaaaaaaaa#.........",
3845 ".....##aaaaaaaaaaaaaaaa##.......",
3846 "....#aaaaaaaaaaaaaaaaaaaa#......",
3847 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3848 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3849 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3850 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3851 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3852 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3853 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3854 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3855 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3856 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3857 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3858 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3859 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3860 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3861 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3862 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3863 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3864 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3865 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3866 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3867 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3868 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3869 "......b#aaaaaaaaaaaaaa#bbbbb....",
3870 ".......b###aaaaaaaa###bbbbb.....",
3871 ".........bb########bbbbbb.......",
3872 "..........bbbbbbbbbbbbbb........",
3873 ".............bbbbbbbb..........."};
3875 static char *info_xpm
[]={
3883 "...........########.............",
3884 "........###abbbbbba###..........",
3885 "......##abbbbbbbbbbbba##........",
3886 ".....#abbbbbbbbbbbbbbbba#.......",
3887 "....#bbbbbbbaccccabbbbbbbd......",
3888 "...#bbbbbbbbccccccbbbbbbbbd.....",
3889 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3890 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3891 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3892 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3893 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3894 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3895 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3896 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3897 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3898 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3899 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3900 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3901 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3902 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3903 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3904 ".....dabbbbbbbbbbbbbbbbad####...",
3905 "......ddabbbbbbbbbbbbadd####....",
3906 ".......#dddabbbbbbaddd#####.....",
3907 "........###dddabbbd#######......",
3908 "..........####dbbbd#####........",
3909 ".............#dbbbd##...........",
3910 "...............dbbd##...........",
3911 "................dbd##...........",
3912 ".................dd##...........",
3913 "..................###...........",
3914 "...................##..........."};
3916 static char *question_xpm
[]={
3924 "...........########.............",
3925 "........###abbbbbba###..........",
3926 "......##abbbbbbbbbbbba##........",
3927 ".....#abbbbbbbbbbbbbbbba#.......",
3928 "....#bbbbbbbbbbbbbbbbbbbbc......",
3929 "...#bbbbbbbaddddddabbbbbbbc.....",
3930 "..#bbbbbbbadabbddddabbbbbbbc....",
3931 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3932 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3933 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3934 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3935 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3936 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3937 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3938 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3939 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3940 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3941 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3942 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3943 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3944 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3945 ".....cabbbbbbbbbbbbbbbbac####...",
3946 "......ccabbbbbbbbbbbbacc####....",
3947 ".......#cccabbbbbbaccc#####.....",
3948 "........###cccabbbc#######......",
3949 "..........####cbbbc#####........",
3950 ".............#cbbbc##...........",
3951 "...............cbbc##...........",
3952 "................cbc##...........",
3953 ".................cc##...........",
3954 "..................###...........",
3955 "...................##..........."};
3957 static char *warning_xpm
[]={
3965 ".............###................",
3966 "............#aabc...............",
3967 "...........#aaaabcd.............",
3968 "...........#aaaaacdd............",
3969 "..........#aaaaaabcdd...........",
3970 "..........#aaaaaaacdd...........",
3971 ".........#aaaaaaaabcdd..........",
3972 ".........#aaaaaaaaacdd..........",
3973 "........#aaaaaaaaaabcdd.........",
3974 "........#aaabcccbaaacdd.........",
3975 ".......#aaaacccccaaabcdd........",
3976 ".......#aaaacccccaaaacdd........",
3977 "......#aaaaacccccaaaabcdd.......",
3978 "......#aaaaacccccaaaaacdd.......",
3979 ".....#aaaaaacccccaaaaabcdd......",
3980 ".....#aaaaaa#ccc#aaaaaacdd......",
3981 "....#aaaaaaabcccbaaaaaabcdd.....",
3982 "....#aaaaaaaacccaaaaaaaacdd.....",
3983 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3984 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3985 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3986 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3987 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3988 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3989 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3990 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3991 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3992 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3993 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3994 "..#ccccccccccccccccccccccccddddd",
3995 "....ddddddddddddddddddddddddddd.",
3996 ".....ddddddddddddddddddddddddd.."};
3998 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3999 const wxArtClient
& WXUNUSED(client
),
4000 const wxSize
& WXUNUSED(size
))
4002 if ( id
== wxART_INFORMATION
)
4003 return wxBitmap(info_xpm
);
4004 if ( id
== wxART_ERROR
)
4005 return wxBitmap(error_xpm
);
4006 if ( id
== wxART_WARNING
)
4007 return wxBitmap(warning_xpm
);
4008 if ( id
== wxART_QUESTION
)
4009 return wxBitmap(question_xpm
);
4010 return wxNullBitmap
;
4014 // ----------------------------------------------------------------------------
4015 // text control geometry
4016 // ----------------------------------------------------------------------------
4018 static inline int GetTextBorderWidth()
4023 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
4024 const wxRect
& rect
) const
4026 wxRect rectTotal
= rect
;
4028 wxCoord widthBorder
= GetTextBorderWidth();
4029 rectTotal
.Inflate(widthBorder
);
4031 // this is what Windows does
4037 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
4039 wxCoord
*extraSpaceBeyond
) const
4041 wxRect rectText
= rect
;
4043 // undo GetTextTotalArea()
4044 if ( rectText
.height
> 0 )
4047 wxCoord widthBorder
= GetTextBorderWidth();
4048 rectText
.Inflate(-widthBorder
);
4050 if ( extraSpaceBeyond
)
4051 *extraSpaceBeyond
= 0;
4056 // ----------------------------------------------------------------------------
4058 // ----------------------------------------------------------------------------
4060 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4063 if ( wxDynamicCast(window
, wxScrollBar
) )
4065 // we only set the width of vert scrollbars and height of the
4067 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4068 size
->y
= m_sizeScrollbarArrow
.y
;
4070 size
->x
= m_sizeScrollbarArrow
.x
;
4072 // skip border width adjustments, they don't make sense for us
4075 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4078 if ( wxDynamicCast(window
, wxButton
) )
4080 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4082 // TODO: don't harcode all this
4083 size
->x
+= 3*window
->GetCharWidth();
4085 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4086 if ( size
->y
< heightBtn
- 8 )
4087 size
->y
= heightBtn
;
4092 // for compatibility with other ports, the buttons default size is never
4093 // less than the standard one, but not when display not PDAs.
4094 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4096 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4098 wxSize szDef
= wxButton::GetDefaultSize();
4099 if ( size
->x
< szDef
.x
)
4104 // no border width adjustments for buttons
4107 #endif // wxUSE_BUTTON
4109 // take into account the border width
4110 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4111 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4112 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4115 // ============================================================================
4117 // ============================================================================
4119 // ----------------------------------------------------------------------------
4120 // wxWin32InputHandler
4121 // ----------------------------------------------------------------------------
4123 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4125 m_renderer
= renderer
;
4128 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
4129 const wxKeyEvent
& event
,
4135 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4136 const wxMouseEvent
& event
)
4138 // clicking on the control gives it focus
4139 if ( event
.ButtonDown() )
4141 wxWindow
*win
= control
->GetInputWindow();
4143 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4144 ( win
->AcceptsFocus() ) )
4155 // ----------------------------------------------------------------------------
4156 // wxWin32ScrollBarInputHandler
4157 // ----------------------------------------------------------------------------
4159 wxWin32ScrollBarInputHandler::
4160 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4161 wxInputHandler
*handler
)
4162 : wxStdScrollBarInputHandler(renderer
, handler
)
4164 m_scrollPaused
= FALSE
;
4168 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4169 const wxControlAction
& action
)
4171 // stop if went beyond the position of the original click (this can only
4172 // happen when we scroll by pages)
4174 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4176 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4177 != wxHT_SCROLLBAR_BAR_2
;
4179 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4181 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4182 != wxHT_SCROLLBAR_BAR_1
;
4187 StopScrolling(scrollbar
);
4189 scrollbar
->Refresh();
4194 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4197 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4198 const wxMouseEvent
& event
)
4200 // remember the current state
4201 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4203 // do process the message
4204 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4206 // analyse the changes
4207 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4209 // we just started dragging the thumb, remember its initial position to
4210 // be able to restore it if the drag is cancelled later
4211 m_eventStartDrag
= event
;
4217 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4218 const wxMouseEvent
& event
)
4220 // we don't highlight scrollbar elements, so there is no need to process
4221 // mouse move events normally - only do it while mouse is captured (i.e.
4222 // when we're dragging the thumb or pressing on something)
4223 if ( !m_winCapture
)
4226 if ( event
.Entering() )
4228 // we're not interested in this at all
4232 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4234 if ( m_scrollPaused
)
4236 // check if the mouse returned to its original location
4238 if ( event
.Leaving() )
4244 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4245 if ( ht
== m_htLast
)
4247 // yes it did, resume scrolling
4248 m_scrollPaused
= FALSE
;
4249 if ( m_timerScroll
)
4251 // we were scrolling by line/page, restart timer
4252 m_timerScroll
->Start(m_interval
);
4254 Press(scrollbar
, TRUE
);
4256 else // we were dragging the thumb
4258 // restore its last location
4259 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4265 else // normal case, scrolling hasn't been paused
4267 // if we're scrolling the scrollbar because the arrow or the shaft was
4268 // pressed, check that the mouse stays on the same scrollbar element
4271 // Always let thumb jump back if we leave the scrollbar
4272 if ( event
.Moving() )
4274 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4276 else // event.Leaving()
4281 // Jump back only if we get far away from it
4282 wxPoint pos
= event
.GetPosition();
4283 if (scrollbar
->HasFlag( wxVERTICAL
))
4285 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4290 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4293 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4296 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4297 // is still ok - we only want to catch the case when the mouse leaves
4298 // the scrollbar here
4299 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4301 ht
= wxHT_SCROLLBAR_THUMB
;
4304 if ( ht
!= m_htLast
)
4306 // what were we doing? 2 possibilities: either an arrow/shaft was
4307 // pressed in which case we have a timer and so we just stop it or
4308 // we were dragging the thumb
4309 if ( m_timerScroll
)
4312 m_interval
= m_timerScroll
->GetInterval();
4313 m_timerScroll
->Stop();
4314 m_scrollPaused
= TRUE
;
4316 // unpress the arrow
4317 Press(scrollbar
, FALSE
);
4319 else // we were dragging the thumb
4321 // remember the current thumb position to be able to restore it
4322 // if the mouse returns to it later
4323 m_eventLastDrag
= event
;
4325 // and restore the original position (before dragging) of the
4327 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4334 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4337 // ----------------------------------------------------------------------------
4338 // wxWin32CheckboxInputHandler
4339 // ----------------------------------------------------------------------------
4341 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4342 const wxKeyEvent
& event
,
4347 wxControlAction action
;
4348 int keycode
= event
.GetKeyCode();
4352 action
= wxACTION_CHECKBOX_TOGGLE
;
4356 case WXK_NUMPAD_SUBTRACT
:
4357 action
= wxACTION_CHECKBOX_CHECK
;
4361 case WXK_NUMPAD_ADD
:
4362 case WXK_NUMPAD_EQUAL
:
4363 action
= wxACTION_CHECKBOX_CLEAR
;
4369 control
->PerformAction(action
);
4378 // ----------------------------------------------------------------------------
4379 // wxWin32TextCtrlInputHandler
4380 // ----------------------------------------------------------------------------
4382 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4383 const wxKeyEvent
& event
,
4386 // handle only MSW-specific text bindings here, the others are handled in
4390 int keycode
= event
.GetKeyCode();
4392 wxControlAction action
;
4393 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4395 action
= wxACTION_TEXT_CUT
;
4397 else if ( keycode
== WXK_INSERT
)
4399 if ( event
.ControlDown() )
4400 action
= wxACTION_TEXT_COPY
;
4401 else if ( event
.ShiftDown() )
4402 action
= wxACTION_TEXT_PASTE
;
4405 if ( action
!= wxACTION_NONE
)
4407 control
->PerformAction(action
);
4413 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4416 // ----------------------------------------------------------------------------
4417 // wxWin32StatusBarInputHandler
4418 // ----------------------------------------------------------------------------
4420 wxWin32StatusBarInputHandler::
4421 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4422 : wxStdInputHandler(handler
)
4427 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4428 const wxPoint
& pt
) const
4430 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4431 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4434 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4436 wxCHECK_MSG( parentTLW
, FALSE
,
4437 _T("the status bar should be a child of a TLW") );
4439 // a maximized window can't be resized anyhow
4440 if ( !parentTLW
->IsMaximized() )
4442 // VZ: I think that the standard Windows behaviour is to only
4443 // show the resizing cursor when the mouse is on top of the
4444 // grip itself but apparently different Windows versions behave
4445 // differently (?) and it seems a better UI to allow resizing
4446 // the status bar even when the mouse is above the grip
4447 wxSize sizeSbar
= statbar
->GetSize();
4449 int diff
= sizeSbar
.x
- pt
.x
;
4450 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4457 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4458 const wxMouseEvent
& event
)
4460 if ( event
.Button(1) )
4462 if ( event
.ButtonDown(1) )
4464 wxWindow
*statbar
= consumer
->GetInputWindow();
4466 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4468 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4472 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4473 wxHT_TOPLEVEL_BORDER_SE
);
4475 statbar
->SetCursor(m_cursorOld
);
4483 return wxStdInputHandler::HandleMouse(consumer
, event
);
4486 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4487 const wxMouseEvent
& event
)
4489 wxWindow
*statbar
= consumer
->GetInputWindow();
4491 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4492 if ( isOnGrip
!= m_isOnGrip
)
4494 m_isOnGrip
= isOnGrip
;
4497 m_cursorOld
= statbar
->GetCursor();
4498 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4502 statbar
->SetCursor(m_cursorOld
);
4506 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4509 // ----------------------------------------------------------------------------
4510 // wxWin32FrameInputHandler
4511 // ----------------------------------------------------------------------------
4513 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4516 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4518 void Attach(wxInputConsumer
*consumer
);
4522 DECLARE_EVENT_TABLE()
4523 void OnSystemMenu(wxCommandEvent
&event
);
4524 void OnCloseFrame(wxCommandEvent
&event
);
4525 void OnClose(wxCloseEvent
&event
);
4527 wxWin32FrameInputHandler
*m_inputHnd
;
4528 wxTopLevelWindow
*m_wnd
;
4529 wxAcceleratorTable m_oldAccelTable
;
4532 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4533 wxWin32FrameInputHandler
*handler
)
4535 m_inputHnd
= handler
;
4539 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4541 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4543 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4544 m_wnd
->PushEventHandler(this);
4546 // VS: This code relies on using generic implementation of
4547 // wxAcceleratorTable in wxUniv!
4548 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4549 m_oldAccelTable
= table
;
4550 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4551 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4552 m_wnd
->SetAcceleratorTable(table
);
4555 void wxWin32SystemMenuEvtHandler::Detach()
4559 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4560 m_wnd
->RemoveEventHandler(this);
4565 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4566 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4567 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4568 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4571 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4573 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4574 !m_wnd
->IsMaximized()) ?
4575 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4576 FRAME_BORDER_THICKNESS
;
4577 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4578 pt
.x
= -pt
.x
+ border
;
4579 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4581 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4582 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4583 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4584 m_wnd
->SetAcceleratorTable(table
);
4587 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4589 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4590 wxTOPLEVEL_BUTTON_CLOSE
);
4593 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4600 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4601 : wxStdFrameInputHandler(handler
)
4603 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4606 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4608 if ( m_menuHandler
)
4610 m_menuHandler
->Detach();
4611 delete m_menuHandler
;
4615 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4616 const wxMouseEvent
& event
)
4618 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4620 wxTopLevelWindow
*tlw
=
4621 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4623 long hit
= tlw
->HitTest(event
.GetPosition());
4625 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4627 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4628 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4629 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4632 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4634 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4635 (event
.RightDown() &&
4636 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4637 hit
== wxHT_TOPLEVEL_ICON
)) )
4639 PopupSystemMenu(tlw
, event
.GetPosition());
4645 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4648 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4649 const wxPoint
& pos
) const
4651 wxMenu
*menu
= new wxMenu
;
4653 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4654 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4655 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4656 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4657 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4658 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4659 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4660 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4661 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4662 menu
->AppendSeparator();
4663 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4665 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4667 if ( window
->IsMaximized() )
4669 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4670 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4671 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4672 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4675 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4678 window
->PopupMenu(menu
, pos
);
4682 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4685 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4687 // always detach if active frame changed:
4688 m_menuHandler
->Detach();
4692 m_menuHandler
->Attach(consumer
);
4696 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);