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 license
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"
43 // for COLOR_* constants
44 #include "wx/msw/private.h"
48 #include "wx/notebook.h"
49 #include "wx/spinbutt.h"
50 #include "wx/settings.h"
53 #include "wx/univ/scrtimer.h"
54 #include "wx/toplevel.h"
55 #include "wx/univ/renderer.h"
56 #include "wx/univ/inphand.h"
57 #include "wx/univ/colschem.h"
58 #include "wx/univ/theme.h"
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 static const int BORDER_THICKNESS
= 2;
66 // the offset between the label and focus rect around it
67 static const int FOCUS_RECT_OFFSET_X
= 1;
68 static const int FOCUS_RECT_OFFSET_Y
= 1;
70 static const int FRAME_BORDER_THICKNESS
= 3;
71 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
72 static const int FRAME_TITLEBAR_HEIGHT
= 18;
73 static const int FRAME_BUTTON_WIDTH
= 16;
74 static const int FRAME_BUTTON_HEIGHT
= 14;
76 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
77 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
78 static const size_t STATUSBAR_GRIP_SIZE
=
79 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
91 IndicatorState_Normal
,
92 IndicatorState_Pressed
, // this one is for check/radioboxes
93 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
94 IndicatorState_Disabled
,
95 IndicatorState_SelectedDisabled
, // only for the menus
101 IndicatorStatus_Checked
,
102 IndicatorStatus_Unchecked
,
106 // wxWin32Renderer: draw the GUI elements in Win32 style
107 // ----------------------------------------------------------------------------
109 class wxWin32Renderer
: public wxRenderer
113 enum wxArrowDirection
128 Arrow_InversedDisabled
,
132 enum wxFrameButtonType
135 FrameButton_Minimize
,
136 FrameButton_Maximize
,
143 wxWin32Renderer(const wxColourScheme
*scheme
);
145 // implement the base class pure virtuals
146 virtual void DrawBackground(wxDC
& dc
,
150 virtual void DrawLabel(wxDC
& dc
,
151 const wxString
& label
,
154 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
156 wxRect
*rectBounds
= NULL
);
157 virtual void DrawButtonLabel(wxDC
& dc
,
158 const wxString
& label
,
159 const wxBitmap
& image
,
162 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
164 wxRect
*rectBounds
= NULL
);
165 virtual void DrawBorder(wxDC
& dc
,
169 wxRect
*rectIn
= (wxRect
*)NULL
);
170 virtual void DrawHorizontalLine(wxDC
& dc
,
171 wxCoord y
, wxCoord x1
, wxCoord x2
);
172 virtual void DrawVerticalLine(wxDC
& dc
,
173 wxCoord x
, wxCoord y1
, wxCoord y2
);
174 virtual void DrawFrame(wxDC
& dc
,
175 const wxString
& label
,
178 int alignment
= wxALIGN_LEFT
,
179 int indexAccel
= -1);
180 virtual void DrawTextBorder(wxDC
& dc
,
184 wxRect
*rectIn
= (wxRect
*)NULL
);
185 virtual void DrawButtonBorder(wxDC
& dc
,
188 wxRect
*rectIn
= (wxRect
*)NULL
);
189 virtual void DrawArrow(wxDC
& dc
,
193 virtual void DrawScrollbarArrow(wxDC
& dc
,
197 { DrawArrow(dc
, dir
, rect
, flags
); }
198 virtual void DrawScrollbarThumb(wxDC
& dc
,
199 wxOrientation orient
,
202 virtual void DrawScrollbarShaft(wxDC
& dc
,
203 wxOrientation orient
,
206 virtual void DrawScrollCorner(wxDC
& dc
,
208 virtual void DrawItem(wxDC
& dc
,
209 const wxString
& label
,
212 virtual void DrawCheckItem(wxDC
& dc
,
213 const wxString
& label
,
214 const wxBitmap
& bitmap
,
217 virtual void DrawCheckButton(wxDC
& dc
,
218 const wxString
& label
,
219 const wxBitmap
& bitmap
,
222 wxAlignment align
= wxALIGN_LEFT
,
223 int indexAccel
= -1);
224 virtual void DrawRadioButton(wxDC
& dc
,
225 const wxString
& label
,
226 const wxBitmap
& bitmap
,
229 wxAlignment align
= wxALIGN_LEFT
,
230 int indexAccel
= -1);
231 virtual void DrawTextLine(wxDC
& dc
,
232 const wxString
& text
,
237 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
238 virtual void DrawTab(wxDC
& dc
,
241 const wxString
& label
,
242 const wxBitmap
& bitmap
= wxNullBitmap
,
244 int indexAccel
= -1);
246 virtual void DrawSliderShaft(wxDC
& dc
,
248 wxOrientation orient
,
250 wxRect
*rectShaft
= NULL
);
251 virtual void DrawSliderThumb(wxDC
& dc
,
253 wxOrientation orient
,
255 virtual void DrawSliderTicks(wxDC
& dc
,
257 const wxSize
& sizeThumb
,
258 wxOrientation orient
,
264 virtual void DrawMenuBarItem(wxDC
& dc
,
266 const wxString
& label
,
268 int indexAccel
= -1);
269 virtual void DrawMenuItem(wxDC
& dc
,
271 const wxMenuGeometryInfo
& geometryInfo
,
272 const wxString
& label
,
273 const wxString
& accel
,
274 const wxBitmap
& bitmap
= wxNullBitmap
,
276 int indexAccel
= -1);
277 virtual void DrawMenuSeparator(wxDC
& dc
,
279 const wxMenuGeometryInfo
& geomInfo
);
281 virtual void DrawStatusField(wxDC
& dc
,
283 const wxString
& label
,
287 virtual void DrawFrameTitleBar(wxDC
& dc
,
289 const wxString
& title
,
292 int specialButton
= 0,
293 int specialButtonFlags
= 0);
294 virtual void DrawFrameBorder(wxDC
& dc
,
297 virtual void DrawFrameBackground(wxDC
& dc
,
300 virtual void DrawFrameTitle(wxDC
& dc
,
302 const wxString
& title
,
304 virtual void DrawFrameIcon(wxDC
& dc
,
308 virtual void DrawFrameButton(wxDC
& dc
,
309 wxCoord x
, wxCoord y
,
312 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
313 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
314 virtual wxSize
GetFrameIconSize() const;
315 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
317 virtual wxIcon
GetStdIcon(int which
) const;
319 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
321 wxBitmap
*bmpPressed
,
322 wxBitmap
*bmpDisabled
);
324 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
325 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
326 virtual bool AreScrollbarsInsideBorder() const;
328 virtual wxSize
GetScrollbarArrowSize() const
329 { return m_sizeScrollbarArrow
; }
330 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
331 wxScrollBar::Element elem
,
332 int thumbPos
= -1) const;
333 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
334 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
335 const wxPoint
& pt
) const;
336 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
338 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
339 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
340 { return fontHeight
+ 2; }
341 virtual wxSize
GetCheckBitmapSize() const
342 { return wxSize(13, 13); }
343 virtual wxSize
GetRadioBitmapSize() const
344 { return wxSize(12, 12); }
345 virtual wxCoord
GetCheckItemMargin() const
348 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
350 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
352 wxCoord
*extraSpaceBeyond
);
354 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
355 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
357 virtual wxCoord
GetSliderDim() const { return 20; }
358 virtual wxCoord
GetSliderTickLen() const { return 4; }
359 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
360 wxOrientation orient
) const;
361 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
362 wxOrientation orient
) const;
363 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
365 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
366 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
367 const wxMenu
& menu
) const;
369 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
372 // helper of DrawLabel() and DrawCheckOrRadioButton()
373 void DoDrawLabel(wxDC
& dc
,
374 const wxString
& label
,
377 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
379 wxRect
*rectBounds
= NULL
,
380 const wxPoint
& focusOffset
381 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
383 // common part of DrawLabel() and DrawItem()
384 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
386 // DrawLabel() and DrawButtonLabel() helper
387 void DrawLabelShadow(wxDC
& dc
,
388 const wxString
& label
,
393 // DrawButtonBorder() helper
394 void DoDrawBackground(wxDC
& dc
,
398 // DrawBorder() helpers: all of them shift and clip the DC after drawing
401 // just draw a rectangle with the given pen
402 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
404 // draw the lower left part of rectangle
405 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
407 // draw the rectange using the first brush for the left and top sides and
408 // the second one for the bottom and right ones
409 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
410 const wxPen
& pen1
, const wxPen
& pen2
);
412 // draw the normal 3D border
413 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
415 // draw the sunken 3D border
416 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
418 // draw the border used for scrollbar arrows
419 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
421 // public DrawArrow()s helper
422 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
423 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
425 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
426 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
427 wxArrowDirection arrowDir
,
428 wxArrowStyle arrowStyle
);
430 // DrawCheckButton/DrawRadioButton helper
431 void DrawCheckOrRadioButton(wxDC
& dc
,
432 const wxString
& label
,
433 const wxBitmap
& bitmap
,
438 wxCoord focusOffsetY
);
440 // draw a normal or transposed line (useful for using the same code fo both
441 // horizontal and vertical widgets)
442 void DrawLine(wxDC
& dc
,
443 wxCoord x1
, wxCoord y1
,
444 wxCoord x2
, wxCoord y2
,
445 bool transpose
= FALSE
)
448 dc
.DrawLine(y1
, x1
, y2
, x2
);
450 dc
.DrawLine(x1
, y1
, x2
, y2
);
453 // get the standard check/radio button bitmap
454 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
455 wxBitmap
GetCheckBitmap(int flags
)
456 { return GetIndicator(IndicatorType_Check
, flags
); }
457 wxBitmap
GetRadioBitmap(int flags
)
458 { return GetIndicator(IndicatorType_Radio
, flags
); }
461 const wxColourScheme
*m_scheme
;
463 // the sizing parameters (TODO make them changeable)
464 wxSize m_sizeScrollbarArrow
;
466 // GDI objects we use for drawing
467 wxColour m_colDarkGrey
,
475 wxFont m_titlebarFont
;
478 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
480 // first row is for the normal state, second - for the disabled
481 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
484 // ----------------------------------------------------------------------------
485 // wxWin32InputHandler and derived classes: process the keyboard and mouse
486 // messages according to Windows standards
487 // ----------------------------------------------------------------------------
489 class wxWin32InputHandler
: public wxInputHandler
492 wxWin32InputHandler(wxWin32Renderer
*renderer
);
494 virtual bool HandleKey(wxInputConsumer
*control
,
495 const wxKeyEvent
& event
,
497 virtual bool HandleMouse(wxInputConsumer
*control
,
498 const wxMouseEvent
& event
);
501 wxWin32Renderer
*m_renderer
;
504 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
507 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
508 wxInputHandler
*handler
);
510 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
511 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
513 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
514 const wxControlAction
& action
);
517 virtual bool IsAllowedButton(int button
) { return button
== 1; }
519 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
521 // we don't highlight anything
524 // the first and last event which caused the thumb to move
525 wxMouseEvent m_eventStartDrag
,
528 // have we paused the scrolling because the mouse moved?
531 // we remember the interval of the timer to be able to restart it
535 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
538 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
539 : wxStdCheckboxInputHandler(handler
) { }
541 virtual bool HandleKey(wxInputConsumer
*control
,
542 const wxKeyEvent
& event
,
546 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
549 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
550 : wxStdTextCtrlInputHandler(handler
) { }
552 virtual bool HandleKey(wxInputConsumer
*control
,
553 const wxKeyEvent
& event
,
557 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
560 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
562 virtual bool HandleMouse(wxInputConsumer
*consumer
,
563 const wxMouseEvent
& event
);
565 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
566 const wxMouseEvent
& event
);
569 // is the given point over the statusbar grip?
570 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
573 // the cursor we had replaced with the resize one
574 wxCursor m_cursorOld
;
576 // was the mouse over the grip last time we checked?
580 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
583 wxWin32FrameInputHandler(wxInputHandler
*handler
)
584 : wxStdFrameInputHandler(handler
) { }
586 virtual bool HandleMouse(wxInputConsumer
*control
,
587 const wxMouseEvent
& event
);
590 // ----------------------------------------------------------------------------
591 // wxWin32ColourScheme: uses (default) Win32 colours
592 // ----------------------------------------------------------------------------
594 class wxWin32ColourScheme
: public wxColourScheme
597 virtual wxColour
Get(StdColour col
) const;
598 virtual wxColour
GetBackground(wxWindow
*win
) const;
601 // ----------------------------------------------------------------------------
603 // ----------------------------------------------------------------------------
605 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
607 class wxWin32Theme
: public wxTheme
611 virtual ~wxWin32Theme();
613 virtual wxRenderer
*GetRenderer();
614 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
615 virtual wxColourScheme
*GetColourScheme();
618 // get the default input handler
619 wxInputHandler
*GetDefaultInputHandler();
621 wxWin32Renderer
*m_renderer
;
623 // the names of the already created handlers and the handlers themselves
624 // (these arrays are synchronized)
625 wxSortedArrayString m_handlerNames
;
626 wxArrayHandlers m_handlers
;
628 wxWin32InputHandler
*m_handlerDefault
;
630 wxWin32ColourScheme
*m_scheme
;
632 WX_DECLARE_THEME(win32
)
635 // ----------------------------------------------------------------------------
637 // ----------------------------------------------------------------------------
639 // frame buttons bitmaps
641 static const char *frame_button_close_xpm
[] = {
656 static const char *frame_button_help_xpm
[] = {
671 static const char *frame_button_maximize_xpm
[] = {
686 static const char *frame_button_minimize_xpm
[] = {
701 static const char *frame_button_restore_xpm
[] = {
718 static const char *checked_menu_xpm
[] = {
719 /* columns rows colors chars-per-pixel */
735 static const char *selected_checked_menu_xpm
[] = {
736 /* columns rows colors chars-per-pixel */
752 static const char *disabled_checked_menu_xpm
[] = {
753 /* columns rows colors chars-per-pixel */
770 static const char *selected_disabled_checked_menu_xpm
[] = {
771 /* columns rows colors chars-per-pixel */
787 // checkbox and radiobox bitmaps below
789 static const char *checked_xpm
[] = {
790 /* columns rows colors chars-per-pixel */
813 static const char *pressed_checked_xpm
[] = {
814 /* columns rows colors chars-per-pixel */
836 static const char *pressed_disabled_checked_xpm
[] = {
837 /* columns rows colors chars-per-pixel */
859 static const char *checked_item_xpm
[] = {
860 /* columns rows colors chars-per-pixel */
881 static const char *unchecked_xpm
[] = {
882 /* columns rows colors chars-per-pixel */
905 static const char *pressed_unchecked_xpm
[] = {
906 /* columns rows colors chars-per-pixel */
928 static const char *unchecked_item_xpm
[] = {
929 /* columns rows colors chars-per-pixel */
949 static const char *checked_radio_xpm
[] = {
950 /* columns rows colors chars-per-pixel */
973 static const char *pressed_checked_radio_xpm
[] = {
974 /* columns rows colors chars-per-pixel */
997 static const char *pressed_disabled_checked_radio_xpm
[] = {
998 /* columns rows colors chars-per-pixel */
1021 static const char *unchecked_radio_xpm
[] = {
1022 /* columns rows colors chars-per-pixel */
1045 static const char *pressed_unchecked_radio_xpm
[] = {
1046 /* columns rows colors chars-per-pixel */
1069 static const char **
1070 bmpIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1075 { checked_xpm
, unchecked_xpm
},
1078 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1081 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1087 { checked_radio_xpm
, unchecked_radio_xpm
},
1090 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1093 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1099 { checked_menu_xpm
, NULL
},
1102 { selected_checked_menu_xpm
, NULL
},
1105 { disabled_checked_menu_xpm
, NULL
},
1107 // disabled selected state
1108 { selected_disabled_checked_menu_xpm
, NULL
},
1112 // ============================================================================
1114 // ============================================================================
1116 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1118 // ----------------------------------------------------------------------------
1120 // ----------------------------------------------------------------------------
1122 wxWin32Theme::wxWin32Theme()
1126 m_handlerDefault
= NULL
;
1129 wxWin32Theme::~wxWin32Theme()
1131 size_t count
= m_handlers
.GetCount();
1132 for ( size_t n
= 0; n
< count
; n
++ )
1134 if ( m_handlers
[n
] != m_handlerDefault
)
1135 delete m_handlers
[n
];
1138 delete m_handlerDefault
;
1144 wxRenderer
*wxWin32Theme::GetRenderer()
1148 m_renderer
= new wxWin32Renderer(GetColourScheme());
1154 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1156 if ( !m_handlerDefault
)
1158 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1161 return m_handlerDefault
;
1164 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1166 wxInputHandler
*handler
;
1167 int n
= m_handlerNames
.Index(control
);
1168 if ( n
== wxNOT_FOUND
)
1170 // create a new handler
1171 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1172 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1173 GetDefaultInputHandler());
1175 else if ( control
== wxINP_HANDLER_BUTTON
)
1176 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1177 #endif // wxUSE_BUTTON
1179 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1180 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1181 #endif // wxUSE_CHECKBOX
1183 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1184 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1185 #endif // wxUSE_COMBOBOX
1187 else if ( control
== wxINP_HANDLER_LISTBOX
)
1188 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1189 #endif // wxUSE_LISTBOX
1190 #if wxUSE_CHECKLISTBOX
1191 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1192 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1193 #endif // wxUSE_CHECKLISTBOX
1195 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1196 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1197 #endif // wxUSE_TEXTCTRL
1199 else if ( control
== wxINP_HANDLER_SLIDER
)
1200 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1201 #endif // wxUSE_SLIDER
1203 else if ( control
== wxINP_HANDLER_SPINBTN
)
1204 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1205 #endif // wxUSE_SPINBTN
1207 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1208 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1209 #endif // wxUSE_NOTEBOOK
1211 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1212 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1213 #endif // wxUSE_STATUSBAR
1214 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1215 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1217 handler
= GetDefaultInputHandler();
1219 n
= m_handlerNames
.Add(control
);
1220 m_handlers
.Insert(handler
, n
);
1222 else // we already have it
1224 handler
= m_handlers
[n
];
1230 wxColourScheme
*wxWin32Theme::GetColourScheme()
1234 m_scheme
= new wxWin32ColourScheme
;
1239 // ============================================================================
1240 // wxWin32ColourScheme
1241 // ============================================================================
1243 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1246 if ( win
->UseBgCol() )
1248 // use the user specified colour
1249 col
= win
->GetBackgroundColour();
1252 if ( win
->IsContainerWindow() )
1254 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1257 if ( !text
->IsEnabled() ) // not IsEditable()
1259 //else: execute code below
1264 // doesn't depend on the state
1270 int flags
= win
->GetStateFlags();
1272 // the colour set by the user should be used for the normal state
1273 // and for the states for which we don't have any specific colours
1274 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1276 if ( wxDynamicCast(win
, wxScrollBar
) )
1277 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1287 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1291 // use the system colours under Windows
1292 #if defined(__WXMSW__)
1293 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1295 case CONTROL_PRESSED
:
1296 case CONTROL_CURRENT
:
1297 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1299 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1301 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1302 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1304 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1305 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1307 #if defined(COLOR_3DDKSHADOW)
1308 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1310 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1313 case CONTROL_TEXT_DISABLED
:
1314 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1316 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1318 case CONTROL_TEXT_DISABLED_SHADOW
:
1319 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1321 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1322 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1323 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1324 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1326 case DESKTOP
: return wxColour(0x808000);
1328 // use the standard Windows colours elsewhere
1329 case WINDOW
: return *wxWHITE
;
1331 case CONTROL_PRESSED
:
1332 case CONTROL_CURRENT
:
1333 case CONTROL
: return wxColour(0xc0c0c0);
1335 case CONTROL_TEXT
: return *wxBLACK
;
1337 case SCROLLBAR
: return wxColour(0xe0e0e0);
1338 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1340 case HIGHLIGHT
: return wxColour(0x800000);
1341 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1343 case SHADOW_DARK
: return *wxBLACK
;
1345 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1346 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1348 case SHADOW_IN
: return wxColour(0xc0c0c0);
1350 case CONTROL_TEXT_DISABLED_SHADOW
:
1351 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1353 case TITLEBAR
: return wxColour(0xaeaaae);
1354 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1355 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1356 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1358 case DESKTOP
: return wxColour(0x808000);
1361 case GAUGE
: return Get(HIGHLIGHT
);
1365 wxFAIL_MSG(_T("invalid standard colour"));
1370 // ============================================================================
1372 // ============================================================================
1374 // ----------------------------------------------------------------------------
1376 // ----------------------------------------------------------------------------
1378 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1382 m_sizeScrollbarArrow
= wxSize(16, 16);
1384 // init colours and pens
1385 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1387 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1388 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1390 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1392 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1393 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1395 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1396 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1398 // init the arrow bitmaps
1399 static const size_t ARROW_WIDTH
= 7;
1400 static const size_t ARROW_LENGTH
= 4;
1403 wxMemoryDC dcNormal
,
1406 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1408 bool isVertical
= n
> Arrow_Right
;
1421 // disabled arrow is larger because of the shadow
1422 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1423 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1425 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1426 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1428 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1429 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1433 dcNormal
.SetPen(m_penBlack
);
1434 dcDisabled
.SetPen(m_penDarkGrey
);
1436 // calculate the position of the point of the arrow
1440 x1
= (ARROW_WIDTH
- 1)/2;
1441 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1445 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1446 y1
= (ARROW_WIDTH
- 1)/2;
1457 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1459 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1460 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1467 if ( n
== Arrow_Up
)
1478 else // left or right arrow
1483 if ( n
== Arrow_Left
)
1496 // draw the shadow for the disabled one
1497 dcDisabled
.SetPen(m_penHighlight
);
1502 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1506 x1
= ARROW_LENGTH
- 1;
1507 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1510 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1511 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1516 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1520 x1
= ARROW_WIDTH
- 1;
1522 x2
= (ARROW_WIDTH
- 1)/2;
1524 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1525 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1530 // create the inversed bitmap but only for the right arrow as we only
1531 // use it for the menus
1532 if ( n
== Arrow_Right
)
1534 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1535 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1537 dcInverse
.Blit(0, 0, w
, h
,
1540 dcInverse
.SelectObject(wxNullBitmap
);
1542 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1543 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1545 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1546 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1548 dcInverse
.Blit(0, 0, w
, h
,
1551 dcInverse
.SelectObject(wxNullBitmap
);
1553 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1554 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1557 dcNormal
.SelectObject(wxNullBitmap
);
1558 dcDisabled
.SelectObject(wxNullBitmap
);
1560 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1561 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1562 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1563 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1565 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1568 // init the frame buttons bitmaps
1569 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1570 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1571 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1572 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1573 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1576 // ----------------------------------------------------------------------------
1578 // ----------------------------------------------------------------------------
1581 The raised border in Win32 looks like this:
1583 IIIIIIIIIIIIIIIIIIIIIIB
1585 I GB I = white (HILIGHT)
1586 I GB H = light grey (LIGHT)
1587 I GB G = dark grey (SHADOI)
1588 I GB B = black (DKSHADOI)
1589 I GB I = hIghlight (COLOR_3DHILIGHT)
1591 IGGGGGGGGGGGGGGGGGGGGGB
1592 BBBBBBBBBBBBBBBBBBBBBBB
1594 The sunken border looks like this:
1596 GGGGGGGGGGGGGGGGGGGGGGI
1597 GBBBBBBBBBBBBBBBBBBBBHI
1604 GHHHHHHHHHHHHHHHHHHHHHI
1605 IIIIIIIIIIIIIIIIIIIIIII
1607 The static border (used for the controls which don't get focus) is like
1610 GGGGGGGGGGGGGGGGGGGGGGW
1618 WWWWWWWWWWWWWWWWWWWWWWW
1620 The most complicated is the double border:
1622 HHHHHHHHHHHHHHHHHHHHHHB
1623 HWWWWWWWWWWWWWWWWWWWWGB
1624 HWHHHHHHHHHHHHHHHHHHHGB
1629 HWHHHHHHHHHHHHHHHHHHHGB
1630 HGGGGGGGGGGGGGGGGGGGGGB
1631 BBBBBBBBBBBBBBBBBBBBBBB
1633 And the simple border is, well, simple:
1635 BBBBBBBBBBBBBBBBBBBBBBB
1644 BBBBBBBBBBBBBBBBBBBBBBB
1647 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1651 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1652 dc
.DrawRectangle(*rect
);
1658 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1660 // draw the bottom and right sides
1662 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1663 rect
->GetRight() + 1, rect
->GetBottom());
1664 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1665 rect
->GetRight(), rect
->GetBottom());
1672 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1673 const wxPen
& pen1
, const wxPen
& pen2
)
1675 // draw the rectangle
1677 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1678 rect
->GetLeft(), rect
->GetBottom());
1679 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1680 rect
->GetRight(), rect
->GetTop());
1682 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1683 rect
->GetRight(), rect
->GetBottom());
1684 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1685 rect
->GetRight() + 1, rect
->GetBottom());
1691 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1693 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1694 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1697 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1699 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1700 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1703 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1707 DrawRect(dc
, rect
, m_penDarkGrey
);
1709 // the arrow is usually drawn inside border of width 2 and is offset by
1710 // another pixel in both directions when it's pressed - as the border
1711 // in this case is more narrow as well, we have to adjust rect like
1719 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1720 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1724 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1726 const wxRect
& rectTotal
,
1727 int WXUNUSED(flags
),
1732 wxRect rect
= rectTotal
;
1736 case wxBORDER_SUNKEN
:
1737 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1739 DrawSunkenBorder(dc
, &rect
);
1743 case wxBORDER_STATIC
:
1744 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1747 case wxBORDER_RAISED
:
1748 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1750 DrawRaisedBorder(dc
, &rect
);
1754 case wxBORDER_DOUBLE
:
1755 DrawArrowBorder(dc
, &rect
);
1756 DrawRect(dc
, &rect
, m_penLightGrey
);
1759 case wxBORDER_SIMPLE
:
1760 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1762 DrawRect(dc
, &rect
, m_penBlack
);
1767 wxFAIL_MSG(_T("unknown border type"));
1770 case wxBORDER_DEFAULT
:
1779 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1784 case wxBORDER_RAISED
:
1785 case wxBORDER_SUNKEN
:
1786 width
= BORDER_THICKNESS
;
1789 case wxBORDER_SIMPLE
:
1790 case wxBORDER_STATIC
:
1794 case wxBORDER_DOUBLE
:
1799 wxFAIL_MSG(_T("unknown border type"));
1802 case wxBORDER_DEFAULT
:
1812 rect
.height
= width
;
1817 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1822 // ----------------------------------------------------------------------------
1824 // ----------------------------------------------------------------------------
1826 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1832 // text controls are not special under windows
1833 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1836 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1837 const wxRect
& rectTotal
,
1841 wxRect rect
= rectTotal
;
1843 if ( flags
& wxCONTROL_PRESSED
)
1845 // button pressed: draw a double border around it
1846 DrawRect(dc
, &rect
, m_penBlack
);
1847 DrawRect(dc
, &rect
, m_penDarkGrey
);
1851 // button not pressed
1853 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1855 // button either default or focused (or both): add an extra border around it
1856 DrawRect(dc
, &rect
, m_penBlack
);
1859 // now draw a normal button
1860 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1861 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1870 // ----------------------------------------------------------------------------
1872 // ----------------------------------------------------------------------------
1874 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1875 wxCoord y
, wxCoord x1
, wxCoord x2
)
1877 dc
.SetPen(m_penDarkGrey
);
1878 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1879 dc
.SetPen(m_penHighlight
);
1881 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1884 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1885 wxCoord x
, wxCoord y1
, wxCoord y2
)
1887 dc
.SetPen(m_penDarkGrey
);
1888 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1889 dc
.SetPen(m_penHighlight
);
1891 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1894 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1895 const wxString
& label
,
1901 wxCoord height
= 0; // of the label
1902 wxRect rectFrame
= rect
;
1903 if ( !label
.empty() )
1905 // the text should touch the top border of the rect, so the frame
1906 // itself should be lower
1907 dc
.GetTextExtent(label
, NULL
, &height
);
1908 rectFrame
.y
+= height
/ 2;
1909 rectFrame
.height
-= height
/ 2;
1911 // we have to draw each part of the frame individually as we can't
1912 // erase the background beyond the label as it might contain some
1913 // pixmap already, so drawing everything and then overwriting part of
1914 // the frame with label doesn't work
1916 // TODO: the +5 and space insertion should be customizable
1919 rectText
.x
= rectFrame
.x
+ 5;
1920 rectText
.y
= rect
.y
;
1921 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1922 rectText
.height
= height
;
1925 label2
<< _T(' ') << label
<< _T(' ');
1926 if ( indexAccel
!= -1 )
1928 // adjust it as we prepended a space
1933 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1935 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1939 // just draw the complete frame
1940 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1941 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1945 // ----------------------------------------------------------------------------
1947 // ----------------------------------------------------------------------------
1949 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1951 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1952 // pixels each while we really need dots here... PS_ALTERNATE might
1953 // work, but it is for NT 5 only
1955 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1957 // draw the pixels manually: note that to behave in the same manner as
1958 // DrawRect(), we must exclude the bottom and right borders from the
1960 wxCoord x1
= rect
.GetLeft(),
1962 x2
= rect
.GetRight(),
1963 y2
= rect
.GetBottom();
1965 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1967 // this seems to be closer than what Windows does than wxINVERT although
1968 // I'm still not sure if it's correct
1969 dc
.SetLogicalFunction(wxAND_REVERSE
);
1972 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1973 dc
.DrawPoint(z
, rect
.GetTop());
1975 wxCoord shift
= z
== x2
? 0 : 1;
1976 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1977 dc
.DrawPoint(x2
, z
);
1979 shift
= z
== y2
? 0 : 1;
1980 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1981 dc
.DrawPoint(z
, y2
);
1983 shift
= z
== x1
? 0 : 1;
1984 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
1985 dc
.DrawPoint(x1
, z
);
1987 dc
.SetLogicalFunction(wxCOPY
);
1991 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
1992 const wxString
& label
,
1997 // draw shadow of the text
1998 dc
.SetTextForeground(m_colHighlight
);
1999 wxRect rectShadow
= rect
;
2002 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2004 // make the text grey
2005 dc
.SetTextForeground(m_colDarkGrey
);
2008 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2009 const wxString
& label
,
2016 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2019 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2020 const wxString
& label
,
2026 const wxPoint
& focusOffset
)
2028 // the underscores are not drawn for focused controls in wxMSW
2029 if ( flags
& wxCONTROL_FOCUSED
)
2034 if ( flags
& wxCONTROL_DISABLED
)
2036 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2037 // currently only can happen for a menu item and it seems that Windows
2038 // doesn't draw the shadow in this case, so we don't do it neither
2039 if ( flags
& wxCONTROL_SELECTED
)
2041 // just make the label text greyed out
2042 dc
.SetTextForeground(m_colDarkGrey
);
2044 else // draw normal disabled label
2046 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2051 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2053 if ( flags
& wxCONTROL_DISABLED
)
2055 // restore the fg colour
2056 dc
.SetTextForeground(*wxBLACK
);
2059 if ( flags
& wxCONTROL_FOCUSED
)
2061 if ( focusOffset
.x
|| focusOffset
.y
)
2063 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2066 DrawFocusRect(dc
, rectLabel
);
2070 *rectBounds
= rectLabel
;
2073 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2074 const wxString
& label
,
2075 const wxBitmap
& image
,
2082 // the underscores are not drawn for focused controls in wxMSW
2083 if ( flags
& wxCONTROL_PRESSED
)
2088 wxRect rectLabel
= rect
;
2089 if ( !label
.empty() )
2091 // shift the label if a button is pressed
2092 if ( flags
& wxCONTROL_PRESSED
)
2098 if ( flags
& wxCONTROL_DISABLED
)
2100 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2103 // leave enough space for the focus rectangle
2104 if ( flags
& wxCONTROL_FOCUSED
)
2106 rectLabel
.Inflate(-2);
2110 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2112 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2114 if ( flags
& wxCONTROL_PRESSED
)
2116 // the focus rectangle is never pressed, so undo the shift done
2124 DrawFocusRect(dc
, rectLabel
);
2128 // ----------------------------------------------------------------------------
2129 // (check)listbox items
2130 // ----------------------------------------------------------------------------
2132 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2133 const wxString
& label
,
2137 wxDCTextColourChanger
colChanger(dc
);
2139 if ( flags
& wxCONTROL_SELECTED
)
2141 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2143 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2144 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2145 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2146 dc
.DrawRectangle(rect
);
2149 wxRect rectText
= rect
;
2151 rectText
.width
-= 2;
2152 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2154 if ( flags
& wxCONTROL_FOCUSED
)
2156 DrawFocusRect(dc
, rect
);
2160 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2161 const wxString
& label
,
2162 const wxBitmap
& bitmap
,
2171 else // use default bitmap
2173 bmp
= wxBitmap(flags
& wxCONTROL_CHECKED
? checked_item_xpm
2174 : unchecked_item_xpm
);
2177 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2178 TRUE
/* use mask */);
2180 wxRect rectLabel
= rect
;
2181 int bmpWidth
= bmp
.GetWidth();
2182 rectLabel
.x
+= bmpWidth
;
2183 rectLabel
.width
-= bmpWidth
;
2185 DrawItem(dc
, label
, rectLabel
, flags
);
2188 // ----------------------------------------------------------------------------
2189 // check/radio buttons
2190 // ----------------------------------------------------------------------------
2192 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2194 IndicatorState indState
;
2195 if ( flags
& wxCONTROL_SELECTED
)
2196 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2197 : IndicatorState_Selected
;
2198 else if ( flags
& wxCONTROL_DISABLED
)
2199 indState
= IndicatorState_Disabled
;
2200 else if ( flags
& wxCONTROL_PRESSED
)
2201 indState
= IndicatorState_Pressed
;
2203 indState
= IndicatorState_Normal
;
2205 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2206 ? IndicatorStatus_Checked
2207 : IndicatorStatus_Unchecked
;
2209 const char **xpm
= bmpIndicators
[indType
][indState
][indStatus
];
2216 return wxNullBitmap
;
2219 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2220 const wxString
& label
,
2221 const wxBitmap
& bitmap
,
2226 wxCoord focusOffsetY
)
2228 // calculate the position of the bitmap and of the label
2229 wxCoord heightBmp
= bitmap
.GetHeight();
2231 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2234 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2235 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2237 // align label vertically with the bitmap - looks nicer like this
2238 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2240 // calc horz position
2241 if ( align
== wxALIGN_RIGHT
)
2243 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2244 rectLabel
.x
= rect
.x
+ 3;
2245 rectLabel
.SetRight(xBmp
);
2247 else // normal (checkbox to the left of the text) case
2250 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2251 rectLabel
.SetRight(rect
.GetRight());
2254 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2257 dc
, label
, rectLabel
,
2259 wxALIGN_LEFT
| wxALIGN_TOP
,
2261 NULL
, // we don't need bounding rect
2262 // use custom vert focus rect offset
2263 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2267 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2268 const wxString
& label
,
2269 const wxBitmap
& bitmap
,
2276 DrawCheckOrRadioButton(dc
, label
,
2278 rect
, flags
, align
, indexAccel
,
2279 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2282 wxBitmap
rbitmap(GetRadioBitmap(flags
));
2283 DrawCheckOrRadioButton(dc
, label
,
2285 rect
, flags
, align
, indexAccel
,
2286 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2290 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2291 const wxString
& label
,
2292 const wxBitmap
& bitmap
,
2299 DrawCheckOrRadioButton(dc
, label
,
2301 rect
, flags
, align
, indexAccel
,
2302 0); // no focus rect offset for checkboxes
2305 wxBitmap
cbitmap(GetCheckBitmap(flags
));
2306 DrawCheckOrRadioButton(dc
, label
,
2308 rect
, flags
, align
, indexAccel
,
2309 0); // no focus rect offset for checkboxes
2313 // ----------------------------------------------------------------------------
2315 // ----------------------------------------------------------------------------
2317 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2318 const wxString
& text
,
2324 // nothing special to do here
2325 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2328 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2330 // we don't draw them
2333 // ----------------------------------------------------------------------------
2335 // ----------------------------------------------------------------------------
2337 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2338 const wxRect
& rectOrig
,
2340 const wxString
& label
,
2341 const wxBitmap
& bitmap
,
2345 wxRect rect
= rectOrig
;
2347 // the current tab is drawn indented (to the top for default case) and
2348 // bigger than the other ones
2349 const wxSize indent
= GetTabIndent();
2350 if ( flags
& wxCONTROL_SELECTED
)
2355 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2359 rect
.Inflate(indent
.x
, 0);
2361 rect
.height
+= indent
.y
;
2365 rect
.Inflate(indent
.x
, 0);
2366 rect
.height
+= indent
.y
;
2371 wxFAIL_MSG(_T("TODO"));
2376 // draw the text, image and the focus around them (if necessary)
2377 wxRect rectLabel
= rect
;
2378 rectLabel
.Deflate(1, 1);
2379 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2380 flags
, wxALIGN_CENTRE
, indexAccel
);
2382 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2383 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2386 x2
= rect
.GetRight(),
2387 y2
= rect
.GetBottom();
2389 // FIXME: all this code will break if the tab indent or the border width,
2390 // it is tied to the fact that both of them are equal to 2
2395 dc
.SetPen(m_penHighlight
);
2396 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2397 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2398 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2400 dc
.SetPen(m_penBlack
);
2401 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2402 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2404 dc
.SetPen(m_penDarkGrey
);
2405 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2407 if ( flags
& wxCONTROL_SELECTED
)
2409 dc
.SetPen(m_penLightGrey
);
2411 // overwrite the part of the border below this tab
2412 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2414 // and the shadow of the tab to the left of us
2415 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2420 dc
.SetPen(m_penHighlight
);
2421 // we need to continue one pixel further to overwrite the corner of
2422 // the border for the selected tab
2423 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2425 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2427 dc
.SetPen(m_penBlack
);
2428 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2429 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2430 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2432 dc
.SetPen(m_penDarkGrey
);
2433 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2434 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2436 if ( flags
& wxCONTROL_SELECTED
)
2438 dc
.SetPen(m_penLightGrey
);
2440 // overwrite the part of the (double!) border above this tab
2441 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2442 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2444 // and the shadow of the tab to the left of us
2445 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2451 wxFAIL_MSG(_T("TODO"));
2455 // ----------------------------------------------------------------------------
2457 // ----------------------------------------------------------------------------
2459 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2460 wxOrientation orient
) const
2464 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2465 if ( orient
== wxHORIZONTAL
)
2467 size
.y
= rect
.height
- 6;
2468 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2472 size
.x
= rect
.width
- 6;
2473 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2479 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2480 wxOrientation orient
) const
2482 static const wxCoord SLIDER_MARGIN
= 6;
2484 wxRect rect
= rectOrig
;
2486 if ( orient
== wxHORIZONTAL
)
2488 // make the rect of minimal width and centre it
2489 rect
.height
= 2*BORDER_THICKNESS
;
2490 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2494 // leave margins on the sides
2495 rect
.Deflate(SLIDER_MARGIN
, 0);
2499 // same as above but in other direction
2500 rect
.width
= 2*BORDER_THICKNESS
;
2501 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2505 rect
.Deflate(0, SLIDER_MARGIN
);
2511 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2512 const wxRect
& rectOrig
,
2513 wxOrientation orient
,
2517 if ( flags
& wxCONTROL_FOCUSED
)
2519 DrawFocusRect(dc
, rectOrig
);
2522 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2527 DrawSunkenBorder(dc
, &rect
);
2530 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2532 wxOrientation orient
,
2536 we are drawing a shape of this form
2541 H DB where H is hightlight colour
2554 The interior of this shape is filled with the hatched brush if the thumb
2558 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2560 bool transpose
= orient
== wxVERTICAL
;
2562 wxCoord x
, y
, x2
, y2
;
2567 x2
= rect
.GetBottom();
2568 y2
= rect
.GetRight();
2574 x2
= rect
.GetRight();
2575 y2
= rect
.GetBottom();
2578 // the size of the pointed part of the thumb
2579 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2581 wxCoord x3
= x
+ sizeArrow
,
2582 y3
= y2
- sizeArrow
;
2584 dc
.SetPen(m_penHighlight
);
2585 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2586 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2587 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2589 dc
.SetPen(m_penBlack
);
2590 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2591 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2593 dc
.SetPen(m_penDarkGrey
);
2594 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2595 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2597 if ( flags
& wxCONTROL_PRESSED
)
2599 // TODO: MSW fills the entire area inside, not just the rect
2600 wxRect rectInt
= rect
;
2602 rectInt
.SetRight(y3
);
2604 rectInt
.SetBottom(y3
);
2607 #if !defined(__WXMGL__)
2608 static const char *stipple_xpm
[] = {
2609 /* columns rows colors chars-per-pixel */
2618 // VS: MGL can only do 8x8 stipple brushes
2619 static const char *stipple_xpm
[] = {
2620 /* columns rows colors chars-per-pixel */
2635 dc
.SetBrush(wxBrush(stipple_xpm
));
2637 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2638 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2639 dc
.SetPen(*wxTRANSPARENT_PEN
);
2640 dc
.DrawRectangle(rectInt
);
2644 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2646 const wxSize
& sizeThumb
,
2647 wxOrientation orient
,
2659 // the variable names correspond to horizontal case, but they can be used
2660 // for both orientations
2661 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2662 if ( orient
== wxHORIZONTAL
)
2664 x1
= rect
.GetLeft();
2665 x2
= rect
.GetRight();
2667 // draw from bottom to top to leave one pixel space between the ticks
2668 // and the slider as Windows do
2669 y1
= rect
.GetBottom();
2674 widthThumb
= sizeThumb
.x
;
2679 x2
= rect
.GetBottom();
2681 y1
= rect
.GetRight();
2682 y2
= rect
.GetLeft();
2686 widthThumb
= sizeThumb
.y
;
2689 // the first tick should be positioned in such way that a thumb drawn in
2690 // the first position points down directly to it
2691 x1
+= widthThumb
/ 2;
2692 x2
-= widthThumb
/ 2;
2694 // this also means that we have slightly less space for the ticks in
2695 // between the first and the last
2698 dc
.SetPen(m_penBlack
);
2700 int range
= end
- start
;
2701 for ( int n
= 0; n
< range
; n
+= step
)
2703 wxCoord x
= x1
+ (len
*n
) / range
;
2705 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2708 // always draw the line at the end position
2709 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2712 // ----------------------------------------------------------------------------
2714 // ----------------------------------------------------------------------------
2716 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2717 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2720 virtual wxSize
GetSize() const { return m_size
; }
2722 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2723 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2725 wxCoord
GetItemHeight() const { return m_heightItem
; }
2728 // the total size of the menu
2731 // the offset of the start of the menu item label
2734 // the offset of the start of the accel label
2737 // the height of a normal (not separator) item
2738 wxCoord m_heightItem
;
2740 friend wxMenuGeometryInfo
*
2741 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2744 // FIXME: all constants are hardcoded but shouldn't be
2745 static const wxCoord MENU_LEFT_MARGIN
= 9;
2746 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2747 static const wxCoord MENU_VERT_MARGIN
= 3;
2749 // the margin around bitmap/check marks (on each side)
2750 static const wxCoord MENU_BMP_MARGIN
= 2;
2752 // the margin between the labels and accel strings
2753 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2755 // the separator height in pixels: in fact, strangely enough, the real height
2756 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2758 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2760 // the size of the standard checkmark bitmap
2761 static const wxCoord MENU_CHECK_SIZE
= 9;
2763 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2764 const wxRect
& rectOrig
,
2765 const wxString
& label
,
2769 wxRect rect
= rectOrig
;
2772 wxDCTextColourChanger
colChanger(dc
);
2774 if ( flags
& wxCONTROL_SELECTED
)
2776 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2778 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2779 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2780 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2781 dc
.DrawRectangle(rect
);
2784 // don't draw the focus rect around menu bar items
2785 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2786 wxALIGN_CENTRE
, indexAccel
);
2789 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2791 const wxMenuGeometryInfo
& gi
,
2792 const wxString
& label
,
2793 const wxString
& accel
,
2794 const wxBitmap
& bitmap
,
2798 const wxWin32MenuGeometryInfo
& geometryInfo
=
2799 (const wxWin32MenuGeometryInfo
&)gi
;
2804 rect
.width
= geometryInfo
.GetSize().x
;
2805 rect
.height
= geometryInfo
.GetItemHeight();
2807 // draw the selected item specially
2808 wxDCTextColourChanger
colChanger(dc
);
2809 if ( flags
& wxCONTROL_SELECTED
)
2811 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2813 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2814 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2815 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2816 dc
.DrawRectangle(rect
);
2819 // draw the bitmap: use the bitmap provided or the standard checkmark for
2820 // the checkable items
2821 wxBitmap bmp
= bitmap
;
2822 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2824 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2829 rect
.SetRight(geometryInfo
.GetLabelOffset());
2830 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2834 rect
.x
= geometryInfo
.GetLabelOffset();
2835 rect
.SetRight(geometryInfo
.GetAccelOffset());
2837 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2839 // draw the accel string
2840 rect
.x
= geometryInfo
.GetAccelOffset();
2841 rect
.SetRight(geometryInfo
.GetSize().x
);
2843 // NB: no accel index here
2844 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2846 // draw the submenu indicator
2847 if ( flags
& wxCONTROL_ISSUBMENU
)
2849 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2850 rect
.width
= MENU_RIGHT_MARGIN
;
2852 wxArrowStyle arrowStyle
;
2853 if ( flags
& wxCONTROL_DISABLED
)
2854 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2856 else if ( flags
& wxCONTROL_SELECTED
)
2857 arrowStyle
= Arrow_Inversed
;
2859 arrowStyle
= Arrow_Normal
;
2861 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2865 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2867 const wxMenuGeometryInfo
& geomInfo
)
2869 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2872 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2874 wxSize size
= sizeText
;
2876 // FIXME: menubar height is configurable under Windows
2883 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2884 const wxMenu
& menu
) const
2886 // prepare the dc: for now we draw all the items with the system font
2888 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2890 // the height of a normal item
2891 wxCoord heightText
= dc
.GetCharHeight();
2896 // the max length of label and accel strings: the menu width is the sum of
2897 // them, even if they're for different items (as the accels should be
2900 // the max length of the bitmap is never 0 as Windows always leaves enough
2901 // space for a check mark indicator
2902 wxCoord widthLabelMax
= 0,
2904 widthBmpMax
= MENU_LEFT_MARGIN
;
2906 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2908 node
= node
->GetNext() )
2910 // height of this item
2913 wxMenuItem
*item
= node
->GetData();
2914 if ( item
->IsSeparator() )
2916 h
= MENU_SEPARATOR_HEIGHT
;
2918 else // not separator
2923 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2924 if ( widthLabel
> widthLabelMax
)
2926 widthLabelMax
= widthLabel
;
2930 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2931 if ( widthAccel
> widthAccelMax
)
2933 widthAccelMax
= widthAccel
;
2936 const wxBitmap
& bmp
= item
->GetBitmap();
2939 wxCoord widthBmp
= bmp
.GetWidth();
2940 if ( widthBmp
> widthBmpMax
)
2941 widthBmpMax
= widthBmp
;
2943 //else if ( item->IsCheckable() ): no need to check for this as
2944 // MENU_LEFT_MARGIN is big enough to show the check mark
2947 h
+= 2*MENU_VERT_MARGIN
;
2949 // remember the item position and height
2950 item
->SetGeometry(height
, h
);
2955 // bundle the metrics into a struct and return it
2956 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2958 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2959 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2960 if ( widthAccelMax
> 0 )
2962 // if we actually have any accesl, add a margin
2963 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2966 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2968 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2969 gi
->m_size
.y
= height
;
2974 // ----------------------------------------------------------------------------
2976 // ----------------------------------------------------------------------------
2978 static const wxCoord STATBAR_BORDER_X
= 2;
2979 static const wxCoord STATBAR_BORDER_Y
= 2;
2981 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2983 if ( borderBetweenFields
)
2984 *borderBetweenFields
= 2;
2986 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2989 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2991 const wxString
& label
,
2996 if ( flags
& wxCONTROL_ISDEFAULT
)
2998 // draw the size grip: it is a normal rect except that in the lower
2999 // right corner we have several bands which may be used for dragging
3000 // the status bar corner
3002 // each band consists of 4 stripes: m_penHighlight, double
3003 // m_penDarkGrey and transparent one
3004 wxCoord x2
= rect
.GetRight(),
3005 y2
= rect
.GetBottom();
3007 // draw the upper left part of the rect normally
3008 dc
.SetPen(m_penDarkGrey
);
3009 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3010 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3012 // draw the grey stripes of the grip
3014 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3015 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3017 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3018 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3021 // draw the white stripes
3022 dc
.SetPen(m_penHighlight
);
3023 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3024 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3026 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3029 // draw the remaining rect boundaries
3030 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3031 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3032 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3037 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3041 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3044 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3046 wxDCClipper
clipper(dc
, rectIn
);
3047 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3050 // ----------------------------------------------------------------------------
3052 // ----------------------------------------------------------------------------
3054 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3056 wxBitmap
*bmpPressed
,
3057 wxBitmap
*bmpDisabled
)
3059 static const wxCoord widthCombo
= 16;
3060 static const wxCoord heightCombo
= 17;
3066 bmpNormal
->Create(widthCombo
, heightCombo
);
3067 dcMem
.SelectObject(*bmpNormal
);
3068 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3069 Arrow_Down
, Arrow_Normal
);
3074 bmpPressed
->Create(widthCombo
, heightCombo
);
3075 dcMem
.SelectObject(*bmpPressed
);
3076 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3077 Arrow_Down
, Arrow_Pressed
);
3082 bmpDisabled
->Create(widthCombo
, heightCombo
);
3083 dcMem
.SelectObject(*bmpDisabled
);
3084 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3085 Arrow_Down
, Arrow_Disabled
);
3089 // ----------------------------------------------------------------------------
3091 // ----------------------------------------------------------------------------
3093 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3094 const wxColour
& col
,
3097 wxBrush
brush(col
, wxSOLID
);
3099 dc
.SetPen(*wxTRANSPARENT_PEN
);
3100 dc
.DrawRectangle(rect
);
3103 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3104 const wxColour
& col
,
3108 // just fill it with the given or default bg colour
3109 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3110 DoDrawBackground(dc
, colBg
, rect
);
3113 // ----------------------------------------------------------------------------
3115 // ----------------------------------------------------------------------------
3117 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3122 // get the bitmap for this arrow
3123 wxArrowDirection arrowDir
;
3126 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3127 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3128 case wxUP
: arrowDir
= Arrow_Up
; break;
3129 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3132 wxFAIL_MSG(_T("unknown arrow direction"));
3136 wxArrowStyle arrowStyle
;
3137 if ( flags
& wxCONTROL_PRESSED
)
3139 // can't be pressed and disabled
3140 arrowStyle
= Arrow_Pressed
;
3144 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3147 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3150 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3152 wxArrowDirection arrowDir
,
3153 wxArrowStyle arrowStyle
)
3155 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3157 // under Windows the arrows always have the same size so just centre it in
3158 // the provided rectangle
3159 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3160 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3162 // Windows does it like this...
3163 if ( arrowDir
== Arrow_Left
)
3167 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3170 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3171 const wxRect
& rectAll
,
3172 wxArrowDirection arrowDir
,
3173 wxArrowStyle arrowStyle
)
3175 wxRect rect
= rectAll
;
3176 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3177 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3178 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3181 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3182 wxOrientation orient
,
3186 // we don't use the flags, the thumb never changes appearance
3187 wxRect rectThumb
= rect
;
3188 DrawArrowBorder(dc
, &rectThumb
);
3189 DrawBackground(dc
, wxNullColour
, rectThumb
);
3192 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3193 wxOrientation orient
,
3194 const wxRect
& rectBar
,
3197 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3198 ? wxColourScheme::SCROLLBAR_PRESSED
3199 : wxColourScheme::SCROLLBAR
;
3200 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3203 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3205 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3208 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3209 wxScrollBar::Element elem
,
3212 return StandardGetScrollbarRect(scrollbar
, elem
,
3213 thumbPos
, m_sizeScrollbarArrow
);
3216 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3218 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3221 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3222 const wxPoint
& pt
) const
3224 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3227 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3230 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3233 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3236 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3239 // ----------------------------------------------------------------------------
3240 // top level windows
3241 // ----------------------------------------------------------------------------
3243 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3245 wxRect client
= GetFrameClientArea(rect
, flags
);
3247 if ( client
.Inside(pt
) )
3248 return wxHT_TOPLEVEL_CLIENT_AREA
;
3250 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3252 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3254 if ( flags
& wxTOPLEVEL_ICON
)
3256 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3257 return wxHT_TOPLEVEL_ICON
;
3260 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3261 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3262 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3264 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3266 if ( btnRect
.Inside(pt
) )
3267 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3268 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3270 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3272 if ( btnRect
.Inside(pt
) )
3273 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3274 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3276 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3278 if ( btnRect
.Inside(pt
) )
3279 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3280 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3282 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3284 if ( btnRect
.Inside(pt
) )
3285 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3286 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3288 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3290 if ( btnRect
.Inside(pt
) )
3291 return wxHT_TOPLEVEL_BUTTON_HELP
;
3292 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3295 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3296 return wxHT_TOPLEVEL_TITLEBAR
;
3299 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3301 // we are certainly at one of borders, lets decide which one:
3304 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3305 if ( pt
.x
< client
.x
)
3306 border
|= wxHT_TOPLEVEL_BORDER_W
;
3307 else if ( pt
.x
>= client
.width
+ client
.x
)
3308 border
|= wxHT_TOPLEVEL_BORDER_E
;
3309 if ( pt
.y
< client
.y
)
3310 border
|= wxHT_TOPLEVEL_BORDER_N
;
3311 else if ( pt
.y
>= client
.height
+ client
.y
)
3312 border
|= wxHT_TOPLEVEL_BORDER_S
;
3316 return wxHT_NOWHERE
;
3319 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3321 const wxString
& title
,
3325 int specialButtonFlags
)
3327 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3329 DrawFrameBorder(dc
, rect
, flags
);
3331 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3333 DrawFrameBackground(dc
, rect
, flags
);
3334 if ( flags
& wxTOPLEVEL_ICON
)
3335 DrawFrameIcon(dc
, rect
, icon
, flags
);
3336 DrawFrameTitle(dc
, rect
, title
, flags
);
3338 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3340 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3341 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3343 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3345 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3346 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3347 specialButtonFlags
: 0);
3348 x
-= FRAME_BUTTON_WIDTH
+ 2;
3350 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3352 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3353 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3354 specialButtonFlags
: 0);
3355 x
-= FRAME_BUTTON_WIDTH
;
3357 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3359 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3360 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3361 specialButtonFlags
: 0);
3362 x
-= FRAME_BUTTON_WIDTH
;
3364 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3366 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3367 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3368 specialButtonFlags
: 0);
3369 x
-= FRAME_BUTTON_WIDTH
;
3371 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3373 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3374 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3375 specialButtonFlags
: 0);
3376 x
-= FRAME_BUTTON_WIDTH
;
3381 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3385 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3389 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3390 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3391 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3392 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3393 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3396 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3400 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3402 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3403 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3404 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3406 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3407 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3409 DrawBackground(dc
, col
, r
);
3412 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3414 const wxString
& title
,
3417 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3418 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3419 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3421 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3422 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3423 if ( flags
& wxTOPLEVEL_ICON
)
3424 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3428 dc
.SetFont(m_titlebarFont
);
3429 dc
.SetTextForeground(col
);
3430 dc
.DrawLabel(title
, wxNullBitmap
, r
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3433 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3440 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3441 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3445 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3446 wxCoord x
, wxCoord y
,
3450 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3455 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3456 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3457 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3458 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3459 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3461 wxFAIL_MSG(wxT("incorrect button specification"));
3464 if ( flags
& wxCONTROL_PRESSED
)
3466 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3467 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3468 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3469 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3473 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3474 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3475 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3476 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3481 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3486 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3488 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3489 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3490 FRAME_BORDER_THICKNESS
;
3493 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3495 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3496 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3502 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3505 wxSize
s(clientSize
);
3507 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3509 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3510 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3511 FRAME_BORDER_THICKNESS
;
3515 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3516 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3521 wxSize
wxWin32Renderer::GetFrameIconSize() const
3523 return wxSize(16, 16);
3527 // ----------------------------------------------------------------------------
3529 // ----------------------------------------------------------------------------
3531 static char *error_xpm
[]={
3538 "...........########.............",
3539 "........###aaaaaaaa###..........",
3540 ".......#aaaaaaaaaaaaaa#.........",
3541 ".....##aaaaaaaaaaaaaaaa##.......",
3542 "....#aaaaaaaaaaaaaaaaaaaa#......",
3543 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3544 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3545 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3546 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3547 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3548 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3549 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3550 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3551 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3552 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3553 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3554 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3555 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3556 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3557 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3558 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3559 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3560 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3561 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3562 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3563 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3564 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3565 "......b#aaaaaaaaaaaaaa#bbbbb....",
3566 ".......b###aaaaaaaa###bbbbb.....",
3567 ".........bb########bbbbbb.......",
3568 "..........bbbbbbbbbbbbbb........",
3569 ".............bbbbbbbb..........."};
3571 static char *info_xpm
[]={
3579 "...........########.............",
3580 "........###abbbbbba###..........",
3581 "......##abbbbbbbbbbbba##........",
3582 ".....#abbbbbbbbbbbbbbbba#.......",
3583 "....#bbbbbbbaccccabbbbbbbd......",
3584 "...#bbbbbbbbccccccbbbbbbbbd.....",
3585 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3586 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3587 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3588 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3589 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3590 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3591 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3592 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3593 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3594 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3595 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3596 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3597 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3598 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3599 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3600 ".....dabbbbbbbbbbbbbbbbad####...",
3601 "......ddabbbbbbbbbbbbadd####....",
3602 ".......#dddabbbbbbaddd#####.....",
3603 "........###dddabbbd#######......",
3604 "..........####dbbbd#####........",
3605 ".............#dbbbd##...........",
3606 "...............dbbd##...........",
3607 "................dbd##...........",
3608 ".................dd##...........",
3609 "..................###...........",
3610 "...................##..........."};
3612 static char *question_xpm
[]={
3620 "...........########.............",
3621 "........###abbbbbba###..........",
3622 "......##abbbbbbbbbbbba##........",
3623 ".....#abbbbbbbbbbbbbbbba#.......",
3624 "....#bbbbbbbbbbbbbbbbbbbbc......",
3625 "...#bbbbbbbaddddddabbbbbbbc.....",
3626 "..#bbbbbbbadabbddddabbbbbbbc....",
3627 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3628 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3629 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3630 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3631 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3632 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3633 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3634 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3635 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3636 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3637 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3638 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3639 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3640 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3641 ".....cabbbbbbbbbbbbbbbbac####...",
3642 "......ccabbbbbbbbbbbbacc####....",
3643 ".......#cccabbbbbbaccc#####.....",
3644 "........###cccabbbc#######......",
3645 "..........####cbbbc#####........",
3646 ".............#cbbbc##...........",
3647 "...............cbbc##...........",
3648 "................cbc##...........",
3649 ".................cc##...........",
3650 "..................###...........",
3651 "...................##..........."};
3653 static char *warning_xpm
[]={
3661 ".............###................",
3662 "............#aabc...............",
3663 "...........#aaaabcd.............",
3664 "...........#aaaaacdd............",
3665 "..........#aaaaaabcdd...........",
3666 "..........#aaaaaaacdd...........",
3667 ".........#aaaaaaaabcdd..........",
3668 ".........#aaaaaaaaacdd..........",
3669 "........#aaaaaaaaaabcdd.........",
3670 "........#aaabcccbaaacdd.........",
3671 ".......#aaaacccccaaabcdd........",
3672 ".......#aaaacccccaaaacdd........",
3673 "......#aaaaacccccaaaabcdd.......",
3674 "......#aaaaacccccaaaaacdd.......",
3675 ".....#aaaaaacccccaaaaabcdd......",
3676 ".....#aaaaaa#ccc#aaaaaacdd......",
3677 "....#aaaaaaabcccbaaaaaabcdd.....",
3678 "....#aaaaaaaacccaaaaaaaacdd.....",
3679 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3680 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3681 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3682 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3683 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3684 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3685 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3686 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3687 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3688 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3689 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3690 "..#ccccccccccccccccccccccccddddd",
3691 "....ddddddddddddddddddddddddddd.",
3692 ".....ddddddddddddddddddddddddd.."};
3694 wxIcon
wxWin32Renderer::GetStdIcon(int which
) const
3698 case wxICON_INFORMATION
:
3699 return wxIcon(info_xpm
);
3701 case wxICON_QUESTION
:
3702 return wxIcon(question_xpm
);
3704 case wxICON_EXCLAMATION
:
3705 return wxIcon(warning_xpm
);
3708 wxFAIL_MSG(wxT("requested non existent standard icon"));
3709 // still fall through
3712 return wxIcon(error_xpm
);
3717 // ----------------------------------------------------------------------------
3718 // text control geometry
3719 // ----------------------------------------------------------------------------
3721 static inline int GetTextBorderWidth()
3726 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3729 wxRect rectTotal
= rect
;
3731 wxCoord widthBorder
= GetTextBorderWidth();
3732 rectTotal
.Inflate(widthBorder
);
3734 // this is what Windows does
3740 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3742 wxCoord
*extraSpaceBeyond
)
3744 wxRect rectText
= rect
;
3746 // undo GetTextTotalArea()
3747 if ( rectText
.height
> 0 )
3750 wxCoord widthBorder
= GetTextBorderWidth();
3751 rectText
.Inflate(-widthBorder
);
3753 if ( extraSpaceBeyond
)
3754 *extraSpaceBeyond
= 0;
3759 // ----------------------------------------------------------------------------
3761 // ----------------------------------------------------------------------------
3763 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3766 if ( wxDynamicCast(window
, wxScrollBar
) )
3768 // we only set the width of vert scrollbars and height of the
3770 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3771 size
->y
= m_sizeScrollbarArrow
.y
;
3773 size
->x
= m_sizeScrollbarArrow
.x
;
3775 // skip border width adjustments, they don't make sense for us
3778 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3781 if ( wxDynamicCast(window
, wxButton
) )
3783 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3785 // TODO: don't harcode all this
3786 size
->x
+= 3*window
->GetCharWidth();
3788 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3789 if ( size
->y
< heightBtn
- 8 )
3790 size
->y
= heightBtn
;
3795 // no border width adjustments for buttons
3798 #endif // wxUSE_BUTTON
3800 // take into account the border width
3801 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3802 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3803 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3806 // ============================================================================
3808 // ============================================================================
3810 // ----------------------------------------------------------------------------
3811 // wxWin32InputHandler
3812 // ----------------------------------------------------------------------------
3814 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3816 m_renderer
= renderer
;
3819 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3820 const wxKeyEvent
& event
,
3826 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3827 const wxMouseEvent
& event
)
3829 // clicking on the control gives it focus
3830 if ( event
.ButtonDown() )
3832 wxWindow
*win
= control
->GetInputWindow();
3833 if ( wxWindow::FindFocus() != control
->GetInputWindow() )
3844 // ----------------------------------------------------------------------------
3845 // wxWin32ScrollBarInputHandler
3846 // ----------------------------------------------------------------------------
3848 wxWin32ScrollBarInputHandler::
3849 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3850 wxInputHandler
*handler
)
3851 : wxStdScrollBarInputHandler(renderer
, handler
)
3853 m_scrollPaused
= FALSE
;
3857 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3858 const wxControlAction
& action
)
3860 // stop if went beyond the position of the original click (this can only
3861 // happen when we scroll by pages)
3863 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3865 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3866 != wxHT_SCROLLBAR_BAR_2
;
3868 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3870 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3871 != wxHT_SCROLLBAR_BAR_1
;
3876 StopScrolling(scrollbar
);
3878 scrollbar
->Refresh();
3883 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3886 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3887 const wxMouseEvent
& event
)
3889 // remember the current state
3890 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3892 // do process the message
3893 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3895 // analyse the changes
3896 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3898 // we just started dragging the thumb, remember its initial position to
3899 // be able to restore it if the drag is cancelled later
3900 m_eventStartDrag
= event
;
3906 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3907 const wxMouseEvent
& event
)
3909 // we don't highlight scrollbar elements, so there is no need to process
3910 // mouse move events normally - only do it while mouse is captured (i.e.
3911 // when we're dragging the thumb or pressing on something)
3912 if ( !m_winCapture
)
3915 if ( event
.Entering() )
3917 // we're not interested in this at all
3921 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3923 if ( m_scrollPaused
)
3925 // check if the mouse returned to its original location
3927 if ( event
.Leaving() )
3933 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3934 if ( ht
== m_htLast
)
3936 // yes it did, resume scrolling
3937 m_scrollPaused
= FALSE
;
3938 if ( m_timerScroll
)
3940 // we were scrolling by line/page, restart timer
3941 m_timerScroll
->Start(m_interval
);
3943 Press(scrollbar
, TRUE
);
3945 else // we were dragging the thumb
3947 // restore its last location
3948 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3954 else // normal case, scrolling hasn't been paused
3956 // if we're scrolling the scrollbar because the arrow or the shaft was
3957 // pressed, check that the mouse stays on the same scrollbar element
3959 if ( event
.Moving() )
3961 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3963 else // event.Leaving()
3968 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3969 // is still ok - we only want to catch the case when the mouse leaves
3970 // the scrollbar here
3971 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3973 ht
= wxHT_SCROLLBAR_THUMB
;
3976 if ( ht
!= m_htLast
)
3978 // what were we doing? 2 possibilities: either an arrow/shaft was
3979 // pressed in which case we have a timer and so we just stop it or
3980 // we were dragging the thumb
3981 if ( m_timerScroll
)
3984 m_interval
= m_timerScroll
->GetInterval();
3985 m_timerScroll
->Stop();
3986 m_scrollPaused
= TRUE
;
3988 // unpress the arrow
3989 Press(scrollbar
, FALSE
);
3991 else // we were dragging the thumb
3993 // remember the current thumb position to be able to restore it
3994 // if the mouse returns to it later
3995 m_eventLastDrag
= event
;
3997 // and restore the original position (before dragging) of the
3999 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4006 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4009 // ----------------------------------------------------------------------------
4010 // wxWin32CheckboxInputHandler
4011 // ----------------------------------------------------------------------------
4013 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4014 const wxKeyEvent
& event
,
4019 wxControlAction action
;
4020 int keycode
= event
.GetKeyCode();
4024 action
= wxACTION_CHECKBOX_TOGGLE
;
4028 case WXK_NUMPAD_SUBTRACT
:
4029 action
= wxACTION_CHECKBOX_CHECK
;
4033 case WXK_NUMPAD_ADD
:
4034 case WXK_NUMPAD_EQUAL
:
4035 action
= wxACTION_CHECKBOX_CLEAR
;
4041 control
->PerformAction(action
);
4050 // ----------------------------------------------------------------------------
4051 // wxWin32TextCtrlInputHandler
4052 // ----------------------------------------------------------------------------
4054 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4055 const wxKeyEvent
& event
,
4058 // handle only MSW-specific text bindings here, the others are handled in
4062 int keycode
= event
.GetKeyCode();
4064 wxControlAction action
;
4065 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4067 action
= wxACTION_TEXT_CUT
;
4069 else if ( keycode
== WXK_INSERT
)
4071 if ( event
.ControlDown() )
4072 action
= wxACTION_TEXT_COPY
;
4073 else if ( event
.ShiftDown() )
4074 action
= wxACTION_TEXT_PASTE
;
4077 if ( action
!= wxACTION_NONE
)
4079 control
->PerformAction(action
);
4085 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4088 // ----------------------------------------------------------------------------
4089 // wxWin32StatusBarInputHandler
4090 // ----------------------------------------------------------------------------
4092 wxWin32StatusBarInputHandler::
4093 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4094 : wxStdInputHandler(handler
)
4099 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4100 const wxPoint
& pt
) const
4102 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4103 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4105 wxSize sizeSbar
= statbar
->GetSize();
4107 return (sizeSbar
.x
- pt
.x
) < (wxCoord
)STATUSBAR_GRIP_SIZE
&&
4108 (sizeSbar
.y
- pt
.y
) < (wxCoord
)STATUSBAR_GRIP_SIZE
;
4114 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4115 const wxMouseEvent
& event
)
4117 if ( event
.Button(1) )
4119 if ( event
.ButtonDown(1) )
4121 wxWindow
*statbar
= consumer
->GetInputWindow();
4123 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4125 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4129 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4130 wxHT_TOPLEVEL_BORDER_SE
);
4132 statbar
->SetCursor(m_cursorOld
);
4140 return wxStdInputHandler::HandleMouse(consumer
, event
);
4143 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4144 const wxMouseEvent
& event
)
4146 wxWindow
*statbar
= consumer
->GetInputWindow();
4148 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4149 if ( isOnGrip
!= m_isOnGrip
)
4151 m_isOnGrip
= isOnGrip
;
4154 m_cursorOld
= statbar
->GetCursor();
4155 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4159 statbar
->SetCursor(m_cursorOld
);
4163 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4166 // ----------------------------------------------------------------------------
4167 // wxWin32FrameInputHandler
4168 // ----------------------------------------------------------------------------
4170 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4171 const wxMouseEvent
& event
)
4173 if ( event
.LeftDClick() )
4175 wxTopLevelWindow
*tlw
=
4176 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4178 long hit
= tlw
->HitTest(event
.GetPosition());
4180 if ( hit
== wxHT_TOPLEVEL_TITLEBAR
)
4182 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4183 tlw
->IsMaximized() ?
4184 wxTOPLEVEL_BUTTON_RESTORE
:
4185 wxTOPLEVEL_BUTTON_MAXIMIZE
);
4190 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);