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() { return m_renderer
; }
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()
1114 m_scheme
= new wxWin32ColourScheme
;
1115 m_renderer
= new wxWin32Renderer(m_scheme
);
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 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1136 if ( !m_handlerDefault
)
1138 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1141 return m_handlerDefault
;
1144 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1146 wxInputHandler
*handler
;
1147 int n
= m_handlerNames
.Index(control
);
1148 if ( n
== wxNOT_FOUND
)
1150 // create a new handler
1151 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1152 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1153 GetDefaultInputHandler());
1155 else if ( control
== wxINP_HANDLER_BUTTON
)
1156 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1157 #endif // wxUSE_BUTTON
1159 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1160 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1161 #endif // wxUSE_CHECKBOX
1163 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1164 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1165 #endif // wxUSE_COMBOBOX
1167 else if ( control
== wxINP_HANDLER_LISTBOX
)
1168 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1169 #endif // wxUSE_LISTBOX
1170 #if wxUSE_CHECKLISTBOX
1171 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1172 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1173 #endif // wxUSE_CHECKLISTBOX
1175 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1176 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1177 #endif // wxUSE_TEXTCTRL
1179 else if ( control
== wxINP_HANDLER_SLIDER
)
1180 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1181 #endif // wxUSE_SLIDER
1183 else if ( control
== wxINP_HANDLER_SPINBTN
)
1184 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1185 #endif // wxUSE_SPINBTN
1187 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1188 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1189 #endif // wxUSE_NOTEBOOK
1191 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1192 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1193 #endif // wxUSE_STATUSBAR
1194 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1195 handler
= new wxStdFrameInputHandler(GetDefaultInputHandler());
1197 handler
= GetDefaultInputHandler();
1199 n
= m_handlerNames
.Add(control
);
1200 m_handlers
.Insert(handler
, n
);
1202 else // we already have it
1204 handler
= m_handlers
[n
];
1210 wxColourScheme
*wxWin32Theme::GetColourScheme()
1215 // ============================================================================
1216 // wxWin32ColourScheme
1217 // ============================================================================
1219 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1222 if ( win
->UseBgCol() )
1224 // use the user specified colour
1225 col
= win
->GetBackgroundColour();
1228 if ( win
->IsContainerWindow() )
1230 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1233 if ( !text
->IsEnabled() ) // not IsEditable()
1235 //else: execute code below
1240 // doesn't depend on the state
1246 int flags
= win
->GetStateFlags();
1248 // the colour set by the user should be used for the normal state
1249 // and for the states for which we don't have any specific colours
1250 if ( !col
.Ok() || (flags
!= 0) )
1252 if ( wxDynamicCast(win
, wxScrollBar
) )
1253 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1263 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1267 // use the system colours under Windows
1268 #if defined(__WXMSW__)
1269 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1271 case CONTROL_PRESSED
:
1272 case CONTROL_CURRENT
:
1273 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1275 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1277 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1278 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1280 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1281 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1283 #if defined(COLOR_3DDKSHADOW)
1284 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1286 case SHADOW_DARK
: return *wxBLACK
;
1289 case CONTROL_TEXT_DISABLED
:
1290 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1292 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1294 case CONTROL_TEXT_DISABLED_SHADOW
:
1295 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1297 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1298 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1299 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1301 // use the standard Windows colours elsewhere
1302 case WINDOW
: return *wxWHITE
;
1304 case CONTROL_PRESSED
:
1305 case CONTROL_CURRENT
:
1306 case CONTROL
: return wxColour(0xc0c0c0);
1308 case CONTROL_TEXT
: return *wxBLACK
;
1310 case SCROLLBAR
: return wxColour(0xe0e0e0);
1311 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1313 case HIGHLIGHT
: return wxColour(0x800000);
1314 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1316 case SHADOW_DARK
: return *wxBLACK
;
1318 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1319 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1321 case SHADOW_IN
: return wxColour(0xc0c0c0);
1323 case CONTROL_TEXT_DISABLED_SHADOW
:
1324 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1326 case TITLEBAR
: return wxColour(0xaeaaae);
1327 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1328 case TITLEBAR_TEXT
: return *wxWHITE
;
1333 wxFAIL_MSG(_T("invalid standard colour"));
1338 // ============================================================================
1340 // ============================================================================
1342 // ----------------------------------------------------------------------------
1344 // ----------------------------------------------------------------------------
1346 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1350 m_sizeScrollbarArrow
= wxSize(16, 16);
1352 // init colours and pens
1353 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1355 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1356 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1358 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1360 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1361 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1363 m_titlebarFont
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
1364 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1366 // init the arrow bitmaps
1367 static const size_t ARROW_WIDTH
= 7;
1368 static const size_t ARROW_LENGTH
= 4;
1371 wxMemoryDC dcNormal
,
1374 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1376 bool isVertical
= n
> Arrow_Right
;
1389 // disabled arrow is larger because of the shadow
1390 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1391 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1393 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1394 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1396 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1397 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1401 dcNormal
.SetPen(m_penBlack
);
1402 dcDisabled
.SetPen(m_penDarkGrey
);
1404 // calculate the position of the point of the arrow
1408 x1
= (ARROW_WIDTH
- 1)/2;
1409 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1413 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1414 y1
= (ARROW_WIDTH
- 1)/2;
1425 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1427 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1428 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1435 if ( n
== Arrow_Up
)
1446 else // left or right arrow
1451 if ( n
== Arrow_Left
)
1464 // draw the shadow for the disabled one
1465 dcDisabled
.SetPen(m_penHighlight
);
1470 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1474 x1
= ARROW_LENGTH
- 1;
1475 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1478 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1479 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1484 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1488 x1
= ARROW_WIDTH
- 1;
1490 x2
= (ARROW_WIDTH
- 1)/2;
1492 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1493 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1498 // create the inversed bitmap but only for the right arrow as we only
1499 // use it for the menus
1500 if ( n
== Arrow_Right
)
1502 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1503 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1505 dcInverse
.Blit(0, 0, w
, h
,
1508 dcInverse
.SelectObject(wxNullBitmap
);
1510 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1511 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1513 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1514 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1516 dcInverse
.Blit(0, 0, w
, h
,
1519 dcInverse
.SelectObject(wxNullBitmap
);
1521 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1522 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1525 dcNormal
.SelectObject(wxNullBitmap
);
1526 dcDisabled
.SelectObject(wxNullBitmap
);
1528 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1529 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1530 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1531 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1533 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1536 // init the frame buttons bitmaps
1537 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1538 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1539 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1540 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1541 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1544 // ----------------------------------------------------------------------------
1546 // ----------------------------------------------------------------------------
1549 The raised border in Win32 looks like this:
1551 IIIIIIIIIIIIIIIIIIIIIIB
1553 I GB I = white (HILIGHT)
1554 I GB H = light grey (LIGHT)
1555 I GB G = dark grey (SHADOI)
1556 I GB B = black (DKSHADOI)
1557 I GB I = hIghlight (COLOR_3DHILIGHT)
1559 IGGGGGGGGGGGGGGGGGGGGGB
1560 BBBBBBBBBBBBBBBBBBBBBBB
1562 The sunken border looks like this:
1564 GGGGGGGGGGGGGGGGGGGGGGI
1565 GBBBBBBBBBBBBBBBBBBBBHI
1572 GHHHHHHHHHHHHHHHHHHHHHI
1573 IIIIIIIIIIIIIIIIIIIIIII
1575 The static border (used for the controls which don't get focus) is like
1578 GGGGGGGGGGGGGGGGGGGGGGW
1586 WWWWWWWWWWWWWWWWWWWWWWW
1588 The most complicated is the double border:
1590 HHHHHHHHHHHHHHHHHHHHHHB
1591 HWWWWWWWWWWWWWWWWWWWWGB
1592 HWHHHHHHHHHHHHHHHHHHHGB
1597 HWHHHHHHHHHHHHHHHHHHHGB
1598 HGGGGGGGGGGGGGGGGGGGGGB
1599 BBBBBBBBBBBBBBBBBBBBBBB
1601 And the simple border is, well, simple:
1603 BBBBBBBBBBBBBBBBBBBBBBB
1612 BBBBBBBBBBBBBBBBBBBBBBB
1615 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1619 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1620 dc
.DrawRectangle(*rect
);
1626 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1628 // draw the bottom and right sides
1630 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1631 rect
->GetRight() + 1, rect
->GetBottom());
1632 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1633 rect
->GetRight(), rect
->GetBottom());
1640 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1641 const wxPen
& pen1
, const wxPen
& pen2
)
1643 // draw the rectangle
1645 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1646 rect
->GetLeft(), rect
->GetBottom());
1647 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1648 rect
->GetRight(), rect
->GetTop());
1650 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1651 rect
->GetRight(), rect
->GetBottom());
1652 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1653 rect
->GetRight() + 1, rect
->GetBottom());
1659 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1661 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1662 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1665 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1667 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1668 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1671 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1675 DrawRect(dc
, rect
, m_penDarkGrey
);
1677 // the arrow is usually drawn inside border of width 2 and is offset by
1678 // another pixel in both directions when it's pressed - as the border
1679 // in this case is more narrow as well, we have to adjust rect like
1687 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1688 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1692 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1694 const wxRect
& rectTotal
,
1695 int WXUNUSED(flags
),
1700 wxRect rect
= rectTotal
;
1704 case wxBORDER_SUNKEN
:
1705 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1707 DrawSunkenBorder(dc
, &rect
);
1711 case wxBORDER_STATIC
:
1712 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1715 case wxBORDER_RAISED
:
1716 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1718 DrawRaisedBorder(dc
, &rect
);
1722 case wxBORDER_DOUBLE
:
1723 DrawArrowBorder(dc
, &rect
);
1724 DrawRect(dc
, &rect
, m_penLightGrey
);
1727 case wxBORDER_SIMPLE
:
1728 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1730 DrawRect(dc
, &rect
, m_penBlack
);
1735 wxFAIL_MSG(_T("unknown border type"));
1738 case wxBORDER_DEFAULT
:
1747 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1752 case wxBORDER_RAISED
:
1753 case wxBORDER_SUNKEN
:
1754 width
= BORDER_THICKNESS
;
1757 case wxBORDER_SIMPLE
:
1758 case wxBORDER_STATIC
:
1762 case wxBORDER_DOUBLE
:
1767 wxFAIL_MSG(_T("unknown border type"));
1770 case wxBORDER_DEFAULT
:
1780 rect
.height
= width
;
1785 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1790 // ----------------------------------------------------------------------------
1792 // ----------------------------------------------------------------------------
1794 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1800 // text controls are not special under windows
1801 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1804 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1805 const wxRect
& rectTotal
,
1809 wxRect rect
= rectTotal
;
1811 if ( flags
& wxCONTROL_PRESSED
)
1813 // button pressed: draw a double border around it
1814 DrawRect(dc
, &rect
, m_penBlack
);
1815 DrawRect(dc
, &rect
, m_penDarkGrey
);
1819 // button not pressed
1821 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1823 // button either default or focused (or both): add an extra border around it
1824 DrawRect(dc
, &rect
, m_penBlack
);
1827 // now draw a normal button
1828 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1829 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1838 // ----------------------------------------------------------------------------
1840 // ----------------------------------------------------------------------------
1842 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1843 wxCoord y
, wxCoord x1
, wxCoord x2
)
1845 dc
.SetPen(m_penDarkGrey
);
1846 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1847 dc
.SetPen(m_penHighlight
);
1849 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1852 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1853 wxCoord x
, wxCoord y1
, wxCoord y2
)
1855 dc
.SetPen(m_penDarkGrey
);
1856 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1857 dc
.SetPen(m_penHighlight
);
1859 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1862 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1863 const wxString
& label
,
1869 wxCoord height
= 0; // of the label
1870 wxRect rectFrame
= rect
;
1871 if ( !label
.empty() )
1873 // the text should touch the top border of the rect, so the frame
1874 // itself should be lower
1875 dc
.GetTextExtent(label
, NULL
, &height
);
1876 rectFrame
.y
+= height
/ 2;
1877 rectFrame
.height
-= height
/ 2;
1879 // we have to draw each part of the frame individually as we can't
1880 // erase the background beyond the label as it might contain some
1881 // pixmap already, so drawing everything and then overwriting part of
1882 // the frame with label doesn't work
1884 // TODO: the +5 and space insertion should be customizable
1887 rectText
.x
= rectFrame
.x
+ 5;
1888 rectText
.y
= rect
.y
;
1889 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1890 rectText
.height
= height
;
1893 label2
<< _T(' ') << label
<< _T(' ');
1894 if ( indexAccel
!= -1 )
1896 // adjust it as we prepended a space
1901 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1903 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1907 // just draw the complete frame
1908 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1909 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1913 // ----------------------------------------------------------------------------
1915 // ----------------------------------------------------------------------------
1917 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1919 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1920 // pixels each while we really need dots here... PS_ALTERNATE might
1921 // work, but it is for NT 5 only
1923 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1925 // draw the pixels manually: note that to behave in the same manner as
1926 // DrawRect(), we must exclude the bottom and right borders from the
1928 wxCoord x1
= rect
.GetLeft(),
1930 x2
= rect
.GetRight(),
1931 y2
= rect
.GetBottom();
1933 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1935 // this seems to be closer than what Windows does than wxINVERT although
1936 // I'm still not sure if it's correct
1937 dc
.SetLogicalFunction(wxAND_REVERSE
);
1940 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1941 dc
.DrawPoint(z
, rect
.GetTop());
1943 wxCoord shift
= z
== x2
? 0 : 1;
1944 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1945 dc
.DrawPoint(x2
, z
);
1947 shift
= z
== y2
? 0 : 1;
1948 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1949 dc
.DrawPoint(z
, y2
);
1951 shift
= z
== x1
? 0 : 1;
1952 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
1953 dc
.DrawPoint(x1
, z
);
1955 dc
.SetLogicalFunction(wxCOPY
);
1959 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
1960 const wxString
& label
,
1965 // draw shadow of the text
1966 dc
.SetTextForeground(m_colHighlight
);
1967 wxRect rectShadow
= rect
;
1970 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1972 // make the text grey
1973 dc
.SetTextForeground(m_colDarkGrey
);
1976 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1977 const wxString
& label
,
1984 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
1987 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
1988 const wxString
& label
,
1994 const wxPoint
& focusOffset
)
1996 // the underscores are not drawn for focused controls in wxMSW
1997 if ( flags
& wxCONTROL_FOCUSED
)
2002 if ( flags
& wxCONTROL_DISABLED
)
2004 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2005 // currently only can happen for a menu item and it seems that Windows
2006 // doesn't draw the shadow in this case, so we don't do it neither
2007 if ( flags
& wxCONTROL_SELECTED
)
2009 // just make the label text greyed out
2010 dc
.SetTextForeground(m_colDarkGrey
);
2012 else // draw normal disabled label
2014 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2019 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2021 if ( flags
& wxCONTROL_DISABLED
)
2023 // restore the fg colour
2024 dc
.SetTextForeground(*wxBLACK
);
2027 if ( flags
& wxCONTROL_FOCUSED
)
2029 if ( focusOffset
.x
|| focusOffset
.y
)
2031 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2034 DrawFocusRect(dc
, rectLabel
);
2038 *rectBounds
= rectLabel
;
2041 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2042 const wxString
& label
,
2043 const wxBitmap
& image
,
2050 // the underscores are not drawn for focused controls in wxMSW
2051 if ( flags
& wxCONTROL_PRESSED
)
2056 wxRect rectLabel
= rect
;
2057 if ( !label
.empty() )
2059 // shift the label if a button is pressed
2060 if ( flags
& wxCONTROL_PRESSED
)
2066 if ( flags
& wxCONTROL_DISABLED
)
2068 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2071 // leave enough space for the focus rectangle
2072 if ( flags
& wxCONTROL_FOCUSED
)
2074 rectLabel
.Inflate(-2);
2078 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2080 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2082 if ( flags
& wxCONTROL_PRESSED
)
2084 // the focus rectangle is never pressed, so undo the shift done
2092 DrawFocusRect(dc
, rectLabel
);
2096 // ----------------------------------------------------------------------------
2097 // (check)listbox items
2098 // ----------------------------------------------------------------------------
2100 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2101 const wxString
& label
,
2105 wxDCTextColourChanger
colChanger(dc
);
2107 if ( flags
& wxCONTROL_SELECTED
)
2109 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2111 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2112 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2113 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2114 dc
.DrawRectangle(rect
);
2117 wxRect rectText
= rect
;
2119 rectText
.width
-= 2;
2120 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2122 if ( flags
& wxCONTROL_FOCUSED
)
2124 DrawFocusRect(dc
, rect
);
2128 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2129 const wxString
& label
,
2130 const wxBitmap
& bitmap
,
2139 else // use default bitmap
2141 bmp
= wxBitmap(flags
& wxCONTROL_CHECKED
? checked_item_xpm
2142 : unchecked_item_xpm
);
2145 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2146 TRUE
/* use mask */);
2148 wxRect rectLabel
= rect
;
2149 int bmpWidth
= bmp
.GetWidth();
2150 rectLabel
.x
+= bmpWidth
;
2151 rectLabel
.width
-= bmpWidth
;
2153 DrawItem(dc
, label
, rectLabel
, flags
);
2156 // ----------------------------------------------------------------------------
2157 // check/radio buttons
2158 // ----------------------------------------------------------------------------
2160 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2162 IndicatorState indState
;
2163 if ( flags
& wxCONTROL_SELECTED
)
2164 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2165 : IndicatorState_Selected
;
2166 else if ( flags
& wxCONTROL_DISABLED
)
2167 indState
= IndicatorState_Disabled
;
2168 else if ( flags
& wxCONTROL_PRESSED
)
2169 indState
= IndicatorState_Pressed
;
2171 indState
= IndicatorState_Normal
;
2173 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2174 ? IndicatorStatus_Checked
2175 : IndicatorStatus_Unchecked
;
2177 const char **xpm
= bmpIndicators
[indType
][indState
][indStatus
];
2178 return xpm
? wxBitmap(xpm
) : wxNullBitmap
;
2181 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2182 const wxString
& label
,
2183 const wxBitmap
& bitmap
,
2188 wxCoord focusOffsetY
)
2190 // calculate the position of the bitmap and of the label
2191 wxCoord heightBmp
= bitmap
.GetHeight();
2193 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2196 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2197 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2199 // align label vertically with the bitmap - looks nicer like this
2200 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2202 // calc horz position
2203 if ( align
== wxALIGN_RIGHT
)
2205 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2206 rectLabel
.x
= rect
.x
+ 3;
2207 rectLabel
.SetRight(xBmp
);
2209 else // normal (checkbox to the left of the text) case
2212 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2213 rectLabel
.SetRight(rect
.GetRight());
2216 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2219 dc
, label
, rectLabel
,
2221 wxALIGN_LEFT
| wxALIGN_TOP
,
2223 NULL
, // we don't need bounding rect
2224 // use custom vert focus rect offset
2225 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2229 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2230 const wxString
& label
,
2231 const wxBitmap
& bitmap
,
2237 DrawCheckOrRadioButton(dc
, label
,
2238 bitmap
.Ok() ? bitmap
: GetRadioBitmap(flags
),
2239 rect
, flags
, align
, indexAccel
,
2240 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2243 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2244 const wxString
& label
,
2245 const wxBitmap
& bitmap
,
2251 DrawCheckOrRadioButton(dc
, label
,
2252 bitmap
.Ok() ? bitmap
: GetCheckBitmap(flags
),
2253 rect
, flags
, align
, indexAccel
,
2254 0); // no focus rect offset for checkboxes
2257 // ----------------------------------------------------------------------------
2259 // ----------------------------------------------------------------------------
2261 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2262 const wxString
& text
,
2268 // nothing special to do here
2269 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2272 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2274 // we don't draw them
2277 // ----------------------------------------------------------------------------
2279 // ----------------------------------------------------------------------------
2281 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2282 const wxRect
& rectOrig
,
2284 const wxString
& label
,
2285 const wxBitmap
& bitmap
,
2289 wxRect rect
= rectOrig
;
2291 // the current tab is drawn indented (to the top for default case) and
2292 // bigger than the other ones
2293 const wxSize indent
= GetTabIndent();
2294 if ( flags
& wxCONTROL_SELECTED
)
2299 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2303 rect
.Inflate(indent
.x
, 0);
2305 rect
.height
+= indent
.y
;
2309 rect
.Inflate(indent
.x
, 0);
2310 rect
.height
+= indent
.y
;
2315 wxFAIL_MSG(_T("TODO"));
2320 // draw the text, image and the focus around them (if necessary)
2321 wxRect rectLabel
= rect
;
2322 rectLabel
.Deflate(1, 1);
2323 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2324 flags
, wxALIGN_CENTRE
, indexAccel
);
2326 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2327 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2330 x2
= rect
.GetRight(),
2331 y2
= rect
.GetBottom();
2333 // FIXME: all this code will break if the tab indent or the border width,
2334 // it is tied to the fact that both of them are equal to 2
2339 dc
.SetPen(m_penHighlight
);
2340 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2341 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2342 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2344 dc
.SetPen(m_penBlack
);
2345 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2346 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2348 dc
.SetPen(m_penDarkGrey
);
2349 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2351 if ( flags
& wxCONTROL_SELECTED
)
2353 dc
.SetPen(m_penLightGrey
);
2355 // overwrite the part of the border below this tab
2356 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2358 // and the shadow of the tab to the left of us
2359 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2364 dc
.SetPen(m_penHighlight
);
2365 // we need to continue one pixel further to overwrite the corner of
2366 // the border for the selected tab
2367 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2369 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2371 dc
.SetPen(m_penBlack
);
2372 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2373 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2374 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2376 dc
.SetPen(m_penDarkGrey
);
2377 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2378 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2380 if ( flags
& wxCONTROL_SELECTED
)
2382 dc
.SetPen(m_penLightGrey
);
2384 // overwrite the part of the (double!) border above this tab
2385 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2386 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2388 // and the shadow of the tab to the left of us
2389 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2395 wxFAIL_MSG(_T("TODO"));
2399 // ----------------------------------------------------------------------------
2401 // ----------------------------------------------------------------------------
2403 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2404 wxOrientation orient
) const
2408 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2409 if ( orient
== wxHORIZONTAL
)
2411 size
.y
= rect
.height
- 6;
2412 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2416 size
.x
= rect
.width
- 6;
2417 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2423 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2424 wxOrientation orient
) const
2426 static const wxCoord SLIDER_MARGIN
= 6;
2428 wxRect rect
= rectOrig
;
2430 if ( orient
== wxHORIZONTAL
)
2432 // make the rect of minimal width and centre it
2433 rect
.height
= 2*BORDER_THICKNESS
;
2434 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2438 // leave margins on the sides
2439 rect
.Deflate(SLIDER_MARGIN
, 0);
2443 // same as above but in other direction
2444 rect
.width
= 2*BORDER_THICKNESS
;
2445 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2449 rect
.Deflate(0, SLIDER_MARGIN
);
2455 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2456 const wxRect
& rectOrig
,
2457 wxOrientation orient
,
2461 if ( flags
& wxCONTROL_FOCUSED
)
2463 DrawFocusRect(dc
, rectOrig
);
2466 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2471 DrawSunkenBorder(dc
, &rect
);
2474 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2476 wxOrientation orient
,
2480 we are drawing a shape of this form
2485 H DB where H is hightlight colour
2498 The interior of this shape is filled with the hatched brush if the thumb
2502 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2504 bool transpose
= orient
== wxVERTICAL
;
2506 wxCoord x
, y
, x2
, y2
;
2511 x2
= rect
.GetBottom();
2512 y2
= rect
.GetRight();
2518 x2
= rect
.GetRight();
2519 y2
= rect
.GetBottom();
2522 // the size of the pointed part of the thumb
2523 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2525 wxCoord x3
= x
+ sizeArrow
,
2526 y3
= y2
- sizeArrow
;
2528 dc
.SetPen(m_penHighlight
);
2529 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2530 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2531 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2533 dc
.SetPen(m_penBlack
);
2534 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2535 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2537 dc
.SetPen(m_penDarkGrey
);
2538 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2539 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2541 if ( flags
& wxCONTROL_PRESSED
)
2543 // TODO: MSW fills the entire area inside, not just the rect
2544 wxRect rectInt
= rect
;
2546 rectInt
.SetRight(y3
);
2548 rectInt
.SetBottom(y3
);
2551 #if !defined(__WXMGL__)
2552 static const char *stipple_xpm
[] = {
2553 /* columns rows colors chars-per-pixel */
2562 // VS: MGL can only do 8x8 stipple brushes
2563 static const char *stipple_xpm
[] = {
2564 /* columns rows colors chars-per-pixel */
2579 dc
.SetBrush(wxBrush(stipple_xpm
));
2581 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2582 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2583 dc
.SetPen(*wxTRANSPARENT_PEN
);
2584 dc
.DrawRectangle(rectInt
);
2588 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2590 const wxSize
& sizeThumb
,
2591 wxOrientation orient
,
2603 // the variable names correspond to horizontal case, but they can be used
2604 // for both orientations
2605 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2606 if ( orient
== wxHORIZONTAL
)
2608 x1
= rect
.GetLeft();
2609 x2
= rect
.GetRight();
2611 // draw from bottom to top to leave one pixel space between the ticks
2612 // and the slider as Windows do
2613 y1
= rect
.GetBottom();
2618 widthThumb
= sizeThumb
.x
;
2623 x2
= rect
.GetBottom();
2625 y1
= rect
.GetRight();
2626 y2
= rect
.GetLeft();
2630 widthThumb
= sizeThumb
.y
;
2633 // the first tick should be positioned in such way that a thumb drawn in
2634 // the first position points down directly to it
2635 x1
+= widthThumb
/ 2;
2636 x2
-= widthThumb
/ 2;
2638 // this also means that we have slightly less space for the ticks in
2639 // between the first and the last
2642 dc
.SetPen(m_penBlack
);
2644 int range
= end
- start
;
2645 for ( int n
= 0; n
< range
; n
+= step
)
2647 wxCoord x
= x1
+ (len
*n
) / range
;
2649 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2652 // always draw the line at the end position
2653 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2656 // ----------------------------------------------------------------------------
2658 // ----------------------------------------------------------------------------
2660 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2661 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2664 virtual wxSize
GetSize() const { return m_size
; }
2666 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2667 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2669 wxCoord
GetItemHeight() const { return m_heightItem
; }
2672 // the total size of the menu
2675 // the offset of the start of the menu item label
2678 // the offset of the start of the accel label
2681 // the height of a normal (not separator) item
2682 wxCoord m_heightItem
;
2684 friend wxMenuGeometryInfo
*
2685 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2688 // FIXME: all constants are hardcoded but shouldn't be
2689 static const wxCoord MENU_LEFT_MARGIN
= 9;
2690 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2691 static const wxCoord MENU_VERT_MARGIN
= 3;
2693 // the margin around bitmap/check marks (on each side)
2694 static const wxCoord MENU_BMP_MARGIN
= 2;
2696 // the margin between the labels and accel strings
2697 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2699 // the separator height in pixels: in fact, strangely enough, the real height
2700 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2702 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2704 // the size of the standard checkmark bitmap
2705 static const wxCoord MENU_CHECK_SIZE
= 9;
2707 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2708 const wxRect
& rectOrig
,
2709 const wxString
& label
,
2713 wxRect rect
= rectOrig
;
2716 wxDCTextColourChanger
colChanger(dc
);
2718 if ( flags
& wxCONTROL_SELECTED
)
2720 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2722 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2723 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2724 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2725 dc
.DrawRectangle(rect
);
2728 // don't draw the focus rect around menu bar items
2729 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2730 wxALIGN_CENTRE
, indexAccel
);
2733 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2735 const wxMenuGeometryInfo
& gi
,
2736 const wxString
& label
,
2737 const wxString
& accel
,
2738 const wxBitmap
& bitmap
,
2742 const wxWin32MenuGeometryInfo
& geometryInfo
=
2743 (const wxWin32MenuGeometryInfo
&)gi
;
2748 rect
.width
= geometryInfo
.GetSize().x
;
2749 rect
.height
= geometryInfo
.GetItemHeight();
2751 // draw the selected item specially
2752 wxDCTextColourChanger
colChanger(dc
);
2753 if ( flags
& wxCONTROL_SELECTED
)
2755 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2757 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2758 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2759 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2760 dc
.DrawRectangle(rect
);
2763 // draw the bitmap: use the bitmap provided or the standard checkmark for
2764 // the checkable items
2765 wxBitmap bmp
= bitmap
;
2766 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2768 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2773 rect
.SetRight(geometryInfo
.GetLabelOffset());
2774 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2778 rect
.x
= geometryInfo
.GetLabelOffset();
2779 rect
.SetRight(geometryInfo
.GetAccelOffset());
2781 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2783 // draw the accel string
2784 rect
.x
= geometryInfo
.GetAccelOffset();
2785 rect
.SetRight(geometryInfo
.GetSize().x
);
2787 // NB: no accel index here
2788 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2790 // draw the submenu indicator
2791 if ( flags
& wxCONTROL_ISSUBMENU
)
2793 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2794 rect
.width
= MENU_RIGHT_MARGIN
;
2796 wxArrowStyle arrowStyle
;
2797 if ( flags
& wxCONTROL_DISABLED
)
2798 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2800 else if ( flags
& wxCONTROL_SELECTED
)
2801 arrowStyle
= Arrow_Inversed
;
2803 arrowStyle
= Arrow_Normal
;
2805 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2809 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2811 const wxMenuGeometryInfo
& geomInfo
)
2813 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2816 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2818 wxSize size
= sizeText
;
2820 // FIXME: menubar height is configurable under Windows
2827 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2828 const wxMenu
& menu
) const
2830 // prepare the dc: for now we draw all the items with the system font
2832 dc
.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
2834 // the height of a normal item
2835 wxCoord heightText
= dc
.GetCharHeight();
2840 // the max length of label and accel strings: the menu width is the sum of
2841 // them, even if they're for different items (as the accels should be
2844 // the max length of the bitmap is never 0 as Windows always leaves enough
2845 // space for a check mark indicator
2846 wxCoord widthLabelMax
= 0,
2848 widthBmpMax
= MENU_LEFT_MARGIN
;
2850 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2852 node
= node
->GetNext() )
2854 // height of this item
2857 wxMenuItem
*item
= node
->GetData();
2858 if ( item
->IsSeparator() )
2860 h
= MENU_SEPARATOR_HEIGHT
;
2862 else // not separator
2867 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2868 if ( widthLabel
> widthLabelMax
)
2870 widthLabelMax
= widthLabel
;
2874 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2875 if ( widthAccel
> widthAccelMax
)
2877 widthAccelMax
= widthAccel
;
2880 const wxBitmap
& bmp
= item
->GetBitmap();
2883 wxCoord widthBmp
= bmp
.GetWidth();
2884 if ( widthBmp
> widthBmpMax
)
2885 widthBmpMax
= widthBmp
;
2887 //else if ( item->IsCheckable() ): no need to check for this as
2888 // MENU_LEFT_MARGIN is big enough to show the check mark
2891 h
+= 2*MENU_VERT_MARGIN
;
2893 // remember the item position and height
2894 item
->SetGeometry(height
, h
);
2899 // bundle the metrics into a struct and return it
2900 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2902 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2903 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2904 if ( widthAccelMax
> 0 )
2906 // if we actually have any accesl, add a margin
2907 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2910 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2912 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2913 gi
->m_size
.y
= height
;
2918 // ----------------------------------------------------------------------------
2920 // ----------------------------------------------------------------------------
2922 static const wxCoord STATBAR_BORDER_X
= 2;
2923 static const wxCoord STATBAR_BORDER_Y
= 2;
2925 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2927 if ( borderBetweenFields
)
2928 *borderBetweenFields
= 2;
2930 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2933 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2935 const wxString
& label
,
2940 if ( flags
& wxCONTROL_ISDEFAULT
)
2942 // draw the size grip: it is a normal rect except that in the lower
2943 // right corner we have several bands which may be used for dragging
2944 // the status bar corner
2946 // each band consists of 4 stripes: m_penHighlight, double
2947 // m_penDarkGrey and transparent one
2948 wxCoord x2
= rect
.GetRight(),
2949 y2
= rect
.GetBottom();
2951 // draw the upper left part of the rect normally
2952 dc
.SetPen(m_penDarkGrey
);
2953 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
2954 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
2956 // draw the grey stripes of the grip
2958 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
2959 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2961 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2962 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
2965 // draw the white stripes
2966 dc
.SetPen(m_penHighlight
);
2967 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
2968 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2970 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2973 // draw the remaining rect boundaries
2974 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
2975 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
2976 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
2981 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
2985 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
2988 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2990 wxDCClipper
clipper(dc
, rectIn
);
2991 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
2994 // ----------------------------------------------------------------------------
2996 // ----------------------------------------------------------------------------
2998 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3000 wxBitmap
*bmpPressed
,
3001 wxBitmap
*bmpDisabled
)
3003 static const wxCoord widthCombo
= 16;
3004 static const wxCoord heightCombo
= 17;
3010 bmpNormal
->Create(widthCombo
, heightCombo
);
3011 dcMem
.SelectObject(*bmpNormal
);
3012 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3013 Arrow_Down
, Arrow_Normal
);
3018 bmpPressed
->Create(widthCombo
, heightCombo
);
3019 dcMem
.SelectObject(*bmpPressed
);
3020 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3021 Arrow_Down
, Arrow_Pressed
);
3026 bmpDisabled
->Create(widthCombo
, heightCombo
);
3027 dcMem
.SelectObject(*bmpDisabled
);
3028 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3029 Arrow_Down
, Arrow_Disabled
);
3033 // ----------------------------------------------------------------------------
3035 // ----------------------------------------------------------------------------
3037 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3038 const wxColour
& col
,
3041 wxBrush
brush(col
, wxSOLID
);
3043 dc
.SetPen(*wxTRANSPARENT_PEN
);
3044 dc
.DrawRectangle(rect
);
3047 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3048 const wxColour
& col
,
3052 // just fill it with the given or default bg colour
3053 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3054 DoDrawBackground(dc
, colBg
, rect
);
3057 // ----------------------------------------------------------------------------
3059 // ----------------------------------------------------------------------------
3061 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3066 // get the bitmap for this arrow
3067 wxArrowDirection arrowDir
;
3070 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3071 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3072 case wxUP
: arrowDir
= Arrow_Up
; break;
3073 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3076 wxFAIL_MSG(_T("unknown arrow direction"));
3080 wxArrowStyle arrowStyle
;
3081 if ( flags
& wxCONTROL_PRESSED
)
3083 // can't be pressed and disabled
3084 arrowStyle
= Arrow_Pressed
;
3088 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3091 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3094 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3096 wxArrowDirection arrowDir
,
3097 wxArrowStyle arrowStyle
)
3099 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3101 // under Windows the arrows always have the same size so just centre it in
3102 // the provided rectangle
3103 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3104 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3106 // Windows does it like this...
3107 if ( arrowDir
== Arrow_Left
)
3111 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3114 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3115 const wxRect
& rectAll
,
3116 wxArrowDirection arrowDir
,
3117 wxArrowStyle arrowStyle
)
3119 wxRect rect
= rectAll
;
3120 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3121 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3122 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3125 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3126 wxOrientation orient
,
3130 // we don't use the flags, the thumb never changes appearance
3131 wxRect rectThumb
= rect
;
3132 DrawArrowBorder(dc
, &rectThumb
);
3133 DrawBackground(dc
, wxNullColour
, rectThumb
);
3136 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3137 wxOrientation orient
,
3138 const wxRect
& rectBar
,
3141 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3142 ? wxColourScheme::SCROLLBAR_PRESSED
3143 : wxColourScheme::SCROLLBAR
;
3144 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3147 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3149 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3152 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3153 wxScrollBar::Element elem
,
3156 return StandardGetScrollbarRect(scrollbar
, elem
,
3157 thumbPos
, m_sizeScrollbarArrow
);
3160 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3162 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3165 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3166 const wxPoint
& pt
) const
3168 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3171 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3174 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3177 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3180 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3183 // ----------------------------------------------------------------------------
3184 // top level windows
3185 // ----------------------------------------------------------------------------
3187 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3189 wxRect client
= GetFrameClientArea(rect
, flags
);
3191 if ( client
.Inside(pt
) )
3192 return wxHT_TOPLEVEL_CLIENT_AREA
;
3194 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3196 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3198 if ( flags
& wxTOPLEVEL_ICON
)
3200 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3201 return wxHT_TOPLEVEL_ICON
;
3204 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3205 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3206 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3208 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3210 if ( btnRect
.Inside(pt
) )
3211 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3212 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3214 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3216 if ( btnRect
.Inside(pt
) )
3217 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3218 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3220 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3222 if ( btnRect
.Inside(pt
) )
3223 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3224 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3226 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3228 if ( btnRect
.Inside(pt
) )
3229 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3230 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3232 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3234 if ( btnRect
.Inside(pt
) )
3235 return wxHT_TOPLEVEL_BUTTON_HELP
;
3236 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3239 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3240 return wxHT_TOPLEVEL_TITLEBAR
;
3243 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3245 // we are certainly at one of borders, lets decide which one:
3248 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3249 if ( pt
.x
< client
.x
)
3250 border
|= wxHT_TOPLEVEL_BORDER_W
;
3251 else if ( pt
.x
>= client
.width
+ client
.x
)
3252 border
|= wxHT_TOPLEVEL_BORDER_E
;
3253 if ( pt
.y
< client
.y
)
3254 border
|= wxHT_TOPLEVEL_BORDER_N
;
3255 else if ( pt
.y
>= client
.height
+ client
.y
)
3256 border
|= wxHT_TOPLEVEL_BORDER_S
;
3260 return wxHT_NOWHERE
;
3263 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3265 const wxString
& title
,
3269 int specialButtonFlags
)
3271 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3273 DrawFrameBorder(dc
, rect
, flags
);
3275 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3277 DrawFrameBackground(dc
, rect
, flags
);
3278 if ( flags
& wxTOPLEVEL_ICON
)
3279 DrawFrameIcon(dc
, rect
, icon
, flags
);
3280 DrawFrameTitle(dc
, rect
, title
, flags
);
3282 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3284 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3285 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3287 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3289 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3290 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3291 specialButtonFlags
: 0);
3292 x
-= FRAME_BUTTON_WIDTH
+ 2;
3294 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3296 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3297 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3298 specialButtonFlags
: 0);
3299 x
-= FRAME_BUTTON_WIDTH
;
3301 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3303 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3304 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3305 specialButtonFlags
: 0);
3306 x
-= FRAME_BUTTON_WIDTH
;
3308 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3310 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3311 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3312 specialButtonFlags
: 0);
3313 x
-= FRAME_BUTTON_WIDTH
;
3315 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3317 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3318 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3319 specialButtonFlags
: 0);
3320 x
-= FRAME_BUTTON_WIDTH
;
3325 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3329 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3333 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3334 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3335 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3336 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3337 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3340 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3344 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3346 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3347 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3348 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3350 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3351 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3353 DrawBackground(dc
, col
, r
);
3356 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3358 const wxString
& title
,
3361 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3362 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3363 if ( flags
& wxTOPLEVEL_ICON
)
3364 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3368 dc
.SetFont(m_titlebarFont
);
3369 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
));
3370 dc
.DrawLabel(title
, wxNullBitmap
, r
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3373 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3380 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3381 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3385 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3386 wxCoord x
, wxCoord y
,
3390 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3395 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3396 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3397 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3398 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3399 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3401 wxFAIL_MSG(wxT("incorrect button specification"));
3404 if ( flags
& wxCONTROL_PRESSED
)
3406 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3407 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3408 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3409 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3413 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3414 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3415 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3416 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3421 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3426 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3428 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3429 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3430 FRAME_BORDER_THICKNESS
;
3433 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3435 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3436 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3442 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3445 wxSize
s(clientSize
);
3447 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3449 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3450 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3451 FRAME_BORDER_THICKNESS
;
3455 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3456 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3461 wxSize
wxWin32Renderer::GetFrameIconSize() const
3463 return wxSize(16, 16);
3467 // ----------------------------------------------------------------------------
3469 // ----------------------------------------------------------------------------
3471 static char *error_xpm
[]={
3478 "...........########.............",
3479 "........###aaaaaaaa###..........",
3480 ".......#aaaaaaaaaaaaaa#.........",
3481 ".....##aaaaaaaaaaaaaaaa##.......",
3482 "....#aaaaaaaaaaaaaaaaaaaa#......",
3483 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3484 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3485 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3486 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3487 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3488 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3489 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3490 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3491 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3492 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3493 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3494 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3495 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3496 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3497 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3498 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3499 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3500 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3501 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3502 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3503 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3504 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3505 "......b#aaaaaaaaaaaaaa#bbbbb....",
3506 ".......b###aaaaaaaa###bbbbb.....",
3507 ".........bb########bbbbbb.......",
3508 "..........bbbbbbbbbbbbbb........",
3509 ".............bbbbbbbb..........."};
3511 static char *info_xpm
[]={
3519 "...........########.............",
3520 "........###abbbbbba###..........",
3521 "......##abbbbbbbbbbbba##........",
3522 ".....#abbbbbbbbbbbbbbbba#.......",
3523 "....#bbbbbbbaccccabbbbbbbd......",
3524 "...#bbbbbbbbccccccbbbbbbbbd.....",
3525 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3526 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3527 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3528 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3529 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3530 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3531 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3532 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3533 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3534 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3535 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3536 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3537 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3538 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3539 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3540 ".....dabbbbbbbbbbbbbbbbad####...",
3541 "......ddabbbbbbbbbbbbadd####....",
3542 ".......#dddabbbbbbaddd#####.....",
3543 "........###dddabbbd#######......",
3544 "..........####dbbbd#####........",
3545 ".............#dbbbd##...........",
3546 "...............dbbd##...........",
3547 "................dbd##...........",
3548 ".................dd##...........",
3549 "..................###...........",
3550 "...................##..........."};
3552 static char *question_xpm
[]={
3560 "...........########.............",
3561 "........###abbbbbba###..........",
3562 "......##abbbbbbbbbbbba##........",
3563 ".....#abbbbbbbbbbbbbbbba#.......",
3564 "....#bbbbbbbbbbbbbbbbbbbbc......",
3565 "...#bbbbbbbaddddddabbbbbbbc.....",
3566 "..#bbbbbbbadabbddddabbbbbbbc....",
3567 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3568 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3569 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3570 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3571 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3572 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3573 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3574 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3575 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3576 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3577 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3578 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3579 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3580 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3581 ".....cabbbbbbbbbbbbbbbbac####...",
3582 "......ccabbbbbbbbbbbbacc####....",
3583 ".......#cccabbbbbbaccc#####.....",
3584 "........###cccabbbc#######......",
3585 "..........####cbbbc#####........",
3586 ".............#cbbbc##...........",
3587 "...............cbbc##...........",
3588 "................cbc##...........",
3589 ".................cc##...........",
3590 "..................###...........",
3591 "...................##..........."};
3593 static char *warning_xpm
[]={
3601 ".............###................",
3602 "............#aabc...............",
3603 "...........#aaaabcd.............",
3604 "...........#aaaaacdd............",
3605 "..........#aaaaaabcdd...........",
3606 "..........#aaaaaaacdd...........",
3607 ".........#aaaaaaaabcdd..........",
3608 ".........#aaaaaaaaacdd..........",
3609 "........#aaaaaaaaaabcdd.........",
3610 "........#aaabcccbaaacdd.........",
3611 ".......#aaaacccccaaabcdd........",
3612 ".......#aaaacccccaaaacdd........",
3613 "......#aaaaacccccaaaabcdd.......",
3614 "......#aaaaacccccaaaaacdd.......",
3615 ".....#aaaaaacccccaaaaabcdd......",
3616 ".....#aaaaaa#ccc#aaaaaacdd......",
3617 "....#aaaaaaabcccbaaaaaabcdd.....",
3618 "....#aaaaaaaacccaaaaaaaacdd.....",
3619 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3620 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3621 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3622 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3623 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3624 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3625 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3626 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3627 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3628 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3629 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3630 "..#ccccccccccccccccccccccccddddd",
3631 "....ddddddddddddddddddddddddddd.",
3632 ".....ddddddddddddddddddddddddd.."};
3634 wxIcon
wxWin32Renderer::GetStdIcon(int which
) const
3638 case wxICON_INFORMATION
:
3639 return wxIcon(info_xpm
);
3641 case wxICON_QUESTION
:
3642 return wxIcon(question_xpm
);
3644 case wxICON_EXCLAMATION
:
3645 return wxIcon(warning_xpm
);
3648 wxFAIL_MSG(wxT("requested non existent standard icon"));
3649 // still fall through
3652 return wxIcon(error_xpm
);
3657 // ----------------------------------------------------------------------------
3658 // text control geometry
3659 // ----------------------------------------------------------------------------
3661 static inline int GetTextBorderWidth()
3666 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3669 wxRect rectTotal
= rect
;
3671 wxCoord widthBorder
= GetTextBorderWidth();
3672 rectTotal
.Inflate(widthBorder
);
3674 // this is what Windows does
3680 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3682 wxCoord
*extraSpaceBeyond
)
3684 wxRect rectText
= rect
;
3686 // undo GetTextTotalArea()
3687 if ( rectText
.height
> 0 )
3690 wxCoord widthBorder
= GetTextBorderWidth();
3691 rectText
.Inflate(-widthBorder
);
3693 if ( extraSpaceBeyond
)
3694 *extraSpaceBeyond
= 0;
3699 // ----------------------------------------------------------------------------
3701 // ----------------------------------------------------------------------------
3703 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3706 if ( wxDynamicCast(window
, wxScrollBar
) )
3708 // we only set the width of vert scrollbars and height of the
3710 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3711 size
->y
= m_sizeScrollbarArrow
.y
;
3713 size
->x
= m_sizeScrollbarArrow
.x
;
3715 // skip border width adjustments, they don't make sense for us
3718 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3721 if ( wxDynamicCast(window
, wxButton
) )
3723 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3725 // TODO: don't harcode all this
3726 size
->x
+= 3*window
->GetCharWidth();
3728 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3729 if ( size
->y
< heightBtn
- 8 )
3730 size
->y
= heightBtn
;
3735 // no border width adjustments for buttons
3738 #endif // wxUSE_BUTTON
3740 // take into account the border width
3741 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3742 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3743 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3746 // ============================================================================
3748 // ============================================================================
3750 // ----------------------------------------------------------------------------
3751 // wxWin32InputHandler
3752 // ----------------------------------------------------------------------------
3754 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3756 m_renderer
= renderer
;
3759 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3760 const wxKeyEvent
& event
,
3766 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3767 const wxMouseEvent
& event
)
3769 // clicking on the control gives it focus
3770 if ( event
.ButtonDown() )
3772 wxWindow
*win
= control
->GetInputWindow();
3773 if ( wxWindow::FindFocus() != control
->GetInputWindow() )
3784 // ----------------------------------------------------------------------------
3785 // wxWin32ScrollBarInputHandler
3786 // ----------------------------------------------------------------------------
3788 wxWin32ScrollBarInputHandler::
3789 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3790 wxInputHandler
*handler
)
3791 : wxStdScrollBarInputHandler(renderer
, handler
)
3793 m_scrollPaused
= FALSE
;
3797 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3798 const wxControlAction
& action
)
3800 // stop if went beyond the position of the original click (this can only
3801 // happen when we scroll by pages)
3803 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3805 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3806 != wxHT_SCROLLBAR_BAR_2
;
3808 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3810 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3811 != wxHT_SCROLLBAR_BAR_1
;
3816 StopScrolling(scrollbar
);
3818 scrollbar
->Refresh();
3823 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3826 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3827 const wxMouseEvent
& event
)
3829 // remember the current state
3830 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3832 // do process the message
3833 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3835 // analyse the changes
3836 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3838 // we just started dragging the thumb, remember its initial position to
3839 // be able to restore it if the drag is cancelled later
3840 m_eventStartDrag
= event
;
3846 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3847 const wxMouseEvent
& event
)
3849 // we don't highlight scrollbar elements, so there is no need to process
3850 // mouse move events normally - only do it while mouse is captured (i.e.
3851 // when we're dragging the thumb or pressing on something)
3852 if ( !m_winCapture
)
3855 if ( event
.Entering() )
3857 // we're not interested in this at all
3861 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3863 if ( m_scrollPaused
)
3865 // check if the mouse returned to its original location
3867 if ( event
.Leaving() )
3873 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3874 if ( ht
== m_htLast
)
3876 // yes it did, resume scrolling
3877 m_scrollPaused
= FALSE
;
3878 if ( m_timerScroll
)
3880 // we were scrolling by line/page, restart timer
3881 m_timerScroll
->Start(m_interval
);
3883 Press(scrollbar
, TRUE
);
3885 else // we were dragging the thumb
3887 // restore its last location
3888 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3894 else // normal case, scrolling hasn't been paused
3896 // if we're scrolling the scrollbar because the arrow or the shaft was
3897 // pressed, check that the mouse stays on the same scrollbar element
3899 if ( event
.Moving() )
3901 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3903 else // event.Leaving()
3908 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3909 // is still ok - we only want to catch the case when the mouse leaves
3910 // the scrollbar here
3911 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3913 ht
= wxHT_SCROLLBAR_THUMB
;
3916 if ( ht
!= m_htLast
)
3918 // what were we doing? 2 possibilities: either an arrow/shaft was
3919 // pressed in which case we have a timer and so we just stop it or
3920 // we were dragging the thumb
3921 if ( m_timerScroll
)
3924 m_interval
= m_timerScroll
->GetInterval();
3925 m_timerScroll
->Stop();
3926 m_scrollPaused
= TRUE
;
3928 // unpress the arrow
3929 Press(scrollbar
, FALSE
);
3931 else // we were dragging the thumb
3933 // remember the current thumb position to be able to restore it
3934 // if the mouse returns to it later
3935 m_eventLastDrag
= event
;
3937 // and restore the original position (before dragging) of the
3939 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3946 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
3949 // ----------------------------------------------------------------------------
3950 // wxWin32CheckboxInputHandler
3951 // ----------------------------------------------------------------------------
3953 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3954 const wxKeyEvent
& event
,
3959 wxControlAction action
;
3960 int keycode
= event
.GetKeyCode();
3964 action
= wxACTION_CHECKBOX_TOGGLE
;
3968 case WXK_NUMPAD_SUBTRACT
:
3969 action
= wxACTION_CHECKBOX_CHECK
;
3973 case WXK_NUMPAD_ADD
:
3974 case WXK_NUMPAD_EQUAL
:
3975 action
= wxACTION_CHECKBOX_CLEAR
;
3981 control
->PerformAction(action
);
3990 // ----------------------------------------------------------------------------
3991 // wxWin32TextCtrlInputHandler
3992 // ----------------------------------------------------------------------------
3994 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3995 const wxKeyEvent
& event
,
3998 // handle only MSW-specific text bindings here, the others are handled in
4002 int keycode
= event
.GetKeyCode();
4004 wxControlAction action
;
4005 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4007 action
= wxACTION_TEXT_CUT
;
4009 else if ( keycode
== WXK_INSERT
)
4011 if ( event
.ControlDown() )
4012 action
= wxACTION_TEXT_COPY
;
4013 else if ( event
.ShiftDown() )
4014 action
= wxACTION_TEXT_PASTE
;
4017 if ( action
!= wxACTION_NONE
)
4019 control
->PerformAction(action
);
4025 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4028 // ----------------------------------------------------------------------------
4029 // wxWin32StatusBarInputHandler
4030 // ----------------------------------------------------------------------------
4032 wxWin32StatusBarInputHandler::
4033 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4034 : wxStdInputHandler(handler
)
4039 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4040 const wxPoint
& pt
) const
4042 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4043 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4045 wxSize sizeSbar
= statbar
->GetSize();
4047 return (sizeSbar
.x
- pt
.x
) < STATUSBAR_GRIP_SIZE
&&
4048 (sizeSbar
.y
- pt
.y
) < STATUSBAR_GRIP_SIZE
;
4054 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4055 const wxMouseEvent
& event
)
4057 if ( event
.Button(1) )
4059 if ( event
.ButtonDown(1) )
4061 wxWindow
*statbar
= consumer
->GetInputWindow();
4063 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4065 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4069 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4070 wxHT_TOPLEVEL_BORDER_SE
);
4072 statbar
->SetCursor(m_cursorOld
);
4080 return wxStdInputHandler::HandleMouse(consumer
, event
);
4083 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4084 const wxMouseEvent
& event
)
4086 wxWindow
*statbar
= consumer
->GetInputWindow();
4088 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4089 if ( isOnGrip
!= m_isOnGrip
)
4091 m_isOnGrip
= isOnGrip
;
4094 m_cursorOld
= statbar
->GetCursor();
4095 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4099 statbar
->SetCursor(m_cursorOld
);
4103 return wxStdInputHandler::HandleMouseMove(consumer
, event
);