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_INACTIVECAPTIONTEXT
));
1300 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1302 case DESKTOP
: return wxColour(0x808000);
1304 // use the standard Windows colours elsewhere
1305 case WINDOW
: return *wxWHITE
;
1307 case CONTROL_PRESSED
:
1308 case CONTROL_CURRENT
:
1309 case CONTROL
: return wxColour(0xc0c0c0);
1311 case CONTROL_TEXT
: return *wxBLACK
;
1313 case SCROLLBAR
: return wxColour(0xe0e0e0);
1314 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1316 case HIGHLIGHT
: return wxColour(0x800000);
1317 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1319 case SHADOW_DARK
: return *wxBLACK
;
1321 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1322 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1324 case SHADOW_IN
: return wxColour(0xc0c0c0);
1326 case CONTROL_TEXT_DISABLED_SHADOW
:
1327 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1329 case TITLEBAR
: return wxColour(0xaeaaae);
1330 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1331 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1332 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1334 case DESKTOP
: return wxColour(0x808000);
1339 wxFAIL_MSG(_T("invalid standard colour"));
1344 // ============================================================================
1346 // ============================================================================
1348 // ----------------------------------------------------------------------------
1350 // ----------------------------------------------------------------------------
1352 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1356 m_sizeScrollbarArrow
= wxSize(16, 16);
1358 // init colours and pens
1359 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1361 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1362 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1364 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1366 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1367 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1369 m_titlebarFont
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
1370 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1372 // init the arrow bitmaps
1373 static const size_t ARROW_WIDTH
= 7;
1374 static const size_t ARROW_LENGTH
= 4;
1377 wxMemoryDC dcNormal
,
1380 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1382 bool isVertical
= n
> Arrow_Right
;
1395 // disabled arrow is larger because of the shadow
1396 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1397 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1399 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1400 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1402 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1403 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1407 dcNormal
.SetPen(m_penBlack
);
1408 dcDisabled
.SetPen(m_penDarkGrey
);
1410 // calculate the position of the point of the arrow
1414 x1
= (ARROW_WIDTH
- 1)/2;
1415 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1419 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1420 y1
= (ARROW_WIDTH
- 1)/2;
1431 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1433 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1434 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1441 if ( n
== Arrow_Up
)
1452 else // left or right arrow
1457 if ( n
== Arrow_Left
)
1470 // draw the shadow for the disabled one
1471 dcDisabled
.SetPen(m_penHighlight
);
1476 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1480 x1
= ARROW_LENGTH
- 1;
1481 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1484 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1485 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1490 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1494 x1
= ARROW_WIDTH
- 1;
1496 x2
= (ARROW_WIDTH
- 1)/2;
1498 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1499 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1504 // create the inversed bitmap but only for the right arrow as we only
1505 // use it for the menus
1506 if ( n
== Arrow_Right
)
1508 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1509 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1511 dcInverse
.Blit(0, 0, w
, h
,
1514 dcInverse
.SelectObject(wxNullBitmap
);
1516 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1517 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1519 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1520 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1522 dcInverse
.Blit(0, 0, w
, h
,
1525 dcInverse
.SelectObject(wxNullBitmap
);
1527 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1528 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1531 dcNormal
.SelectObject(wxNullBitmap
);
1532 dcDisabled
.SelectObject(wxNullBitmap
);
1534 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1535 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1536 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1537 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1539 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1542 // init the frame buttons bitmaps
1543 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1544 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1545 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1546 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1547 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1550 // ----------------------------------------------------------------------------
1552 // ----------------------------------------------------------------------------
1555 The raised border in Win32 looks like this:
1557 IIIIIIIIIIIIIIIIIIIIIIB
1559 I GB I = white (HILIGHT)
1560 I GB H = light grey (LIGHT)
1561 I GB G = dark grey (SHADOI)
1562 I GB B = black (DKSHADOI)
1563 I GB I = hIghlight (COLOR_3DHILIGHT)
1565 IGGGGGGGGGGGGGGGGGGGGGB
1566 BBBBBBBBBBBBBBBBBBBBBBB
1568 The sunken border looks like this:
1570 GGGGGGGGGGGGGGGGGGGGGGI
1571 GBBBBBBBBBBBBBBBBBBBBHI
1578 GHHHHHHHHHHHHHHHHHHHHHI
1579 IIIIIIIIIIIIIIIIIIIIIII
1581 The static border (used for the controls which don't get focus) is like
1584 GGGGGGGGGGGGGGGGGGGGGGW
1592 WWWWWWWWWWWWWWWWWWWWWWW
1594 The most complicated is the double border:
1596 HHHHHHHHHHHHHHHHHHHHHHB
1597 HWWWWWWWWWWWWWWWWWWWWGB
1598 HWHHHHHHHHHHHHHHHHHHHGB
1603 HWHHHHHHHHHHHHHHHHHHHGB
1604 HGGGGGGGGGGGGGGGGGGGGGB
1605 BBBBBBBBBBBBBBBBBBBBBBB
1607 And the simple border is, well, simple:
1609 BBBBBBBBBBBBBBBBBBBBBBB
1618 BBBBBBBBBBBBBBBBBBBBBBB
1621 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1625 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1626 dc
.DrawRectangle(*rect
);
1632 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1634 // draw the bottom and right sides
1636 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1637 rect
->GetRight() + 1, rect
->GetBottom());
1638 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1639 rect
->GetRight(), rect
->GetBottom());
1646 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1647 const wxPen
& pen1
, const wxPen
& pen2
)
1649 // draw the rectangle
1651 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1652 rect
->GetLeft(), rect
->GetBottom());
1653 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1654 rect
->GetRight(), rect
->GetTop());
1656 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1657 rect
->GetRight(), rect
->GetBottom());
1658 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1659 rect
->GetRight() + 1, rect
->GetBottom());
1665 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1667 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1668 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1671 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1673 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1674 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1677 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1681 DrawRect(dc
, rect
, m_penDarkGrey
);
1683 // the arrow is usually drawn inside border of width 2 and is offset by
1684 // another pixel in both directions when it's pressed - as the border
1685 // in this case is more narrow as well, we have to adjust rect like
1693 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1694 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1698 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1700 const wxRect
& rectTotal
,
1701 int WXUNUSED(flags
),
1706 wxRect rect
= rectTotal
;
1710 case wxBORDER_SUNKEN
:
1711 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1713 DrawSunkenBorder(dc
, &rect
);
1717 case wxBORDER_STATIC
:
1718 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1721 case wxBORDER_RAISED
:
1722 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1724 DrawRaisedBorder(dc
, &rect
);
1728 case wxBORDER_DOUBLE
:
1729 DrawArrowBorder(dc
, &rect
);
1730 DrawRect(dc
, &rect
, m_penLightGrey
);
1733 case wxBORDER_SIMPLE
:
1734 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1736 DrawRect(dc
, &rect
, m_penBlack
);
1741 wxFAIL_MSG(_T("unknown border type"));
1744 case wxBORDER_DEFAULT
:
1753 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1758 case wxBORDER_RAISED
:
1759 case wxBORDER_SUNKEN
:
1760 width
= BORDER_THICKNESS
;
1763 case wxBORDER_SIMPLE
:
1764 case wxBORDER_STATIC
:
1768 case wxBORDER_DOUBLE
:
1773 wxFAIL_MSG(_T("unknown border type"));
1776 case wxBORDER_DEFAULT
:
1786 rect
.height
= width
;
1791 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1796 // ----------------------------------------------------------------------------
1798 // ----------------------------------------------------------------------------
1800 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1806 // text controls are not special under windows
1807 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1810 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1811 const wxRect
& rectTotal
,
1815 wxRect rect
= rectTotal
;
1817 if ( flags
& wxCONTROL_PRESSED
)
1819 // button pressed: draw a double border around it
1820 DrawRect(dc
, &rect
, m_penBlack
);
1821 DrawRect(dc
, &rect
, m_penDarkGrey
);
1825 // button not pressed
1827 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1829 // button either default or focused (or both): add an extra border around it
1830 DrawRect(dc
, &rect
, m_penBlack
);
1833 // now draw a normal button
1834 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1835 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1844 // ----------------------------------------------------------------------------
1846 // ----------------------------------------------------------------------------
1848 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1849 wxCoord y
, wxCoord x1
, wxCoord x2
)
1851 dc
.SetPen(m_penDarkGrey
);
1852 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1853 dc
.SetPen(m_penHighlight
);
1855 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1858 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1859 wxCoord x
, wxCoord y1
, wxCoord y2
)
1861 dc
.SetPen(m_penDarkGrey
);
1862 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1863 dc
.SetPen(m_penHighlight
);
1865 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1868 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1869 const wxString
& label
,
1875 wxCoord height
= 0; // of the label
1876 wxRect rectFrame
= rect
;
1877 if ( !label
.empty() )
1879 // the text should touch the top border of the rect, so the frame
1880 // itself should be lower
1881 dc
.GetTextExtent(label
, NULL
, &height
);
1882 rectFrame
.y
+= height
/ 2;
1883 rectFrame
.height
-= height
/ 2;
1885 // we have to draw each part of the frame individually as we can't
1886 // erase the background beyond the label as it might contain some
1887 // pixmap already, so drawing everything and then overwriting part of
1888 // the frame with label doesn't work
1890 // TODO: the +5 and space insertion should be customizable
1893 rectText
.x
= rectFrame
.x
+ 5;
1894 rectText
.y
= rect
.y
;
1895 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1896 rectText
.height
= height
;
1899 label2
<< _T(' ') << label
<< _T(' ');
1900 if ( indexAccel
!= -1 )
1902 // adjust it as we prepended a space
1907 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1909 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1913 // just draw the complete frame
1914 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1915 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1919 // ----------------------------------------------------------------------------
1921 // ----------------------------------------------------------------------------
1923 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1925 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1926 // pixels each while we really need dots here... PS_ALTERNATE might
1927 // work, but it is for NT 5 only
1929 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1931 // draw the pixels manually: note that to behave in the same manner as
1932 // DrawRect(), we must exclude the bottom and right borders from the
1934 wxCoord x1
= rect
.GetLeft(),
1936 x2
= rect
.GetRight(),
1937 y2
= rect
.GetBottom();
1939 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1941 // this seems to be closer than what Windows does than wxINVERT although
1942 // I'm still not sure if it's correct
1943 dc
.SetLogicalFunction(wxAND_REVERSE
);
1946 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
1947 dc
.DrawPoint(z
, rect
.GetTop());
1949 wxCoord shift
= z
== x2
? 0 : 1;
1950 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
1951 dc
.DrawPoint(x2
, z
);
1953 shift
= z
== y2
? 0 : 1;
1954 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
1955 dc
.DrawPoint(z
, y2
);
1957 shift
= z
== x1
? 0 : 1;
1958 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
1959 dc
.DrawPoint(x1
, z
);
1961 dc
.SetLogicalFunction(wxCOPY
);
1965 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
1966 const wxString
& label
,
1971 // draw shadow of the text
1972 dc
.SetTextForeground(m_colHighlight
);
1973 wxRect rectShadow
= rect
;
1976 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
1978 // make the text grey
1979 dc
.SetTextForeground(m_colDarkGrey
);
1982 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1983 const wxString
& label
,
1990 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
1993 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
1994 const wxString
& label
,
2000 const wxPoint
& focusOffset
)
2002 // the underscores are not drawn for focused controls in wxMSW
2003 if ( flags
& wxCONTROL_FOCUSED
)
2008 if ( flags
& wxCONTROL_DISABLED
)
2010 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2011 // currently only can happen for a menu item and it seems that Windows
2012 // doesn't draw the shadow in this case, so we don't do it neither
2013 if ( flags
& wxCONTROL_SELECTED
)
2015 // just make the label text greyed out
2016 dc
.SetTextForeground(m_colDarkGrey
);
2018 else // draw normal disabled label
2020 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2025 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2027 if ( flags
& wxCONTROL_DISABLED
)
2029 // restore the fg colour
2030 dc
.SetTextForeground(*wxBLACK
);
2033 if ( flags
& wxCONTROL_FOCUSED
)
2035 if ( focusOffset
.x
|| focusOffset
.y
)
2037 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2040 DrawFocusRect(dc
, rectLabel
);
2044 *rectBounds
= rectLabel
;
2047 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2048 const wxString
& label
,
2049 const wxBitmap
& image
,
2056 // the underscores are not drawn for focused controls in wxMSW
2057 if ( flags
& wxCONTROL_PRESSED
)
2062 wxRect rectLabel
= rect
;
2063 if ( !label
.empty() )
2065 // shift the label if a button is pressed
2066 if ( flags
& wxCONTROL_PRESSED
)
2072 if ( flags
& wxCONTROL_DISABLED
)
2074 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2077 // leave enough space for the focus rectangle
2078 if ( flags
& wxCONTROL_FOCUSED
)
2080 rectLabel
.Inflate(-2);
2084 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2086 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2088 if ( flags
& wxCONTROL_PRESSED
)
2090 // the focus rectangle is never pressed, so undo the shift done
2098 DrawFocusRect(dc
, rectLabel
);
2102 // ----------------------------------------------------------------------------
2103 // (check)listbox items
2104 // ----------------------------------------------------------------------------
2106 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2107 const wxString
& label
,
2111 wxDCTextColourChanger
colChanger(dc
);
2113 if ( flags
& wxCONTROL_SELECTED
)
2115 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2117 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2118 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2119 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2120 dc
.DrawRectangle(rect
);
2123 wxRect rectText
= rect
;
2125 rectText
.width
-= 2;
2126 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2128 if ( flags
& wxCONTROL_FOCUSED
)
2130 DrawFocusRect(dc
, rect
);
2134 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2135 const wxString
& label
,
2136 const wxBitmap
& bitmap
,
2145 else // use default bitmap
2147 bmp
= wxBitmap(flags
& wxCONTROL_CHECKED
? checked_item_xpm
2148 : unchecked_item_xpm
);
2151 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2152 TRUE
/* use mask */);
2154 wxRect rectLabel
= rect
;
2155 int bmpWidth
= bmp
.GetWidth();
2156 rectLabel
.x
+= bmpWidth
;
2157 rectLabel
.width
-= bmpWidth
;
2159 DrawItem(dc
, label
, rectLabel
, flags
);
2162 // ----------------------------------------------------------------------------
2163 // check/radio buttons
2164 // ----------------------------------------------------------------------------
2166 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2168 IndicatorState indState
;
2169 if ( flags
& wxCONTROL_SELECTED
)
2170 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2171 : IndicatorState_Selected
;
2172 else if ( flags
& wxCONTROL_DISABLED
)
2173 indState
= IndicatorState_Disabled
;
2174 else if ( flags
& wxCONTROL_PRESSED
)
2175 indState
= IndicatorState_Pressed
;
2177 indState
= IndicatorState_Normal
;
2179 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2180 ? IndicatorStatus_Checked
2181 : IndicatorStatus_Unchecked
;
2183 const char **xpm
= bmpIndicators
[indType
][indState
][indStatus
];
2184 return xpm
? wxBitmap(xpm
) : wxNullBitmap
;
2187 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2188 const wxString
& label
,
2189 const wxBitmap
& bitmap
,
2194 wxCoord focusOffsetY
)
2196 // calculate the position of the bitmap and of the label
2197 wxCoord heightBmp
= bitmap
.GetHeight();
2199 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2202 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2203 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2205 // align label vertically with the bitmap - looks nicer like this
2206 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2208 // calc horz position
2209 if ( align
== wxALIGN_RIGHT
)
2211 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2212 rectLabel
.x
= rect
.x
+ 3;
2213 rectLabel
.SetRight(xBmp
);
2215 else // normal (checkbox to the left of the text) case
2218 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2219 rectLabel
.SetRight(rect
.GetRight());
2222 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2225 dc
, label
, rectLabel
,
2227 wxALIGN_LEFT
| wxALIGN_TOP
,
2229 NULL
, // we don't need bounding rect
2230 // use custom vert focus rect offset
2231 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2235 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2236 const wxString
& label
,
2237 const wxBitmap
& bitmap
,
2243 DrawCheckOrRadioButton(dc
, label
,
2244 bitmap
.Ok() ? bitmap
: GetRadioBitmap(flags
),
2245 rect
, flags
, align
, indexAccel
,
2246 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2249 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2250 const wxString
& label
,
2251 const wxBitmap
& bitmap
,
2257 DrawCheckOrRadioButton(dc
, label
,
2258 bitmap
.Ok() ? bitmap
: GetCheckBitmap(flags
),
2259 rect
, flags
, align
, indexAccel
,
2260 0); // no focus rect offset for checkboxes
2263 // ----------------------------------------------------------------------------
2265 // ----------------------------------------------------------------------------
2267 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2268 const wxString
& text
,
2274 // nothing special to do here
2275 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2278 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2280 // we don't draw them
2283 // ----------------------------------------------------------------------------
2285 // ----------------------------------------------------------------------------
2287 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2288 const wxRect
& rectOrig
,
2290 const wxString
& label
,
2291 const wxBitmap
& bitmap
,
2295 wxRect rect
= rectOrig
;
2297 // the current tab is drawn indented (to the top for default case) and
2298 // bigger than the other ones
2299 const wxSize indent
= GetTabIndent();
2300 if ( flags
& wxCONTROL_SELECTED
)
2305 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2309 rect
.Inflate(indent
.x
, 0);
2311 rect
.height
+= indent
.y
;
2315 rect
.Inflate(indent
.x
, 0);
2316 rect
.height
+= indent
.y
;
2321 wxFAIL_MSG(_T("TODO"));
2326 // draw the text, image and the focus around them (if necessary)
2327 wxRect rectLabel
= rect
;
2328 rectLabel
.Deflate(1, 1);
2329 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2330 flags
, wxALIGN_CENTRE
, indexAccel
);
2332 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2333 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2336 x2
= rect
.GetRight(),
2337 y2
= rect
.GetBottom();
2339 // FIXME: all this code will break if the tab indent or the border width,
2340 // it is tied to the fact that both of them are equal to 2
2345 dc
.SetPen(m_penHighlight
);
2346 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2347 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2348 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2350 dc
.SetPen(m_penBlack
);
2351 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2352 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2354 dc
.SetPen(m_penDarkGrey
);
2355 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2357 if ( flags
& wxCONTROL_SELECTED
)
2359 dc
.SetPen(m_penLightGrey
);
2361 // overwrite the part of the border below this tab
2362 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2364 // and the shadow of the tab to the left of us
2365 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2370 dc
.SetPen(m_penHighlight
);
2371 // we need to continue one pixel further to overwrite the corner of
2372 // the border for the selected tab
2373 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2375 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2377 dc
.SetPen(m_penBlack
);
2378 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2379 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2380 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2382 dc
.SetPen(m_penDarkGrey
);
2383 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2384 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2386 if ( flags
& wxCONTROL_SELECTED
)
2388 dc
.SetPen(m_penLightGrey
);
2390 // overwrite the part of the (double!) border above this tab
2391 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2392 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2394 // and the shadow of the tab to the left of us
2395 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2401 wxFAIL_MSG(_T("TODO"));
2405 // ----------------------------------------------------------------------------
2407 // ----------------------------------------------------------------------------
2409 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2410 wxOrientation orient
) const
2414 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2415 if ( orient
== wxHORIZONTAL
)
2417 size
.y
= rect
.height
- 6;
2418 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2422 size
.x
= rect
.width
- 6;
2423 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2429 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2430 wxOrientation orient
) const
2432 static const wxCoord SLIDER_MARGIN
= 6;
2434 wxRect rect
= rectOrig
;
2436 if ( orient
== wxHORIZONTAL
)
2438 // make the rect of minimal width and centre it
2439 rect
.height
= 2*BORDER_THICKNESS
;
2440 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2444 // leave margins on the sides
2445 rect
.Deflate(SLIDER_MARGIN
, 0);
2449 // same as above but in other direction
2450 rect
.width
= 2*BORDER_THICKNESS
;
2451 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2455 rect
.Deflate(0, SLIDER_MARGIN
);
2461 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2462 const wxRect
& rectOrig
,
2463 wxOrientation orient
,
2467 if ( flags
& wxCONTROL_FOCUSED
)
2469 DrawFocusRect(dc
, rectOrig
);
2472 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2477 DrawSunkenBorder(dc
, &rect
);
2480 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2482 wxOrientation orient
,
2486 we are drawing a shape of this form
2491 H DB where H is hightlight colour
2504 The interior of this shape is filled with the hatched brush if the thumb
2508 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2510 bool transpose
= orient
== wxVERTICAL
;
2512 wxCoord x
, y
, x2
, y2
;
2517 x2
= rect
.GetBottom();
2518 y2
= rect
.GetRight();
2524 x2
= rect
.GetRight();
2525 y2
= rect
.GetBottom();
2528 // the size of the pointed part of the thumb
2529 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2531 wxCoord x3
= x
+ sizeArrow
,
2532 y3
= y2
- sizeArrow
;
2534 dc
.SetPen(m_penHighlight
);
2535 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2536 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2537 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2539 dc
.SetPen(m_penBlack
);
2540 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2541 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2543 dc
.SetPen(m_penDarkGrey
);
2544 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2545 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2547 if ( flags
& wxCONTROL_PRESSED
)
2549 // TODO: MSW fills the entire area inside, not just the rect
2550 wxRect rectInt
= rect
;
2552 rectInt
.SetRight(y3
);
2554 rectInt
.SetBottom(y3
);
2557 #if !defined(__WXMGL__)
2558 static const char *stipple_xpm
[] = {
2559 /* columns rows colors chars-per-pixel */
2568 // VS: MGL can only do 8x8 stipple brushes
2569 static const char *stipple_xpm
[] = {
2570 /* columns rows colors chars-per-pixel */
2585 dc
.SetBrush(wxBrush(stipple_xpm
));
2587 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2588 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2589 dc
.SetPen(*wxTRANSPARENT_PEN
);
2590 dc
.DrawRectangle(rectInt
);
2594 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2596 const wxSize
& sizeThumb
,
2597 wxOrientation orient
,
2609 // the variable names correspond to horizontal case, but they can be used
2610 // for both orientations
2611 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2612 if ( orient
== wxHORIZONTAL
)
2614 x1
= rect
.GetLeft();
2615 x2
= rect
.GetRight();
2617 // draw from bottom to top to leave one pixel space between the ticks
2618 // and the slider as Windows do
2619 y1
= rect
.GetBottom();
2624 widthThumb
= sizeThumb
.x
;
2629 x2
= rect
.GetBottom();
2631 y1
= rect
.GetRight();
2632 y2
= rect
.GetLeft();
2636 widthThumb
= sizeThumb
.y
;
2639 // the first tick should be positioned in such way that a thumb drawn in
2640 // the first position points down directly to it
2641 x1
+= widthThumb
/ 2;
2642 x2
-= widthThumb
/ 2;
2644 // this also means that we have slightly less space for the ticks in
2645 // between the first and the last
2648 dc
.SetPen(m_penBlack
);
2650 int range
= end
- start
;
2651 for ( int n
= 0; n
< range
; n
+= step
)
2653 wxCoord x
= x1
+ (len
*n
) / range
;
2655 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2658 // always draw the line at the end position
2659 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2662 // ----------------------------------------------------------------------------
2664 // ----------------------------------------------------------------------------
2666 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2667 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2670 virtual wxSize
GetSize() const { return m_size
; }
2672 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2673 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2675 wxCoord
GetItemHeight() const { return m_heightItem
; }
2678 // the total size of the menu
2681 // the offset of the start of the menu item label
2684 // the offset of the start of the accel label
2687 // the height of a normal (not separator) item
2688 wxCoord m_heightItem
;
2690 friend wxMenuGeometryInfo
*
2691 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2694 // FIXME: all constants are hardcoded but shouldn't be
2695 static const wxCoord MENU_LEFT_MARGIN
= 9;
2696 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2697 static const wxCoord MENU_VERT_MARGIN
= 3;
2699 // the margin around bitmap/check marks (on each side)
2700 static const wxCoord MENU_BMP_MARGIN
= 2;
2702 // the margin between the labels and accel strings
2703 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2705 // the separator height in pixels: in fact, strangely enough, the real height
2706 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2708 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2710 // the size of the standard checkmark bitmap
2711 static const wxCoord MENU_CHECK_SIZE
= 9;
2713 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2714 const wxRect
& rectOrig
,
2715 const wxString
& label
,
2719 wxRect rect
= rectOrig
;
2722 wxDCTextColourChanger
colChanger(dc
);
2724 if ( flags
& wxCONTROL_SELECTED
)
2726 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2728 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2729 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2730 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2731 dc
.DrawRectangle(rect
);
2734 // don't draw the focus rect around menu bar items
2735 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2736 wxALIGN_CENTRE
, indexAccel
);
2739 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2741 const wxMenuGeometryInfo
& gi
,
2742 const wxString
& label
,
2743 const wxString
& accel
,
2744 const wxBitmap
& bitmap
,
2748 const wxWin32MenuGeometryInfo
& geometryInfo
=
2749 (const wxWin32MenuGeometryInfo
&)gi
;
2754 rect
.width
= geometryInfo
.GetSize().x
;
2755 rect
.height
= geometryInfo
.GetItemHeight();
2757 // draw the selected item specially
2758 wxDCTextColourChanger
colChanger(dc
);
2759 if ( flags
& wxCONTROL_SELECTED
)
2761 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2763 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2764 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2765 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2766 dc
.DrawRectangle(rect
);
2769 // draw the bitmap: use the bitmap provided or the standard checkmark for
2770 // the checkable items
2771 wxBitmap bmp
= bitmap
;
2772 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2774 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2779 rect
.SetRight(geometryInfo
.GetLabelOffset());
2780 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2784 rect
.x
= geometryInfo
.GetLabelOffset();
2785 rect
.SetRight(geometryInfo
.GetAccelOffset());
2787 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2789 // draw the accel string
2790 rect
.x
= geometryInfo
.GetAccelOffset();
2791 rect
.SetRight(geometryInfo
.GetSize().x
);
2793 // NB: no accel index here
2794 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2796 // draw the submenu indicator
2797 if ( flags
& wxCONTROL_ISSUBMENU
)
2799 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2800 rect
.width
= MENU_RIGHT_MARGIN
;
2802 wxArrowStyle arrowStyle
;
2803 if ( flags
& wxCONTROL_DISABLED
)
2804 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2806 else if ( flags
& wxCONTROL_SELECTED
)
2807 arrowStyle
= Arrow_Inversed
;
2809 arrowStyle
= Arrow_Normal
;
2811 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2815 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2817 const wxMenuGeometryInfo
& geomInfo
)
2819 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2822 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2824 wxSize size
= sizeText
;
2826 // FIXME: menubar height is configurable under Windows
2833 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2834 const wxMenu
& menu
) const
2836 // prepare the dc: for now we draw all the items with the system font
2838 dc
.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
2840 // the height of a normal item
2841 wxCoord heightText
= dc
.GetCharHeight();
2846 // the max length of label and accel strings: the menu width is the sum of
2847 // them, even if they're for different items (as the accels should be
2850 // the max length of the bitmap is never 0 as Windows always leaves enough
2851 // space for a check mark indicator
2852 wxCoord widthLabelMax
= 0,
2854 widthBmpMax
= MENU_LEFT_MARGIN
;
2856 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2858 node
= node
->GetNext() )
2860 // height of this item
2863 wxMenuItem
*item
= node
->GetData();
2864 if ( item
->IsSeparator() )
2866 h
= MENU_SEPARATOR_HEIGHT
;
2868 else // not separator
2873 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2874 if ( widthLabel
> widthLabelMax
)
2876 widthLabelMax
= widthLabel
;
2880 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2881 if ( widthAccel
> widthAccelMax
)
2883 widthAccelMax
= widthAccel
;
2886 const wxBitmap
& bmp
= item
->GetBitmap();
2889 wxCoord widthBmp
= bmp
.GetWidth();
2890 if ( widthBmp
> widthBmpMax
)
2891 widthBmpMax
= widthBmp
;
2893 //else if ( item->IsCheckable() ): no need to check for this as
2894 // MENU_LEFT_MARGIN is big enough to show the check mark
2897 h
+= 2*MENU_VERT_MARGIN
;
2899 // remember the item position and height
2900 item
->SetGeometry(height
, h
);
2905 // bundle the metrics into a struct and return it
2906 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2908 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2909 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2910 if ( widthAccelMax
> 0 )
2912 // if we actually have any accesl, add a margin
2913 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2916 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2918 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2919 gi
->m_size
.y
= height
;
2924 // ----------------------------------------------------------------------------
2926 // ----------------------------------------------------------------------------
2928 static const wxCoord STATBAR_BORDER_X
= 2;
2929 static const wxCoord STATBAR_BORDER_Y
= 2;
2931 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2933 if ( borderBetweenFields
)
2934 *borderBetweenFields
= 2;
2936 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2939 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2941 const wxString
& label
,
2946 if ( flags
& wxCONTROL_ISDEFAULT
)
2948 // draw the size grip: it is a normal rect except that in the lower
2949 // right corner we have several bands which may be used for dragging
2950 // the status bar corner
2952 // each band consists of 4 stripes: m_penHighlight, double
2953 // m_penDarkGrey and transparent one
2954 wxCoord x2
= rect
.GetRight(),
2955 y2
= rect
.GetBottom();
2957 // draw the upper left part of the rect normally
2958 dc
.SetPen(m_penDarkGrey
);
2959 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
2960 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
2962 // draw the grey stripes of the grip
2964 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
2965 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2967 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2968 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
2971 // draw the white stripes
2972 dc
.SetPen(m_penHighlight
);
2973 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
2974 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2976 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2979 // draw the remaining rect boundaries
2980 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
2981 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
2982 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
2987 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
2991 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
2994 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2996 wxDCClipper
clipper(dc
, rectIn
);
2997 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3000 // ----------------------------------------------------------------------------
3002 // ----------------------------------------------------------------------------
3004 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3006 wxBitmap
*bmpPressed
,
3007 wxBitmap
*bmpDisabled
)
3009 static const wxCoord widthCombo
= 16;
3010 static const wxCoord heightCombo
= 17;
3016 bmpNormal
->Create(widthCombo
, heightCombo
);
3017 dcMem
.SelectObject(*bmpNormal
);
3018 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3019 Arrow_Down
, Arrow_Normal
);
3024 bmpPressed
->Create(widthCombo
, heightCombo
);
3025 dcMem
.SelectObject(*bmpPressed
);
3026 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3027 Arrow_Down
, Arrow_Pressed
);
3032 bmpDisabled
->Create(widthCombo
, heightCombo
);
3033 dcMem
.SelectObject(*bmpDisabled
);
3034 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3035 Arrow_Down
, Arrow_Disabled
);
3039 // ----------------------------------------------------------------------------
3041 // ----------------------------------------------------------------------------
3043 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3044 const wxColour
& col
,
3047 wxBrush
brush(col
, wxSOLID
);
3049 dc
.SetPen(*wxTRANSPARENT_PEN
);
3050 dc
.DrawRectangle(rect
);
3053 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3054 const wxColour
& col
,
3058 // just fill it with the given or default bg colour
3059 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3060 DoDrawBackground(dc
, colBg
, rect
);
3063 // ----------------------------------------------------------------------------
3065 // ----------------------------------------------------------------------------
3067 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3072 // get the bitmap for this arrow
3073 wxArrowDirection arrowDir
;
3076 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3077 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3078 case wxUP
: arrowDir
= Arrow_Up
; break;
3079 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3082 wxFAIL_MSG(_T("unknown arrow direction"));
3086 wxArrowStyle arrowStyle
;
3087 if ( flags
& wxCONTROL_PRESSED
)
3089 // can't be pressed and disabled
3090 arrowStyle
= Arrow_Pressed
;
3094 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3097 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3100 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3102 wxArrowDirection arrowDir
,
3103 wxArrowStyle arrowStyle
)
3105 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3107 // under Windows the arrows always have the same size so just centre it in
3108 // the provided rectangle
3109 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3110 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3112 // Windows does it like this...
3113 if ( arrowDir
== Arrow_Left
)
3117 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3120 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3121 const wxRect
& rectAll
,
3122 wxArrowDirection arrowDir
,
3123 wxArrowStyle arrowStyle
)
3125 wxRect rect
= rectAll
;
3126 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3127 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3128 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3131 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3132 wxOrientation orient
,
3136 // we don't use the flags, the thumb never changes appearance
3137 wxRect rectThumb
= rect
;
3138 DrawArrowBorder(dc
, &rectThumb
);
3139 DrawBackground(dc
, wxNullColour
, rectThumb
);
3142 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3143 wxOrientation orient
,
3144 const wxRect
& rectBar
,
3147 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3148 ? wxColourScheme::SCROLLBAR_PRESSED
3149 : wxColourScheme::SCROLLBAR
;
3150 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3153 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3155 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3158 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3159 wxScrollBar::Element elem
,
3162 return StandardGetScrollbarRect(scrollbar
, elem
,
3163 thumbPos
, m_sizeScrollbarArrow
);
3166 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3168 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3171 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3172 const wxPoint
& pt
) const
3174 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3177 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3180 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3183 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3186 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3189 // ----------------------------------------------------------------------------
3190 // top level windows
3191 // ----------------------------------------------------------------------------
3193 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3195 wxRect client
= GetFrameClientArea(rect
, flags
);
3197 if ( client
.Inside(pt
) )
3198 return wxHT_TOPLEVEL_CLIENT_AREA
;
3200 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3202 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3204 if ( flags
& wxTOPLEVEL_ICON
)
3206 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3207 return wxHT_TOPLEVEL_ICON
;
3210 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3211 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3212 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3214 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3216 if ( btnRect
.Inside(pt
) )
3217 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3218 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3220 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3222 if ( btnRect
.Inside(pt
) )
3223 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3224 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3226 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3228 if ( btnRect
.Inside(pt
) )
3229 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3230 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3232 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3234 if ( btnRect
.Inside(pt
) )
3235 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3236 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3238 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3240 if ( btnRect
.Inside(pt
) )
3241 return wxHT_TOPLEVEL_BUTTON_HELP
;
3242 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3245 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3246 return wxHT_TOPLEVEL_TITLEBAR
;
3249 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3251 // we are certainly at one of borders, lets decide which one:
3254 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3255 if ( pt
.x
< client
.x
)
3256 border
|= wxHT_TOPLEVEL_BORDER_W
;
3257 else if ( pt
.x
>= client
.width
+ client
.x
)
3258 border
|= wxHT_TOPLEVEL_BORDER_E
;
3259 if ( pt
.y
< client
.y
)
3260 border
|= wxHT_TOPLEVEL_BORDER_N
;
3261 else if ( pt
.y
>= client
.height
+ client
.y
)
3262 border
|= wxHT_TOPLEVEL_BORDER_S
;
3266 return wxHT_NOWHERE
;
3269 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3271 const wxString
& title
,
3275 int specialButtonFlags
)
3277 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3279 DrawFrameBorder(dc
, rect
, flags
);
3281 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3283 DrawFrameBackground(dc
, rect
, flags
);
3284 if ( flags
& wxTOPLEVEL_ICON
)
3285 DrawFrameIcon(dc
, rect
, icon
, flags
);
3286 DrawFrameTitle(dc
, rect
, title
, flags
);
3288 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3290 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3291 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3293 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3295 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3296 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3297 specialButtonFlags
: 0);
3298 x
-= FRAME_BUTTON_WIDTH
+ 2;
3300 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3302 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3303 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3304 specialButtonFlags
: 0);
3305 x
-= FRAME_BUTTON_WIDTH
;
3307 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3309 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3310 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3311 specialButtonFlags
: 0);
3312 x
-= FRAME_BUTTON_WIDTH
;
3314 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3316 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3317 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3318 specialButtonFlags
: 0);
3319 x
-= FRAME_BUTTON_WIDTH
;
3321 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3323 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3324 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3325 specialButtonFlags
: 0);
3326 x
-= FRAME_BUTTON_WIDTH
;
3331 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3335 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3339 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3340 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3341 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3342 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3343 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3346 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3350 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3352 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3353 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3354 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3356 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3357 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3359 DrawBackground(dc
, col
, r
);
3362 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3364 const wxString
& title
,
3367 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3368 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3369 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3371 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3372 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3373 if ( flags
& wxTOPLEVEL_ICON
)
3374 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3378 dc
.SetFont(m_titlebarFont
);
3379 dc
.SetTextForeground(col
);
3380 dc
.DrawLabel(title
, wxNullBitmap
, r
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3383 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3390 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3391 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3395 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3396 wxCoord x
, wxCoord y
,
3400 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3405 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3406 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3407 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3408 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3409 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3411 wxFAIL_MSG(wxT("incorrect button specification"));
3414 if ( flags
& wxCONTROL_PRESSED
)
3416 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3417 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3418 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3419 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3423 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3424 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3425 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3426 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3431 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3436 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3438 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3439 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3440 FRAME_BORDER_THICKNESS
;
3443 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3445 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3446 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3452 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3455 wxSize
s(clientSize
);
3457 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3459 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3460 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3461 FRAME_BORDER_THICKNESS
;
3465 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3466 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3471 wxSize
wxWin32Renderer::GetFrameIconSize() const
3473 return wxSize(16, 16);
3477 // ----------------------------------------------------------------------------
3479 // ----------------------------------------------------------------------------
3481 static char *error_xpm
[]={
3488 "...........########.............",
3489 "........###aaaaaaaa###..........",
3490 ".......#aaaaaaaaaaaaaa#.........",
3491 ".....##aaaaaaaaaaaaaaaa##.......",
3492 "....#aaaaaaaaaaaaaaaaaaaa#......",
3493 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3494 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3495 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3496 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3497 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3498 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3499 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3500 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3501 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3502 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3503 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3504 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3505 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3506 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3507 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3508 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3509 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3510 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3511 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3512 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3513 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3514 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3515 "......b#aaaaaaaaaaaaaa#bbbbb....",
3516 ".......b###aaaaaaaa###bbbbb.....",
3517 ".........bb########bbbbbb.......",
3518 "..........bbbbbbbbbbbbbb........",
3519 ".............bbbbbbbb..........."};
3521 static char *info_xpm
[]={
3529 "...........########.............",
3530 "........###abbbbbba###..........",
3531 "......##abbbbbbbbbbbba##........",
3532 ".....#abbbbbbbbbbbbbbbba#.......",
3533 "....#bbbbbbbaccccabbbbbbbd......",
3534 "...#bbbbbbbbccccccbbbbbbbbd.....",
3535 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3536 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3537 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3538 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3539 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3540 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3541 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3542 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3543 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3544 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3545 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3546 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3547 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3548 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3549 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3550 ".....dabbbbbbbbbbbbbbbbad####...",
3551 "......ddabbbbbbbbbbbbadd####....",
3552 ".......#dddabbbbbbaddd#####.....",
3553 "........###dddabbbd#######......",
3554 "..........####dbbbd#####........",
3555 ".............#dbbbd##...........",
3556 "...............dbbd##...........",
3557 "................dbd##...........",
3558 ".................dd##...........",
3559 "..................###...........",
3560 "...................##..........."};
3562 static char *question_xpm
[]={
3570 "...........########.............",
3571 "........###abbbbbba###..........",
3572 "......##abbbbbbbbbbbba##........",
3573 ".....#abbbbbbbbbbbbbbbba#.......",
3574 "....#bbbbbbbbbbbbbbbbbbbbc......",
3575 "...#bbbbbbbaddddddabbbbbbbc.....",
3576 "..#bbbbbbbadabbddddabbbbbbbc....",
3577 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3578 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3579 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3580 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3581 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3582 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3583 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3584 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3585 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3586 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3587 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3588 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3589 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3590 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3591 ".....cabbbbbbbbbbbbbbbbac####...",
3592 "......ccabbbbbbbbbbbbacc####....",
3593 ".......#cccabbbbbbaccc#####.....",
3594 "........###cccabbbc#######......",
3595 "..........####cbbbc#####........",
3596 ".............#cbbbc##...........",
3597 "...............cbbc##...........",
3598 "................cbc##...........",
3599 ".................cc##...........",
3600 "..................###...........",
3601 "...................##..........."};
3603 static char *warning_xpm
[]={
3611 ".............###................",
3612 "............#aabc...............",
3613 "...........#aaaabcd.............",
3614 "...........#aaaaacdd............",
3615 "..........#aaaaaabcdd...........",
3616 "..........#aaaaaaacdd...........",
3617 ".........#aaaaaaaabcdd..........",
3618 ".........#aaaaaaaaacdd..........",
3619 "........#aaaaaaaaaabcdd.........",
3620 "........#aaabcccbaaacdd.........",
3621 ".......#aaaacccccaaabcdd........",
3622 ".......#aaaacccccaaaacdd........",
3623 "......#aaaaacccccaaaabcdd.......",
3624 "......#aaaaacccccaaaaacdd.......",
3625 ".....#aaaaaacccccaaaaabcdd......",
3626 ".....#aaaaaa#ccc#aaaaaacdd......",
3627 "....#aaaaaaabcccbaaaaaabcdd.....",
3628 "....#aaaaaaaacccaaaaaaaacdd.....",
3629 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3630 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3631 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3632 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3633 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3634 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3635 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3636 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3637 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3638 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3639 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3640 "..#ccccccccccccccccccccccccddddd",
3641 "....ddddddddddddddddddddddddddd.",
3642 ".....ddddddddddddddddddddddddd.."};
3644 wxIcon
wxWin32Renderer::GetStdIcon(int which
) const
3648 case wxICON_INFORMATION
:
3649 return wxIcon(info_xpm
);
3651 case wxICON_QUESTION
:
3652 return wxIcon(question_xpm
);
3654 case wxICON_EXCLAMATION
:
3655 return wxIcon(warning_xpm
);
3658 wxFAIL_MSG(wxT("requested non existent standard icon"));
3659 // still fall through
3662 return wxIcon(error_xpm
);
3667 // ----------------------------------------------------------------------------
3668 // text control geometry
3669 // ----------------------------------------------------------------------------
3671 static inline int GetTextBorderWidth()
3676 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3679 wxRect rectTotal
= rect
;
3681 wxCoord widthBorder
= GetTextBorderWidth();
3682 rectTotal
.Inflate(widthBorder
);
3684 // this is what Windows does
3690 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3692 wxCoord
*extraSpaceBeyond
)
3694 wxRect rectText
= rect
;
3696 // undo GetTextTotalArea()
3697 if ( rectText
.height
> 0 )
3700 wxCoord widthBorder
= GetTextBorderWidth();
3701 rectText
.Inflate(-widthBorder
);
3703 if ( extraSpaceBeyond
)
3704 *extraSpaceBeyond
= 0;
3709 // ----------------------------------------------------------------------------
3711 // ----------------------------------------------------------------------------
3713 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3716 if ( wxDynamicCast(window
, wxScrollBar
) )
3718 // we only set the width of vert scrollbars and height of the
3720 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3721 size
->y
= m_sizeScrollbarArrow
.y
;
3723 size
->x
= m_sizeScrollbarArrow
.x
;
3725 // skip border width adjustments, they don't make sense for us
3728 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3731 if ( wxDynamicCast(window
, wxButton
) )
3733 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3735 // TODO: don't harcode all this
3736 size
->x
+= 3*window
->GetCharWidth();
3738 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3739 if ( size
->y
< heightBtn
- 8 )
3740 size
->y
= heightBtn
;
3745 // no border width adjustments for buttons
3748 #endif // wxUSE_BUTTON
3750 // take into account the border width
3751 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3752 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3753 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3756 // ============================================================================
3758 // ============================================================================
3760 // ----------------------------------------------------------------------------
3761 // wxWin32InputHandler
3762 // ----------------------------------------------------------------------------
3764 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3766 m_renderer
= renderer
;
3769 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3770 const wxKeyEvent
& event
,
3776 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3777 const wxMouseEvent
& event
)
3779 // clicking on the control gives it focus
3780 if ( event
.ButtonDown() )
3782 wxWindow
*win
= control
->GetInputWindow();
3783 if ( wxWindow::FindFocus() != control
->GetInputWindow() )
3794 // ----------------------------------------------------------------------------
3795 // wxWin32ScrollBarInputHandler
3796 // ----------------------------------------------------------------------------
3798 wxWin32ScrollBarInputHandler::
3799 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3800 wxInputHandler
*handler
)
3801 : wxStdScrollBarInputHandler(renderer
, handler
)
3803 m_scrollPaused
= FALSE
;
3807 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3808 const wxControlAction
& action
)
3810 // stop if went beyond the position of the original click (this can only
3811 // happen when we scroll by pages)
3813 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3815 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3816 != wxHT_SCROLLBAR_BAR_2
;
3818 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3820 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3821 != wxHT_SCROLLBAR_BAR_1
;
3826 StopScrolling(scrollbar
);
3828 scrollbar
->Refresh();
3833 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3836 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3837 const wxMouseEvent
& event
)
3839 // remember the current state
3840 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3842 // do process the message
3843 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3845 // analyse the changes
3846 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3848 // we just started dragging the thumb, remember its initial position to
3849 // be able to restore it if the drag is cancelled later
3850 m_eventStartDrag
= event
;
3856 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3857 const wxMouseEvent
& event
)
3859 // we don't highlight scrollbar elements, so there is no need to process
3860 // mouse move events normally - only do it while mouse is captured (i.e.
3861 // when we're dragging the thumb or pressing on something)
3862 if ( !m_winCapture
)
3865 if ( event
.Entering() )
3867 // we're not interested in this at all
3871 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3873 if ( m_scrollPaused
)
3875 // check if the mouse returned to its original location
3877 if ( event
.Leaving() )
3883 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3884 if ( ht
== m_htLast
)
3886 // yes it did, resume scrolling
3887 m_scrollPaused
= FALSE
;
3888 if ( m_timerScroll
)
3890 // we were scrolling by line/page, restart timer
3891 m_timerScroll
->Start(m_interval
);
3893 Press(scrollbar
, TRUE
);
3895 else // we were dragging the thumb
3897 // restore its last location
3898 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3904 else // normal case, scrolling hasn't been paused
3906 // if we're scrolling the scrollbar because the arrow or the shaft was
3907 // pressed, check that the mouse stays on the same scrollbar element
3909 if ( event
.Moving() )
3911 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3913 else // event.Leaving()
3918 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3919 // is still ok - we only want to catch the case when the mouse leaves
3920 // the scrollbar here
3921 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3923 ht
= wxHT_SCROLLBAR_THUMB
;
3926 if ( ht
!= m_htLast
)
3928 // what were we doing? 2 possibilities: either an arrow/shaft was
3929 // pressed in which case we have a timer and so we just stop it or
3930 // we were dragging the thumb
3931 if ( m_timerScroll
)
3934 m_interval
= m_timerScroll
->GetInterval();
3935 m_timerScroll
->Stop();
3936 m_scrollPaused
= TRUE
;
3938 // unpress the arrow
3939 Press(scrollbar
, FALSE
);
3941 else // we were dragging the thumb
3943 // remember the current thumb position to be able to restore it
3944 // if the mouse returns to it later
3945 m_eventLastDrag
= event
;
3947 // and restore the original position (before dragging) of the
3949 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3956 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
3959 // ----------------------------------------------------------------------------
3960 // wxWin32CheckboxInputHandler
3961 // ----------------------------------------------------------------------------
3963 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3964 const wxKeyEvent
& event
,
3969 wxControlAction action
;
3970 int keycode
= event
.GetKeyCode();
3974 action
= wxACTION_CHECKBOX_TOGGLE
;
3978 case WXK_NUMPAD_SUBTRACT
:
3979 action
= wxACTION_CHECKBOX_CHECK
;
3983 case WXK_NUMPAD_ADD
:
3984 case WXK_NUMPAD_EQUAL
:
3985 action
= wxACTION_CHECKBOX_CLEAR
;
3991 control
->PerformAction(action
);
4000 // ----------------------------------------------------------------------------
4001 // wxWin32TextCtrlInputHandler
4002 // ----------------------------------------------------------------------------
4004 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4005 const wxKeyEvent
& event
,
4008 // handle only MSW-specific text bindings here, the others are handled in
4012 int keycode
= event
.GetKeyCode();
4014 wxControlAction action
;
4015 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4017 action
= wxACTION_TEXT_CUT
;
4019 else if ( keycode
== WXK_INSERT
)
4021 if ( event
.ControlDown() )
4022 action
= wxACTION_TEXT_COPY
;
4023 else if ( event
.ShiftDown() )
4024 action
= wxACTION_TEXT_PASTE
;
4027 if ( action
!= wxACTION_NONE
)
4029 control
->PerformAction(action
);
4035 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4038 // ----------------------------------------------------------------------------
4039 // wxWin32StatusBarInputHandler
4040 // ----------------------------------------------------------------------------
4042 wxWin32StatusBarInputHandler::
4043 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4044 : wxStdInputHandler(handler
)
4049 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4050 const wxPoint
& pt
) const
4052 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4053 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4055 wxSize sizeSbar
= statbar
->GetSize();
4057 return (sizeSbar
.x
- pt
.x
) < STATUSBAR_GRIP_SIZE
&&
4058 (sizeSbar
.y
- pt
.y
) < STATUSBAR_GRIP_SIZE
;
4064 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4065 const wxMouseEvent
& event
)
4067 if ( event
.Button(1) )
4069 if ( event
.ButtonDown(1) )
4071 wxWindow
*statbar
= consumer
->GetInputWindow();
4073 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4075 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4079 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4080 wxHT_TOPLEVEL_BORDER_SE
);
4082 statbar
->SetCursor(m_cursorOld
);
4090 return wxStdInputHandler::HandleMouse(consumer
, event
);
4093 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4094 const wxMouseEvent
& event
)
4096 wxWindow
*statbar
= consumer
->GetInputWindow();
4098 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4099 if ( isOnGrip
!= m_isOnGrip
)
4101 m_isOnGrip
= isOnGrip
;
4104 m_cursorOld
= statbar
->GetCursor();
4105 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4109 statbar
->SetCursor(m_cursorOld
);
4113 return wxStdInputHandler::HandleMouseMove(consumer
, event
);