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 // ----------------------------------------------------------------------------
581 // wxWin32ColourScheme: uses (default) Win32 colours
582 // ----------------------------------------------------------------------------
584 class wxWin32ColourScheme
: public wxColourScheme
587 virtual wxColour
Get(StdColour col
) const;
588 virtual wxColour
GetBackground(wxWindow
*win
) const;
591 // ----------------------------------------------------------------------------
593 // ----------------------------------------------------------------------------
595 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
597 class wxWin32Theme
: public wxTheme
601 virtual ~wxWin32Theme();
603 virtual wxRenderer
*GetRenderer();
604 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
605 virtual wxColourScheme
*GetColourScheme();
608 // get the default input handler
609 wxInputHandler
*GetDefaultInputHandler();
611 wxWin32Renderer
*m_renderer
;
613 // the names of the already created handlers and the handlers themselves
614 // (these arrays are synchronized)
615 wxSortedArrayString m_handlerNames
;
616 wxArrayHandlers m_handlers
;
618 wxWin32InputHandler
*m_handlerDefault
;
620 wxWin32ColourScheme
*m_scheme
;
622 WX_DECLARE_THEME(win32
)
625 // ----------------------------------------------------------------------------
627 // ----------------------------------------------------------------------------
629 // frame buttons bitmaps
631 static const char *frame_button_close_xpm
[] = {
646 static const char *frame_button_help_xpm
[] = {
661 static const char *frame_button_maximize_xpm
[] = {
676 static const char *frame_button_minimize_xpm
[] = {
691 static const char *frame_button_restore_xpm
[] = {
708 static const char *checked_menu_xpm
[] = {
709 /* columns rows colors chars-per-pixel */
725 static const char *selected_checked_menu_xpm
[] = {
726 /* columns rows colors chars-per-pixel */
742 static const char *disabled_checked_menu_xpm
[] = {
743 /* columns rows colors chars-per-pixel */
760 static const char *selected_disabled_checked_menu_xpm
[] = {
761 /* columns rows colors chars-per-pixel */
777 // checkbox and radiobox bitmaps below
779 static const char *checked_xpm
[] = {
780 /* columns rows colors chars-per-pixel */
803 static const char *pressed_checked_xpm
[] = {
804 /* columns rows colors chars-per-pixel */
826 static const char *pressed_disabled_checked_xpm
[] = {
827 /* columns rows colors chars-per-pixel */
849 static const char *checked_item_xpm
[] = {
850 /* columns rows colors chars-per-pixel */
871 static const char *unchecked_xpm
[] = {
872 /* columns rows colors chars-per-pixel */
895 static const char *pressed_unchecked_xpm
[] = {
896 /* columns rows colors chars-per-pixel */
918 static const char *unchecked_item_xpm
[] = {
919 /* columns rows colors chars-per-pixel */
939 static const char *checked_radio_xpm
[] = {
940 /* columns rows colors chars-per-pixel */
963 static const char *pressed_checked_radio_xpm
[] = {
964 /* columns rows colors chars-per-pixel */
987 static const char *pressed_disabled_checked_radio_xpm
[] = {
988 /* columns rows colors chars-per-pixel */
1011 static const char *unchecked_radio_xpm
[] = {
1012 /* columns rows colors chars-per-pixel */
1035 static const char *pressed_unchecked_radio_xpm
[] = {
1036 /* columns rows colors chars-per-pixel */
1059 static const char **
1060 bmpIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1065 { checked_xpm
, unchecked_xpm
},
1068 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1071 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1077 { checked_radio_xpm
, unchecked_radio_xpm
},
1080 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1083 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1089 { checked_menu_xpm
, NULL
},
1092 { selected_checked_menu_xpm
, NULL
},
1095 { disabled_checked_menu_xpm
, NULL
},
1097 // disabled selected state
1098 { selected_disabled_checked_menu_xpm
, NULL
},
1102 // ============================================================================
1104 // ============================================================================
1106 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1108 // ----------------------------------------------------------------------------
1110 // ----------------------------------------------------------------------------
1112 wxWin32Theme::wxWin32Theme()
1116 m_handlerDefault
= NULL
;
1119 wxWin32Theme::~wxWin32Theme()
1121 size_t count
= m_handlers
.GetCount();
1122 for ( size_t n
= 0; n
< count
; n
++ )
1124 if ( m_handlers
[n
] != m_handlerDefault
)
1125 delete m_handlers
[n
];
1128 delete m_handlerDefault
;
1134 wxRenderer
*wxWin32Theme::GetRenderer()
1138 m_renderer
= new wxWin32Renderer(GetColourScheme());
1144 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1146 if ( !m_handlerDefault
)
1148 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1151 return m_handlerDefault
;
1154 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1156 wxInputHandler
*handler
;
1157 int n
= m_handlerNames
.Index(control
);
1158 if ( n
== wxNOT_FOUND
)
1160 // create a new handler
1161 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1162 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1163 GetDefaultInputHandler());
1165 else if ( control
== wxINP_HANDLER_BUTTON
)
1166 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1167 #endif // wxUSE_BUTTON
1169 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1170 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1171 #endif // wxUSE_CHECKBOX
1173 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1174 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1175 #endif // wxUSE_COMBOBOX
1177 else if ( control
== wxINP_HANDLER_LISTBOX
)
1178 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1179 #endif // wxUSE_LISTBOX
1180 #if wxUSE_CHECKLISTBOX
1181 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1182 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1183 #endif // wxUSE_CHECKLISTBOX
1185 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1186 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1187 #endif // wxUSE_TEXTCTRL
1189 else if ( control
== wxINP_HANDLER_SLIDER
)
1190 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1191 #endif // wxUSE_SLIDER
1193 else if ( control
== wxINP_HANDLER_SPINBTN
)
1194 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1195 #endif // wxUSE_SPINBTN
1197 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1198 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1199 #endif // wxUSE_NOTEBOOK
1201 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1202 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1203 #endif // wxUSE_STATUSBAR
1204 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1205 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
1207 handler
= GetDefaultInputHandler();
1209 n
= m_handlerNames
.Add(control
);
1210 m_handlers
.Insert(handler
, n
);
1212 else // we already have it
1214 handler
= m_handlers
[n
];
1220 wxColourScheme
*wxWin32Theme::GetColourScheme()
1224 m_scheme
= new wxWin32ColourScheme
;
1229 // ============================================================================
1230 // wxWin32ColourScheme
1231 // ============================================================================
1233 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1236 if ( win
->UseBgCol() )
1238 // use the user specified colour
1239 col
= win
->GetBackgroundColour();
1242 if ( win
->IsContainerWindow() )
1244 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1247 if ( !text
->IsEnabled() ) // not IsEditable()
1249 //else: execute code below
1254 // doesn't depend on the state
1260 int flags
= win
->GetStateFlags();
1262 // the colour set by the user should be used for the normal state
1263 // and for the states for which we don't have any specific colours
1264 if ( !col
.Ok() || (flags
!= 0) )
1266 if ( wxDynamicCast(win
, wxScrollBar
) )
1267 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1277 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1281 // use the system colours under Windows
1282 #if defined(__WXMSW__)
1283 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1285 case CONTROL_PRESSED
:
1286 case CONTROL_CURRENT
:
1287 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1289 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1291 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1292 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1294 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1295 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1297 #if defined(COLOR_3DDKSHADOW)
1298 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1300 case SHADOW_DARK
: return *wxBLACK
;
1303 case CONTROL_TEXT_DISABLED
:
1304 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1306 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1308 case CONTROL_TEXT_DISABLED_SHADOW
:
1309 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1311 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1312 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1313 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1314 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1316 case DESKTOP
: return wxColour(0x808000);
1318 // use the standard Windows colours elsewhere
1319 case WINDOW
: return *wxWHITE
;
1321 case CONTROL_PRESSED
:
1322 case CONTROL_CURRENT
:
1323 case CONTROL
: return wxColour(0xc0c0c0);
1325 case CONTROL_TEXT
: return *wxBLACK
;
1327 case SCROLLBAR
: return wxColour(0xe0e0e0);
1328 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1330 case HIGHLIGHT
: return wxColour(0x800000);
1331 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1333 case SHADOW_DARK
: return *wxBLACK
;
1335 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1336 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1338 case SHADOW_IN
: return wxColour(0xc0c0c0);
1340 case CONTROL_TEXT_DISABLED_SHADOW
:
1341 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1343 case TITLEBAR
: return wxColour(0xaeaaae);
1344 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1345 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1346 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1348 case DESKTOP
: return wxColour(0x808000);
1353 wxFAIL_MSG(_T("invalid standard colour"));
1358 // ============================================================================
1360 // ============================================================================
1362 // ----------------------------------------------------------------------------
1364 // ----------------------------------------------------------------------------
1366 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1370 m_sizeScrollbarArrow
= wxSize(16, 16);
1372 // init colours and pens
1373 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1375 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1376 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1378 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1380 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1381 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1383 m_titlebarFont
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
1384 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1386 // init the arrow bitmaps
1387 static const size_t ARROW_WIDTH
= 7;
1388 static const size_t ARROW_LENGTH
= 4;
1391 wxMemoryDC dcNormal
,
1394 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1396 bool isVertical
= n
> Arrow_Right
;
1409 // disabled arrow is larger because of the shadow
1410 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1411 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1413 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1414 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1416 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1417 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1421 dcNormal
.SetPen(m_penBlack
);
1422 dcDisabled
.SetPen(m_penDarkGrey
);
1424 // calculate the position of the point of the arrow
1428 x1
= (ARROW_WIDTH
- 1)/2;
1429 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1433 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1434 y1
= (ARROW_WIDTH
- 1)/2;
1445 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1447 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1448 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1455 if ( n
== Arrow_Up
)
1466 else // left or right arrow
1471 if ( n
== Arrow_Left
)
1484 // draw the shadow for the disabled one
1485 dcDisabled
.SetPen(m_penHighlight
);
1490 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1494 x1
= ARROW_LENGTH
- 1;
1495 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1498 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1499 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1504 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1508 x1
= ARROW_WIDTH
- 1;
1510 x2
= (ARROW_WIDTH
- 1)/2;
1512 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1513 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1518 // create the inversed bitmap but only for the right arrow as we only
1519 // use it for the menus
1520 if ( n
== Arrow_Right
)
1522 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1523 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1525 dcInverse
.Blit(0, 0, w
, h
,
1528 dcInverse
.SelectObject(wxNullBitmap
);
1530 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1531 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1533 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1534 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1536 dcInverse
.Blit(0, 0, w
, h
,
1539 dcInverse
.SelectObject(wxNullBitmap
);
1541 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1542 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1545 dcNormal
.SelectObject(wxNullBitmap
);
1546 dcDisabled
.SelectObject(wxNullBitmap
);
1548 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1549 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1550 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1551 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1553 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1556 // init the frame buttons bitmaps
1557 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1558 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1559 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1560 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1561 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1564 // ----------------------------------------------------------------------------
1566 // ----------------------------------------------------------------------------
1569 The raised border in Win32 looks like this:
1571 IIIIIIIIIIIIIIIIIIIIIIB
1573 I GB I = white (HILIGHT)
1574 I GB H = light grey (LIGHT)
1575 I GB G = dark grey (SHADOI)
1576 I GB B = black (DKSHADOI)
1577 I GB I = hIghlight (COLOR_3DHILIGHT)
1579 IGGGGGGGGGGGGGGGGGGGGGB
1580 BBBBBBBBBBBBBBBBBBBBBBB
1582 The sunken border looks like this:
1584 GGGGGGGGGGGGGGGGGGGGGGI
1585 GBBBBBBBBBBBBBBBBBBBBHI
1592 GHHHHHHHHHHHHHHHHHHHHHI
1593 IIIIIIIIIIIIIIIIIIIIIII
1595 The static border (used for the controls which don't get focus) is like
1598 GGGGGGGGGGGGGGGGGGGGGGW
1606 WWWWWWWWWWWWWWWWWWWWWWW
1608 The most complicated is the double border:
1610 HHHHHHHHHHHHHHHHHHHHHHB
1611 HWWWWWWWWWWWWWWWWWWWWGB
1612 HWHHHHHHHHHHHHHHHHHHHGB
1617 HWHHHHHHHHHHHHHHHHHHHGB
1618 HGGGGGGGGGGGGGGGGGGGGGB
1619 BBBBBBBBBBBBBBBBBBBBBBB
1621 And the simple border is, well, simple:
1623 BBBBBBBBBBBBBBBBBBBBBBB
1632 BBBBBBBBBBBBBBBBBBBBBBB
1635 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1639 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1640 dc
.DrawRectangle(*rect
);
1646 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1648 // draw the bottom and right sides
1650 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1651 rect
->GetRight() + 1, rect
->GetBottom());
1652 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1653 rect
->GetRight(), rect
->GetBottom());
1660 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1661 const wxPen
& pen1
, const wxPen
& pen2
)
1663 // draw the rectangle
1665 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1666 rect
->GetLeft(), rect
->GetBottom());
1667 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1668 rect
->GetRight(), rect
->GetTop());
1670 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1671 rect
->GetRight(), rect
->GetBottom());
1672 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1673 rect
->GetRight() + 1, rect
->GetBottom());
1679 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1681 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1682 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1685 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1687 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1688 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1691 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1695 DrawRect(dc
, rect
, m_penDarkGrey
);
1697 // the arrow is usually drawn inside border of width 2 and is offset by
1698 // another pixel in both directions when it's pressed - as the border
1699 // in this case is more narrow as well, we have to adjust rect like
1707 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1708 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1712 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1714 const wxRect
& rectTotal
,
1715 int WXUNUSED(flags
),
1720 wxRect rect
= rectTotal
;
1724 case wxBORDER_SUNKEN
:
1725 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1727 DrawSunkenBorder(dc
, &rect
);
1731 case wxBORDER_STATIC
:
1732 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1735 case wxBORDER_RAISED
:
1736 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1738 DrawRaisedBorder(dc
, &rect
);
1742 case wxBORDER_DOUBLE
:
1743 DrawArrowBorder(dc
, &rect
);
1744 DrawRect(dc
, &rect
, m_penLightGrey
);
1747 case wxBORDER_SIMPLE
:
1748 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1750 DrawRect(dc
, &rect
, m_penBlack
);
1755 wxFAIL_MSG(_T("unknown border type"));
1758 case wxBORDER_DEFAULT
:
1767 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1772 case wxBORDER_RAISED
:
1773 case wxBORDER_SUNKEN
:
1774 width
= BORDER_THICKNESS
;
1777 case wxBORDER_SIMPLE
:
1778 case wxBORDER_STATIC
:
1782 case wxBORDER_DOUBLE
:
1787 wxFAIL_MSG(_T("unknown border type"));
1790 case wxBORDER_DEFAULT
:
1800 rect
.height
= width
;
1805 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1810 // ----------------------------------------------------------------------------
1812 // ----------------------------------------------------------------------------
1814 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1820 // text controls are not special under windows
1821 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1824 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1825 const wxRect
& rectTotal
,
1829 wxRect rect
= rectTotal
;
1831 if ( flags
& wxCONTROL_PRESSED
)
1833 // button pressed: draw a double border around it
1834 DrawRect(dc
, &rect
, m_penBlack
);
1835 DrawRect(dc
, &rect
, m_penDarkGrey
);
1839 // button not pressed
1841 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1843 // button either default or focused (or both): add an extra border around it
1844 DrawRect(dc
, &rect
, m_penBlack
);
1847 // now draw a normal button
1848 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1849 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1858 // ----------------------------------------------------------------------------
1860 // ----------------------------------------------------------------------------
1862 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1863 wxCoord y
, wxCoord x1
, wxCoord x2
)
1865 dc
.SetPen(m_penDarkGrey
);
1866 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1867 dc
.SetPen(m_penHighlight
);
1869 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1872 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1873 wxCoord x
, wxCoord y1
, wxCoord y2
)
1875 dc
.SetPen(m_penDarkGrey
);
1876 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1877 dc
.SetPen(m_penHighlight
);
1879 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1882 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1883 const wxString
& label
,
1889 wxCoord height
= 0; // of the label
1890 wxRect rectFrame
= rect
;
1891 if ( !label
.empty() )
1893 // the text should touch the top border of the rect, so the frame
1894 // itself should be lower
1895 dc
.GetTextExtent(label
, NULL
, &height
);
1896 rectFrame
.y
+= height
/ 2;
1897 rectFrame
.height
-= height
/ 2;
1899 // we have to draw each part of the frame individually as we can't
1900 // erase the background beyond the label as it might contain some
1901 // pixmap already, so drawing everything and then overwriting part of
1902 // the frame with label doesn't work
1904 // TODO: the +5 and space insertion should be customizable
1907 rectText
.x
= rectFrame
.x
+ 5;
1908 rectText
.y
= rect
.y
;
1909 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1910 rectText
.height
= height
;
1913 label2
<< _T(' ') << label
<< _T(' ');
1914 if ( indexAccel
!= -1 )
1916 // adjust it as we prepended a space
1921 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1923 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1927 // just draw the complete frame
1928 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1929 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1933 // ----------------------------------------------------------------------------
1935 // ----------------------------------------------------------------------------
1937 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1939 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1940 // pixels each while we really need dots here... PS_ALTERNATE might
1941 // work, but it is for NT 5 only
1943 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1945 // draw the pixels manually: note that to behave in the same manner as
1946 // DrawRect(), we must exclude the bottom and right borders from the
1948 wxCoord x1
= rect
.GetLeft(),
1950 x2
= rect
.GetRight(),
1951 y2
= rect
.GetBottom();
1953 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1955 // this seems to be closer than what Windows does than wxINVERT although
1956 // I'm still not sure if it's correct
1957 dc
.SetLogicalFunction(wxAND_REVERSE
);
1960 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1961 dc
.DrawPoint(z
, rect
.GetTop());
1963 wxCoord shift
= z
== x2
? 0 : 1;
1964 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1965 dc
.DrawPoint(x2
, z
);
1967 shift
= z
== y2
? 0 : 1;
1968 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1969 dc
.DrawPoint(z
, y2
);
1971 shift
= z
== x1
? 0 : 1;
1972 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
1973 dc
.DrawPoint(x1
, z
);
1975 dc
.SetLogicalFunction(wxCOPY
);
1979 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
1980 const wxString
& label
,
1985 // draw shadow of the text
1986 dc
.SetTextForeground(m_colHighlight
);
1987 wxRect rectShadow
= rect
;
1990 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1992 // make the text grey
1993 dc
.SetTextForeground(m_colDarkGrey
);
1996 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1997 const wxString
& label
,
2004 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2007 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2008 const wxString
& label
,
2014 const wxPoint
& focusOffset
)
2016 // the underscores are not drawn for focused controls in wxMSW
2017 if ( flags
& wxCONTROL_FOCUSED
)
2022 if ( flags
& wxCONTROL_DISABLED
)
2024 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2025 // currently only can happen for a menu item and it seems that Windows
2026 // doesn't draw the shadow in this case, so we don't do it neither
2027 if ( flags
& wxCONTROL_SELECTED
)
2029 // just make the label text greyed out
2030 dc
.SetTextForeground(m_colDarkGrey
);
2032 else // draw normal disabled label
2034 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2039 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2041 if ( flags
& wxCONTROL_DISABLED
)
2043 // restore the fg colour
2044 dc
.SetTextForeground(*wxBLACK
);
2047 if ( flags
& wxCONTROL_FOCUSED
)
2049 if ( focusOffset
.x
|| focusOffset
.y
)
2051 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2054 DrawFocusRect(dc
, rectLabel
);
2058 *rectBounds
= rectLabel
;
2061 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2062 const wxString
& label
,
2063 const wxBitmap
& image
,
2070 // the underscores are not drawn for focused controls in wxMSW
2071 if ( flags
& wxCONTROL_PRESSED
)
2076 wxRect rectLabel
= rect
;
2077 if ( !label
.empty() )
2079 // shift the label if a button is pressed
2080 if ( flags
& wxCONTROL_PRESSED
)
2086 if ( flags
& wxCONTROL_DISABLED
)
2088 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2091 // leave enough space for the focus rectangle
2092 if ( flags
& wxCONTROL_FOCUSED
)
2094 rectLabel
.Inflate(-2);
2098 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2100 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2102 if ( flags
& wxCONTROL_PRESSED
)
2104 // the focus rectangle is never pressed, so undo the shift done
2112 DrawFocusRect(dc
, rectLabel
);
2116 // ----------------------------------------------------------------------------
2117 // (check)listbox items
2118 // ----------------------------------------------------------------------------
2120 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2121 const wxString
& label
,
2125 wxDCTextColourChanger
colChanger(dc
);
2127 if ( flags
& wxCONTROL_SELECTED
)
2129 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2131 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2132 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2133 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2134 dc
.DrawRectangle(rect
);
2137 wxRect rectText
= rect
;
2139 rectText
.width
-= 2;
2140 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2142 if ( flags
& wxCONTROL_FOCUSED
)
2144 DrawFocusRect(dc
, rect
);
2148 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2149 const wxString
& label
,
2150 const wxBitmap
& bitmap
,
2159 else // use default bitmap
2161 bmp
= wxBitmap(flags
& wxCONTROL_CHECKED
? checked_item_xpm
2162 : unchecked_item_xpm
);
2165 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2166 TRUE
/* use mask */);
2168 wxRect rectLabel
= rect
;
2169 int bmpWidth
= bmp
.GetWidth();
2170 rectLabel
.x
+= bmpWidth
;
2171 rectLabel
.width
-= bmpWidth
;
2173 DrawItem(dc
, label
, rectLabel
, flags
);
2176 // ----------------------------------------------------------------------------
2177 // check/radio buttons
2178 // ----------------------------------------------------------------------------
2180 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2182 IndicatorState indState
;
2183 if ( flags
& wxCONTROL_SELECTED
)
2184 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2185 : IndicatorState_Selected
;
2186 else if ( flags
& wxCONTROL_DISABLED
)
2187 indState
= IndicatorState_Disabled
;
2188 else if ( flags
& wxCONTROL_PRESSED
)
2189 indState
= IndicatorState_Pressed
;
2191 indState
= IndicatorState_Normal
;
2193 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2194 ? IndicatorStatus_Checked
2195 : IndicatorStatus_Unchecked
;
2197 const char **xpm
= bmpIndicators
[indType
][indState
][indStatus
];
2198 return xpm
? wxBitmap(xpm
) : wxNullBitmap
;
2201 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2202 const wxString
& label
,
2203 const wxBitmap
& bitmap
,
2208 wxCoord focusOffsetY
)
2210 // calculate the position of the bitmap and of the label
2211 wxCoord heightBmp
= bitmap
.GetHeight();
2213 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2216 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2217 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2219 // align label vertically with the bitmap - looks nicer like this
2220 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2222 // calc horz position
2223 if ( align
== wxALIGN_RIGHT
)
2225 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2226 rectLabel
.x
= rect
.x
+ 3;
2227 rectLabel
.SetRight(xBmp
);
2229 else // normal (checkbox to the left of the text) case
2232 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2233 rectLabel
.SetRight(rect
.GetRight());
2236 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2239 dc
, label
, rectLabel
,
2241 wxALIGN_LEFT
| wxALIGN_TOP
,
2243 NULL
, // we don't need bounding rect
2244 // use custom vert focus rect offset
2245 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2249 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2250 const wxString
& label
,
2251 const wxBitmap
& bitmap
,
2257 DrawCheckOrRadioButton(dc
, label
,
2258 bitmap
.Ok() ? bitmap
: GetRadioBitmap(flags
),
2259 rect
, flags
, align
, indexAccel
,
2260 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2263 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2264 const wxString
& label
,
2265 const wxBitmap
& bitmap
,
2271 DrawCheckOrRadioButton(dc
, label
,
2272 bitmap
.Ok() ? bitmap
: GetCheckBitmap(flags
),
2273 rect
, flags
, align
, indexAccel
,
2274 0); // no focus rect offset for checkboxes
2277 // ----------------------------------------------------------------------------
2279 // ----------------------------------------------------------------------------
2281 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2282 const wxString
& text
,
2288 // nothing special to do here
2289 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2292 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2294 // we don't draw them
2297 // ----------------------------------------------------------------------------
2299 // ----------------------------------------------------------------------------
2301 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2302 const wxRect
& rectOrig
,
2304 const wxString
& label
,
2305 const wxBitmap
& bitmap
,
2309 wxRect rect
= rectOrig
;
2311 // the current tab is drawn indented (to the top for default case) and
2312 // bigger than the other ones
2313 const wxSize indent
= GetTabIndent();
2314 if ( flags
& wxCONTROL_SELECTED
)
2319 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2323 rect
.Inflate(indent
.x
, 0);
2325 rect
.height
+= indent
.y
;
2329 rect
.Inflate(indent
.x
, 0);
2330 rect
.height
+= indent
.y
;
2335 wxFAIL_MSG(_T("TODO"));
2340 // draw the text, image and the focus around them (if necessary)
2341 wxRect rectLabel
= rect
;
2342 rectLabel
.Deflate(1, 1);
2343 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2344 flags
, wxALIGN_CENTRE
, indexAccel
);
2346 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2347 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2350 x2
= rect
.GetRight(),
2351 y2
= rect
.GetBottom();
2353 // FIXME: all this code will break if the tab indent or the border width,
2354 // it is tied to the fact that both of them are equal to 2
2359 dc
.SetPen(m_penHighlight
);
2360 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2361 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2362 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2364 dc
.SetPen(m_penBlack
);
2365 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2366 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2368 dc
.SetPen(m_penDarkGrey
);
2369 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2371 if ( flags
& wxCONTROL_SELECTED
)
2373 dc
.SetPen(m_penLightGrey
);
2375 // overwrite the part of the border below this tab
2376 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2378 // and the shadow of the tab to the left of us
2379 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2384 dc
.SetPen(m_penHighlight
);
2385 // we need to continue one pixel further to overwrite the corner of
2386 // the border for the selected tab
2387 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2389 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2391 dc
.SetPen(m_penBlack
);
2392 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2393 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2394 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2396 dc
.SetPen(m_penDarkGrey
);
2397 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2398 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2400 if ( flags
& wxCONTROL_SELECTED
)
2402 dc
.SetPen(m_penLightGrey
);
2404 // overwrite the part of the (double!) border above this tab
2405 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2406 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2408 // and the shadow of the tab to the left of us
2409 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2415 wxFAIL_MSG(_T("TODO"));
2419 // ----------------------------------------------------------------------------
2421 // ----------------------------------------------------------------------------
2423 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2424 wxOrientation orient
) const
2428 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2429 if ( orient
== wxHORIZONTAL
)
2431 size
.y
= rect
.height
- 6;
2432 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2436 size
.x
= rect
.width
- 6;
2437 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2443 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2444 wxOrientation orient
) const
2446 static const wxCoord SLIDER_MARGIN
= 6;
2448 wxRect rect
= rectOrig
;
2450 if ( orient
== wxHORIZONTAL
)
2452 // make the rect of minimal width and centre it
2453 rect
.height
= 2*BORDER_THICKNESS
;
2454 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2458 // leave margins on the sides
2459 rect
.Deflate(SLIDER_MARGIN
, 0);
2463 // same as above but in other direction
2464 rect
.width
= 2*BORDER_THICKNESS
;
2465 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2469 rect
.Deflate(0, SLIDER_MARGIN
);
2475 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2476 const wxRect
& rectOrig
,
2477 wxOrientation orient
,
2481 if ( flags
& wxCONTROL_FOCUSED
)
2483 DrawFocusRect(dc
, rectOrig
);
2486 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2491 DrawSunkenBorder(dc
, &rect
);
2494 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2496 wxOrientation orient
,
2500 we are drawing a shape of this form
2505 H DB where H is hightlight colour
2518 The interior of this shape is filled with the hatched brush if the thumb
2522 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2524 bool transpose
= orient
== wxVERTICAL
;
2526 wxCoord x
, y
, x2
, y2
;
2531 x2
= rect
.GetBottom();
2532 y2
= rect
.GetRight();
2538 x2
= rect
.GetRight();
2539 y2
= rect
.GetBottom();
2542 // the size of the pointed part of the thumb
2543 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2545 wxCoord x3
= x
+ sizeArrow
,
2546 y3
= y2
- sizeArrow
;
2548 dc
.SetPen(m_penHighlight
);
2549 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2550 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2551 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2553 dc
.SetPen(m_penBlack
);
2554 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2555 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2557 dc
.SetPen(m_penDarkGrey
);
2558 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2559 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2561 if ( flags
& wxCONTROL_PRESSED
)
2563 // TODO: MSW fills the entire area inside, not just the rect
2564 wxRect rectInt
= rect
;
2566 rectInt
.SetRight(y3
);
2568 rectInt
.SetBottom(y3
);
2571 #if !defined(__WXMGL__)
2572 static const char *stipple_xpm
[] = {
2573 /* columns rows colors chars-per-pixel */
2582 // VS: MGL can only do 8x8 stipple brushes
2583 static const char *stipple_xpm
[] = {
2584 /* columns rows colors chars-per-pixel */
2599 dc
.SetBrush(wxBrush(stipple_xpm
));
2601 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2602 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2603 dc
.SetPen(*wxTRANSPARENT_PEN
);
2604 dc
.DrawRectangle(rectInt
);
2608 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2610 const wxSize
& sizeThumb
,
2611 wxOrientation orient
,
2623 // the variable names correspond to horizontal case, but they can be used
2624 // for both orientations
2625 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2626 if ( orient
== wxHORIZONTAL
)
2628 x1
= rect
.GetLeft();
2629 x2
= rect
.GetRight();
2631 // draw from bottom to top to leave one pixel space between the ticks
2632 // and the slider as Windows do
2633 y1
= rect
.GetBottom();
2638 widthThumb
= sizeThumb
.x
;
2643 x2
= rect
.GetBottom();
2645 y1
= rect
.GetRight();
2646 y2
= rect
.GetLeft();
2650 widthThumb
= sizeThumb
.y
;
2653 // the first tick should be positioned in such way that a thumb drawn in
2654 // the first position points down directly to it
2655 x1
+= widthThumb
/ 2;
2656 x2
-= widthThumb
/ 2;
2658 // this also means that we have slightly less space for the ticks in
2659 // between the first and the last
2662 dc
.SetPen(m_penBlack
);
2664 int range
= end
- start
;
2665 for ( int n
= 0; n
< range
; n
+= step
)
2667 wxCoord x
= x1
+ (len
*n
) / range
;
2669 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2672 // always draw the line at the end position
2673 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2676 // ----------------------------------------------------------------------------
2678 // ----------------------------------------------------------------------------
2680 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2681 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2684 virtual wxSize
GetSize() const { return m_size
; }
2686 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2687 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2689 wxCoord
GetItemHeight() const { return m_heightItem
; }
2692 // the total size of the menu
2695 // the offset of the start of the menu item label
2698 // the offset of the start of the accel label
2701 // the height of a normal (not separator) item
2702 wxCoord m_heightItem
;
2704 friend wxMenuGeometryInfo
*
2705 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2708 // FIXME: all constants are hardcoded but shouldn't be
2709 static const wxCoord MENU_LEFT_MARGIN
= 9;
2710 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2711 static const wxCoord MENU_VERT_MARGIN
= 3;
2713 // the margin around bitmap/check marks (on each side)
2714 static const wxCoord MENU_BMP_MARGIN
= 2;
2716 // the margin between the labels and accel strings
2717 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2719 // the separator height in pixels: in fact, strangely enough, the real height
2720 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2722 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2724 // the size of the standard checkmark bitmap
2725 static const wxCoord MENU_CHECK_SIZE
= 9;
2727 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2728 const wxRect
& rectOrig
,
2729 const wxString
& label
,
2733 wxRect rect
= rectOrig
;
2736 wxDCTextColourChanger
colChanger(dc
);
2738 if ( flags
& wxCONTROL_SELECTED
)
2740 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2742 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2743 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2744 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2745 dc
.DrawRectangle(rect
);
2748 // don't draw the focus rect around menu bar items
2749 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2750 wxALIGN_CENTRE
, indexAccel
);
2753 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2755 const wxMenuGeometryInfo
& gi
,
2756 const wxString
& label
,
2757 const wxString
& accel
,
2758 const wxBitmap
& bitmap
,
2762 const wxWin32MenuGeometryInfo
& geometryInfo
=
2763 (const wxWin32MenuGeometryInfo
&)gi
;
2768 rect
.width
= geometryInfo
.GetSize().x
;
2769 rect
.height
= geometryInfo
.GetItemHeight();
2771 // draw the selected item specially
2772 wxDCTextColourChanger
colChanger(dc
);
2773 if ( flags
& wxCONTROL_SELECTED
)
2775 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2777 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2778 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2779 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2780 dc
.DrawRectangle(rect
);
2783 // draw the bitmap: use the bitmap provided or the standard checkmark for
2784 // the checkable items
2785 wxBitmap bmp
= bitmap
;
2786 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2788 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2793 rect
.SetRight(geometryInfo
.GetLabelOffset());
2794 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2798 rect
.x
= geometryInfo
.GetLabelOffset();
2799 rect
.SetRight(geometryInfo
.GetAccelOffset());
2801 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2803 // draw the accel string
2804 rect
.x
= geometryInfo
.GetAccelOffset();
2805 rect
.SetRight(geometryInfo
.GetSize().x
);
2807 // NB: no accel index here
2808 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2810 // draw the submenu indicator
2811 if ( flags
& wxCONTROL_ISSUBMENU
)
2813 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2814 rect
.width
= MENU_RIGHT_MARGIN
;
2816 wxArrowStyle arrowStyle
;
2817 if ( flags
& wxCONTROL_DISABLED
)
2818 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2820 else if ( flags
& wxCONTROL_SELECTED
)
2821 arrowStyle
= Arrow_Inversed
;
2823 arrowStyle
= Arrow_Normal
;
2825 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2829 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2831 const wxMenuGeometryInfo
& geomInfo
)
2833 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2836 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2838 wxSize size
= sizeText
;
2840 // FIXME: menubar height is configurable under Windows
2847 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2848 const wxMenu
& menu
) const
2850 // prepare the dc: for now we draw all the items with the system font
2852 dc
.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
2854 // the height of a normal item
2855 wxCoord heightText
= dc
.GetCharHeight();
2860 // the max length of label and accel strings: the menu width is the sum of
2861 // them, even if they're for different items (as the accels should be
2864 // the max length of the bitmap is never 0 as Windows always leaves enough
2865 // space for a check mark indicator
2866 wxCoord widthLabelMax
= 0,
2868 widthBmpMax
= MENU_LEFT_MARGIN
;
2870 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2872 node
= node
->GetNext() )
2874 // height of this item
2877 wxMenuItem
*item
= node
->GetData();
2878 if ( item
->IsSeparator() )
2880 h
= MENU_SEPARATOR_HEIGHT
;
2882 else // not separator
2887 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2888 if ( widthLabel
> widthLabelMax
)
2890 widthLabelMax
= widthLabel
;
2894 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2895 if ( widthAccel
> widthAccelMax
)
2897 widthAccelMax
= widthAccel
;
2900 const wxBitmap
& bmp
= item
->GetBitmap();
2903 wxCoord widthBmp
= bmp
.GetWidth();
2904 if ( widthBmp
> widthBmpMax
)
2905 widthBmpMax
= widthBmp
;
2907 //else if ( item->IsCheckable() ): no need to check for this as
2908 // MENU_LEFT_MARGIN is big enough to show the check mark
2911 h
+= 2*MENU_VERT_MARGIN
;
2913 // remember the item position and height
2914 item
->SetGeometry(height
, h
);
2919 // bundle the metrics into a struct and return it
2920 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2922 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2923 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2924 if ( widthAccelMax
> 0 )
2926 // if we actually have any accesl, add a margin
2927 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2930 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2932 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2933 gi
->m_size
.y
= height
;
2938 // ----------------------------------------------------------------------------
2940 // ----------------------------------------------------------------------------
2942 static const wxCoord STATBAR_BORDER_X
= 2;
2943 static const wxCoord STATBAR_BORDER_Y
= 2;
2945 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2947 if ( borderBetweenFields
)
2948 *borderBetweenFields
= 2;
2950 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2953 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2955 const wxString
& label
,
2960 if ( flags
& wxCONTROL_ISDEFAULT
)
2962 // draw the size grip: it is a normal rect except that in the lower
2963 // right corner we have several bands which may be used for dragging
2964 // the status bar corner
2966 // each band consists of 4 stripes: m_penHighlight, double
2967 // m_penDarkGrey and transparent one
2968 wxCoord x2
= rect
.GetRight(),
2969 y2
= rect
.GetBottom();
2971 // draw the upper left part of the rect normally
2972 dc
.SetPen(m_penDarkGrey
);
2973 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
2974 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
2976 // draw the grey stripes of the grip
2978 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
2979 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2981 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2982 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
2985 // draw the white stripes
2986 dc
.SetPen(m_penHighlight
);
2987 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
2988 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2990 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2993 // draw the remaining rect boundaries
2994 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
2995 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
2996 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3001 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3005 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3008 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3010 wxDCClipper
clipper(dc
, rectIn
);
3011 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3014 // ----------------------------------------------------------------------------
3016 // ----------------------------------------------------------------------------
3018 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3020 wxBitmap
*bmpPressed
,
3021 wxBitmap
*bmpDisabled
)
3023 static const wxCoord widthCombo
= 16;
3024 static const wxCoord heightCombo
= 17;
3030 bmpNormal
->Create(widthCombo
, heightCombo
);
3031 dcMem
.SelectObject(*bmpNormal
);
3032 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3033 Arrow_Down
, Arrow_Normal
);
3038 bmpPressed
->Create(widthCombo
, heightCombo
);
3039 dcMem
.SelectObject(*bmpPressed
);
3040 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3041 Arrow_Down
, Arrow_Pressed
);
3046 bmpDisabled
->Create(widthCombo
, heightCombo
);
3047 dcMem
.SelectObject(*bmpDisabled
);
3048 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3049 Arrow_Down
, Arrow_Disabled
);
3053 // ----------------------------------------------------------------------------
3055 // ----------------------------------------------------------------------------
3057 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3058 const wxColour
& col
,
3061 wxBrush
brush(col
, wxSOLID
);
3063 dc
.SetPen(*wxTRANSPARENT_PEN
);
3064 dc
.DrawRectangle(rect
);
3067 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3068 const wxColour
& col
,
3072 // just fill it with the given or default bg colour
3073 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3074 DoDrawBackground(dc
, colBg
, rect
);
3077 // ----------------------------------------------------------------------------
3079 // ----------------------------------------------------------------------------
3081 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3086 // get the bitmap for this arrow
3087 wxArrowDirection arrowDir
;
3090 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3091 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3092 case wxUP
: arrowDir
= Arrow_Up
; break;
3093 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3096 wxFAIL_MSG(_T("unknown arrow direction"));
3100 wxArrowStyle arrowStyle
;
3101 if ( flags
& wxCONTROL_PRESSED
)
3103 // can't be pressed and disabled
3104 arrowStyle
= Arrow_Pressed
;
3108 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3111 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3114 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3116 wxArrowDirection arrowDir
,
3117 wxArrowStyle arrowStyle
)
3119 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3121 // under Windows the arrows always have the same size so just centre it in
3122 // the provided rectangle
3123 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3124 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3126 // Windows does it like this...
3127 if ( arrowDir
== Arrow_Left
)
3131 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3134 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3135 const wxRect
& rectAll
,
3136 wxArrowDirection arrowDir
,
3137 wxArrowStyle arrowStyle
)
3139 wxRect rect
= rectAll
;
3140 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3141 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3142 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3145 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3146 wxOrientation orient
,
3150 // we don't use the flags, the thumb never changes appearance
3151 wxRect rectThumb
= rect
;
3152 DrawArrowBorder(dc
, &rectThumb
);
3153 DrawBackground(dc
, wxNullColour
, rectThumb
);
3156 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3157 wxOrientation orient
,
3158 const wxRect
& rectBar
,
3161 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3162 ? wxColourScheme::SCROLLBAR_PRESSED
3163 : wxColourScheme::SCROLLBAR
;
3164 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3167 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3169 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3172 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3173 wxScrollBar::Element elem
,
3176 return StandardGetScrollbarRect(scrollbar
, elem
,
3177 thumbPos
, m_sizeScrollbarArrow
);
3180 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3182 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3185 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3186 const wxPoint
& pt
) const
3188 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3191 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3194 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3197 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3200 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3203 // ----------------------------------------------------------------------------
3204 // top level windows
3205 // ----------------------------------------------------------------------------
3207 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3209 wxRect client
= GetFrameClientArea(rect
, flags
);
3211 if ( client
.Inside(pt
) )
3212 return wxHT_TOPLEVEL_CLIENT_AREA
;
3214 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3216 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3218 if ( flags
& wxTOPLEVEL_ICON
)
3220 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3221 return wxHT_TOPLEVEL_ICON
;
3224 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3225 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3226 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3228 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3230 if ( btnRect
.Inside(pt
) )
3231 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3232 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3234 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3236 if ( btnRect
.Inside(pt
) )
3237 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3238 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3240 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3242 if ( btnRect
.Inside(pt
) )
3243 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3244 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3246 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3248 if ( btnRect
.Inside(pt
) )
3249 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3250 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3252 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3254 if ( btnRect
.Inside(pt
) )
3255 return wxHT_TOPLEVEL_BUTTON_HELP
;
3256 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3259 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3260 return wxHT_TOPLEVEL_TITLEBAR
;
3263 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3265 // we are certainly at one of borders, lets decide which one:
3268 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3269 if ( pt
.x
< client
.x
)
3270 border
|= wxHT_TOPLEVEL_BORDER_W
;
3271 else if ( pt
.x
>= client
.width
+ client
.x
)
3272 border
|= wxHT_TOPLEVEL_BORDER_E
;
3273 if ( pt
.y
< client
.y
)
3274 border
|= wxHT_TOPLEVEL_BORDER_N
;
3275 else if ( pt
.y
>= client
.height
+ client
.y
)
3276 border
|= wxHT_TOPLEVEL_BORDER_S
;
3280 return wxHT_NOWHERE
;
3283 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3285 const wxString
& title
,
3289 int specialButtonFlags
)
3291 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3293 DrawFrameBorder(dc
, rect
, flags
);
3295 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3297 DrawFrameBackground(dc
, rect
, flags
);
3298 if ( flags
& wxTOPLEVEL_ICON
)
3299 DrawFrameIcon(dc
, rect
, icon
, flags
);
3300 DrawFrameTitle(dc
, rect
, title
, flags
);
3302 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3304 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3305 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3307 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3309 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3310 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3311 specialButtonFlags
: 0);
3312 x
-= FRAME_BUTTON_WIDTH
+ 2;
3314 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3316 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3317 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3318 specialButtonFlags
: 0);
3319 x
-= FRAME_BUTTON_WIDTH
;
3321 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3323 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3324 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3325 specialButtonFlags
: 0);
3326 x
-= FRAME_BUTTON_WIDTH
;
3328 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3330 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3331 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3332 specialButtonFlags
: 0);
3333 x
-= FRAME_BUTTON_WIDTH
;
3335 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3337 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3338 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3339 specialButtonFlags
: 0);
3340 x
-= FRAME_BUTTON_WIDTH
;
3345 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3349 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3353 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3354 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3355 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3356 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3357 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3360 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3364 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3366 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3367 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3368 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3370 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3371 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3373 DrawBackground(dc
, col
, r
);
3376 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3378 const wxString
& title
,
3381 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3382 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3383 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3385 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3386 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3387 if ( flags
& wxTOPLEVEL_ICON
)
3388 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3392 dc
.SetFont(m_titlebarFont
);
3393 dc
.SetTextForeground(col
);
3394 dc
.DrawLabel(title
, wxNullBitmap
, r
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3397 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3404 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3405 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3409 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3410 wxCoord x
, wxCoord y
,
3414 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3419 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3420 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3421 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3422 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3423 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3425 wxFAIL_MSG(wxT("incorrect button specification"));
3428 if ( flags
& wxCONTROL_PRESSED
)
3430 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3431 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3432 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3433 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3437 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3438 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3439 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3440 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3445 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3450 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3452 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3453 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3454 FRAME_BORDER_THICKNESS
;
3457 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3459 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3460 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3466 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3469 wxSize
s(clientSize
);
3471 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3473 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3474 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3475 FRAME_BORDER_THICKNESS
;
3479 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3480 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3485 wxSize
wxWin32Renderer::GetFrameIconSize() const
3487 return wxSize(16, 16);
3491 // ----------------------------------------------------------------------------
3493 // ----------------------------------------------------------------------------
3495 static char *error_xpm
[]={
3502 "...........########.............",
3503 "........###aaaaaaaa###..........",
3504 ".......#aaaaaaaaaaaaaa#.........",
3505 ".....##aaaaaaaaaaaaaaaa##.......",
3506 "....#aaaaaaaaaaaaaaaaaaaa#......",
3507 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3508 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3509 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3510 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3511 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3512 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3513 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3514 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3515 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3516 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3517 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3518 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3519 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3520 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3521 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3522 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3523 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3524 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3525 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3526 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3527 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3528 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3529 "......b#aaaaaaaaaaaaaa#bbbbb....",
3530 ".......b###aaaaaaaa###bbbbb.....",
3531 ".........bb########bbbbbb.......",
3532 "..........bbbbbbbbbbbbbb........",
3533 ".............bbbbbbbb..........."};
3535 static char *info_xpm
[]={
3543 "...........########.............",
3544 "........###abbbbbba###..........",
3545 "......##abbbbbbbbbbbba##........",
3546 ".....#abbbbbbbbbbbbbbbba#.......",
3547 "....#bbbbbbbaccccabbbbbbbd......",
3548 "...#bbbbbbbbccccccbbbbbbbbd.....",
3549 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3550 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3551 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3552 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3553 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3554 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3555 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3556 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3557 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3558 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3559 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3560 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3561 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3562 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3563 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3564 ".....dabbbbbbbbbbbbbbbbad####...",
3565 "......ddabbbbbbbbbbbbadd####....",
3566 ".......#dddabbbbbbaddd#####.....",
3567 "........###dddabbbd#######......",
3568 "..........####dbbbd#####........",
3569 ".............#dbbbd##...........",
3570 "...............dbbd##...........",
3571 "................dbd##...........",
3572 ".................dd##...........",
3573 "..................###...........",
3574 "...................##..........."};
3576 static char *question_xpm
[]={
3584 "...........########.............",
3585 "........###abbbbbba###..........",
3586 "......##abbbbbbbbbbbba##........",
3587 ".....#abbbbbbbbbbbbbbbba#.......",
3588 "....#bbbbbbbbbbbbbbbbbbbbc......",
3589 "...#bbbbbbbaddddddabbbbbbbc.....",
3590 "..#bbbbbbbadabbddddabbbbbbbc....",
3591 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3592 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3593 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3594 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3595 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3596 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3597 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3598 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3599 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3600 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3601 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3602 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3603 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3604 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3605 ".....cabbbbbbbbbbbbbbbbac####...",
3606 "......ccabbbbbbbbbbbbacc####....",
3607 ".......#cccabbbbbbaccc#####.....",
3608 "........###cccabbbc#######......",
3609 "..........####cbbbc#####........",
3610 ".............#cbbbc##...........",
3611 "...............cbbc##...........",
3612 "................cbc##...........",
3613 ".................cc##...........",
3614 "..................###...........",
3615 "...................##..........."};
3617 static char *warning_xpm
[]={
3625 ".............###................",
3626 "............#aabc...............",
3627 "...........#aaaabcd.............",
3628 "...........#aaaaacdd............",
3629 "..........#aaaaaabcdd...........",
3630 "..........#aaaaaaacdd...........",
3631 ".........#aaaaaaaabcdd..........",
3632 ".........#aaaaaaaaacdd..........",
3633 "........#aaaaaaaaaabcdd.........",
3634 "........#aaabcccbaaacdd.........",
3635 ".......#aaaacccccaaabcdd........",
3636 ".......#aaaacccccaaaacdd........",
3637 "......#aaaaacccccaaaabcdd.......",
3638 "......#aaaaacccccaaaaacdd.......",
3639 ".....#aaaaaacccccaaaaabcdd......",
3640 ".....#aaaaaa#ccc#aaaaaacdd......",
3641 "....#aaaaaaabcccbaaaaaabcdd.....",
3642 "....#aaaaaaaacccaaaaaaaacdd.....",
3643 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3644 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3645 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3646 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3647 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3648 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3649 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3650 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3651 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3652 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3653 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3654 "..#ccccccccccccccccccccccccddddd",
3655 "....ddddddddddddddddddddddddddd.",
3656 ".....ddddddddddddddddddddddddd.."};
3658 wxIcon
wxWin32Renderer::GetStdIcon(int which
) const
3662 case wxICON_INFORMATION
:
3663 return wxIcon(info_xpm
);
3665 case wxICON_QUESTION
:
3666 return wxIcon(question_xpm
);
3668 case wxICON_EXCLAMATION
:
3669 return wxIcon(warning_xpm
);
3672 wxFAIL_MSG(wxT("requested non existent standard icon"));
3673 // still fall through
3676 return wxIcon(error_xpm
);
3681 // ----------------------------------------------------------------------------
3682 // text control geometry
3683 // ----------------------------------------------------------------------------
3685 static inline int GetTextBorderWidth()
3690 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3693 wxRect rectTotal
= rect
;
3695 wxCoord widthBorder
= GetTextBorderWidth();
3696 rectTotal
.Inflate(widthBorder
);
3698 // this is what Windows does
3704 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3706 wxCoord
*extraSpaceBeyond
)
3708 wxRect rectText
= rect
;
3710 // undo GetTextTotalArea()
3711 if ( rectText
.height
> 0 )
3714 wxCoord widthBorder
= GetTextBorderWidth();
3715 rectText
.Inflate(-widthBorder
);
3717 if ( extraSpaceBeyond
)
3718 *extraSpaceBeyond
= 0;
3723 // ----------------------------------------------------------------------------
3725 // ----------------------------------------------------------------------------
3727 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3730 if ( wxDynamicCast(window
, wxScrollBar
) )
3732 // we only set the width of vert scrollbars and height of the
3734 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3735 size
->y
= m_sizeScrollbarArrow
.y
;
3737 size
->x
= m_sizeScrollbarArrow
.x
;
3739 // skip border width adjustments, they don't make sense for us
3742 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3745 if ( wxDynamicCast(window
, wxButton
) )
3747 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3749 // TODO: don't harcode all this
3750 size
->x
+= 3*window
->GetCharWidth();
3752 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3753 if ( size
->y
< heightBtn
- 8 )
3754 size
->y
= heightBtn
;
3759 // no border width adjustments for buttons
3762 #endif // wxUSE_BUTTON
3764 // take into account the border width
3765 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3766 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3767 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3770 // ============================================================================
3772 // ============================================================================
3774 // ----------------------------------------------------------------------------
3775 // wxWin32InputHandler
3776 // ----------------------------------------------------------------------------
3778 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3780 m_renderer
= renderer
;
3783 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3784 const wxKeyEvent
& event
,
3790 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3791 const wxMouseEvent
& event
)
3793 // clicking on the control gives it focus
3794 if ( event
.ButtonDown() )
3796 wxWindow
*win
= control
->GetInputWindow();
3797 if ( wxWindow::FindFocus() != control
->GetInputWindow() )
3808 // ----------------------------------------------------------------------------
3809 // wxWin32ScrollBarInputHandler
3810 // ----------------------------------------------------------------------------
3812 wxWin32ScrollBarInputHandler::
3813 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3814 wxInputHandler
*handler
)
3815 : wxStdScrollBarInputHandler(renderer
, handler
)
3817 m_scrollPaused
= FALSE
;
3821 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3822 const wxControlAction
& action
)
3824 // stop if went beyond the position of the original click (this can only
3825 // happen when we scroll by pages)
3827 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3829 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3830 != wxHT_SCROLLBAR_BAR_2
;
3832 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3834 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3835 != wxHT_SCROLLBAR_BAR_1
;
3840 StopScrolling(scrollbar
);
3842 scrollbar
->Refresh();
3847 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3850 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3851 const wxMouseEvent
& event
)
3853 // remember the current state
3854 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3856 // do process the message
3857 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3859 // analyse the changes
3860 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3862 // we just started dragging the thumb, remember its initial position to
3863 // be able to restore it if the drag is cancelled later
3864 m_eventStartDrag
= event
;
3870 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3871 const wxMouseEvent
& event
)
3873 // we don't highlight scrollbar elements, so there is no need to process
3874 // mouse move events normally - only do it while mouse is captured (i.e.
3875 // when we're dragging the thumb or pressing on something)
3876 if ( !m_winCapture
)
3879 if ( event
.Entering() )
3881 // we're not interested in this at all
3885 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3887 if ( m_scrollPaused
)
3889 // check if the mouse returned to its original location
3891 if ( event
.Leaving() )
3897 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3898 if ( ht
== m_htLast
)
3900 // yes it did, resume scrolling
3901 m_scrollPaused
= FALSE
;
3902 if ( m_timerScroll
)
3904 // we were scrolling by line/page, restart timer
3905 m_timerScroll
->Start(m_interval
);
3907 Press(scrollbar
, TRUE
);
3909 else // we were dragging the thumb
3911 // restore its last location
3912 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3918 else // normal case, scrolling hasn't been paused
3920 // if we're scrolling the scrollbar because the arrow or the shaft was
3921 // pressed, check that the mouse stays on the same scrollbar element
3923 if ( event
.Moving() )
3925 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3927 else // event.Leaving()
3932 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3933 // is still ok - we only want to catch the case when the mouse leaves
3934 // the scrollbar here
3935 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3937 ht
= wxHT_SCROLLBAR_THUMB
;
3940 if ( ht
!= m_htLast
)
3942 // what were we doing? 2 possibilities: either an arrow/shaft was
3943 // pressed in which case we have a timer and so we just stop it or
3944 // we were dragging the thumb
3945 if ( m_timerScroll
)
3948 m_interval
= m_timerScroll
->GetInterval();
3949 m_timerScroll
->Stop();
3950 m_scrollPaused
= TRUE
;
3952 // unpress the arrow
3953 Press(scrollbar
, FALSE
);
3955 else // we were dragging the thumb
3957 // remember the current thumb position to be able to restore it
3958 // if the mouse returns to it later
3959 m_eventLastDrag
= event
;
3961 // and restore the original position (before dragging) of the
3963 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3970 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
3973 // ----------------------------------------------------------------------------
3974 // wxWin32CheckboxInputHandler
3975 // ----------------------------------------------------------------------------
3977 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3978 const wxKeyEvent
& event
,
3983 wxControlAction action
;
3984 int keycode
= event
.GetKeyCode();
3988 action
= wxACTION_CHECKBOX_TOGGLE
;
3992 case WXK_NUMPAD_SUBTRACT
:
3993 action
= wxACTION_CHECKBOX_CHECK
;
3997 case WXK_NUMPAD_ADD
:
3998 case WXK_NUMPAD_EQUAL
:
3999 action
= wxACTION_CHECKBOX_CLEAR
;
4005 control
->PerformAction(action
);
4014 // ----------------------------------------------------------------------------
4015 // wxWin32TextCtrlInputHandler
4016 // ----------------------------------------------------------------------------
4018 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4019 const wxKeyEvent
& event
,
4022 // handle only MSW-specific text bindings here, the others are handled in
4026 int keycode
= event
.GetKeyCode();
4028 wxControlAction action
;
4029 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4031 action
= wxACTION_TEXT_CUT
;
4033 else if ( keycode
== WXK_INSERT
)
4035 if ( event
.ControlDown() )
4036 action
= wxACTION_TEXT_COPY
;
4037 else if ( event
.ShiftDown() )
4038 action
= wxACTION_TEXT_PASTE
;
4041 if ( action
!= wxACTION_NONE
)
4043 control
->PerformAction(action
);
4049 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4052 // ----------------------------------------------------------------------------
4053 // wxWin32StatusBarInputHandler
4054 // ----------------------------------------------------------------------------
4056 wxWin32StatusBarInputHandler::
4057 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4058 : wxStdInputHandler(handler
)
4063 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4064 const wxPoint
& pt
) const
4066 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4067 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4069 wxSize sizeSbar
= statbar
->GetSize();
4071 return (sizeSbar
.x
- pt
.x
) < (wxCoord
)STATUSBAR_GRIP_SIZE
&&
4072 (sizeSbar
.y
- pt
.y
) < (wxCoord
)STATUSBAR_GRIP_SIZE
;
4078 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4079 const wxMouseEvent
& event
)
4081 if ( event
.Button(1) )
4083 if ( event
.ButtonDown(1) )
4085 wxWindow
*statbar
= consumer
->GetInputWindow();
4087 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4089 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4093 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4094 wxHT_TOPLEVEL_BORDER_SE
);
4096 statbar
->SetCursor(m_cursorOld
);
4104 return wxStdInputHandler::HandleMouse(consumer
, event
);
4107 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4108 const wxMouseEvent
& event
)
4110 wxWindow
*statbar
= consumer
->GetInputWindow();
4112 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4113 if ( isOnGrip
!= m_isOnGrip
)
4115 m_isOnGrip
= isOnGrip
;
4118 m_cursorOld
= statbar
->GetCursor();
4119 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4123 statbar
->SetCursor(m_cursorOld
);
4127 return wxStdInputHandler::HandleMouseMove(consumer
, event
);