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"
53 #include "wx/artprov.h"
54 #include "wx/toplevel.h"
56 #include "wx/univ/scrtimer.h"
57 #include "wx/univ/renderer.h"
58 #include "wx/univ/inphand.h"
59 #include "wx/univ/colschem.h"
60 #include "wx/univ/theme.h"
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 static const int BORDER_THICKNESS
= 2;
68 // the offset between the label and focus rect around it
69 static const int FOCUS_RECT_OFFSET_X
= 1;
70 static const int FOCUS_RECT_OFFSET_Y
= 1;
72 static const int FRAME_BORDER_THICKNESS
= 3;
73 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
74 static const int FRAME_TITLEBAR_HEIGHT
= 18;
75 static const int FRAME_BUTTON_WIDTH
= 16;
76 static const int FRAME_BUTTON_HEIGHT
= 14;
78 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
79 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
80 static const size_t STATUSBAR_GRIP_SIZE
=
81 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
93 IndicatorState_Normal
,
94 IndicatorState_Pressed
, // this one is for check/radioboxes
95 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
96 IndicatorState_Disabled
,
97 IndicatorState_SelectedDisabled
, // only for the menus
103 IndicatorStatus_Checked
,
104 IndicatorStatus_Unchecked
,
108 // wxWin32Renderer: draw the GUI elements in Win32 style
109 // ----------------------------------------------------------------------------
111 class wxWin32Renderer
: public wxRenderer
115 enum wxArrowDirection
130 Arrow_InversedDisabled
,
134 enum wxFrameButtonType
137 FrameButton_Minimize
,
138 FrameButton_Maximize
,
145 wxWin32Renderer(const wxColourScheme
*scheme
);
147 // implement the base class pure virtuals
148 virtual void DrawBackground(wxDC
& dc
,
152 wxWindow
*window
= NULL
);
153 virtual void DrawLabel(wxDC
& dc
,
154 const wxString
& label
,
157 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
159 wxRect
*rectBounds
= NULL
);
160 virtual void DrawButtonLabel(wxDC
& dc
,
161 const wxString
& label
,
162 const wxBitmap
& image
,
165 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
167 wxRect
*rectBounds
= NULL
);
168 virtual void DrawBorder(wxDC
& dc
,
172 wxRect
*rectIn
= (wxRect
*)NULL
);
173 virtual void DrawHorizontalLine(wxDC
& dc
,
174 wxCoord y
, wxCoord x1
, wxCoord x2
);
175 virtual void DrawVerticalLine(wxDC
& dc
,
176 wxCoord x
, wxCoord y1
, wxCoord y2
);
177 virtual void DrawFrame(wxDC
& dc
,
178 const wxString
& label
,
181 int alignment
= wxALIGN_LEFT
,
182 int indexAccel
= -1);
183 virtual void DrawTextBorder(wxDC
& dc
,
187 wxRect
*rectIn
= (wxRect
*)NULL
);
188 virtual void DrawButtonBorder(wxDC
& dc
,
191 wxRect
*rectIn
= (wxRect
*)NULL
);
192 virtual void DrawArrow(wxDC
& dc
,
196 virtual void DrawScrollbarArrow(wxDC
& dc
,
200 { DrawArrow(dc
, dir
, rect
, flags
); }
201 virtual void DrawScrollbarThumb(wxDC
& dc
,
202 wxOrientation orient
,
205 virtual void DrawScrollbarShaft(wxDC
& dc
,
206 wxOrientation orient
,
209 virtual void DrawScrollCorner(wxDC
& dc
,
211 virtual void DrawItem(wxDC
& dc
,
212 const wxString
& label
,
215 virtual void DrawCheckItem(wxDC
& dc
,
216 const wxString
& label
,
217 const wxBitmap
& bitmap
,
220 virtual void DrawCheckButton(wxDC
& dc
,
221 const wxString
& label
,
222 const wxBitmap
& bitmap
,
225 wxAlignment align
= wxALIGN_LEFT
,
226 int indexAccel
= -1);
227 virtual void DrawRadioButton(wxDC
& dc
,
228 const wxString
& label
,
229 const wxBitmap
& bitmap
,
232 wxAlignment align
= wxALIGN_LEFT
,
233 int indexAccel
= -1);
234 virtual void DrawToolBarButton(wxDC
& dc
,
235 const wxString
& label
,
236 const wxBitmap
& bitmap
,
239 virtual void DrawTextLine(wxDC
& dc
,
240 const wxString
& text
,
245 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
246 virtual void DrawTab(wxDC
& dc
,
249 const wxString
& label
,
250 const wxBitmap
& bitmap
= wxNullBitmap
,
252 int indexAccel
= -1);
254 virtual void DrawSliderShaft(wxDC
& dc
,
256 wxOrientation orient
,
258 wxRect
*rectShaft
= NULL
);
259 virtual void DrawSliderThumb(wxDC
& dc
,
261 wxOrientation orient
,
263 virtual void DrawSliderTicks(wxDC
& dc
,
265 const wxSize
& sizeThumb
,
266 wxOrientation orient
,
272 virtual void DrawMenuBarItem(wxDC
& dc
,
274 const wxString
& label
,
276 int indexAccel
= -1);
277 virtual void DrawMenuItem(wxDC
& dc
,
279 const wxMenuGeometryInfo
& geometryInfo
,
280 const wxString
& label
,
281 const wxString
& accel
,
282 const wxBitmap
& bitmap
= wxNullBitmap
,
284 int indexAccel
= -1);
285 virtual void DrawMenuSeparator(wxDC
& dc
,
287 const wxMenuGeometryInfo
& geomInfo
);
289 virtual void DrawStatusField(wxDC
& dc
,
291 const wxString
& label
,
295 virtual void DrawFrameTitleBar(wxDC
& dc
,
297 const wxString
& title
,
300 int specialButton
= 0,
301 int specialButtonFlags
= 0);
302 virtual void DrawFrameBorder(wxDC
& dc
,
305 virtual void DrawFrameBackground(wxDC
& dc
,
308 virtual void DrawFrameTitle(wxDC
& dc
,
310 const wxString
& title
,
312 virtual void DrawFrameIcon(wxDC
& dc
,
316 virtual void DrawFrameButton(wxDC
& dc
,
317 wxCoord x
, wxCoord y
,
320 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
321 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
322 virtual wxSize
GetFrameMinSize(int flags
) const;
323 virtual wxSize
GetFrameIconSize() const;
324 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) 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(4, 4); }
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
,
409 wxWindow
*window
= NULL
);
411 // DrawBorder() helpers: all of them shift and clip the DC after drawing
414 // just draw a rectangle with the given pen
415 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
417 // draw the lower left part of rectangle
418 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
420 // draw the rectange using the first brush for the left and top sides and
421 // the second one for the bottom and right ones
422 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
423 const wxPen
& pen1
, const wxPen
& pen2
);
425 // draw the normal 3D border
426 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
428 // draw the sunken 3D border
429 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
431 // draw the border used for scrollbar arrows
432 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
434 // public DrawArrow()s helper
435 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
436 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
438 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
439 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
440 wxArrowDirection arrowDir
,
441 wxArrowStyle arrowStyle
);
443 // DrawCheckButton/DrawRadioButton helper
444 void DrawCheckOrRadioButton(wxDC
& dc
,
445 const wxString
& label
,
446 const wxBitmap
& bitmap
,
451 wxCoord focusOffsetY
);
453 // draw a normal or transposed line (useful for using the same code fo both
454 // horizontal and vertical widgets)
455 void DrawLine(wxDC
& dc
,
456 wxCoord x1
, wxCoord y1
,
457 wxCoord x2
, wxCoord y2
,
458 bool transpose
= FALSE
)
461 dc
.DrawLine(y1
, x1
, y2
, x2
);
463 dc
.DrawLine(x1
, y1
, x2
, y2
);
466 // get the standard check/radio button bitmap
467 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
468 wxBitmap
GetCheckBitmap(int flags
)
469 { return GetIndicator(IndicatorType_Check
, flags
); }
470 wxBitmap
GetRadioBitmap(int flags
)
471 { return GetIndicator(IndicatorType_Radio
, flags
); }
474 const wxColourScheme
*m_scheme
;
476 // the sizing parameters (TODO make them changeable)
477 wxSize m_sizeScrollbarArrow
;
479 // GDI objects we use for drawing
480 wxColour m_colDarkGrey
,
488 wxFont m_titlebarFont
;
490 // the checked and unchecked bitmaps for DrawCheckItem()
491 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
493 // the bitmaps returned by GetIndicator()
494 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
496 [IndicatorStatus_Max
];
499 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
501 // first row is for the normal state, second - for the disabled
502 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
505 // ----------------------------------------------------------------------------
506 // wxWin32InputHandler and derived classes: process the keyboard and mouse
507 // messages according to Windows standards
508 // ----------------------------------------------------------------------------
510 class wxWin32InputHandler
: public wxInputHandler
513 wxWin32InputHandler(wxWin32Renderer
*renderer
);
515 virtual bool HandleKey(wxInputConsumer
*control
,
516 const wxKeyEvent
& event
,
518 virtual bool HandleMouse(wxInputConsumer
*control
,
519 const wxMouseEvent
& event
);
522 wxWin32Renderer
*m_renderer
;
525 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
528 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
529 wxInputHandler
*handler
);
531 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
532 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
534 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
535 const wxControlAction
& action
);
538 virtual bool IsAllowedButton(int button
) { return button
== 1; }
540 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
542 // we don't highlight anything
545 // the first and last event which caused the thumb to move
546 wxMouseEvent m_eventStartDrag
,
549 // have we paused the scrolling because the mouse moved?
552 // we remember the interval of the timer to be able to restart it
556 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
559 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
560 : wxStdCheckboxInputHandler(handler
) { }
562 virtual bool HandleKey(wxInputConsumer
*control
,
563 const wxKeyEvent
& event
,
567 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
570 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
571 : wxStdTextCtrlInputHandler(handler
) { }
573 virtual bool HandleKey(wxInputConsumer
*control
,
574 const wxKeyEvent
& event
,
578 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
581 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
583 virtual bool HandleMouse(wxInputConsumer
*consumer
,
584 const wxMouseEvent
& event
);
586 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
587 const wxMouseEvent
& event
);
590 // is the given point over the statusbar grip?
591 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
594 // the cursor we had replaced with the resize one
595 wxCursor m_cursorOld
;
597 // was the mouse over the grip last time we checked?
601 class wxWin32SystemMenuEvtHandler
;
603 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
606 wxWin32FrameInputHandler(wxInputHandler
*handler
);
607 ~wxWin32FrameInputHandler();
609 virtual bool HandleMouse(wxInputConsumer
*control
,
610 const wxMouseEvent
& event
);
612 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
614 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
617 // was the mouse over the grip last time we checked?
618 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
621 // ----------------------------------------------------------------------------
622 // wxWin32ColourScheme: uses (default) Win32 colours
623 // ----------------------------------------------------------------------------
625 class wxWin32ColourScheme
: public wxColourScheme
628 virtual wxColour
Get(StdColour col
) const;
629 virtual wxColour
GetBackground(wxWindow
*win
) const;
632 // ----------------------------------------------------------------------------
633 // wxWin32ArtProvider
634 // ----------------------------------------------------------------------------
636 class wxWin32ArtProvider
: public wxArtProvider
639 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
640 const wxArtClient
& client
,
644 // ----------------------------------------------------------------------------
646 // ----------------------------------------------------------------------------
648 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
650 class wxWin32Theme
: public wxTheme
654 virtual ~wxWin32Theme();
656 virtual wxRenderer
*GetRenderer();
657 virtual wxArtProvider
*GetArtProvider();
658 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
659 virtual wxColourScheme
*GetColourScheme();
662 // get the default input handler
663 wxInputHandler
*GetDefaultInputHandler();
665 wxWin32Renderer
*m_renderer
;
667 wxWin32ArtProvider
*m_artProvider
;
669 // the names of the already created handlers and the handlers themselves
670 // (these arrays are synchronized)
671 wxSortedArrayString m_handlerNames
;
672 wxArrayHandlers m_handlers
;
674 wxWin32InputHandler
*m_handlerDefault
;
676 wxWin32ColourScheme
*m_scheme
;
678 WX_DECLARE_THEME(win32
)
681 // ----------------------------------------------------------------------------
683 // ----------------------------------------------------------------------------
685 // frame buttons bitmaps
687 static const char *frame_button_close_xpm
[] = {
702 static const char *frame_button_help_xpm
[] = {
717 static const char *frame_button_maximize_xpm
[] = {
732 static const char *frame_button_minimize_xpm
[] = {
747 static const char *frame_button_restore_xpm
[] = {
764 static const char *checked_menu_xpm
[] = {
765 /* columns rows colors chars-per-pixel */
781 static const char *selected_checked_menu_xpm
[] = {
782 /* columns rows colors chars-per-pixel */
798 static const char *disabled_checked_menu_xpm
[] = {
799 /* columns rows colors chars-per-pixel */
816 static const char *selected_disabled_checked_menu_xpm
[] = {
817 /* columns rows colors chars-per-pixel */
833 // checkbox and radiobox bitmaps below
835 static const char *checked_xpm
[] = {
836 /* columns rows colors chars-per-pixel */
859 static const char *pressed_checked_xpm
[] = {
860 /* columns rows colors chars-per-pixel */
882 static const char *pressed_disabled_checked_xpm
[] = {
883 /* columns rows colors chars-per-pixel */
905 static const char *checked_item_xpm
[] = {
906 /* columns rows colors chars-per-pixel */
927 static const char *unchecked_xpm
[] = {
928 /* columns rows colors chars-per-pixel */
951 static const char *pressed_unchecked_xpm
[] = {
952 /* columns rows colors chars-per-pixel */
974 static const char *unchecked_item_xpm
[] = {
975 /* columns rows colors chars-per-pixel */
995 static const char *checked_radio_xpm
[] = {
996 /* columns rows colors chars-per-pixel */
1019 static const char *pressed_checked_radio_xpm
[] = {
1020 /* columns rows colors chars-per-pixel */
1043 static const char *pressed_disabled_checked_radio_xpm
[] = {
1044 /* columns rows colors chars-per-pixel */
1067 static const char *unchecked_radio_xpm
[] = {
1068 /* columns rows colors chars-per-pixel */
1091 static const char *pressed_unchecked_radio_xpm
[] = {
1092 /* columns rows colors chars-per-pixel */
1115 static const char **
1116 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1121 { checked_xpm
, unchecked_xpm
},
1124 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1127 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1133 { checked_radio_xpm
, unchecked_radio_xpm
},
1136 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1139 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1145 { checked_menu_xpm
, NULL
},
1148 { selected_checked_menu_xpm
, NULL
},
1151 { disabled_checked_menu_xpm
, NULL
},
1153 // disabled selected state
1154 { selected_disabled_checked_menu_xpm
, NULL
},
1158 static const char **xpmChecked
[IndicatorStatus_Max
] =
1164 // ============================================================================
1166 // ============================================================================
1168 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1170 // ----------------------------------------------------------------------------
1172 // ----------------------------------------------------------------------------
1174 wxWin32Theme::wxWin32Theme()
1178 m_handlerDefault
= NULL
;
1179 m_artProvider
= NULL
;
1182 wxWin32Theme::~wxWin32Theme()
1184 size_t count
= m_handlers
.GetCount();
1185 for ( size_t n
= 0; n
< count
; n
++ )
1187 if ( m_handlers
[n
] != m_handlerDefault
)
1188 delete m_handlers
[n
];
1191 delete m_handlerDefault
;
1195 wxArtProvider::RemoveProvider(m_artProvider
);
1198 wxRenderer
*wxWin32Theme::GetRenderer()
1202 m_renderer
= new wxWin32Renderer(GetColourScheme());
1208 wxArtProvider
*wxWin32Theme::GetArtProvider()
1210 if ( !m_artProvider
)
1212 m_artProvider
= new wxWin32ArtProvider
;
1215 return m_artProvider
;
1218 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1220 if ( !m_handlerDefault
)
1222 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1225 return m_handlerDefault
;
1228 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1230 wxInputHandler
*handler
;
1231 int n
= m_handlerNames
.Index(control
);
1232 if ( n
== wxNOT_FOUND
)
1234 // create a new handler
1235 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1236 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1237 GetDefaultInputHandler());
1239 else if ( control
== wxINP_HANDLER_BUTTON
)
1240 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1241 #endif // wxUSE_BUTTON
1243 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1244 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1245 #endif // wxUSE_CHECKBOX
1247 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1248 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1249 #endif // wxUSE_COMBOBOX
1251 else if ( control
== wxINP_HANDLER_LISTBOX
)
1252 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1253 #endif // wxUSE_LISTBOX
1254 #if wxUSE_CHECKLISTBOX
1255 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1256 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1257 #endif // wxUSE_CHECKLISTBOX
1259 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1260 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1261 #endif // wxUSE_TEXTCTRL
1263 else if ( control
== wxINP_HANDLER_SLIDER
)
1264 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1265 #endif // wxUSE_SLIDER
1267 else if ( control
== wxINP_HANDLER_SPINBTN
)
1268 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1269 #endif // wxUSE_SPINBTN
1271 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1272 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1273 #endif // wxUSE_NOTEBOOK
1275 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1276 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1277 #endif // wxUSE_STATUSBAR
1279 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1280 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1281 #endif // wxUSE_TOOLBAR
1282 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1283 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1285 handler
= GetDefaultInputHandler();
1287 n
= m_handlerNames
.Add(control
);
1288 m_handlers
.Insert(handler
, n
);
1290 else // we already have it
1292 handler
= m_handlers
[n
];
1298 wxColourScheme
*wxWin32Theme::GetColourScheme()
1302 m_scheme
= new wxWin32ColourScheme
;
1307 // ============================================================================
1308 // wxWin32ColourScheme
1309 // ============================================================================
1311 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1314 if ( win
->UseBgCol() )
1316 // use the user specified colour
1317 col
= win
->GetBackgroundColour();
1320 if ( win
->IsContainerWindow() )
1322 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1325 if ( !text
->IsEnabled() ) // not IsEditable()
1327 //else: execute code below
1332 // doesn't depend on the state
1338 int flags
= win
->GetStateFlags();
1340 // the colour set by the user should be used for the normal state
1341 // and for the states for which we don't have any specific colours
1342 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1344 if ( wxDynamicCast(win
, wxScrollBar
) )
1345 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1355 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1359 // use the system colours under Windows
1360 #if defined(__WXMSW__)
1361 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1363 case CONTROL_PRESSED
:
1364 case CONTROL_CURRENT
:
1365 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1367 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1369 #if defined(COLOR_3DLIGHT)
1370 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1372 case SCROLLBAR
: return wxColour(0xe0e0e0);
1374 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1376 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1377 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1379 #if defined(COLOR_3DDKSHADOW)
1380 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1382 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1385 case CONTROL_TEXT_DISABLED
:
1386 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1388 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1390 case CONTROL_TEXT_DISABLED_SHADOW
:
1391 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1393 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1394 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1395 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1396 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1398 case DESKTOP
: return wxColour(0x808000);
1400 // use the standard Windows colours elsewhere
1401 case WINDOW
: return *wxWHITE
;
1403 case CONTROL_PRESSED
:
1404 case CONTROL_CURRENT
:
1405 case CONTROL
: return wxColour(0xc0c0c0);
1407 case CONTROL_TEXT
: return *wxBLACK
;
1409 case SCROLLBAR
: return wxColour(0xe0e0e0);
1410 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1412 case HIGHLIGHT
: return wxColour(0x800000);
1413 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1415 case SHADOW_DARK
: return *wxBLACK
;
1417 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1418 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1420 case SHADOW_IN
: return wxColour(0xc0c0c0);
1422 case CONTROL_TEXT_DISABLED_SHADOW
:
1423 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1425 case TITLEBAR
: return wxColour(0xaeaaae);
1426 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1427 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1428 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1430 case DESKTOP
: return wxColour(0x808000);
1433 case GAUGE
: return Get(HIGHLIGHT
);
1437 wxFAIL_MSG(_T("invalid standard colour"));
1442 // ============================================================================
1444 // ============================================================================
1446 // ----------------------------------------------------------------------------
1448 // ----------------------------------------------------------------------------
1450 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1454 m_sizeScrollbarArrow
= wxSize(16, 16);
1456 // init colours and pens
1457 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1459 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1460 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1462 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1464 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1465 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1467 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1468 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1470 // init the arrow bitmaps
1471 static const size_t ARROW_WIDTH
= 7;
1472 static const size_t ARROW_LENGTH
= 4;
1475 wxMemoryDC dcNormal
,
1478 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1480 bool isVertical
= n
> Arrow_Right
;
1493 // disabled arrow is larger because of the shadow
1494 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1495 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1497 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1498 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1500 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1501 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1505 dcNormal
.SetPen(m_penBlack
);
1506 dcDisabled
.SetPen(m_penDarkGrey
);
1508 // calculate the position of the point of the arrow
1512 x1
= (ARROW_WIDTH
- 1)/2;
1513 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1517 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1518 y1
= (ARROW_WIDTH
- 1)/2;
1529 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1531 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1532 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1539 if ( n
== Arrow_Up
)
1550 else // left or right arrow
1555 if ( n
== Arrow_Left
)
1568 // draw the shadow for the disabled one
1569 dcDisabled
.SetPen(m_penHighlight
);
1574 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1578 x1
= ARROW_LENGTH
- 1;
1579 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1582 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1583 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1588 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1592 x1
= ARROW_WIDTH
- 1;
1594 x2
= (ARROW_WIDTH
- 1)/2;
1596 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1597 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1602 // create the inversed bitmap but only for the right arrow as we only
1603 // use it for the menus
1604 if ( n
== Arrow_Right
)
1606 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1607 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1609 dcInverse
.Blit(0, 0, w
, h
,
1612 dcInverse
.SelectObject(wxNullBitmap
);
1614 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1615 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1617 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1618 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1620 dcInverse
.Blit(0, 0, w
, h
,
1623 dcInverse
.SelectObject(wxNullBitmap
);
1625 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1626 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1629 dcNormal
.SelectObject(wxNullBitmap
);
1630 dcDisabled
.SelectObject(wxNullBitmap
);
1632 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1633 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1634 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1635 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1637 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1640 // init the frame buttons bitmaps
1641 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1642 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1643 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1644 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1645 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1648 // ----------------------------------------------------------------------------
1650 // ----------------------------------------------------------------------------
1653 The raised border in Win32 looks like this:
1655 IIIIIIIIIIIIIIIIIIIIIIB
1657 I GB I = white (HILIGHT)
1658 I GB H = light grey (LIGHT)
1659 I GB G = dark grey (SHADOI)
1660 I GB B = black (DKSHADOI)
1661 I GB I = hIghlight (COLOR_3DHILIGHT)
1663 IGGGGGGGGGGGGGGGGGGGGGB
1664 BBBBBBBBBBBBBBBBBBBBBBB
1666 The sunken border looks like this:
1668 GGGGGGGGGGGGGGGGGGGGGGI
1669 GBBBBBBBBBBBBBBBBBBBBHI
1676 GHHHHHHHHHHHHHHHHHHHHHI
1677 IIIIIIIIIIIIIIIIIIIIIII
1679 The static border (used for the controls which don't get focus) is like
1682 GGGGGGGGGGGGGGGGGGGGGGW
1690 WWWWWWWWWWWWWWWWWWWWWWW
1692 The most complicated is the double border:
1694 HHHHHHHHHHHHHHHHHHHHHHB
1695 HWWWWWWWWWWWWWWWWWWWWGB
1696 HWHHHHHHHHHHHHHHHHHHHGB
1701 HWHHHHHHHHHHHHHHHHHHHGB
1702 HGGGGGGGGGGGGGGGGGGGGGB
1703 BBBBBBBBBBBBBBBBBBBBBBB
1705 And the simple border is, well, simple:
1707 BBBBBBBBBBBBBBBBBBBBBBB
1716 BBBBBBBBBBBBBBBBBBBBBBB
1719 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1723 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1724 dc
.DrawRectangle(*rect
);
1730 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1732 // draw the bottom and right sides
1734 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1735 rect
->GetRight() + 1, rect
->GetBottom());
1736 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1737 rect
->GetRight(), rect
->GetBottom());
1743 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1744 const wxPen
& pen1
, const wxPen
& pen2
)
1746 // draw the rectangle
1748 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1749 rect
->GetLeft(), rect
->GetBottom());
1750 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1751 rect
->GetRight(), rect
->GetTop());
1753 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1754 rect
->GetRight(), rect
->GetBottom());
1755 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1756 rect
->GetRight() + 1, rect
->GetBottom());
1762 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1764 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1765 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1768 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1770 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1771 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1774 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1778 DrawRect(dc
, rect
, m_penDarkGrey
);
1780 // the arrow is usually drawn inside border of width 2 and is offset by
1781 // another pixel in both directions when it's pressed - as the border
1782 // in this case is more narrow as well, we have to adjust rect like
1790 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1791 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1795 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1797 const wxRect
& rectTotal
,
1798 int WXUNUSED(flags
),
1803 wxRect rect
= rectTotal
;
1807 case wxBORDER_SUNKEN
:
1808 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1810 DrawSunkenBorder(dc
, &rect
);
1814 case wxBORDER_STATIC
:
1815 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1818 case wxBORDER_RAISED
:
1819 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1821 DrawRaisedBorder(dc
, &rect
);
1825 case wxBORDER_DOUBLE
:
1826 DrawArrowBorder(dc
, &rect
);
1827 DrawRect(dc
, &rect
, m_penLightGrey
);
1830 case wxBORDER_SIMPLE
:
1831 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1833 DrawRect(dc
, &rect
, m_penBlack
);
1838 wxFAIL_MSG(_T("unknown border type"));
1841 case wxBORDER_DEFAULT
:
1850 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1855 case wxBORDER_RAISED
:
1856 case wxBORDER_SUNKEN
:
1857 width
= BORDER_THICKNESS
;
1860 case wxBORDER_SIMPLE
:
1861 case wxBORDER_STATIC
:
1865 case wxBORDER_DOUBLE
:
1871 // char *crash = NULL;
1873 wxFAIL_MSG(_T("unknown border type"));
1877 case wxBORDER_DEFAULT
:
1887 rect
.height
= width
;
1892 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1897 // ----------------------------------------------------------------------------
1899 // ----------------------------------------------------------------------------
1901 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1907 // text controls are not special under windows
1908 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1911 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1912 const wxRect
& rectTotal
,
1916 wxRect rect
= rectTotal
;
1918 if ( flags
& wxCONTROL_PRESSED
)
1920 // button pressed: draw a double border around it
1921 DrawRect(dc
, &rect
, m_penBlack
);
1922 DrawRect(dc
, &rect
, m_penDarkGrey
);
1926 // button not pressed
1928 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1930 // button either default or focused (or both): add an extra border around it
1931 DrawRect(dc
, &rect
, m_penBlack
);
1934 // now draw a normal button
1935 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1936 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1945 // ----------------------------------------------------------------------------
1947 // ----------------------------------------------------------------------------
1949 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1950 wxCoord y
, wxCoord x1
, wxCoord x2
)
1952 dc
.SetPen(m_penDarkGrey
);
1953 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1954 dc
.SetPen(m_penHighlight
);
1956 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1959 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1960 wxCoord x
, wxCoord y1
, wxCoord y2
)
1962 dc
.SetPen(m_penDarkGrey
);
1963 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1964 dc
.SetPen(m_penHighlight
);
1966 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1969 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1970 const wxString
& label
,
1976 wxCoord height
= 0; // of the label
1977 wxRect rectFrame
= rect
;
1978 if ( !label
.empty() )
1980 // the text should touch the top border of the rect, so the frame
1981 // itself should be lower
1982 dc
.GetTextExtent(label
, NULL
, &height
);
1983 rectFrame
.y
+= height
/ 2;
1984 rectFrame
.height
-= height
/ 2;
1986 // we have to draw each part of the frame individually as we can't
1987 // erase the background beyond the label as it might contain some
1988 // pixmap already, so drawing everything and then overwriting part of
1989 // the frame with label doesn't work
1991 // TODO: the +5 and space insertion should be customizable
1994 rectText
.x
= rectFrame
.x
+ 5;
1995 rectText
.y
= rect
.y
;
1996 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1997 rectText
.height
= height
;
2000 label2
<< _T(' ') << label
<< _T(' ');
2001 if ( indexAccel
!= -1 )
2003 // adjust it as we prepended a space
2008 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2010 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2014 // just draw the complete frame
2015 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2016 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2020 // ----------------------------------------------------------------------------
2022 // ----------------------------------------------------------------------------
2024 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2026 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2027 // pixels each while we really need dots here... PS_ALTERNATE might
2028 // work, but it is for NT 5 only
2030 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2032 // draw the pixels manually: note that to behave in the same manner as
2033 // DrawRect(), we must exclude the bottom and right borders from the
2035 wxCoord x1
= rect
.GetLeft(),
2037 x2
= rect
.GetRight(),
2038 y2
= rect
.GetBottom();
2040 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2042 // this seems to be closer than what Windows does than wxINVERT although
2043 // I'm still not sure if it's correct
2044 dc
.SetLogicalFunction(wxAND_REVERSE
);
2047 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2048 dc
.DrawPoint(z
, rect
.GetTop());
2050 wxCoord shift
= z
== x2
? 0 : 1;
2051 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2052 dc
.DrawPoint(x2
, z
);
2054 shift
= z
== y2
? 0 : 1;
2055 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2056 dc
.DrawPoint(z
, y2
);
2058 shift
= z
== x1
? 0 : 1;
2059 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2060 dc
.DrawPoint(x1
, z
);
2062 dc
.SetLogicalFunction(wxCOPY
);
2066 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2067 const wxString
& label
,
2072 // draw shadow of the text
2073 dc
.SetTextForeground(m_colHighlight
);
2074 wxRect rectShadow
= rect
;
2077 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2079 // make the text grey
2080 dc
.SetTextForeground(m_colDarkGrey
);
2083 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2084 const wxString
& label
,
2091 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2094 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2095 const wxString
& label
,
2101 const wxPoint
& focusOffset
)
2103 // the underscores are not drawn for focused controls in wxMSW
2104 if ( flags
& wxCONTROL_FOCUSED
)
2109 if ( flags
& wxCONTROL_DISABLED
)
2111 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2112 // currently only can happen for a menu item and it seems that Windows
2113 // doesn't draw the shadow in this case, so we don't do it neither
2114 if ( flags
& wxCONTROL_SELECTED
)
2116 // just make the label text greyed out
2117 dc
.SetTextForeground(m_colDarkGrey
);
2119 else // draw normal disabled label
2121 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2126 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2128 if ( flags
& wxCONTROL_DISABLED
)
2130 // restore the fg colour
2131 dc
.SetTextForeground(*wxBLACK
);
2134 if ( flags
& wxCONTROL_FOCUSED
)
2136 if ( focusOffset
.x
|| focusOffset
.y
)
2138 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2141 DrawFocusRect(dc
, rectLabel
);
2145 *rectBounds
= rectLabel
;
2148 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2149 const wxString
& label
,
2150 const wxBitmap
& image
,
2157 // the underscores are not drawn for focused controls in wxMSW
2158 if ( flags
& wxCONTROL_PRESSED
)
2163 wxRect rectLabel
= rect
;
2164 if ( !label
.empty() )
2166 // shift the label if a button is pressed
2167 if ( flags
& wxCONTROL_PRESSED
)
2173 if ( flags
& wxCONTROL_DISABLED
)
2175 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2178 // leave enough space for the focus rectangle
2179 if ( flags
& wxCONTROL_FOCUSED
)
2181 rectLabel
.Inflate(-2);
2185 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2187 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2189 if ( flags
& wxCONTROL_PRESSED
)
2191 // the focus rectangle is never pressed, so undo the shift done
2199 DrawFocusRect(dc
, rectLabel
);
2203 // ----------------------------------------------------------------------------
2204 // (check)listbox items
2205 // ----------------------------------------------------------------------------
2207 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2208 const wxString
& label
,
2212 wxDCTextColourChanger
colChanger(dc
);
2214 if ( flags
& wxCONTROL_SELECTED
)
2216 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2218 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2219 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2220 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2221 dc
.DrawRectangle(rect
);
2224 wxRect rectText
= rect
;
2226 rectText
.width
-= 2;
2227 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2229 if ( flags
& wxCONTROL_FOCUSED
)
2231 DrawFocusRect(dc
, rect
);
2235 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2236 const wxString
& label
,
2237 const wxBitmap
& bitmap
,
2246 else // use default bitmap
2248 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2249 ? IndicatorStatus_Checked
2250 : IndicatorStatus_Unchecked
;
2252 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2254 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2257 bmp
= m_bmpCheckBitmaps
[i
];
2260 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2261 TRUE
/* use mask */);
2263 wxRect rectLabel
= rect
;
2264 int bmpWidth
= bmp
.GetWidth();
2265 rectLabel
.x
+= bmpWidth
;
2266 rectLabel
.width
-= bmpWidth
;
2268 DrawItem(dc
, label
, rectLabel
, flags
);
2271 // ----------------------------------------------------------------------------
2272 // check/radio buttons
2273 // ----------------------------------------------------------------------------
2275 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2277 IndicatorState indState
;
2278 if ( flags
& wxCONTROL_SELECTED
)
2279 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2280 : IndicatorState_Selected
;
2281 else if ( flags
& wxCONTROL_DISABLED
)
2282 indState
= IndicatorState_Disabled
;
2283 else if ( flags
& wxCONTROL_PRESSED
)
2284 indState
= IndicatorState_Pressed
;
2286 indState
= IndicatorState_Normal
;
2288 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2289 ? IndicatorStatus_Checked
2290 : IndicatorStatus_Unchecked
;
2292 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2295 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2298 // create and cache it
2299 bmp
= wxBitmap(xpm
);
2300 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2307 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2308 const wxString
& label
,
2309 const wxBitmap
& bitmap
,
2314 wxCoord focusOffsetY
)
2316 // calculate the position of the bitmap and of the label
2317 wxCoord heightBmp
= bitmap
.GetHeight();
2319 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2322 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2323 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2325 // align label vertically with the bitmap - looks nicer like this
2326 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2328 // calc horz position
2329 if ( align
== wxALIGN_RIGHT
)
2331 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2332 rectLabel
.x
= rect
.x
+ 3;
2333 rectLabel
.SetRight(xBmp
);
2335 else // normal (checkbox to the left of the text) case
2338 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2339 rectLabel
.SetRight(rect
.GetRight());
2342 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2345 dc
, label
, rectLabel
,
2347 wxALIGN_LEFT
| wxALIGN_TOP
,
2349 NULL
, // we don't need bounding rect
2350 // use custom vert focus rect offset
2351 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2355 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2356 const wxString
& label
,
2357 const wxBitmap
& bitmap
,
2367 bmp
= GetRadioBitmap(flags
);
2369 DrawCheckOrRadioButton(dc
, label
,
2371 rect
, flags
, align
, indexAccel
,
2372 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2375 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2376 const wxString
& label
,
2377 const wxBitmap
& bitmap
,
2387 bmp
= GetCheckBitmap(flags
);
2389 DrawCheckOrRadioButton(dc
, label
,
2391 rect
, flags
, align
, indexAccel
,
2392 0); // no focus rect offset for checkboxes
2395 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2396 const wxString
& label
,
2397 const wxBitmap
& bitmap
,
2398 const wxRect
& rectOrig
,
2401 if ( !label
.empty() || bitmap
.Ok() )
2403 wxRect rect
= rectOrig
;
2404 rect
.Deflate(BORDER_THICKNESS
);
2406 if ( flags
& wxCONTROL_PRESSED
)
2408 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2410 else if ( flags
& wxCONTROL_CURRENT
)
2412 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2415 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2419 // leave a small gap aroudn the line, also account for the toolbar
2421 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2422 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2423 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2427 // ----------------------------------------------------------------------------
2429 // ----------------------------------------------------------------------------
2431 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2432 const wxString
& text
,
2438 // nothing special to do here
2439 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2442 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2444 // we don't draw them
2447 // ----------------------------------------------------------------------------
2449 // ----------------------------------------------------------------------------
2451 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2452 const wxRect
& rectOrig
,
2454 const wxString
& label
,
2455 const wxBitmap
& bitmap
,
2459 wxRect rect
= rectOrig
;
2461 // the current tab is drawn indented (to the top for default case) and
2462 // bigger than the other ones
2463 const wxSize indent
= GetTabIndent();
2464 if ( flags
& wxCONTROL_SELECTED
)
2469 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2473 rect
.Inflate(indent
.x
, 0);
2475 rect
.height
+= indent
.y
;
2479 rect
.Inflate(indent
.x
, 0);
2480 rect
.height
+= indent
.y
;
2485 wxFAIL_MSG(_T("TODO"));
2490 // draw the text, image and the focus around them (if necessary)
2491 wxRect rectLabel
= rect
;
2492 rectLabel
.Deflate(1, 1);
2493 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2494 flags
, wxALIGN_CENTRE
, indexAccel
);
2496 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2497 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2500 x2
= rect
.GetRight(),
2501 y2
= rect
.GetBottom();
2503 // FIXME: all this code will break if the tab indent or the border width,
2504 // it is tied to the fact that both of them are equal to 2
2509 dc
.SetPen(m_penHighlight
);
2510 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2511 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2512 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2514 dc
.SetPen(m_penBlack
);
2515 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2516 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2518 dc
.SetPen(m_penDarkGrey
);
2519 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2521 if ( flags
& wxCONTROL_SELECTED
)
2523 dc
.SetPen(m_penLightGrey
);
2525 // overwrite the part of the border below this tab
2526 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2528 // and the shadow of the tab to the left of us
2529 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2534 dc
.SetPen(m_penHighlight
);
2535 // we need to continue one pixel further to overwrite the corner of
2536 // the border for the selected tab
2537 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2539 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2541 dc
.SetPen(m_penBlack
);
2542 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2543 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2544 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2546 dc
.SetPen(m_penDarkGrey
);
2547 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2548 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2550 if ( flags
& wxCONTROL_SELECTED
)
2552 dc
.SetPen(m_penLightGrey
);
2554 // overwrite the part of the (double!) border above this tab
2555 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2556 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2558 // and the shadow of the tab to the left of us
2559 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2565 wxFAIL_MSG(_T("TODO"));
2569 // ----------------------------------------------------------------------------
2571 // ----------------------------------------------------------------------------
2573 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2574 wxOrientation orient
) const
2578 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2579 if ( orient
== wxHORIZONTAL
)
2581 size
.y
= rect
.height
- 6;
2582 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2586 size
.x
= rect
.width
- 6;
2587 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2593 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2594 wxOrientation orient
) const
2596 static const wxCoord SLIDER_MARGIN
= 6;
2598 wxRect rect
= rectOrig
;
2600 if ( orient
== wxHORIZONTAL
)
2602 // make the rect of minimal width and centre it
2603 rect
.height
= 2*BORDER_THICKNESS
;
2604 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2608 // leave margins on the sides
2609 rect
.Deflate(SLIDER_MARGIN
, 0);
2613 // same as above but in other direction
2614 rect
.width
= 2*BORDER_THICKNESS
;
2615 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2619 rect
.Deflate(0, SLIDER_MARGIN
);
2625 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2626 const wxRect
& rectOrig
,
2627 wxOrientation orient
,
2631 if ( flags
& wxCONTROL_FOCUSED
)
2633 DrawFocusRect(dc
, rectOrig
);
2636 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2641 DrawSunkenBorder(dc
, &rect
);
2644 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2646 wxOrientation orient
,
2650 we are drawing a shape of this form
2655 H DB where H is hightlight colour
2668 The interior of this shape is filled with the hatched brush if the thumb
2672 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2674 bool transpose
= orient
== wxVERTICAL
;
2676 wxCoord x
, y
, x2
, y2
;
2681 x2
= rect
.GetBottom();
2682 y2
= rect
.GetRight();
2688 x2
= rect
.GetRight();
2689 y2
= rect
.GetBottom();
2692 // the size of the pointed part of the thumb
2693 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2695 wxCoord x3
= x
+ sizeArrow
,
2696 y3
= y2
- sizeArrow
;
2698 dc
.SetPen(m_penHighlight
);
2699 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2700 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2701 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2703 dc
.SetPen(m_penBlack
);
2704 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2705 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2707 dc
.SetPen(m_penDarkGrey
);
2708 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2709 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2711 if ( flags
& wxCONTROL_PRESSED
)
2713 // TODO: MSW fills the entire area inside, not just the rect
2714 wxRect rectInt
= rect
;
2716 rectInt
.SetRight(y3
);
2718 rectInt
.SetBottom(y3
);
2721 #if !defined(__WXMGL__)
2722 static const char *stipple_xpm
[] = {
2723 /* columns rows colors chars-per-pixel */
2732 // VS: MGL can only do 8x8 stipple brushes
2733 static const char *stipple_xpm
[] = {
2734 /* columns rows colors chars-per-pixel */
2749 dc
.SetBrush(wxBrush(stipple_xpm
));
2751 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2752 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2753 dc
.SetPen(*wxTRANSPARENT_PEN
);
2754 dc
.DrawRectangle(rectInt
);
2758 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2760 const wxSize
& sizeThumb
,
2761 wxOrientation orient
,
2773 // this would lead to an infinite loop below
2774 wxCHECK_RET( step
> 1, _T("invalid step in wxRenderer::DrawSliderTicks") );
2776 // the variable names correspond to horizontal case, but they can be used
2777 // for both orientations
2778 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2779 if ( orient
== wxHORIZONTAL
)
2781 x1
= rect
.GetLeft();
2782 x2
= rect
.GetRight();
2784 // draw from bottom to top to leave one pixel space between the ticks
2785 // and the slider as Windows do
2786 y1
= rect
.GetBottom();
2791 widthThumb
= sizeThumb
.x
;
2796 x2
= rect
.GetBottom();
2798 y1
= rect
.GetRight();
2799 y2
= rect
.GetLeft();
2803 widthThumb
= sizeThumb
.y
;
2806 // the first tick should be positioned in such way that a thumb drawn in
2807 // the first position points down directly to it
2808 x1
+= widthThumb
/ 2;
2809 x2
-= widthThumb
/ 2;
2811 // this also means that we have slightly less space for the ticks in
2812 // between the first and the last
2815 dc
.SetPen(m_penBlack
);
2817 int range
= end
- start
;
2818 for ( int n
= 0; n
< range
; n
+= step
)
2820 wxCoord x
= x1
+ (len
*n
) / range
;
2822 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2825 // always draw the line at the end position
2826 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2829 // ----------------------------------------------------------------------------
2831 // ----------------------------------------------------------------------------
2833 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2834 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2837 virtual wxSize
GetSize() const { return m_size
; }
2839 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2840 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2842 wxCoord
GetItemHeight() const { return m_heightItem
; }
2845 // the total size of the menu
2848 // the offset of the start of the menu item label
2851 // the offset of the start of the accel label
2854 // the height of a normal (not separator) item
2855 wxCoord m_heightItem
;
2857 friend wxMenuGeometryInfo
*
2858 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2861 // FIXME: all constants are hardcoded but shouldn't be
2862 static const wxCoord MENU_LEFT_MARGIN
= 9;
2863 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2864 static const wxCoord MENU_VERT_MARGIN
= 3;
2866 // the margin around bitmap/check marks (on each side)
2867 static const wxCoord MENU_BMP_MARGIN
= 2;
2869 // the margin between the labels and accel strings
2870 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2872 // the separator height in pixels: in fact, strangely enough, the real height
2873 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2875 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2877 // the size of the standard checkmark bitmap
2878 static const wxCoord MENU_CHECK_SIZE
= 9;
2880 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2881 const wxRect
& rectOrig
,
2882 const wxString
& label
,
2886 wxRect rect
= rectOrig
;
2889 wxDCTextColourChanger
colChanger(dc
);
2891 if ( flags
& wxCONTROL_SELECTED
)
2893 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2895 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2896 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2897 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2898 dc
.DrawRectangle(rect
);
2901 // don't draw the focus rect around menu bar items
2902 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2903 wxALIGN_CENTRE
, indexAccel
);
2906 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2908 const wxMenuGeometryInfo
& gi
,
2909 const wxString
& label
,
2910 const wxString
& accel
,
2911 const wxBitmap
& bitmap
,
2915 const wxWin32MenuGeometryInfo
& geometryInfo
=
2916 (const wxWin32MenuGeometryInfo
&)gi
;
2921 rect
.width
= geometryInfo
.GetSize().x
;
2922 rect
.height
= geometryInfo
.GetItemHeight();
2924 // draw the selected item specially
2925 wxDCTextColourChanger
colChanger(dc
);
2926 if ( flags
& wxCONTROL_SELECTED
)
2928 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2930 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2931 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2932 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2933 dc
.DrawRectangle(rect
);
2936 // draw the bitmap: use the bitmap provided or the standard checkmark for
2937 // the checkable items
2938 wxBitmap bmp
= bitmap
;
2939 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2941 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2946 rect
.SetRight(geometryInfo
.GetLabelOffset());
2947 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2951 rect
.x
= geometryInfo
.GetLabelOffset();
2952 rect
.SetRight(geometryInfo
.GetAccelOffset());
2954 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2956 // draw the accel string
2957 rect
.x
= geometryInfo
.GetAccelOffset();
2958 rect
.SetRight(geometryInfo
.GetSize().x
);
2960 // NB: no accel index here
2961 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2963 // draw the submenu indicator
2964 if ( flags
& wxCONTROL_ISSUBMENU
)
2966 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2967 rect
.width
= MENU_RIGHT_MARGIN
;
2969 wxArrowStyle arrowStyle
;
2970 if ( flags
& wxCONTROL_DISABLED
)
2971 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2973 else if ( flags
& wxCONTROL_SELECTED
)
2974 arrowStyle
= Arrow_Inversed
;
2976 arrowStyle
= Arrow_Normal
;
2978 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2982 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2984 const wxMenuGeometryInfo
& geomInfo
)
2986 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2989 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2991 wxSize size
= sizeText
;
2993 // FIXME: menubar height is configurable under Windows
3000 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3001 const wxMenu
& menu
) const
3003 // prepare the dc: for now we draw all the items with the system font
3005 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3007 // the height of a normal item
3008 wxCoord heightText
= dc
.GetCharHeight();
3013 // the max length of label and accel strings: the menu width is the sum of
3014 // them, even if they're for different items (as the accels should be
3017 // the max length of the bitmap is never 0 as Windows always leaves enough
3018 // space for a check mark indicator
3019 wxCoord widthLabelMax
= 0,
3021 widthBmpMax
= MENU_LEFT_MARGIN
;
3023 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
3025 node
= node
->GetNext() )
3027 // height of this item
3030 wxMenuItem
*item
= node
->GetData();
3031 if ( item
->IsSeparator() )
3033 h
= MENU_SEPARATOR_HEIGHT
;
3035 else // not separator
3040 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3041 if ( widthLabel
> widthLabelMax
)
3043 widthLabelMax
= widthLabel
;
3047 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3048 if ( widthAccel
> widthAccelMax
)
3050 widthAccelMax
= widthAccel
;
3053 const wxBitmap
& bmp
= item
->GetBitmap();
3056 wxCoord widthBmp
= bmp
.GetWidth();
3057 if ( widthBmp
> widthBmpMax
)
3058 widthBmpMax
= widthBmp
;
3060 //else if ( item->IsCheckable() ): no need to check for this as
3061 // MENU_LEFT_MARGIN is big enough to show the check mark
3064 h
+= 2*MENU_VERT_MARGIN
;
3066 // remember the item position and height
3067 item
->SetGeometry(height
, h
);
3072 // bundle the metrics into a struct and return it
3073 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3075 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3076 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3077 if ( widthAccelMax
> 0 )
3079 // if we actually have any accesl, add a margin
3080 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3083 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3085 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3086 gi
->m_size
.y
= height
;
3091 // ----------------------------------------------------------------------------
3093 // ----------------------------------------------------------------------------
3095 static const wxCoord STATBAR_BORDER_X
= 2;
3096 static const wxCoord STATBAR_BORDER_Y
= 2;
3098 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3100 if ( borderBetweenFields
)
3101 *borderBetweenFields
= 2;
3103 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3106 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3108 const wxString
& label
,
3113 if ( flags
& wxCONTROL_ISDEFAULT
)
3115 // draw the size grip: it is a normal rect except that in the lower
3116 // right corner we have several bands which may be used for dragging
3117 // the status bar corner
3119 // each band consists of 4 stripes: m_penHighlight, double
3120 // m_penDarkGrey and transparent one
3121 wxCoord x2
= rect
.GetRight(),
3122 y2
= rect
.GetBottom();
3124 // draw the upper left part of the rect normally
3125 dc
.SetPen(m_penDarkGrey
);
3126 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3127 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3129 // draw the grey stripes of the grip
3131 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3132 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3134 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3135 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3138 // draw the white stripes
3139 dc
.SetPen(m_penHighlight
);
3140 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3141 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3143 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3146 // draw the remaining rect boundaries
3147 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3148 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3149 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3154 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3158 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3161 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3163 wxDCClipper
clipper(dc
, rectIn
);
3164 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3167 // ----------------------------------------------------------------------------
3169 // ----------------------------------------------------------------------------
3171 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3173 wxBitmap
*bmpPressed
,
3174 wxBitmap
*bmpDisabled
)
3176 static const wxCoord widthCombo
= 16;
3177 static const wxCoord heightCombo
= 17;
3183 bmpNormal
->Create(widthCombo
, heightCombo
);
3184 dcMem
.SelectObject(*bmpNormal
);
3185 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3186 Arrow_Down
, Arrow_Normal
);
3191 bmpPressed
->Create(widthCombo
, heightCombo
);
3192 dcMem
.SelectObject(*bmpPressed
);
3193 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3194 Arrow_Down
, Arrow_Pressed
);
3199 bmpDisabled
->Create(widthCombo
, heightCombo
);
3200 dcMem
.SelectObject(*bmpDisabled
);
3201 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3202 Arrow_Down
, Arrow_Disabled
);
3206 // ----------------------------------------------------------------------------
3208 // ----------------------------------------------------------------------------
3210 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3211 const wxColour
& col
,
3215 wxBrush
brush(col
, wxSOLID
);
3217 dc
.SetPen(*wxTRANSPARENT_PEN
);
3218 dc
.DrawRectangle(rect
);
3221 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3222 const wxColour
& col
,
3227 // just fill it with the given or default bg colour
3228 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3229 DoDrawBackground(dc
, colBg
, rect
, window
);
3232 // ----------------------------------------------------------------------------
3234 // ----------------------------------------------------------------------------
3236 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3241 // get the bitmap for this arrow
3242 wxArrowDirection arrowDir
;
3245 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3246 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3247 case wxUP
: arrowDir
= Arrow_Up
; break;
3248 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3251 wxFAIL_MSG(_T("unknown arrow direction"));
3255 wxArrowStyle arrowStyle
;
3256 if ( flags
& wxCONTROL_PRESSED
)
3258 // can't be pressed and disabled
3259 arrowStyle
= Arrow_Pressed
;
3263 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3266 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3269 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3271 wxArrowDirection arrowDir
,
3272 wxArrowStyle arrowStyle
)
3274 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3276 // under Windows the arrows always have the same size so just centre it in
3277 // the provided rectangle
3278 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3279 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3281 // Windows does it like this...
3282 if ( arrowDir
== Arrow_Left
)
3286 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3289 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3290 const wxRect
& rectAll
,
3291 wxArrowDirection arrowDir
,
3292 wxArrowStyle arrowStyle
)
3294 wxRect rect
= rectAll
;
3295 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3296 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3297 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3300 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3301 wxOrientation orient
,
3305 // we don't use the flags, the thumb never changes appearance
3306 wxRect rectThumb
= rect
;
3307 DrawArrowBorder(dc
, &rectThumb
);
3308 DrawBackground(dc
, wxNullColour
, rectThumb
);
3311 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3312 wxOrientation orient
,
3313 const wxRect
& rectBar
,
3316 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3317 ? wxColourScheme::SCROLLBAR_PRESSED
3318 : wxColourScheme::SCROLLBAR
;
3319 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3322 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3324 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3327 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3328 wxScrollBar::Element elem
,
3331 return StandardGetScrollbarRect(scrollbar
, elem
,
3332 thumbPos
, m_sizeScrollbarArrow
);
3335 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3337 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3340 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3341 const wxPoint
& pt
) const
3343 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3346 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3349 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3352 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3355 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3358 // ----------------------------------------------------------------------------
3359 // top level windows
3360 // ----------------------------------------------------------------------------
3362 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3364 wxRect client
= GetFrameClientArea(rect
, flags
);
3366 if ( client
.Inside(pt
) )
3367 return wxHT_TOPLEVEL_CLIENT_AREA
;
3369 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3371 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3373 if ( flags
& wxTOPLEVEL_ICON
)
3375 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3376 return wxHT_TOPLEVEL_ICON
;
3379 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3380 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3381 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3383 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3385 if ( btnRect
.Inside(pt
) )
3386 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3387 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3389 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3391 if ( btnRect
.Inside(pt
) )
3392 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3393 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3395 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3397 if ( btnRect
.Inside(pt
) )
3398 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3399 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3401 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3403 if ( btnRect
.Inside(pt
) )
3404 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3405 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3407 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3409 if ( btnRect
.Inside(pt
) )
3410 return wxHT_TOPLEVEL_BUTTON_HELP
;
3411 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3414 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3415 return wxHT_TOPLEVEL_TITLEBAR
;
3418 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3420 // we are certainly at one of borders, lets decide which one:
3423 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3424 if ( pt
.x
< client
.x
)
3425 border
|= wxHT_TOPLEVEL_BORDER_W
;
3426 else if ( pt
.x
>= client
.width
+ client
.x
)
3427 border
|= wxHT_TOPLEVEL_BORDER_E
;
3428 if ( pt
.y
< client
.y
)
3429 border
|= wxHT_TOPLEVEL_BORDER_N
;
3430 else if ( pt
.y
>= client
.height
+ client
.y
)
3431 border
|= wxHT_TOPLEVEL_BORDER_S
;
3435 return wxHT_NOWHERE
;
3438 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3440 const wxString
& title
,
3444 int specialButtonFlags
)
3446 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3448 DrawFrameBorder(dc
, rect
, flags
);
3450 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3452 DrawFrameBackground(dc
, rect
, flags
);
3453 if ( flags
& wxTOPLEVEL_ICON
)
3454 DrawFrameIcon(dc
, rect
, icon
, flags
);
3455 DrawFrameTitle(dc
, rect
, title
, flags
);
3457 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3459 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3460 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3462 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3464 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3465 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3466 specialButtonFlags
: 0);
3467 x
-= FRAME_BUTTON_WIDTH
+ 2;
3469 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3471 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3472 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3473 specialButtonFlags
: 0);
3474 x
-= FRAME_BUTTON_WIDTH
;
3476 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3478 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3479 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3480 specialButtonFlags
: 0);
3481 x
-= FRAME_BUTTON_WIDTH
;
3483 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3485 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3486 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3487 specialButtonFlags
: 0);
3488 x
-= FRAME_BUTTON_WIDTH
;
3490 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3492 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3493 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3494 specialButtonFlags
: 0);
3495 x
-= FRAME_BUTTON_WIDTH
;
3500 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3504 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3508 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3509 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3510 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3511 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3512 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3515 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3519 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3521 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3522 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3523 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3525 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3526 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3528 DrawBackground(dc
, col
, r
);
3531 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3533 const wxString
& title
,
3536 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3537 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3538 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3540 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3541 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3542 if ( flags
& wxTOPLEVEL_ICON
)
3544 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3545 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3553 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3554 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3555 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3556 r
.width
-= FRAME_BUTTON_WIDTH
;
3557 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3558 r
.width
-= FRAME_BUTTON_WIDTH
;
3559 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3560 r
.width
-= FRAME_BUTTON_WIDTH
;
3561 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3562 r
.width
-= FRAME_BUTTON_WIDTH
;
3564 dc
.SetFont(m_titlebarFont
);
3565 dc
.SetTextForeground(col
);
3568 dc
.GetTextExtent(title
, &textW
, NULL
);
3569 if ( textW
> r
.width
)
3571 // text is too big, let's shorten it and add "..." after it:
3572 size_t len
= title
.length();
3573 wxCoord WSoFar
, letterW
;
3575 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3576 if ( WSoFar
> r
.width
)
3578 // not enough space to draw anything
3584 for (size_t i
= 0; i
< len
; i
++)
3586 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3587 if ( letterW
+ WSoFar
> r
.width
)
3593 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3594 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3597 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3598 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3601 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3608 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3609 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3613 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3614 wxCoord x
, wxCoord y
,
3618 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3623 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3624 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3625 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3626 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3627 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3629 wxFAIL_MSG(wxT("incorrect button specification"));
3632 if ( flags
& wxCONTROL_PRESSED
)
3634 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3635 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3636 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3637 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3641 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3642 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3643 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3644 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3649 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3654 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3656 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3657 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3658 FRAME_BORDER_THICKNESS
;
3661 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3663 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3664 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3670 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3673 wxSize
s(clientSize
);
3675 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3677 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3678 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3679 FRAME_BORDER_THICKNESS
;
3683 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3684 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3689 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3693 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3695 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3696 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3697 FRAME_BORDER_THICKNESS
;
3702 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3704 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3706 if ( flags
& wxTOPLEVEL_ICON
)
3707 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3708 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3709 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3710 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3711 s
.x
+= FRAME_BUTTON_WIDTH
;
3712 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3713 s
.x
+= FRAME_BUTTON_WIDTH
;
3714 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3715 s
.x
+= FRAME_BUTTON_WIDTH
;
3716 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3717 s
.x
+= FRAME_BUTTON_WIDTH
;
3723 wxSize
wxWin32Renderer::GetFrameIconSize() const
3725 return wxSize(16, 16);
3729 // ----------------------------------------------------------------------------
3731 // ----------------------------------------------------------------------------
3733 static char *error_xpm
[]={
3740 "...........########.............",
3741 "........###aaaaaaaa###..........",
3742 ".......#aaaaaaaaaaaaaa#.........",
3743 ".....##aaaaaaaaaaaaaaaa##.......",
3744 "....#aaaaaaaaaaaaaaaaaaaa#......",
3745 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3746 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3747 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3748 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3749 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3750 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3751 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3752 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3753 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3754 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3755 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3756 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3757 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3758 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3759 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3760 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3761 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3762 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3763 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3764 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3765 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3766 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3767 "......b#aaaaaaaaaaaaaa#bbbbb....",
3768 ".......b###aaaaaaaa###bbbbb.....",
3769 ".........bb########bbbbbb.......",
3770 "..........bbbbbbbbbbbbbb........",
3771 ".............bbbbbbbb..........."};
3773 static char *info_xpm
[]={
3781 "...........########.............",
3782 "........###abbbbbba###..........",
3783 "......##abbbbbbbbbbbba##........",
3784 ".....#abbbbbbbbbbbbbbbba#.......",
3785 "....#bbbbbbbaccccabbbbbbbd......",
3786 "...#bbbbbbbbccccccbbbbbbbbd.....",
3787 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3788 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3789 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3790 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3791 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3792 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3793 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3794 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3795 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3796 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3797 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3798 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3799 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3800 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3801 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3802 ".....dabbbbbbbbbbbbbbbbad####...",
3803 "......ddabbbbbbbbbbbbadd####....",
3804 ".......#dddabbbbbbaddd#####.....",
3805 "........###dddabbbd#######......",
3806 "..........####dbbbd#####........",
3807 ".............#dbbbd##...........",
3808 "...............dbbd##...........",
3809 "................dbd##...........",
3810 ".................dd##...........",
3811 "..................###...........",
3812 "...................##..........."};
3814 static char *question_xpm
[]={
3822 "...........########.............",
3823 "........###abbbbbba###..........",
3824 "......##abbbbbbbbbbbba##........",
3825 ".....#abbbbbbbbbbbbbbbba#.......",
3826 "....#bbbbbbbbbbbbbbbbbbbbc......",
3827 "...#bbbbbbbaddddddabbbbbbbc.....",
3828 "..#bbbbbbbadabbddddabbbbbbbc....",
3829 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3830 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3831 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3832 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3833 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3834 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3835 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3836 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3837 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3838 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3839 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3840 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3841 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3842 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3843 ".....cabbbbbbbbbbbbbbbbac####...",
3844 "......ccabbbbbbbbbbbbacc####....",
3845 ".......#cccabbbbbbaccc#####.....",
3846 "........###cccabbbc#######......",
3847 "..........####cbbbc#####........",
3848 ".............#cbbbc##...........",
3849 "...............cbbc##...........",
3850 "................cbc##...........",
3851 ".................cc##...........",
3852 "..................###...........",
3853 "...................##..........."};
3855 static char *warning_xpm
[]={
3863 ".............###................",
3864 "............#aabc...............",
3865 "...........#aaaabcd.............",
3866 "...........#aaaaacdd............",
3867 "..........#aaaaaabcdd...........",
3868 "..........#aaaaaaacdd...........",
3869 ".........#aaaaaaaabcdd..........",
3870 ".........#aaaaaaaaacdd..........",
3871 "........#aaaaaaaaaabcdd.........",
3872 "........#aaabcccbaaacdd.........",
3873 ".......#aaaacccccaaabcdd........",
3874 ".......#aaaacccccaaaacdd........",
3875 "......#aaaaacccccaaaabcdd.......",
3876 "......#aaaaacccccaaaaacdd.......",
3877 ".....#aaaaaacccccaaaaabcdd......",
3878 ".....#aaaaaa#ccc#aaaaaacdd......",
3879 "....#aaaaaaabcccbaaaaaabcdd.....",
3880 "....#aaaaaaaacccaaaaaaaacdd.....",
3881 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3882 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3883 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3884 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3885 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3886 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3887 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3888 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3889 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3890 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3891 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3892 "..#ccccccccccccccccccccccccddddd",
3893 "....ddddddddddddddddddddddddddd.",
3894 ".....ddddddddddddddddddddddddd.."};
3896 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3897 const wxArtClient
& WXUNUSED(client
),
3898 const wxSize
& WXUNUSED(size
))
3900 if ( id
== wxART_INFORMATION
)
3901 return wxBitmap(info_xpm
);
3902 if ( id
== wxART_ERROR
)
3903 return wxBitmap(error_xpm
);
3904 if ( id
== wxART_WARNING
)
3905 return wxBitmap(warning_xpm
);
3906 if ( id
== wxART_QUESTION
)
3907 return wxBitmap(question_xpm
);
3908 return wxNullBitmap
;
3912 // ----------------------------------------------------------------------------
3913 // text control geometry
3914 // ----------------------------------------------------------------------------
3916 static inline int GetTextBorderWidth()
3921 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3922 const wxRect
& rect
) const
3924 wxRect rectTotal
= rect
;
3926 wxCoord widthBorder
= GetTextBorderWidth();
3927 rectTotal
.Inflate(widthBorder
);
3929 // this is what Windows does
3935 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3937 wxCoord
*extraSpaceBeyond
) const
3939 wxRect rectText
= rect
;
3941 // undo GetTextTotalArea()
3942 if ( rectText
.height
> 0 )
3945 wxCoord widthBorder
= GetTextBorderWidth();
3946 rectText
.Inflate(-widthBorder
);
3948 if ( extraSpaceBeyond
)
3949 *extraSpaceBeyond
= 0;
3954 // ----------------------------------------------------------------------------
3956 // ----------------------------------------------------------------------------
3958 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3961 if ( wxDynamicCast(window
, wxScrollBar
) )
3963 // we only set the width of vert scrollbars and height of the
3965 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3966 size
->y
= m_sizeScrollbarArrow
.y
;
3968 size
->x
= m_sizeScrollbarArrow
.x
;
3970 // skip border width adjustments, they don't make sense for us
3973 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3976 if ( wxDynamicCast(window
, wxButton
) )
3978 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3980 // TODO: don't harcode all this
3981 size
->x
+= 3*window
->GetCharWidth();
3983 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3984 if ( size
->y
< heightBtn
- 8 )
3985 size
->y
= heightBtn
;
3990 // no border width adjustments for buttons
3993 #endif // wxUSE_BUTTON
3995 // take into account the border width
3996 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3997 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3998 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4001 // ============================================================================
4003 // ============================================================================
4005 // ----------------------------------------------------------------------------
4006 // wxWin32InputHandler
4007 // ----------------------------------------------------------------------------
4009 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4011 m_renderer
= renderer
;
4014 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
4015 const wxKeyEvent
& event
,
4021 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4022 const wxMouseEvent
& event
)
4024 // clicking on the control gives it focus
4025 if ( event
.ButtonDown() )
4027 wxWindow
*win
= control
->GetInputWindow();
4029 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4030 ( win
->AcceptsFocus() ) )
4041 // ----------------------------------------------------------------------------
4042 // wxWin32ScrollBarInputHandler
4043 // ----------------------------------------------------------------------------
4045 wxWin32ScrollBarInputHandler::
4046 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4047 wxInputHandler
*handler
)
4048 : wxStdScrollBarInputHandler(renderer
, handler
)
4050 m_scrollPaused
= FALSE
;
4054 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4055 const wxControlAction
& action
)
4057 // stop if went beyond the position of the original click (this can only
4058 // happen when we scroll by pages)
4060 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4062 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4063 != wxHT_SCROLLBAR_BAR_2
;
4065 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4067 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4068 != wxHT_SCROLLBAR_BAR_1
;
4073 StopScrolling(scrollbar
);
4075 scrollbar
->Refresh();
4080 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4083 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4084 const wxMouseEvent
& event
)
4086 // remember the current state
4087 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4089 // do process the message
4090 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4092 // analyse the changes
4093 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4095 // we just started dragging the thumb, remember its initial position to
4096 // be able to restore it if the drag is cancelled later
4097 m_eventStartDrag
= event
;
4103 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4104 const wxMouseEvent
& event
)
4106 // we don't highlight scrollbar elements, so there is no need to process
4107 // mouse move events normally - only do it while mouse is captured (i.e.
4108 // when we're dragging the thumb or pressing on something)
4109 if ( !m_winCapture
)
4112 if ( event
.Entering() )
4114 // we're not interested in this at all
4118 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4120 if ( m_scrollPaused
)
4122 // check if the mouse returned to its original location
4124 if ( event
.Leaving() )
4130 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4131 if ( ht
== m_htLast
)
4133 // yes it did, resume scrolling
4134 m_scrollPaused
= FALSE
;
4135 if ( m_timerScroll
)
4137 // we were scrolling by line/page, restart timer
4138 m_timerScroll
->Start(m_interval
);
4140 Press(scrollbar
, TRUE
);
4142 else // we were dragging the thumb
4144 // restore its last location
4145 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4151 else // normal case, scrolling hasn't been paused
4153 // if we're scrolling the scrollbar because the arrow or the shaft was
4154 // pressed, check that the mouse stays on the same scrollbar element
4157 // Always let thumb jump back if we leave the scrollbar
4158 if ( event
.Moving() )
4160 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4162 else // event.Leaving()
4167 // Jump back only if we get far away from it
4168 wxPoint pos
= event
.GetPosition();
4169 if (scrollbar
->HasFlag( wxVERTICAL
))
4171 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4176 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4179 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4182 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4183 // is still ok - we only want to catch the case when the mouse leaves
4184 // the scrollbar here
4185 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4187 ht
= wxHT_SCROLLBAR_THUMB
;
4190 if ( ht
!= m_htLast
)
4192 // what were we doing? 2 possibilities: either an arrow/shaft was
4193 // pressed in which case we have a timer and so we just stop it or
4194 // we were dragging the thumb
4195 if ( m_timerScroll
)
4198 m_interval
= m_timerScroll
->GetInterval();
4199 m_timerScroll
->Stop();
4200 m_scrollPaused
= TRUE
;
4202 // unpress the arrow
4203 Press(scrollbar
, FALSE
);
4205 else // we were dragging the thumb
4207 // remember the current thumb position to be able to restore it
4208 // if the mouse returns to it later
4209 m_eventLastDrag
= event
;
4211 // and restore the original position (before dragging) of the
4213 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4220 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4223 // ----------------------------------------------------------------------------
4224 // wxWin32CheckboxInputHandler
4225 // ----------------------------------------------------------------------------
4227 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4228 const wxKeyEvent
& event
,
4233 wxControlAction action
;
4234 int keycode
= event
.GetKeyCode();
4238 action
= wxACTION_CHECKBOX_TOGGLE
;
4242 case WXK_NUMPAD_SUBTRACT
:
4243 action
= wxACTION_CHECKBOX_CHECK
;
4247 case WXK_NUMPAD_ADD
:
4248 case WXK_NUMPAD_EQUAL
:
4249 action
= wxACTION_CHECKBOX_CLEAR
;
4255 control
->PerformAction(action
);
4264 // ----------------------------------------------------------------------------
4265 // wxWin32TextCtrlInputHandler
4266 // ----------------------------------------------------------------------------
4268 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4269 const wxKeyEvent
& event
,
4272 // handle only MSW-specific text bindings here, the others are handled in
4276 int keycode
= event
.GetKeyCode();
4278 wxControlAction action
;
4279 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4281 action
= wxACTION_TEXT_CUT
;
4283 else if ( keycode
== WXK_INSERT
)
4285 if ( event
.ControlDown() )
4286 action
= wxACTION_TEXT_COPY
;
4287 else if ( event
.ShiftDown() )
4288 action
= wxACTION_TEXT_PASTE
;
4291 if ( action
!= wxACTION_NONE
)
4293 control
->PerformAction(action
);
4299 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4302 // ----------------------------------------------------------------------------
4303 // wxWin32StatusBarInputHandler
4304 // ----------------------------------------------------------------------------
4306 wxWin32StatusBarInputHandler::
4307 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4308 : wxStdInputHandler(handler
)
4313 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4314 const wxPoint
& pt
) const
4316 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4317 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4320 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4322 wxCHECK_MSG( parentTLW
, FALSE
,
4323 _T("the status bar should be a child of a TLW") );
4325 // a maximized window can't be resized anyhow
4326 if ( !parentTLW
->IsMaximized() )
4328 // VZ: I think that the standard Windows behaviour is to only
4329 // show the resizing cursor when the mouse is on top of the
4330 // grip itself but apparently different Windows versions behave
4331 // differently (?) and it seems a better UI to allow resizing
4332 // the status bar even when the mouse is above the grip
4333 wxSize sizeSbar
= statbar
->GetSize();
4335 int diff
= sizeSbar
.x
- pt
.x
;
4336 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4343 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4344 const wxMouseEvent
& event
)
4346 if ( event
.Button(1) )
4348 if ( event
.ButtonDown(1) )
4350 wxWindow
*statbar
= consumer
->GetInputWindow();
4352 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4354 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4358 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4359 wxHT_TOPLEVEL_BORDER_SE
);
4361 statbar
->SetCursor(m_cursorOld
);
4369 return wxStdInputHandler::HandleMouse(consumer
, event
);
4372 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4373 const wxMouseEvent
& event
)
4375 wxWindow
*statbar
= consumer
->GetInputWindow();
4377 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4378 if ( isOnGrip
!= m_isOnGrip
)
4380 m_isOnGrip
= isOnGrip
;
4383 m_cursorOld
= statbar
->GetCursor();
4384 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4388 statbar
->SetCursor(m_cursorOld
);
4392 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4395 // ----------------------------------------------------------------------------
4396 // wxWin32FrameInputHandler
4397 // ----------------------------------------------------------------------------
4399 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4402 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4404 void Attach(wxInputConsumer
*consumer
);
4408 DECLARE_EVENT_TABLE()
4409 void OnSystemMenu(wxCommandEvent
&event
);
4410 void OnCloseFrame(wxCommandEvent
&event
);
4411 void OnClose(wxCloseEvent
&event
);
4413 wxWin32FrameInputHandler
*m_inputHnd
;
4414 wxTopLevelWindow
*m_wnd
;
4415 wxAcceleratorTable m_oldAccelTable
;
4418 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4419 wxWin32FrameInputHandler
*handler
)
4421 m_inputHnd
= handler
;
4425 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4427 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4429 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4430 m_wnd
->PushEventHandler(this);
4432 // VS: This code relies on using generic implementation of
4433 // wxAcceleratorTable in wxUniv!
4434 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4435 m_oldAccelTable
= table
;
4436 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4437 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4438 m_wnd
->SetAcceleratorTable(table
);
4441 void wxWin32SystemMenuEvtHandler::Detach()
4445 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4446 m_wnd
->RemoveEventHandler(this);
4451 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4452 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4453 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4454 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4457 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4459 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4460 !m_wnd
->IsMaximized()) ?
4461 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4462 FRAME_BORDER_THICKNESS
;
4463 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4464 pt
.x
= -pt
.x
+ border
;
4465 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4467 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4468 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4469 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4470 m_wnd
->SetAcceleratorTable(table
);
4473 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4475 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4476 wxTOPLEVEL_BUTTON_CLOSE
);
4479 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4486 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4487 : wxStdFrameInputHandler(handler
)
4489 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4492 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4494 if ( m_menuHandler
)
4496 m_menuHandler
->Detach();
4497 delete m_menuHandler
;
4501 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4502 const wxMouseEvent
& event
)
4504 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4506 wxTopLevelWindow
*tlw
=
4507 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4509 long hit
= tlw
->HitTest(event
.GetPosition());
4511 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4513 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4514 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4515 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4518 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4520 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4521 (event
.RightDown() &&
4522 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4523 hit
== wxHT_TOPLEVEL_ICON
)) )
4525 PopupSystemMenu(tlw
, event
.GetPosition());
4531 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4534 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4535 const wxPoint
& pos
) const
4537 wxMenu
*menu
= new wxMenu
;
4539 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4540 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4541 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4542 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4543 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4544 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4545 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4546 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4547 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4548 menu
->AppendSeparator();
4549 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4551 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4553 if ( window
->IsMaximized() )
4555 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4556 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4557 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4558 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4561 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4564 window
->PopupMenu(menu
, pos
);
4568 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4571 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4573 // always detach if active frame changed:
4574 m_menuHandler
->Detach();
4578 m_menuHandler
->Attach(consumer
);
4582 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);