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"
41 #include "wx/toolbar.h"
44 // for COLOR_* constants
45 #include "wx/msw/private.h"
49 #include "wx/notebook.h"
50 #include "wx/spinbutt.h"
51 #include "wx/settings.h"
54 #include "wx/univ/scrtimer.h"
55 #include "wx/toplevel.h"
56 #include "wx/univ/renderer.h"
57 #include "wx/univ/inphand.h"
58 #include "wx/univ/colschem.h"
59 #include "wx/univ/theme.h"
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 static const int BORDER_THICKNESS
= 2;
67 // the offset between the label and focus rect around it
68 static const int FOCUS_RECT_OFFSET_X
= 1;
69 static const int FOCUS_RECT_OFFSET_Y
= 1;
71 static const int FRAME_BORDER_THICKNESS
= 3;
72 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
73 static const int FRAME_TITLEBAR_HEIGHT
= 18;
74 static const int FRAME_BUTTON_WIDTH
= 16;
75 static const int FRAME_BUTTON_HEIGHT
= 14;
77 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
78 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
79 static const size_t STATUSBAR_GRIP_SIZE
=
80 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
92 IndicatorState_Normal
,
93 IndicatorState_Pressed
, // this one is for check/radioboxes
94 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
95 IndicatorState_Disabled
,
96 IndicatorState_SelectedDisabled
, // only for the menus
102 IndicatorStatus_Checked
,
103 IndicatorStatus_Unchecked
,
107 // wxWin32Renderer: draw the GUI elements in Win32 style
108 // ----------------------------------------------------------------------------
110 class wxWin32Renderer
: public wxRenderer
114 enum wxArrowDirection
129 Arrow_InversedDisabled
,
133 enum wxFrameButtonType
136 FrameButton_Minimize
,
137 FrameButton_Maximize
,
144 wxWin32Renderer(const wxColourScheme
*scheme
);
146 // implement the base class pure virtuals
147 virtual void DrawBackground(wxDC
& dc
,
151 virtual void DrawLabel(wxDC
& dc
,
152 const wxString
& label
,
155 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
157 wxRect
*rectBounds
= NULL
);
158 virtual void DrawButtonLabel(wxDC
& dc
,
159 const wxString
& label
,
160 const wxBitmap
& image
,
163 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
165 wxRect
*rectBounds
= NULL
);
166 virtual void DrawBorder(wxDC
& dc
,
170 wxRect
*rectIn
= (wxRect
*)NULL
);
171 virtual void DrawHorizontalLine(wxDC
& dc
,
172 wxCoord y
, wxCoord x1
, wxCoord x2
);
173 virtual void DrawVerticalLine(wxDC
& dc
,
174 wxCoord x
, wxCoord y1
, wxCoord y2
);
175 virtual void DrawFrame(wxDC
& dc
,
176 const wxString
& label
,
179 int alignment
= wxALIGN_LEFT
,
180 int indexAccel
= -1);
181 virtual void DrawTextBorder(wxDC
& dc
,
185 wxRect
*rectIn
= (wxRect
*)NULL
);
186 virtual void DrawButtonBorder(wxDC
& dc
,
189 wxRect
*rectIn
= (wxRect
*)NULL
);
190 virtual void DrawArrow(wxDC
& dc
,
194 virtual void DrawScrollbarArrow(wxDC
& dc
,
198 { DrawArrow(dc
, dir
, rect
, flags
); }
199 virtual void DrawScrollbarThumb(wxDC
& dc
,
200 wxOrientation orient
,
203 virtual void DrawScrollbarShaft(wxDC
& dc
,
204 wxOrientation orient
,
207 virtual void DrawScrollCorner(wxDC
& dc
,
209 virtual void DrawItem(wxDC
& dc
,
210 const wxString
& label
,
213 virtual void DrawCheckItem(wxDC
& dc
,
214 const wxString
& label
,
215 const wxBitmap
& bitmap
,
218 virtual void DrawCheckButton(wxDC
& dc
,
219 const wxString
& label
,
220 const wxBitmap
& bitmap
,
223 wxAlignment align
= wxALIGN_LEFT
,
224 int indexAccel
= -1);
225 virtual void DrawRadioButton(wxDC
& dc
,
226 const wxString
& label
,
227 const wxBitmap
& bitmap
,
230 wxAlignment align
= wxALIGN_LEFT
,
231 int indexAccel
= -1);
232 virtual void DrawToolBarButton(wxDC
& dc
,
233 const wxString
& label
,
234 const wxBitmap
& bitmap
,
237 virtual void DrawTextLine(wxDC
& dc
,
238 const wxString
& text
,
243 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
244 virtual void DrawTab(wxDC
& dc
,
247 const wxString
& label
,
248 const wxBitmap
& bitmap
= wxNullBitmap
,
250 int indexAccel
= -1);
252 virtual void DrawSliderShaft(wxDC
& dc
,
254 wxOrientation orient
,
256 wxRect
*rectShaft
= NULL
);
257 virtual void DrawSliderThumb(wxDC
& dc
,
259 wxOrientation orient
,
261 virtual void DrawSliderTicks(wxDC
& dc
,
263 const wxSize
& sizeThumb
,
264 wxOrientation orient
,
270 virtual void DrawMenuBarItem(wxDC
& dc
,
272 const wxString
& label
,
274 int indexAccel
= -1);
275 virtual void DrawMenuItem(wxDC
& dc
,
277 const wxMenuGeometryInfo
& geometryInfo
,
278 const wxString
& label
,
279 const wxString
& accel
,
280 const wxBitmap
& bitmap
= wxNullBitmap
,
282 int indexAccel
= -1);
283 virtual void DrawMenuSeparator(wxDC
& dc
,
285 const wxMenuGeometryInfo
& geomInfo
);
287 virtual void DrawStatusField(wxDC
& dc
,
289 const wxString
& label
,
293 virtual void DrawFrameTitleBar(wxDC
& dc
,
295 const wxString
& title
,
298 int specialButton
= 0,
299 int specialButtonFlags
= 0);
300 virtual void DrawFrameBorder(wxDC
& dc
,
303 virtual void DrawFrameBackground(wxDC
& dc
,
306 virtual void DrawFrameTitle(wxDC
& dc
,
308 const wxString
& title
,
310 virtual void DrawFrameIcon(wxDC
& dc
,
314 virtual void DrawFrameButton(wxDC
& dc
,
315 wxCoord x
, wxCoord y
,
318 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
319 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
320 virtual wxSize
GetFrameMinSize(int flags
) const;
321 virtual wxSize
GetFrameIconSize() const;
322 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
324 virtual wxIcon
GetStdIcon(int which
) const;
326 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
328 wxBitmap
*bmpPressed
,
329 wxBitmap
*bmpDisabled
);
331 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
332 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
333 virtual bool AreScrollbarsInsideBorder() const;
335 virtual wxSize
GetScrollbarArrowSize() const
336 { return m_sizeScrollbarArrow
; }
337 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
338 wxScrollBar::Element elem
,
339 int thumbPos
= -1) const;
340 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
341 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
342 const wxPoint
& pt
) const;
343 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
345 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
346 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
347 { return fontHeight
+ 2; }
348 virtual wxSize
GetCheckBitmapSize() const
349 { return wxSize(13, 13); }
350 virtual wxSize
GetRadioBitmapSize() const
351 { return wxSize(12, 12); }
352 virtual wxCoord
GetCheckItemMargin() const
355 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
356 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
357 virtual wxSize
GetToolBarMargin() const
358 { return wxSize(6, 6); }
360 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
361 const wxRect
& rect
) const;
362 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
364 wxCoord
*extraSpaceBeyond
) const;
366 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
367 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
369 virtual wxCoord
GetSliderDim() const { return 20; }
370 virtual wxCoord
GetSliderTickLen() const { return 4; }
371 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
372 wxOrientation orient
) const;
373 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
374 wxOrientation orient
) const;
375 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
377 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
378 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
379 const wxMenu
& menu
) const;
381 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
384 // helper of DrawLabel() and DrawCheckOrRadioButton()
385 void DoDrawLabel(wxDC
& dc
,
386 const wxString
& label
,
389 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
391 wxRect
*rectBounds
= NULL
,
392 const wxPoint
& focusOffset
393 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
395 // common part of DrawLabel() and DrawItem()
396 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
398 // DrawLabel() and DrawButtonLabel() helper
399 void DrawLabelShadow(wxDC
& dc
,
400 const wxString
& label
,
405 // DrawButtonBorder() helper
406 void DoDrawBackground(wxDC
& dc
,
410 // DrawBorder() helpers: all of them shift and clip the DC after drawing
413 // just draw a rectangle with the given pen
414 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
416 // draw the lower left part of rectangle
417 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
419 // draw the rectange using the first brush for the left and top sides and
420 // the second one for the bottom and right ones
421 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
422 const wxPen
& pen1
, const wxPen
& pen2
);
424 // draw the normal 3D border
425 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
427 // draw the sunken 3D border
428 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
430 // draw the border used for scrollbar arrows
431 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
433 // public DrawArrow()s helper
434 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
435 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
437 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
438 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
439 wxArrowDirection arrowDir
,
440 wxArrowStyle arrowStyle
);
442 // DrawCheckButton/DrawRadioButton helper
443 void DrawCheckOrRadioButton(wxDC
& dc
,
444 const wxString
& label
,
445 const wxBitmap
& bitmap
,
450 wxCoord focusOffsetY
);
452 // draw a normal or transposed line (useful for using the same code fo both
453 // horizontal and vertical widgets)
454 void DrawLine(wxDC
& dc
,
455 wxCoord x1
, wxCoord y1
,
456 wxCoord x2
, wxCoord y2
,
457 bool transpose
= FALSE
)
460 dc
.DrawLine(y1
, x1
, y2
, x2
);
462 dc
.DrawLine(x1
, y1
, x2
, y2
);
465 // get the standard check/radio button bitmap
466 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
467 wxBitmap
GetCheckBitmap(int flags
)
468 { return GetIndicator(IndicatorType_Check
, flags
); }
469 wxBitmap
GetRadioBitmap(int flags
)
470 { return GetIndicator(IndicatorType_Radio
, flags
); }
473 const wxColourScheme
*m_scheme
;
475 // the sizing parameters (TODO make them changeable)
476 wxSize m_sizeScrollbarArrow
;
478 // GDI objects we use for drawing
479 wxColour m_colDarkGrey
,
487 wxFont m_titlebarFont
;
489 // the checked and unchecked bitmaps for DrawCheckItem()
490 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
492 // the bitmaps returned by GetIndicator()
493 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
495 [IndicatorStatus_Max
];
498 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
500 // first row is for the normal state, second - for the disabled
501 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
504 // ----------------------------------------------------------------------------
505 // wxWin32InputHandler and derived classes: process the keyboard and mouse
506 // messages according to Windows standards
507 // ----------------------------------------------------------------------------
509 class wxWin32InputHandler
: public wxInputHandler
512 wxWin32InputHandler(wxWin32Renderer
*renderer
);
514 virtual bool HandleKey(wxInputConsumer
*control
,
515 const wxKeyEvent
& event
,
517 virtual bool HandleMouse(wxInputConsumer
*control
,
518 const wxMouseEvent
& event
);
521 wxWin32Renderer
*m_renderer
;
524 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
527 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
528 wxInputHandler
*handler
);
530 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
531 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
533 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
534 const wxControlAction
& action
);
537 virtual bool IsAllowedButton(int button
) { return button
== 1; }
539 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
541 // we don't highlight anything
544 // the first and last event which caused the thumb to move
545 wxMouseEvent m_eventStartDrag
,
548 // have we paused the scrolling because the mouse moved?
551 // we remember the interval of the timer to be able to restart it
555 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
558 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
559 : wxStdCheckboxInputHandler(handler
) { }
561 virtual bool HandleKey(wxInputConsumer
*control
,
562 const wxKeyEvent
& event
,
566 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
569 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
570 : wxStdTextCtrlInputHandler(handler
) { }
572 virtual bool HandleKey(wxInputConsumer
*control
,
573 const wxKeyEvent
& event
,
577 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
580 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
582 virtual bool HandleMouse(wxInputConsumer
*consumer
,
583 const wxMouseEvent
& event
);
585 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
586 const wxMouseEvent
& event
);
589 // is the given point over the statusbar grip?
590 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
593 // the cursor we had replaced with the resize one
594 wxCursor m_cursorOld
;
596 // was the mouse over the grip last time we checked?
600 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
603 wxWin32FrameInputHandler(wxInputHandler
*handler
)
604 : wxStdFrameInputHandler(handler
) { }
606 virtual bool HandleMouse(wxInputConsumer
*control
,
607 const wxMouseEvent
& event
);
610 // ----------------------------------------------------------------------------
611 // wxWin32ColourScheme: uses (default) Win32 colours
612 // ----------------------------------------------------------------------------
614 class wxWin32ColourScheme
: public wxColourScheme
617 virtual wxColour
Get(StdColour col
) const;
618 virtual wxColour
GetBackground(wxWindow
*win
) const;
621 // ----------------------------------------------------------------------------
623 // ----------------------------------------------------------------------------
625 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
627 class wxWin32Theme
: public wxTheme
631 virtual ~wxWin32Theme();
633 virtual wxRenderer
*GetRenderer();
634 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
635 virtual wxColourScheme
*GetColourScheme();
638 // get the default input handler
639 wxInputHandler
*GetDefaultInputHandler();
641 wxWin32Renderer
*m_renderer
;
643 // the names of the already created handlers and the handlers themselves
644 // (these arrays are synchronized)
645 wxSortedArrayString m_handlerNames
;
646 wxArrayHandlers m_handlers
;
648 wxWin32InputHandler
*m_handlerDefault
;
650 wxWin32ColourScheme
*m_scheme
;
652 WX_DECLARE_THEME(win32
)
655 // ----------------------------------------------------------------------------
657 // ----------------------------------------------------------------------------
659 // frame buttons bitmaps
661 static const char *frame_button_close_xpm
[] = {
676 static const char *frame_button_help_xpm
[] = {
691 static const char *frame_button_maximize_xpm
[] = {
706 static const char *frame_button_minimize_xpm
[] = {
721 static const char *frame_button_restore_xpm
[] = {
738 static const char *checked_menu_xpm
[] = {
739 /* columns rows colors chars-per-pixel */
755 static const char *selected_checked_menu_xpm
[] = {
756 /* columns rows colors chars-per-pixel */
772 static const char *disabled_checked_menu_xpm
[] = {
773 /* columns rows colors chars-per-pixel */
790 static const char *selected_disabled_checked_menu_xpm
[] = {
791 /* columns rows colors chars-per-pixel */
807 // checkbox and radiobox bitmaps below
809 static const char *checked_xpm
[] = {
810 /* columns rows colors chars-per-pixel */
833 static const char *pressed_checked_xpm
[] = {
834 /* columns rows colors chars-per-pixel */
856 static const char *pressed_disabled_checked_xpm
[] = {
857 /* columns rows colors chars-per-pixel */
879 static const char *checked_item_xpm
[] = {
880 /* columns rows colors chars-per-pixel */
901 static const char *unchecked_xpm
[] = {
902 /* columns rows colors chars-per-pixel */
925 static const char *pressed_unchecked_xpm
[] = {
926 /* columns rows colors chars-per-pixel */
948 static const char *unchecked_item_xpm
[] = {
949 /* columns rows colors chars-per-pixel */
969 static const char *checked_radio_xpm
[] = {
970 /* columns rows colors chars-per-pixel */
993 static const char *pressed_checked_radio_xpm
[] = {
994 /* columns rows colors chars-per-pixel */
1017 static const char *pressed_disabled_checked_radio_xpm
[] = {
1018 /* columns rows colors chars-per-pixel */
1041 static const char *unchecked_radio_xpm
[] = {
1042 /* columns rows colors chars-per-pixel */
1065 static const char *pressed_unchecked_radio_xpm
[] = {
1066 /* columns rows colors chars-per-pixel */
1089 static const char **
1090 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1095 { checked_xpm
, unchecked_xpm
},
1098 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1101 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1107 { checked_radio_xpm
, unchecked_radio_xpm
},
1110 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1113 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1119 { checked_menu_xpm
, NULL
},
1122 { selected_checked_menu_xpm
, NULL
},
1125 { disabled_checked_menu_xpm
, NULL
},
1127 // disabled selected state
1128 { selected_disabled_checked_menu_xpm
, NULL
},
1132 static const char **xpmChecked
[IndicatorStatus_Max
] =
1138 // ============================================================================
1140 // ============================================================================
1142 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1144 // ----------------------------------------------------------------------------
1146 // ----------------------------------------------------------------------------
1148 wxWin32Theme::wxWin32Theme()
1152 m_handlerDefault
= NULL
;
1155 wxWin32Theme::~wxWin32Theme()
1157 size_t count
= m_handlers
.GetCount();
1158 for ( size_t n
= 0; n
< count
; n
++ )
1160 if ( m_handlers
[n
] != m_handlerDefault
)
1161 delete m_handlers
[n
];
1164 delete m_handlerDefault
;
1170 wxRenderer
*wxWin32Theme::GetRenderer()
1174 m_renderer
= new wxWin32Renderer(GetColourScheme());
1180 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1182 if ( !m_handlerDefault
)
1184 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1187 return m_handlerDefault
;
1190 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1192 wxInputHandler
*handler
;
1193 int n
= m_handlerNames
.Index(control
);
1194 if ( n
== wxNOT_FOUND
)
1196 // create a new handler
1197 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1198 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1199 GetDefaultInputHandler());
1201 else if ( control
== wxINP_HANDLER_BUTTON
)
1202 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1203 #endif // wxUSE_BUTTON
1205 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1206 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1207 #endif // wxUSE_CHECKBOX
1209 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1210 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1211 #endif // wxUSE_COMBOBOX
1213 else if ( control
== wxINP_HANDLER_LISTBOX
)
1214 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1215 #endif // wxUSE_LISTBOX
1216 #if wxUSE_CHECKLISTBOX
1217 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1218 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1219 #endif // wxUSE_CHECKLISTBOX
1221 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1222 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1223 #endif // wxUSE_TEXTCTRL
1225 else if ( control
== wxINP_HANDLER_SLIDER
)
1226 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1227 #endif // wxUSE_SLIDER
1229 else if ( control
== wxINP_HANDLER_SPINBTN
)
1230 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1231 #endif // wxUSE_SPINBTN
1233 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1234 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1235 #endif // wxUSE_NOTEBOOK
1237 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1238 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1239 #endif // wxUSE_STATUSBAR
1241 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1242 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1243 #endif // wxUSE_TOOLBAR
1244 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1245 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1247 handler
= GetDefaultInputHandler();
1249 n
= m_handlerNames
.Add(control
);
1250 m_handlers
.Insert(handler
, n
);
1252 else // we already have it
1254 handler
= m_handlers
[n
];
1260 wxColourScheme
*wxWin32Theme::GetColourScheme()
1264 m_scheme
= new wxWin32ColourScheme
;
1269 // ============================================================================
1270 // wxWin32ColourScheme
1271 // ============================================================================
1273 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1276 if ( win
->UseBgCol() )
1278 // use the user specified colour
1279 col
= win
->GetBackgroundColour();
1282 if ( win
->IsContainerWindow() )
1284 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1287 if ( !text
->IsEnabled() ) // not IsEditable()
1289 //else: execute code below
1294 // doesn't depend on the state
1300 int flags
= win
->GetStateFlags();
1302 // the colour set by the user should be used for the normal state
1303 // and for the states for which we don't have any specific colours
1304 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1306 if ( wxDynamicCast(win
, wxScrollBar
) )
1307 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1317 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1321 // use the system colours under Windows
1322 #if defined(__WXMSW__)
1323 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1325 case CONTROL_PRESSED
:
1326 case CONTROL_CURRENT
:
1327 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1329 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1331 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_SCROLLBAR
));
1332 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1334 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1335 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1337 #if defined(COLOR_3DDKSHADOW)
1338 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1340 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1343 case CONTROL_TEXT_DISABLED
:
1344 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1346 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1348 case CONTROL_TEXT_DISABLED_SHADOW
:
1349 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1351 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1352 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1353 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1354 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1356 case DESKTOP
: return wxColour(0x808000);
1358 // use the standard Windows colours elsewhere
1359 case WINDOW
: return *wxWHITE
;
1361 case CONTROL_PRESSED
:
1362 case CONTROL_CURRENT
:
1363 case CONTROL
: return wxColour(0xc0c0c0);
1365 case CONTROL_TEXT
: return *wxBLACK
;
1367 case SCROLLBAR
: return wxColour(0xe0e0e0);
1368 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1370 case HIGHLIGHT
: return wxColour(0x800000);
1371 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1373 case SHADOW_DARK
: return *wxBLACK
;
1375 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1376 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1378 case SHADOW_IN
: return wxColour(0xc0c0c0);
1380 case CONTROL_TEXT_DISABLED_SHADOW
:
1381 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1383 case TITLEBAR
: return wxColour(0xaeaaae);
1384 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1385 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1386 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1388 case DESKTOP
: return wxColour(0x808000);
1391 case GAUGE
: return Get(HIGHLIGHT
);
1395 wxFAIL_MSG(_T("invalid standard colour"));
1400 // ============================================================================
1402 // ============================================================================
1404 // ----------------------------------------------------------------------------
1406 // ----------------------------------------------------------------------------
1408 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1412 m_sizeScrollbarArrow
= wxSize(16, 16);
1414 // init colours and pens
1415 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1417 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1418 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1420 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1422 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1423 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1425 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1426 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1428 // init the arrow bitmaps
1429 static const size_t ARROW_WIDTH
= 7;
1430 static const size_t ARROW_LENGTH
= 4;
1433 wxMemoryDC dcNormal
,
1436 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1438 bool isVertical
= n
> Arrow_Right
;
1451 // disabled arrow is larger because of the shadow
1452 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1453 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1455 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1456 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1458 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1459 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1463 dcNormal
.SetPen(m_penBlack
);
1464 dcDisabled
.SetPen(m_penDarkGrey
);
1466 // calculate the position of the point of the arrow
1470 x1
= (ARROW_WIDTH
- 1)/2;
1471 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1475 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1476 y1
= (ARROW_WIDTH
- 1)/2;
1487 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1489 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1490 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1497 if ( n
== Arrow_Up
)
1508 else // left or right arrow
1513 if ( n
== Arrow_Left
)
1526 // draw the shadow for the disabled one
1527 dcDisabled
.SetPen(m_penHighlight
);
1532 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1536 x1
= ARROW_LENGTH
- 1;
1537 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1540 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1541 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1546 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1550 x1
= ARROW_WIDTH
- 1;
1552 x2
= (ARROW_WIDTH
- 1)/2;
1554 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1555 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1560 // create the inversed bitmap but only for the right arrow as we only
1561 // use it for the menus
1562 if ( n
== Arrow_Right
)
1564 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1565 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1567 dcInverse
.Blit(0, 0, w
, h
,
1570 dcInverse
.SelectObject(wxNullBitmap
);
1572 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1573 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1575 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1576 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1578 dcInverse
.Blit(0, 0, w
, h
,
1581 dcInverse
.SelectObject(wxNullBitmap
);
1583 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1584 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1587 dcNormal
.SelectObject(wxNullBitmap
);
1588 dcDisabled
.SelectObject(wxNullBitmap
);
1590 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1591 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1592 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1593 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1595 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1598 // init the frame buttons bitmaps
1599 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1600 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1601 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1602 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1603 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1606 // ----------------------------------------------------------------------------
1608 // ----------------------------------------------------------------------------
1611 The raised border in Win32 looks like this:
1613 IIIIIIIIIIIIIIIIIIIIIIB
1615 I GB I = white (HILIGHT)
1616 I GB H = light grey (LIGHT)
1617 I GB G = dark grey (SHADOI)
1618 I GB B = black (DKSHADOI)
1619 I GB I = hIghlight (COLOR_3DHILIGHT)
1621 IGGGGGGGGGGGGGGGGGGGGGB
1622 BBBBBBBBBBBBBBBBBBBBBBB
1624 The sunken border looks like this:
1626 GGGGGGGGGGGGGGGGGGGGGGI
1627 GBBBBBBBBBBBBBBBBBBBBHI
1634 GHHHHHHHHHHHHHHHHHHHHHI
1635 IIIIIIIIIIIIIIIIIIIIIII
1637 The static border (used for the controls which don't get focus) is like
1640 GGGGGGGGGGGGGGGGGGGGGGW
1648 WWWWWWWWWWWWWWWWWWWWWWW
1650 The most complicated is the double border:
1652 HHHHHHHHHHHHHHHHHHHHHHB
1653 HWWWWWWWWWWWWWWWWWWWWGB
1654 HWHHHHHHHHHHHHHHHHHHHGB
1659 HWHHHHHHHHHHHHHHHHHHHGB
1660 HGGGGGGGGGGGGGGGGGGGGGB
1661 BBBBBBBBBBBBBBBBBBBBBBB
1663 And the simple border is, well, simple:
1665 BBBBBBBBBBBBBBBBBBBBBBB
1674 BBBBBBBBBBBBBBBBBBBBBBB
1677 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1681 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1682 dc
.DrawRectangle(*rect
);
1688 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1690 // draw the bottom and right sides
1692 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1693 rect
->GetRight() + 1, rect
->GetBottom());
1694 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1695 rect
->GetRight(), rect
->GetBottom());
1702 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1703 const wxPen
& pen1
, const wxPen
& pen2
)
1705 // draw the rectangle
1707 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1708 rect
->GetLeft(), rect
->GetBottom());
1709 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1710 rect
->GetRight(), rect
->GetTop());
1712 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1713 rect
->GetRight(), rect
->GetBottom());
1714 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1715 rect
->GetRight() + 1, rect
->GetBottom());
1721 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1723 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1724 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1727 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1729 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1730 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1733 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1737 DrawRect(dc
, rect
, m_penDarkGrey
);
1739 // the arrow is usually drawn inside border of width 2 and is offset by
1740 // another pixel in both directions when it's pressed - as the border
1741 // in this case is more narrow as well, we have to adjust rect like
1749 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1750 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1754 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1756 const wxRect
& rectTotal
,
1757 int WXUNUSED(flags
),
1762 wxRect rect
= rectTotal
;
1766 case wxBORDER_SUNKEN
:
1767 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1769 DrawSunkenBorder(dc
, &rect
);
1773 case wxBORDER_STATIC
:
1774 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1777 case wxBORDER_RAISED
:
1778 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1780 DrawRaisedBorder(dc
, &rect
);
1784 case wxBORDER_DOUBLE
:
1785 DrawArrowBorder(dc
, &rect
);
1786 DrawRect(dc
, &rect
, m_penLightGrey
);
1789 case wxBORDER_SIMPLE
:
1790 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1792 DrawRect(dc
, &rect
, m_penBlack
);
1797 wxFAIL_MSG(_T("unknown border type"));
1800 case wxBORDER_DEFAULT
:
1809 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1814 case wxBORDER_RAISED
:
1815 case wxBORDER_SUNKEN
:
1816 width
= BORDER_THICKNESS
;
1819 case wxBORDER_SIMPLE
:
1820 case wxBORDER_STATIC
:
1824 case wxBORDER_DOUBLE
:
1829 wxFAIL_MSG(_T("unknown border type"));
1832 case wxBORDER_DEFAULT
:
1842 rect
.height
= width
;
1847 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1852 // ----------------------------------------------------------------------------
1854 // ----------------------------------------------------------------------------
1856 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1862 // text controls are not special under windows
1863 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1866 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1867 const wxRect
& rectTotal
,
1871 wxRect rect
= rectTotal
;
1873 if ( flags
& wxCONTROL_PRESSED
)
1875 // button pressed: draw a double border around it
1876 DrawRect(dc
, &rect
, m_penBlack
);
1877 DrawRect(dc
, &rect
, m_penDarkGrey
);
1881 // button not pressed
1883 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1885 // button either default or focused (or both): add an extra border around it
1886 DrawRect(dc
, &rect
, m_penBlack
);
1889 // now draw a normal button
1890 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1891 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1900 // ----------------------------------------------------------------------------
1902 // ----------------------------------------------------------------------------
1904 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1905 wxCoord y
, wxCoord x1
, wxCoord x2
)
1907 dc
.SetPen(m_penDarkGrey
);
1908 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1909 dc
.SetPen(m_penHighlight
);
1911 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1914 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1915 wxCoord x
, wxCoord y1
, wxCoord y2
)
1917 dc
.SetPen(m_penDarkGrey
);
1918 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1919 dc
.SetPen(m_penHighlight
);
1921 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1924 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1925 const wxString
& label
,
1931 wxCoord height
= 0; // of the label
1932 wxRect rectFrame
= rect
;
1933 if ( !label
.empty() )
1935 // the text should touch the top border of the rect, so the frame
1936 // itself should be lower
1937 dc
.GetTextExtent(label
, NULL
, &height
);
1938 rectFrame
.y
+= height
/ 2;
1939 rectFrame
.height
-= height
/ 2;
1941 // we have to draw each part of the frame individually as we can't
1942 // erase the background beyond the label as it might contain some
1943 // pixmap already, so drawing everything and then overwriting part of
1944 // the frame with label doesn't work
1946 // TODO: the +5 and space insertion should be customizable
1949 rectText
.x
= rectFrame
.x
+ 5;
1950 rectText
.y
= rect
.y
;
1951 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1952 rectText
.height
= height
;
1955 label2
<< _T(' ') << label
<< _T(' ');
1956 if ( indexAccel
!= -1 )
1958 // adjust it as we prepended a space
1963 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
1965 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
1969 // just draw the complete frame
1970 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
1971 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
1975 // ----------------------------------------------------------------------------
1977 // ----------------------------------------------------------------------------
1979 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
1981 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
1982 // pixels each while we really need dots here... PS_ALTERNATE might
1983 // work, but it is for NT 5 only
1985 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
1987 // draw the pixels manually: note that to behave in the same manner as
1988 // DrawRect(), we must exclude the bottom and right borders from the
1990 wxCoord x1
= rect
.GetLeft(),
1992 x2
= rect
.GetRight(),
1993 y2
= rect
.GetBottom();
1995 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
1997 // this seems to be closer than what Windows does than wxINVERT although
1998 // I'm still not sure if it's correct
1999 dc
.SetLogicalFunction(wxAND_REVERSE
);
2002 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2003 dc
.DrawPoint(z
, rect
.GetTop());
2005 wxCoord shift
= z
== x2
? 0 : 1;
2006 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2007 dc
.DrawPoint(x2
, z
);
2009 shift
= z
== y2
? 0 : 1;
2010 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2011 dc
.DrawPoint(z
, y2
);
2013 shift
= z
== x1
? 0 : 1;
2014 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2015 dc
.DrawPoint(x1
, z
);
2017 dc
.SetLogicalFunction(wxCOPY
);
2021 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2022 const wxString
& label
,
2027 // draw shadow of the text
2028 dc
.SetTextForeground(m_colHighlight
);
2029 wxRect rectShadow
= rect
;
2032 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2034 // make the text grey
2035 dc
.SetTextForeground(m_colDarkGrey
);
2038 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2039 const wxString
& label
,
2046 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2049 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2050 const wxString
& label
,
2056 const wxPoint
& focusOffset
)
2058 // the underscores are not drawn for focused controls in wxMSW
2059 if ( flags
& wxCONTROL_FOCUSED
)
2064 if ( flags
& wxCONTROL_DISABLED
)
2066 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2067 // currently only can happen for a menu item and it seems that Windows
2068 // doesn't draw the shadow in this case, so we don't do it neither
2069 if ( flags
& wxCONTROL_SELECTED
)
2071 // just make the label text greyed out
2072 dc
.SetTextForeground(m_colDarkGrey
);
2074 else // draw normal disabled label
2076 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2081 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2083 if ( flags
& wxCONTROL_DISABLED
)
2085 // restore the fg colour
2086 dc
.SetTextForeground(*wxBLACK
);
2089 if ( flags
& wxCONTROL_FOCUSED
)
2091 if ( focusOffset
.x
|| focusOffset
.y
)
2093 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2096 DrawFocusRect(dc
, rectLabel
);
2100 *rectBounds
= rectLabel
;
2103 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2104 const wxString
& label
,
2105 const wxBitmap
& image
,
2112 // the underscores are not drawn for focused controls in wxMSW
2113 if ( flags
& wxCONTROL_PRESSED
)
2118 wxRect rectLabel
= rect
;
2119 if ( !label
.empty() )
2121 // shift the label if a button is pressed
2122 if ( flags
& wxCONTROL_PRESSED
)
2128 if ( flags
& wxCONTROL_DISABLED
)
2130 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2133 // leave enough space for the focus rectangle
2134 if ( flags
& wxCONTROL_FOCUSED
)
2136 rectLabel
.Inflate(-2);
2140 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2142 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2144 if ( flags
& wxCONTROL_PRESSED
)
2146 // the focus rectangle is never pressed, so undo the shift done
2154 DrawFocusRect(dc
, rectLabel
);
2158 // ----------------------------------------------------------------------------
2159 // (check)listbox items
2160 // ----------------------------------------------------------------------------
2162 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2163 const wxString
& label
,
2167 wxDCTextColourChanger
colChanger(dc
);
2169 if ( flags
& wxCONTROL_SELECTED
)
2171 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2173 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2174 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2175 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2176 dc
.DrawRectangle(rect
);
2179 wxRect rectText
= rect
;
2181 rectText
.width
-= 2;
2182 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2184 if ( flags
& wxCONTROL_FOCUSED
)
2186 DrawFocusRect(dc
, rect
);
2190 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2191 const wxString
& label
,
2192 const wxBitmap
& bitmap
,
2201 else // use default bitmap
2203 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2204 ? IndicatorStatus_Checked
2205 : IndicatorStatus_Unchecked
;
2207 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2209 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2212 bmp
= m_bmpCheckBitmaps
[i
];
2215 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2216 TRUE
/* use mask */);
2218 wxRect rectLabel
= rect
;
2219 int bmpWidth
= bmp
.GetWidth();
2220 rectLabel
.x
+= bmpWidth
;
2221 rectLabel
.width
-= bmpWidth
;
2223 DrawItem(dc
, label
, rectLabel
, flags
);
2226 // ----------------------------------------------------------------------------
2227 // check/radio buttons
2228 // ----------------------------------------------------------------------------
2230 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2232 IndicatorState indState
;
2233 if ( flags
& wxCONTROL_SELECTED
)
2234 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2235 : IndicatorState_Selected
;
2236 else if ( flags
& wxCONTROL_DISABLED
)
2237 indState
= IndicatorState_Disabled
;
2238 else if ( flags
& wxCONTROL_PRESSED
)
2239 indState
= IndicatorState_Pressed
;
2241 indState
= IndicatorState_Normal
;
2243 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2244 ? IndicatorStatus_Checked
2245 : IndicatorStatus_Unchecked
;
2247 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2250 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2253 // create and cache it
2254 bmp
= wxBitmap(xpm
);
2255 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2262 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2263 const wxString
& label
,
2264 const wxBitmap
& bitmap
,
2269 wxCoord focusOffsetY
)
2271 // calculate the position of the bitmap and of the label
2272 wxCoord heightBmp
= bitmap
.GetHeight();
2274 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2277 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2278 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2280 // align label vertically with the bitmap - looks nicer like this
2281 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2283 // calc horz position
2284 if ( align
== wxALIGN_RIGHT
)
2286 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2287 rectLabel
.x
= rect
.x
+ 3;
2288 rectLabel
.SetRight(xBmp
);
2290 else // normal (checkbox to the left of the text) case
2293 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2294 rectLabel
.SetRight(rect
.GetRight());
2297 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2300 dc
, label
, rectLabel
,
2302 wxALIGN_LEFT
| wxALIGN_TOP
,
2304 NULL
, // we don't need bounding rect
2305 // use custom vert focus rect offset
2306 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2310 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2311 const wxString
& label
,
2312 const wxBitmap
& bitmap
,
2322 bmp
= GetRadioBitmap(flags
);
2324 DrawCheckOrRadioButton(dc
, label
,
2326 rect
, flags
, align
, indexAccel
,
2327 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2330 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2331 const wxString
& label
,
2332 const wxBitmap
& bitmap
,
2342 bmp
= GetCheckBitmap(flags
);
2344 DrawCheckOrRadioButton(dc
, label
,
2346 rect
, flags
, align
, indexAccel
,
2347 0); // no focus rect offset for checkboxes
2350 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2351 const wxString
& label
,
2352 const wxBitmap
& bitmap
,
2353 const wxRect
& rectOrig
,
2356 if ( !label
.empty() || bitmap
.Ok() )
2358 wxRect rect
= rectOrig
;
2359 rect
.Deflate(BORDER_THICKNESS
);
2361 if ( flags
& wxCONTROL_PRESSED
)
2363 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2365 else if ( flags
& wxCONTROL_CURRENT
)
2367 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2370 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2378 // ----------------------------------------------------------------------------
2380 // ----------------------------------------------------------------------------
2382 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2383 const wxString
& text
,
2389 // nothing special to do here
2390 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2393 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2395 // we don't draw them
2398 // ----------------------------------------------------------------------------
2400 // ----------------------------------------------------------------------------
2402 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2403 const wxRect
& rectOrig
,
2405 const wxString
& label
,
2406 const wxBitmap
& bitmap
,
2410 wxRect rect
= rectOrig
;
2412 // the current tab is drawn indented (to the top for default case) and
2413 // bigger than the other ones
2414 const wxSize indent
= GetTabIndent();
2415 if ( flags
& wxCONTROL_SELECTED
)
2420 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2424 rect
.Inflate(indent
.x
, 0);
2426 rect
.height
+= indent
.y
;
2430 rect
.Inflate(indent
.x
, 0);
2431 rect
.height
+= indent
.y
;
2436 wxFAIL_MSG(_T("TODO"));
2441 // draw the text, image and the focus around them (if necessary)
2442 wxRect rectLabel
= rect
;
2443 rectLabel
.Deflate(1, 1);
2444 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2445 flags
, wxALIGN_CENTRE
, indexAccel
);
2447 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2448 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2451 x2
= rect
.GetRight(),
2452 y2
= rect
.GetBottom();
2454 // FIXME: all this code will break if the tab indent or the border width,
2455 // it is tied to the fact that both of them are equal to 2
2460 dc
.SetPen(m_penHighlight
);
2461 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2462 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2463 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2465 dc
.SetPen(m_penBlack
);
2466 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2467 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2469 dc
.SetPen(m_penDarkGrey
);
2470 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2472 if ( flags
& wxCONTROL_SELECTED
)
2474 dc
.SetPen(m_penLightGrey
);
2476 // overwrite the part of the border below this tab
2477 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2479 // and the shadow of the tab to the left of us
2480 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2485 dc
.SetPen(m_penHighlight
);
2486 // we need to continue one pixel further to overwrite the corner of
2487 // the border for the selected tab
2488 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2490 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2492 dc
.SetPen(m_penBlack
);
2493 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2494 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2495 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2497 dc
.SetPen(m_penDarkGrey
);
2498 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2499 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2501 if ( flags
& wxCONTROL_SELECTED
)
2503 dc
.SetPen(m_penLightGrey
);
2505 // overwrite the part of the (double!) border above this tab
2506 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2507 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2509 // and the shadow of the tab to the left of us
2510 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2516 wxFAIL_MSG(_T("TODO"));
2520 // ----------------------------------------------------------------------------
2522 // ----------------------------------------------------------------------------
2524 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2525 wxOrientation orient
) const
2529 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2530 if ( orient
== wxHORIZONTAL
)
2532 size
.y
= rect
.height
- 6;
2533 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2537 size
.x
= rect
.width
- 6;
2538 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2544 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2545 wxOrientation orient
) const
2547 static const wxCoord SLIDER_MARGIN
= 6;
2549 wxRect rect
= rectOrig
;
2551 if ( orient
== wxHORIZONTAL
)
2553 // make the rect of minimal width and centre it
2554 rect
.height
= 2*BORDER_THICKNESS
;
2555 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2559 // leave margins on the sides
2560 rect
.Deflate(SLIDER_MARGIN
, 0);
2564 // same as above but in other direction
2565 rect
.width
= 2*BORDER_THICKNESS
;
2566 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2570 rect
.Deflate(0, SLIDER_MARGIN
);
2576 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2577 const wxRect
& rectOrig
,
2578 wxOrientation orient
,
2582 if ( flags
& wxCONTROL_FOCUSED
)
2584 DrawFocusRect(dc
, rectOrig
);
2587 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2592 DrawSunkenBorder(dc
, &rect
);
2595 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2597 wxOrientation orient
,
2601 we are drawing a shape of this form
2606 H DB where H is hightlight colour
2619 The interior of this shape is filled with the hatched brush if the thumb
2623 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2625 bool transpose
= orient
== wxVERTICAL
;
2627 wxCoord x
, y
, x2
, y2
;
2632 x2
= rect
.GetBottom();
2633 y2
= rect
.GetRight();
2639 x2
= rect
.GetRight();
2640 y2
= rect
.GetBottom();
2643 // the size of the pointed part of the thumb
2644 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2646 wxCoord x3
= x
+ sizeArrow
,
2647 y3
= y2
- sizeArrow
;
2649 dc
.SetPen(m_penHighlight
);
2650 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2651 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2652 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2654 dc
.SetPen(m_penBlack
);
2655 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2656 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2658 dc
.SetPen(m_penDarkGrey
);
2659 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2660 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2662 if ( flags
& wxCONTROL_PRESSED
)
2664 // TODO: MSW fills the entire area inside, not just the rect
2665 wxRect rectInt
= rect
;
2667 rectInt
.SetRight(y3
);
2669 rectInt
.SetBottom(y3
);
2672 #if !defined(__WXMGL__)
2673 static const char *stipple_xpm
[] = {
2674 /* columns rows colors chars-per-pixel */
2683 // VS: MGL can only do 8x8 stipple brushes
2684 static const char *stipple_xpm
[] = {
2685 /* columns rows colors chars-per-pixel */
2700 dc
.SetBrush(wxBrush(stipple_xpm
));
2702 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2703 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2704 dc
.SetPen(*wxTRANSPARENT_PEN
);
2705 dc
.DrawRectangle(rectInt
);
2709 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2711 const wxSize
& sizeThumb
,
2712 wxOrientation orient
,
2724 // the variable names correspond to horizontal case, but they can be used
2725 // for both orientations
2726 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2727 if ( orient
== wxHORIZONTAL
)
2729 x1
= rect
.GetLeft();
2730 x2
= rect
.GetRight();
2732 // draw from bottom to top to leave one pixel space between the ticks
2733 // and the slider as Windows do
2734 y1
= rect
.GetBottom();
2739 widthThumb
= sizeThumb
.x
;
2744 x2
= rect
.GetBottom();
2746 y1
= rect
.GetRight();
2747 y2
= rect
.GetLeft();
2751 widthThumb
= sizeThumb
.y
;
2754 // the first tick should be positioned in such way that a thumb drawn in
2755 // the first position points down directly to it
2756 x1
+= widthThumb
/ 2;
2757 x2
-= widthThumb
/ 2;
2759 // this also means that we have slightly less space for the ticks in
2760 // between the first and the last
2763 dc
.SetPen(m_penBlack
);
2765 int range
= end
- start
;
2766 for ( int n
= 0; n
< range
; n
+= step
)
2768 wxCoord x
= x1
+ (len
*n
) / range
;
2770 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2773 // always draw the line at the end position
2774 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2777 // ----------------------------------------------------------------------------
2779 // ----------------------------------------------------------------------------
2781 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2782 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2785 virtual wxSize
GetSize() const { return m_size
; }
2787 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2788 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2790 wxCoord
GetItemHeight() const { return m_heightItem
; }
2793 // the total size of the menu
2796 // the offset of the start of the menu item label
2799 // the offset of the start of the accel label
2802 // the height of a normal (not separator) item
2803 wxCoord m_heightItem
;
2805 friend wxMenuGeometryInfo
*
2806 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2809 // FIXME: all constants are hardcoded but shouldn't be
2810 static const wxCoord MENU_LEFT_MARGIN
= 9;
2811 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2812 static const wxCoord MENU_VERT_MARGIN
= 3;
2814 // the margin around bitmap/check marks (on each side)
2815 static const wxCoord MENU_BMP_MARGIN
= 2;
2817 // the margin between the labels and accel strings
2818 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2820 // the separator height in pixels: in fact, strangely enough, the real height
2821 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2823 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2825 // the size of the standard checkmark bitmap
2826 static const wxCoord MENU_CHECK_SIZE
= 9;
2828 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2829 const wxRect
& rectOrig
,
2830 const wxString
& label
,
2834 wxRect rect
= rectOrig
;
2837 wxDCTextColourChanger
colChanger(dc
);
2839 if ( flags
& wxCONTROL_SELECTED
)
2841 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2843 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2844 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2845 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2846 dc
.DrawRectangle(rect
);
2849 // don't draw the focus rect around menu bar items
2850 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2851 wxALIGN_CENTRE
, indexAccel
);
2854 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2856 const wxMenuGeometryInfo
& gi
,
2857 const wxString
& label
,
2858 const wxString
& accel
,
2859 const wxBitmap
& bitmap
,
2863 const wxWin32MenuGeometryInfo
& geometryInfo
=
2864 (const wxWin32MenuGeometryInfo
&)gi
;
2869 rect
.width
= geometryInfo
.GetSize().x
;
2870 rect
.height
= geometryInfo
.GetItemHeight();
2872 // draw the selected item specially
2873 wxDCTextColourChanger
colChanger(dc
);
2874 if ( flags
& wxCONTROL_SELECTED
)
2876 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2878 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2879 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2880 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2881 dc
.DrawRectangle(rect
);
2884 // draw the bitmap: use the bitmap provided or the standard checkmark for
2885 // the checkable items
2886 wxBitmap bmp
= bitmap
;
2887 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2889 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2894 rect
.SetRight(geometryInfo
.GetLabelOffset());
2895 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2899 rect
.x
= geometryInfo
.GetLabelOffset();
2900 rect
.SetRight(geometryInfo
.GetAccelOffset());
2902 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2904 // draw the accel string
2905 rect
.x
= geometryInfo
.GetAccelOffset();
2906 rect
.SetRight(geometryInfo
.GetSize().x
);
2908 // NB: no accel index here
2909 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2911 // draw the submenu indicator
2912 if ( flags
& wxCONTROL_ISSUBMENU
)
2914 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2915 rect
.width
= MENU_RIGHT_MARGIN
;
2917 wxArrowStyle arrowStyle
;
2918 if ( flags
& wxCONTROL_DISABLED
)
2919 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2921 else if ( flags
& wxCONTROL_SELECTED
)
2922 arrowStyle
= Arrow_Inversed
;
2924 arrowStyle
= Arrow_Normal
;
2926 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2930 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2932 const wxMenuGeometryInfo
& geomInfo
)
2934 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2937 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2939 wxSize size
= sizeText
;
2941 // FIXME: menubar height is configurable under Windows
2948 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2949 const wxMenu
& menu
) const
2951 // prepare the dc: for now we draw all the items with the system font
2953 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2955 // the height of a normal item
2956 wxCoord heightText
= dc
.GetCharHeight();
2961 // the max length of label and accel strings: the menu width is the sum of
2962 // them, even if they're for different items (as the accels should be
2965 // the max length of the bitmap is never 0 as Windows always leaves enough
2966 // space for a check mark indicator
2967 wxCoord widthLabelMax
= 0,
2969 widthBmpMax
= MENU_LEFT_MARGIN
;
2971 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
2973 node
= node
->GetNext() )
2975 // height of this item
2978 wxMenuItem
*item
= node
->GetData();
2979 if ( item
->IsSeparator() )
2981 h
= MENU_SEPARATOR_HEIGHT
;
2983 else // not separator
2988 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2989 if ( widthLabel
> widthLabelMax
)
2991 widthLabelMax
= widthLabel
;
2995 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2996 if ( widthAccel
> widthAccelMax
)
2998 widthAccelMax
= widthAccel
;
3001 const wxBitmap
& bmp
= item
->GetBitmap();
3004 wxCoord widthBmp
= bmp
.GetWidth();
3005 if ( widthBmp
> widthBmpMax
)
3006 widthBmpMax
= widthBmp
;
3008 //else if ( item->IsCheckable() ): no need to check for this as
3009 // MENU_LEFT_MARGIN is big enough to show the check mark
3012 h
+= 2*MENU_VERT_MARGIN
;
3014 // remember the item position and height
3015 item
->SetGeometry(height
, h
);
3020 // bundle the metrics into a struct and return it
3021 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3023 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3024 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3025 if ( widthAccelMax
> 0 )
3027 // if we actually have any accesl, add a margin
3028 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3031 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3033 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3034 gi
->m_size
.y
= height
;
3039 // ----------------------------------------------------------------------------
3041 // ----------------------------------------------------------------------------
3043 static const wxCoord STATBAR_BORDER_X
= 2;
3044 static const wxCoord STATBAR_BORDER_Y
= 2;
3046 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3048 if ( borderBetweenFields
)
3049 *borderBetweenFields
= 2;
3051 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3054 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3056 const wxString
& label
,
3061 if ( flags
& wxCONTROL_ISDEFAULT
)
3063 // draw the size grip: it is a normal rect except that in the lower
3064 // right corner we have several bands which may be used for dragging
3065 // the status bar corner
3067 // each band consists of 4 stripes: m_penHighlight, double
3068 // m_penDarkGrey and transparent one
3069 wxCoord x2
= rect
.GetRight(),
3070 y2
= rect
.GetBottom();
3072 // draw the upper left part of the rect normally
3073 dc
.SetPen(m_penDarkGrey
);
3074 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3075 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3077 // draw the grey stripes of the grip
3079 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3080 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3082 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3083 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3086 // draw the white stripes
3087 dc
.SetPen(m_penHighlight
);
3088 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3089 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3091 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3094 // draw the remaining rect boundaries
3095 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3096 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3097 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3102 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3106 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3109 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3111 wxDCClipper
clipper(dc
, rectIn
);
3112 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3115 // ----------------------------------------------------------------------------
3117 // ----------------------------------------------------------------------------
3119 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3121 wxBitmap
*bmpPressed
,
3122 wxBitmap
*bmpDisabled
)
3124 static const wxCoord widthCombo
= 16;
3125 static const wxCoord heightCombo
= 17;
3131 bmpNormal
->Create(widthCombo
, heightCombo
);
3132 dcMem
.SelectObject(*bmpNormal
);
3133 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3134 Arrow_Down
, Arrow_Normal
);
3139 bmpPressed
->Create(widthCombo
, heightCombo
);
3140 dcMem
.SelectObject(*bmpPressed
);
3141 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3142 Arrow_Down
, Arrow_Pressed
);
3147 bmpDisabled
->Create(widthCombo
, heightCombo
);
3148 dcMem
.SelectObject(*bmpDisabled
);
3149 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3150 Arrow_Down
, Arrow_Disabled
);
3154 // ----------------------------------------------------------------------------
3156 // ----------------------------------------------------------------------------
3158 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3159 const wxColour
& col
,
3162 wxBrush
brush(col
, wxSOLID
);
3164 dc
.SetPen(*wxTRANSPARENT_PEN
);
3165 dc
.DrawRectangle(rect
);
3168 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3169 const wxColour
& col
,
3173 // just fill it with the given or default bg colour
3174 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3175 DoDrawBackground(dc
, colBg
, rect
);
3178 // ----------------------------------------------------------------------------
3180 // ----------------------------------------------------------------------------
3182 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3187 // get the bitmap for this arrow
3188 wxArrowDirection arrowDir
;
3191 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3192 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3193 case wxUP
: arrowDir
= Arrow_Up
; break;
3194 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3197 wxFAIL_MSG(_T("unknown arrow direction"));
3201 wxArrowStyle arrowStyle
;
3202 if ( flags
& wxCONTROL_PRESSED
)
3204 // can't be pressed and disabled
3205 arrowStyle
= Arrow_Pressed
;
3209 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3212 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3215 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3217 wxArrowDirection arrowDir
,
3218 wxArrowStyle arrowStyle
)
3220 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3222 // under Windows the arrows always have the same size so just centre it in
3223 // the provided rectangle
3224 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3225 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3227 // Windows does it like this...
3228 if ( arrowDir
== Arrow_Left
)
3232 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3235 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3236 const wxRect
& rectAll
,
3237 wxArrowDirection arrowDir
,
3238 wxArrowStyle arrowStyle
)
3240 wxRect rect
= rectAll
;
3241 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3242 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3243 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3246 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3247 wxOrientation orient
,
3251 // we don't use the flags, the thumb never changes appearance
3252 wxRect rectThumb
= rect
;
3253 DrawArrowBorder(dc
, &rectThumb
);
3254 DrawBackground(dc
, wxNullColour
, rectThumb
);
3257 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3258 wxOrientation orient
,
3259 const wxRect
& rectBar
,
3262 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3263 ? wxColourScheme::SCROLLBAR_PRESSED
3264 : wxColourScheme::SCROLLBAR
;
3265 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3268 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3270 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3273 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3274 wxScrollBar::Element elem
,
3277 return StandardGetScrollbarRect(scrollbar
, elem
,
3278 thumbPos
, m_sizeScrollbarArrow
);
3281 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3283 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3286 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3287 const wxPoint
& pt
) const
3289 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3292 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3295 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3298 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3301 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3304 // ----------------------------------------------------------------------------
3305 // top level windows
3306 // ----------------------------------------------------------------------------
3308 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3310 wxRect client
= GetFrameClientArea(rect
, flags
);
3312 if ( client
.Inside(pt
) )
3313 return wxHT_TOPLEVEL_CLIENT_AREA
;
3315 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3317 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3319 if ( flags
& wxTOPLEVEL_ICON
)
3321 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3322 return wxHT_TOPLEVEL_ICON
;
3325 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3326 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3327 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3329 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3331 if ( btnRect
.Inside(pt
) )
3332 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3333 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3335 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3337 if ( btnRect
.Inside(pt
) )
3338 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3339 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3341 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3343 if ( btnRect
.Inside(pt
) )
3344 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3345 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3347 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3349 if ( btnRect
.Inside(pt
) )
3350 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3351 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3353 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3355 if ( btnRect
.Inside(pt
) )
3356 return wxHT_TOPLEVEL_BUTTON_HELP
;
3357 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3360 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3361 return wxHT_TOPLEVEL_TITLEBAR
;
3364 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3366 // we are certainly at one of borders, lets decide which one:
3369 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3370 if ( pt
.x
< client
.x
)
3371 border
|= wxHT_TOPLEVEL_BORDER_W
;
3372 else if ( pt
.x
>= client
.width
+ client
.x
)
3373 border
|= wxHT_TOPLEVEL_BORDER_E
;
3374 if ( pt
.y
< client
.y
)
3375 border
|= wxHT_TOPLEVEL_BORDER_N
;
3376 else if ( pt
.y
>= client
.height
+ client
.y
)
3377 border
|= wxHT_TOPLEVEL_BORDER_S
;
3381 return wxHT_NOWHERE
;
3384 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3386 const wxString
& title
,
3390 int specialButtonFlags
)
3392 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3394 DrawFrameBorder(dc
, rect
, flags
);
3396 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3398 DrawFrameBackground(dc
, rect
, flags
);
3399 if ( flags
& wxTOPLEVEL_ICON
)
3400 DrawFrameIcon(dc
, rect
, icon
, flags
);
3401 DrawFrameTitle(dc
, rect
, title
, flags
);
3403 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3405 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3406 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3408 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3410 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3411 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3412 specialButtonFlags
: 0);
3413 x
-= FRAME_BUTTON_WIDTH
+ 2;
3415 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3417 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3418 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3419 specialButtonFlags
: 0);
3420 x
-= FRAME_BUTTON_WIDTH
;
3422 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3424 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3425 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3426 specialButtonFlags
: 0);
3427 x
-= FRAME_BUTTON_WIDTH
;
3429 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3431 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3432 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3433 specialButtonFlags
: 0);
3434 x
-= FRAME_BUTTON_WIDTH
;
3436 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3438 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3439 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3440 specialButtonFlags
: 0);
3441 x
-= FRAME_BUTTON_WIDTH
;
3446 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3450 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3454 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3455 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3456 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3457 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3458 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3461 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3465 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3467 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3468 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3469 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3471 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3472 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3474 DrawBackground(dc
, col
, r
);
3477 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3479 const wxString
& title
,
3482 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3483 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3484 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3486 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3487 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3488 if ( flags
& wxTOPLEVEL_ICON
)
3490 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3491 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3499 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3500 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3501 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3502 r
.width
-= FRAME_BUTTON_WIDTH
;
3503 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3504 r
.width
-= FRAME_BUTTON_WIDTH
;
3505 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3506 r
.width
-= FRAME_BUTTON_WIDTH
;
3507 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3508 r
.width
-= FRAME_BUTTON_WIDTH
;
3510 dc
.SetFont(m_titlebarFont
);
3511 dc
.SetTextForeground(col
);
3514 dc
.GetTextExtent(title
, &textW
, NULL
);
3515 if ( textW
> r
.width
)
3517 // text is too big, let's shorten it and add "..." after it:
3518 size_t len
= title
.length();
3519 wxCoord WSoFar
, letterW
;
3521 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3522 if ( WSoFar
> r
.width
)
3524 // not enough space to draw anything
3530 for (size_t i
= 0; i
< len
; i
++)
3532 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3533 if ( letterW
+ WSoFar
> r
.width
)
3539 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3540 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3543 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3544 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3547 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3554 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3555 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3559 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3560 wxCoord x
, wxCoord y
,
3564 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3569 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3570 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3571 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3572 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3573 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3575 wxFAIL_MSG(wxT("incorrect button specification"));
3578 if ( flags
& wxCONTROL_PRESSED
)
3580 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3581 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3582 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3583 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3587 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3588 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3589 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3590 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3595 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3600 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3602 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3603 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3604 FRAME_BORDER_THICKNESS
;
3607 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3609 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3610 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3616 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3619 wxSize
s(clientSize
);
3621 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3623 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3624 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3625 FRAME_BORDER_THICKNESS
;
3629 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3630 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3635 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3639 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3641 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3642 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3643 FRAME_BORDER_THICKNESS
;
3648 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3650 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3652 if ( flags
& wxTOPLEVEL_ICON
)
3653 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3654 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3655 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3656 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3657 s
.x
+= FRAME_BUTTON_WIDTH
;
3658 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3659 s
.x
+= FRAME_BUTTON_WIDTH
;
3660 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3661 s
.x
+= FRAME_BUTTON_WIDTH
;
3662 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3663 s
.x
+= FRAME_BUTTON_WIDTH
;
3669 wxSize
wxWin32Renderer::GetFrameIconSize() const
3671 return wxSize(16, 16);
3675 // ----------------------------------------------------------------------------
3677 // ----------------------------------------------------------------------------
3679 static char *error_xpm
[]={
3686 "...........########.............",
3687 "........###aaaaaaaa###..........",
3688 ".......#aaaaaaaaaaaaaa#.........",
3689 ".....##aaaaaaaaaaaaaaaa##.......",
3690 "....#aaaaaaaaaaaaaaaaaaaa#......",
3691 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3692 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3693 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3694 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3695 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3696 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3697 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3698 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3699 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3700 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3701 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3702 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3703 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3704 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3705 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3706 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3707 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3708 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3709 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3710 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3711 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3712 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3713 "......b#aaaaaaaaaaaaaa#bbbbb....",
3714 ".......b###aaaaaaaa###bbbbb.....",
3715 ".........bb########bbbbbb.......",
3716 "..........bbbbbbbbbbbbbb........",
3717 ".............bbbbbbbb..........."};
3719 static char *info_xpm
[]={
3727 "...........########.............",
3728 "........###abbbbbba###..........",
3729 "......##abbbbbbbbbbbba##........",
3730 ".....#abbbbbbbbbbbbbbbba#.......",
3731 "....#bbbbbbbaccccabbbbbbbd......",
3732 "...#bbbbbbbbccccccbbbbbbbbd.....",
3733 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3734 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3735 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3736 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3737 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3738 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3739 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3740 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3741 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3742 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3743 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3744 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3745 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3746 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3747 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3748 ".....dabbbbbbbbbbbbbbbbad####...",
3749 "......ddabbbbbbbbbbbbadd####....",
3750 ".......#dddabbbbbbaddd#####.....",
3751 "........###dddabbbd#######......",
3752 "..........####dbbbd#####........",
3753 ".............#dbbbd##...........",
3754 "...............dbbd##...........",
3755 "................dbd##...........",
3756 ".................dd##...........",
3757 "..................###...........",
3758 "...................##..........."};
3760 static char *question_xpm
[]={
3768 "...........########.............",
3769 "........###abbbbbba###..........",
3770 "......##abbbbbbbbbbbba##........",
3771 ".....#abbbbbbbbbbbbbbbba#.......",
3772 "....#bbbbbbbbbbbbbbbbbbbbc......",
3773 "...#bbbbbbbaddddddabbbbbbbc.....",
3774 "..#bbbbbbbadabbddddabbbbbbbc....",
3775 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3776 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3777 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3778 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3779 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3780 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3781 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3782 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3783 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3784 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3785 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3786 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3787 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3788 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3789 ".....cabbbbbbbbbbbbbbbbac####...",
3790 "......ccabbbbbbbbbbbbacc####....",
3791 ".......#cccabbbbbbaccc#####.....",
3792 "........###cccabbbc#######......",
3793 "..........####cbbbc#####........",
3794 ".............#cbbbc##...........",
3795 "...............cbbc##...........",
3796 "................cbc##...........",
3797 ".................cc##...........",
3798 "..................###...........",
3799 "...................##..........."};
3801 static char *warning_xpm
[]={
3809 ".............###................",
3810 "............#aabc...............",
3811 "...........#aaaabcd.............",
3812 "...........#aaaaacdd............",
3813 "..........#aaaaaabcdd...........",
3814 "..........#aaaaaaacdd...........",
3815 ".........#aaaaaaaabcdd..........",
3816 ".........#aaaaaaaaacdd..........",
3817 "........#aaaaaaaaaabcdd.........",
3818 "........#aaabcccbaaacdd.........",
3819 ".......#aaaacccccaaabcdd........",
3820 ".......#aaaacccccaaaacdd........",
3821 "......#aaaaacccccaaaabcdd.......",
3822 "......#aaaaacccccaaaaacdd.......",
3823 ".....#aaaaaacccccaaaaabcdd......",
3824 ".....#aaaaaa#ccc#aaaaaacdd......",
3825 "....#aaaaaaabcccbaaaaaabcdd.....",
3826 "....#aaaaaaaacccaaaaaaaacdd.....",
3827 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3828 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3829 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3830 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3831 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3832 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3833 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3834 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3835 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3836 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3837 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3838 "..#ccccccccccccccccccccccccddddd",
3839 "....ddddddddddddddddddddddddddd.",
3840 ".....ddddddddddddddddddddddddd.."};
3842 wxIcon
wxWin32Renderer::GetStdIcon(int which
) const
3846 case wxICON_INFORMATION
:
3847 return wxIcon(info_xpm
);
3849 case wxICON_QUESTION
:
3850 return wxIcon(question_xpm
);
3852 case wxICON_EXCLAMATION
:
3853 return wxIcon(warning_xpm
);
3856 wxFAIL_MSG(wxT("requested non existent standard icon"));
3857 // still fall through
3860 return wxIcon(error_xpm
);
3865 // ----------------------------------------------------------------------------
3866 // text control geometry
3867 // ----------------------------------------------------------------------------
3869 static inline int GetTextBorderWidth()
3874 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3875 const wxRect
& rect
) const
3877 wxRect rectTotal
= rect
;
3879 wxCoord widthBorder
= GetTextBorderWidth();
3880 rectTotal
.Inflate(widthBorder
);
3882 // this is what Windows does
3888 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3890 wxCoord
*extraSpaceBeyond
) const
3892 wxRect rectText
= rect
;
3894 // undo GetTextTotalArea()
3895 if ( rectText
.height
> 0 )
3898 wxCoord widthBorder
= GetTextBorderWidth();
3899 rectText
.Inflate(-widthBorder
);
3901 if ( extraSpaceBeyond
)
3902 *extraSpaceBeyond
= 0;
3907 // ----------------------------------------------------------------------------
3909 // ----------------------------------------------------------------------------
3911 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3914 if ( wxDynamicCast(window
, wxScrollBar
) )
3916 // we only set the width of vert scrollbars and height of the
3918 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3919 size
->y
= m_sizeScrollbarArrow
.y
;
3921 size
->x
= m_sizeScrollbarArrow
.x
;
3923 // skip border width adjustments, they don't make sense for us
3926 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3929 if ( wxDynamicCast(window
, wxButton
) )
3931 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3933 // TODO: don't harcode all this
3934 size
->x
+= 3*window
->GetCharWidth();
3936 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3937 if ( size
->y
< heightBtn
- 8 )
3938 size
->y
= heightBtn
;
3943 // no border width adjustments for buttons
3946 #endif // wxUSE_BUTTON
3948 // take into account the border width
3949 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3950 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3951 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3954 // ============================================================================
3956 // ============================================================================
3958 // ----------------------------------------------------------------------------
3959 // wxWin32InputHandler
3960 // ----------------------------------------------------------------------------
3962 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
3964 m_renderer
= renderer
;
3967 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
3968 const wxKeyEvent
& event
,
3974 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3975 const wxMouseEvent
& event
)
3977 // clicking on the control gives it focus
3978 if ( event
.ButtonDown() )
3980 wxWindow
*win
= control
->GetInputWindow();
3982 if ( wxWindow::FindFocus() != control
->GetInputWindow() )
3993 // ----------------------------------------------------------------------------
3994 // wxWin32ScrollBarInputHandler
3995 // ----------------------------------------------------------------------------
3997 wxWin32ScrollBarInputHandler::
3998 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
3999 wxInputHandler
*handler
)
4000 : wxStdScrollBarInputHandler(renderer
, handler
)
4002 m_scrollPaused
= FALSE
;
4006 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4007 const wxControlAction
& action
)
4009 // stop if went beyond the position of the original click (this can only
4010 // happen when we scroll by pages)
4012 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4014 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4015 != wxHT_SCROLLBAR_BAR_2
;
4017 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4019 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4020 != wxHT_SCROLLBAR_BAR_1
;
4025 StopScrolling(scrollbar
);
4027 scrollbar
->Refresh();
4032 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4035 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4036 const wxMouseEvent
& event
)
4038 // remember the current state
4039 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4041 // do process the message
4042 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4044 // analyse the changes
4045 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4047 // we just started dragging the thumb, remember its initial position to
4048 // be able to restore it if the drag is cancelled later
4049 m_eventStartDrag
= event
;
4055 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4056 const wxMouseEvent
& event
)
4058 // we don't highlight scrollbar elements, so there is no need to process
4059 // mouse move events normally - only do it while mouse is captured (i.e.
4060 // when we're dragging the thumb or pressing on something)
4061 if ( !m_winCapture
)
4064 if ( event
.Entering() )
4066 // we're not interested in this at all
4070 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4072 if ( m_scrollPaused
)
4074 // check if the mouse returned to its original location
4076 if ( event
.Leaving() )
4082 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4083 if ( ht
== m_htLast
)
4085 // yes it did, resume scrolling
4086 m_scrollPaused
= FALSE
;
4087 if ( m_timerScroll
)
4089 // we were scrolling by line/page, restart timer
4090 m_timerScroll
->Start(m_interval
);
4092 Press(scrollbar
, TRUE
);
4094 else // we were dragging the thumb
4096 // restore its last location
4097 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4103 else // normal case, scrolling hasn't been paused
4105 // if we're scrolling the scrollbar because the arrow or the shaft was
4106 // pressed, check that the mouse stays on the same scrollbar element
4108 if ( event
.Moving() )
4110 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4112 else // event.Leaving()
4117 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4118 // is still ok - we only want to catch the case when the mouse leaves
4119 // the scrollbar here
4120 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4122 ht
= wxHT_SCROLLBAR_THUMB
;
4125 if ( ht
!= m_htLast
)
4127 // what were we doing? 2 possibilities: either an arrow/shaft was
4128 // pressed in which case we have a timer and so we just stop it or
4129 // we were dragging the thumb
4130 if ( m_timerScroll
)
4133 m_interval
= m_timerScroll
->GetInterval();
4134 m_timerScroll
->Stop();
4135 m_scrollPaused
= TRUE
;
4137 // unpress the arrow
4138 Press(scrollbar
, FALSE
);
4140 else // we were dragging the thumb
4142 // remember the current thumb position to be able to restore it
4143 // if the mouse returns to it later
4144 m_eventLastDrag
= event
;
4146 // and restore the original position (before dragging) of the
4148 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4155 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4158 // ----------------------------------------------------------------------------
4159 // wxWin32CheckboxInputHandler
4160 // ----------------------------------------------------------------------------
4162 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4163 const wxKeyEvent
& event
,
4168 wxControlAction action
;
4169 int keycode
= event
.GetKeyCode();
4173 action
= wxACTION_CHECKBOX_TOGGLE
;
4177 case WXK_NUMPAD_SUBTRACT
:
4178 action
= wxACTION_CHECKBOX_CHECK
;
4182 case WXK_NUMPAD_ADD
:
4183 case WXK_NUMPAD_EQUAL
:
4184 action
= wxACTION_CHECKBOX_CLEAR
;
4190 control
->PerformAction(action
);
4199 // ----------------------------------------------------------------------------
4200 // wxWin32TextCtrlInputHandler
4201 // ----------------------------------------------------------------------------
4203 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4204 const wxKeyEvent
& event
,
4207 // handle only MSW-specific text bindings here, the others are handled in
4211 int keycode
= event
.GetKeyCode();
4213 wxControlAction action
;
4214 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4216 action
= wxACTION_TEXT_CUT
;
4218 else if ( keycode
== WXK_INSERT
)
4220 if ( event
.ControlDown() )
4221 action
= wxACTION_TEXT_COPY
;
4222 else if ( event
.ShiftDown() )
4223 action
= wxACTION_TEXT_PASTE
;
4226 if ( action
!= wxACTION_NONE
)
4228 control
->PerformAction(action
);
4234 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4237 // ----------------------------------------------------------------------------
4238 // wxWin32StatusBarInputHandler
4239 // ----------------------------------------------------------------------------
4241 wxWin32StatusBarInputHandler::
4242 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4243 : wxStdInputHandler(handler
)
4248 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4249 const wxPoint
& pt
) const
4251 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4252 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4255 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4257 wxCHECK_MSG( parentTLW
, FALSE
,
4258 _T("the status bar should be a child of a TLW") );
4260 // a maximized window can't be resized anyhow
4261 if ( !parentTLW
->IsMaximized() )
4263 // VZ: I think that the standard Windows behaviour is to only
4264 // show the resizing cursor when the mouse is on top of the
4265 // grip itself but apparently different Windows versions behave
4266 // differently (?) and it seems a better UI to allow resizing
4267 // the status bar even when the mouse is above the grip
4268 wxSize sizeSbar
= statbar
->GetSize();
4270 int diff
= sizeSbar
.x
- pt
.x
;
4271 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4278 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4279 const wxMouseEvent
& event
)
4281 if ( event
.Button(1) )
4283 if ( event
.ButtonDown(1) )
4285 wxWindow
*statbar
= consumer
->GetInputWindow();
4287 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4289 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4293 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4294 wxHT_TOPLEVEL_BORDER_SE
);
4296 statbar
->SetCursor(m_cursorOld
);
4304 return wxStdInputHandler::HandleMouse(consumer
, event
);
4307 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4308 const wxMouseEvent
& event
)
4310 wxWindow
*statbar
= consumer
->GetInputWindow();
4312 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4313 if ( isOnGrip
!= m_isOnGrip
)
4315 m_isOnGrip
= isOnGrip
;
4318 m_cursorOld
= statbar
->GetCursor();
4319 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4323 statbar
->SetCursor(m_cursorOld
);
4327 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4330 // ----------------------------------------------------------------------------
4331 // wxWin32FrameInputHandler
4332 // ----------------------------------------------------------------------------
4334 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4335 const wxMouseEvent
& event
)
4337 if ( event
.LeftDClick() )
4339 wxTopLevelWindow
*tlw
=
4340 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4342 long hit
= tlw
->HitTest(event
.GetPosition());
4344 if ( hit
== wxHT_TOPLEVEL_TITLEBAR
)
4346 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4347 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4348 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4353 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);