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());
1744 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1745 const wxPen
& pen1
, const wxPen
& pen2
)
1747 // draw the rectangle
1749 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1750 rect
->GetLeft(), rect
->GetBottom());
1751 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1752 rect
->GetRight(), rect
->GetTop());
1754 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1755 rect
->GetRight(), rect
->GetBottom());
1756 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1757 rect
->GetRight() + 1, rect
->GetBottom());
1763 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1765 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1766 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1769 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1771 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1772 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1775 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1779 DrawRect(dc
, rect
, m_penDarkGrey
);
1781 // the arrow is usually drawn inside border of width 2 and is offset by
1782 // another pixel in both directions when it's pressed - as the border
1783 // in this case is more narrow as well, we have to adjust rect like
1791 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1792 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1796 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1798 const wxRect
& rectTotal
,
1799 int WXUNUSED(flags
),
1804 wxRect rect
= rectTotal
;
1808 case wxBORDER_SUNKEN
:
1809 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1811 DrawSunkenBorder(dc
, &rect
);
1815 case wxBORDER_STATIC
:
1816 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1819 case wxBORDER_RAISED
:
1820 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1822 DrawRaisedBorder(dc
, &rect
);
1826 case wxBORDER_DOUBLE
:
1827 DrawArrowBorder(dc
, &rect
);
1828 DrawRect(dc
, &rect
, m_penLightGrey
);
1831 case wxBORDER_SIMPLE
:
1832 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1834 DrawRect(dc
, &rect
, m_penBlack
);
1839 wxFAIL_MSG(_T("unknown border type"));
1842 case wxBORDER_DEFAULT
:
1851 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1856 case wxBORDER_RAISED
:
1857 case wxBORDER_SUNKEN
:
1858 width
= BORDER_THICKNESS
;
1861 case wxBORDER_SIMPLE
:
1862 case wxBORDER_STATIC
:
1866 case wxBORDER_DOUBLE
:
1872 // char *crash = NULL;
1874 wxFAIL_MSG(_T("unknown border type"));
1878 case wxBORDER_DEFAULT
:
1888 rect
.height
= width
;
1893 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1898 // ----------------------------------------------------------------------------
1900 // ----------------------------------------------------------------------------
1902 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1908 // text controls are not special under windows
1909 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1912 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1913 const wxRect
& rectTotal
,
1917 wxRect rect
= rectTotal
;
1919 if ( flags
& wxCONTROL_PRESSED
)
1921 // button pressed: draw a double border around it
1922 DrawRect(dc
, &rect
, m_penBlack
);
1923 DrawRect(dc
, &rect
, m_penDarkGrey
);
1927 // button not pressed
1929 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1931 // button either default or focused (or both): add an extra border around it
1932 DrawRect(dc
, &rect
, m_penBlack
);
1935 // now draw a normal button
1936 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1937 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1946 // ----------------------------------------------------------------------------
1948 // ----------------------------------------------------------------------------
1950 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1951 wxCoord y
, wxCoord x1
, wxCoord x2
)
1953 dc
.SetPen(m_penDarkGrey
);
1954 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1955 dc
.SetPen(m_penHighlight
);
1957 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1960 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1961 wxCoord x
, wxCoord y1
, wxCoord y2
)
1963 dc
.SetPen(m_penDarkGrey
);
1964 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1965 dc
.SetPen(m_penHighlight
);
1967 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1970 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1971 const wxString
& label
,
1977 wxCoord height
= 0; // of the label
1978 wxRect rectFrame
= rect
;
1979 if ( !label
.empty() )
1981 // the text should touch the top border of the rect, so the frame
1982 // itself should be lower
1983 dc
.GetTextExtent(label
, NULL
, &height
);
1984 rectFrame
.y
+= height
/ 2;
1985 rectFrame
.height
-= height
/ 2;
1987 // we have to draw each part of the frame individually as we can't
1988 // erase the background beyond the label as it might contain some
1989 // pixmap already, so drawing everything and then overwriting part of
1990 // the frame with label doesn't work
1992 // TODO: the +5 and space insertion should be customizable
1995 rectText
.x
= rectFrame
.x
+ 5;
1996 rectText
.y
= rect
.y
;
1997 rectText
.width
= rectFrame
.width
- 7; // +2 border width
1998 rectText
.height
= height
;
2001 label2
<< _T(' ') << label
<< _T(' ');
2002 if ( indexAccel
!= -1 )
2004 // adjust it as we prepended a space
2009 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2011 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2015 // just draw the complete frame
2016 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2017 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2021 // ----------------------------------------------------------------------------
2023 // ----------------------------------------------------------------------------
2025 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2027 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2028 // pixels each while we really need dots here... PS_ALTERNATE might
2029 // work, but it is for NT 5 only
2031 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2033 // draw the pixels manually: note that to behave in the same manner as
2034 // DrawRect(), we must exclude the bottom and right borders from the
2036 wxCoord x1
= rect
.GetLeft(),
2038 x2
= rect
.GetRight(),
2039 y2
= rect
.GetBottom();
2041 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2043 // this seems to be closer than what Windows does than wxINVERT although
2044 // I'm still not sure if it's correct
2045 dc
.SetLogicalFunction(wxAND_REVERSE
);
2048 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2049 dc
.DrawPoint(z
, rect
.GetTop());
2051 wxCoord shift
= z
== x2
? 0 : 1;
2052 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2053 dc
.DrawPoint(x2
, z
);
2055 shift
= z
== y2
? 0 : 1;
2056 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2057 dc
.DrawPoint(z
, y2
);
2059 shift
= z
== x1
? 0 : 1;
2060 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2061 dc
.DrawPoint(x1
, z
);
2063 dc
.SetLogicalFunction(wxCOPY
);
2067 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2068 const wxString
& label
,
2073 // draw shadow of the text
2074 dc
.SetTextForeground(m_colHighlight
);
2075 wxRect rectShadow
= rect
;
2078 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2080 // make the text grey
2081 dc
.SetTextForeground(m_colDarkGrey
);
2084 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2085 const wxString
& label
,
2092 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2095 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2096 const wxString
& label
,
2102 const wxPoint
& focusOffset
)
2104 // the underscores are not drawn for focused controls in wxMSW
2105 if ( flags
& wxCONTROL_FOCUSED
)
2110 if ( flags
& wxCONTROL_DISABLED
)
2112 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2113 // currently only can happen for a menu item and it seems that Windows
2114 // doesn't draw the shadow in this case, so we don't do it neither
2115 if ( flags
& wxCONTROL_SELECTED
)
2117 // just make the label text greyed out
2118 dc
.SetTextForeground(m_colDarkGrey
);
2120 else // draw normal disabled label
2122 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2127 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2129 if ( flags
& wxCONTROL_DISABLED
)
2131 // restore the fg colour
2132 dc
.SetTextForeground(*wxBLACK
);
2135 if ( flags
& wxCONTROL_FOCUSED
)
2137 if ( focusOffset
.x
|| focusOffset
.y
)
2139 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2142 DrawFocusRect(dc
, rectLabel
);
2146 *rectBounds
= rectLabel
;
2149 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2150 const wxString
& label
,
2151 const wxBitmap
& image
,
2158 // the underscores are not drawn for focused controls in wxMSW
2159 if ( flags
& wxCONTROL_PRESSED
)
2164 wxRect rectLabel
= rect
;
2165 if ( !label
.empty() )
2167 // shift the label if a button is pressed
2168 if ( flags
& wxCONTROL_PRESSED
)
2174 if ( flags
& wxCONTROL_DISABLED
)
2176 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2179 // leave enough space for the focus rectangle
2180 if ( flags
& wxCONTROL_FOCUSED
)
2182 rectLabel
.Inflate(-2);
2186 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2188 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2190 if ( flags
& wxCONTROL_PRESSED
)
2192 // the focus rectangle is never pressed, so undo the shift done
2200 DrawFocusRect(dc
, rectLabel
);
2204 // ----------------------------------------------------------------------------
2205 // (check)listbox items
2206 // ----------------------------------------------------------------------------
2208 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2209 const wxString
& label
,
2213 wxDCTextColourChanger
colChanger(dc
);
2215 if ( flags
& wxCONTROL_SELECTED
)
2217 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2219 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2220 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2221 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2222 dc
.DrawRectangle(rect
);
2225 wxRect rectText
= rect
;
2227 rectText
.width
-= 2;
2228 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2230 if ( flags
& wxCONTROL_FOCUSED
)
2232 DrawFocusRect(dc
, rect
);
2236 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2237 const wxString
& label
,
2238 const wxBitmap
& bitmap
,
2247 else // use default bitmap
2249 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2250 ? IndicatorStatus_Checked
2251 : IndicatorStatus_Unchecked
;
2253 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2255 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2258 bmp
= m_bmpCheckBitmaps
[i
];
2261 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2262 TRUE
/* use mask */);
2264 wxRect rectLabel
= rect
;
2265 int bmpWidth
= bmp
.GetWidth();
2266 rectLabel
.x
+= bmpWidth
;
2267 rectLabel
.width
-= bmpWidth
;
2269 DrawItem(dc
, label
, rectLabel
, flags
);
2272 // ----------------------------------------------------------------------------
2273 // check/radio buttons
2274 // ----------------------------------------------------------------------------
2276 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2278 IndicatorState indState
;
2279 if ( flags
& wxCONTROL_SELECTED
)
2280 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2281 : IndicatorState_Selected
;
2282 else if ( flags
& wxCONTROL_DISABLED
)
2283 indState
= IndicatorState_Disabled
;
2284 else if ( flags
& wxCONTROL_PRESSED
)
2285 indState
= IndicatorState_Pressed
;
2287 indState
= IndicatorState_Normal
;
2289 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2290 ? IndicatorStatus_Checked
2291 : IndicatorStatus_Unchecked
;
2293 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2296 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2299 // create and cache it
2300 bmp
= wxBitmap(xpm
);
2301 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2308 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2309 const wxString
& label
,
2310 const wxBitmap
& bitmap
,
2315 wxCoord focusOffsetY
)
2317 // calculate the position of the bitmap and of the label
2318 wxCoord heightBmp
= bitmap
.GetHeight();
2320 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2323 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2324 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2326 // align label vertically with the bitmap - looks nicer like this
2327 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2329 // calc horz position
2330 if ( align
== wxALIGN_RIGHT
)
2332 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2333 rectLabel
.x
= rect
.x
+ 3;
2334 rectLabel
.SetRight(xBmp
);
2336 else // normal (checkbox to the left of the text) case
2339 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2340 rectLabel
.SetRight(rect
.GetRight());
2343 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2346 dc
, label
, rectLabel
,
2348 wxALIGN_LEFT
| wxALIGN_TOP
,
2350 NULL
, // we don't need bounding rect
2351 // use custom vert focus rect offset
2352 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2356 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2357 const wxString
& label
,
2358 const wxBitmap
& bitmap
,
2368 bmp
= GetRadioBitmap(flags
);
2370 DrawCheckOrRadioButton(dc
, label
,
2372 rect
, flags
, align
, indexAccel
,
2373 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2376 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2377 const wxString
& label
,
2378 const wxBitmap
& bitmap
,
2388 bmp
= GetCheckBitmap(flags
);
2390 DrawCheckOrRadioButton(dc
, label
,
2392 rect
, flags
, align
, indexAccel
,
2393 0); // no focus rect offset for checkboxes
2396 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2397 const wxString
& label
,
2398 const wxBitmap
& bitmap
,
2399 const wxRect
& rectOrig
,
2402 if ( !label
.empty() || bitmap
.Ok() )
2404 wxRect rect
= rectOrig
;
2405 rect
.Deflate(BORDER_THICKNESS
);
2407 if ( flags
& wxCONTROL_PRESSED
)
2409 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2411 else if ( flags
& wxCONTROL_CURRENT
)
2413 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2416 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2420 // leave a small gap aroudn the line, also account for the toolbar
2422 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2423 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2424 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2428 // ----------------------------------------------------------------------------
2430 // ----------------------------------------------------------------------------
2432 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2433 const wxString
& text
,
2439 // nothing special to do here
2440 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2443 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2445 // we don't draw them
2448 // ----------------------------------------------------------------------------
2450 // ----------------------------------------------------------------------------
2452 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2453 const wxRect
& rectOrig
,
2455 const wxString
& label
,
2456 const wxBitmap
& bitmap
,
2460 wxRect rect
= rectOrig
;
2462 // the current tab is drawn indented (to the top for default case) and
2463 // bigger than the other ones
2464 const wxSize indent
= GetTabIndent();
2465 if ( flags
& wxCONTROL_SELECTED
)
2470 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2474 rect
.Inflate(indent
.x
, 0);
2476 rect
.height
+= indent
.y
;
2480 rect
.Inflate(indent
.x
, 0);
2481 rect
.height
+= indent
.y
;
2486 wxFAIL_MSG(_T("TODO"));
2491 // draw the text, image and the focus around them (if necessary)
2492 wxRect rectLabel
= rect
;
2493 rectLabel
.Deflate(1, 1);
2494 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2495 flags
, wxALIGN_CENTRE
, indexAccel
);
2497 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2498 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2501 x2
= rect
.GetRight(),
2502 y2
= rect
.GetBottom();
2504 // FIXME: all this code will break if the tab indent or the border width,
2505 // it is tied to the fact that both of them are equal to 2
2510 dc
.SetPen(m_penHighlight
);
2511 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2512 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2513 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2515 dc
.SetPen(m_penBlack
);
2516 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2517 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2519 dc
.SetPen(m_penDarkGrey
);
2520 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2522 if ( flags
& wxCONTROL_SELECTED
)
2524 dc
.SetPen(m_penLightGrey
);
2526 // overwrite the part of the border below this tab
2527 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2529 // and the shadow of the tab to the left of us
2530 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2535 dc
.SetPen(m_penHighlight
);
2536 // we need to continue one pixel further to overwrite the corner of
2537 // the border for the selected tab
2538 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2540 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2542 dc
.SetPen(m_penBlack
);
2543 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2544 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2545 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2547 dc
.SetPen(m_penDarkGrey
);
2548 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2549 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2551 if ( flags
& wxCONTROL_SELECTED
)
2553 dc
.SetPen(m_penLightGrey
);
2555 // overwrite the part of the (double!) border above this tab
2556 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2557 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2559 // and the shadow of the tab to the left of us
2560 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2566 wxFAIL_MSG(_T("TODO"));
2570 // ----------------------------------------------------------------------------
2572 // ----------------------------------------------------------------------------
2574 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2575 wxOrientation orient
) const
2579 wxRect rectShaft
= GetSliderShaftRect(rect
, orient
);
2580 if ( orient
== wxHORIZONTAL
)
2582 size
.y
= rect
.height
- 6;
2583 size
.x
= wxMin(size
.y
/ 2, rectShaft
.width
);
2587 size
.x
= rect
.width
- 6;
2588 size
.y
= wxMin(size
.x
/ 2, rectShaft
.height
);
2594 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2595 wxOrientation orient
) const
2597 static const wxCoord SLIDER_MARGIN
= 6;
2599 wxRect rect
= rectOrig
;
2601 if ( orient
== wxHORIZONTAL
)
2603 // make the rect of minimal width and centre it
2604 rect
.height
= 2*BORDER_THICKNESS
;
2605 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
2609 // leave margins on the sides
2610 rect
.Deflate(SLIDER_MARGIN
, 0);
2614 // same as above but in other direction
2615 rect
.width
= 2*BORDER_THICKNESS
;
2616 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
2620 rect
.Deflate(0, SLIDER_MARGIN
);
2626 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2627 const wxRect
& rectOrig
,
2628 wxOrientation orient
,
2632 if ( flags
& wxCONTROL_FOCUSED
)
2634 DrawFocusRect(dc
, rectOrig
);
2637 wxRect rect
= GetSliderShaftRect(rectOrig
, orient
);
2642 DrawSunkenBorder(dc
, &rect
);
2645 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2647 wxOrientation orient
,
2651 we are drawing a shape of this form
2656 H DB where H is hightlight colour
2669 The interior of this shape is filled with the hatched brush if the thumb
2673 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2675 bool transpose
= orient
== wxVERTICAL
;
2677 wxCoord x
, y
, x2
, y2
;
2682 x2
= rect
.GetBottom();
2683 y2
= rect
.GetRight();
2689 x2
= rect
.GetRight();
2690 y2
= rect
.GetBottom();
2693 // the size of the pointed part of the thumb
2694 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2696 wxCoord x3
= x
+ sizeArrow
,
2697 y3
= y2
- sizeArrow
;
2699 dc
.SetPen(m_penHighlight
);
2700 DrawLine(dc
, x
, y
, x2
, y
, transpose
);
2701 DrawLine(dc
, x
, y
+ 1, x
, y2
- sizeArrow
, transpose
);
2702 DrawLine(dc
, x
, y3
, x3
, y2
, transpose
);
2704 dc
.SetPen(m_penBlack
);
2705 DrawLine(dc
, x3
, y2
, x2
, y3
, transpose
);
2706 DrawLine(dc
, x2
, y3
, x2
, y
- 1, transpose
);
2708 dc
.SetPen(m_penDarkGrey
);
2709 DrawLine(dc
, x3
, y2
- 1, x2
- 1, y3
, transpose
);
2710 DrawLine(dc
, x2
- 1, y3
, x2
- 1, y
, transpose
);
2712 if ( flags
& wxCONTROL_PRESSED
)
2714 // TODO: MSW fills the entire area inside, not just the rect
2715 wxRect rectInt
= rect
;
2717 rectInt
.SetRight(y3
);
2719 rectInt
.SetBottom(y3
);
2722 #if !defined(__WXMGL__)
2723 static const char *stipple_xpm
[] = {
2724 /* columns rows colors chars-per-pixel */
2733 // VS: MGL can only do 8x8 stipple brushes
2734 static const char *stipple_xpm
[] = {
2735 /* columns rows colors chars-per-pixel */
2750 dc
.SetBrush(wxBrush(stipple_xpm
));
2752 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2753 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2754 dc
.SetPen(*wxTRANSPARENT_PEN
);
2755 dc
.DrawRectangle(rectInt
);
2759 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2761 const wxSize
& sizeThumb
,
2762 wxOrientation orient
,
2774 // the variable names correspond to horizontal case, but they can be used
2775 // for both orientations
2776 wxCoord x1
, x2
, y1
, y2
, len
, widthThumb
;
2777 if ( orient
== wxHORIZONTAL
)
2779 x1
= rect
.GetLeft();
2780 x2
= rect
.GetRight();
2782 // draw from bottom to top to leave one pixel space between the ticks
2783 // and the slider as Windows do
2784 y1
= rect
.GetBottom();
2789 widthThumb
= sizeThumb
.x
;
2794 x2
= rect
.GetBottom();
2796 y1
= rect
.GetRight();
2797 y2
= rect
.GetLeft();
2801 widthThumb
= sizeThumb
.y
;
2804 // the first tick should be positioned in such way that a thumb drawn in
2805 // the first position points down directly to it
2806 x1
+= widthThumb
/ 2;
2807 x2
-= widthThumb
/ 2;
2809 // this also means that we have slightly less space for the ticks in
2810 // between the first and the last
2813 dc
.SetPen(m_penBlack
);
2815 int range
= end
- start
;
2816 for ( int n
= 0; n
< range
; n
+= step
)
2818 wxCoord x
= x1
+ (len
*n
) / range
;
2820 DrawLine(dc
, x
, y1
, x
, y2
, orient
== wxVERTICAL
);
2823 // always draw the line at the end position
2824 DrawLine(dc
, x2
, y1
, x2
, y2
, orient
== wxVERTICAL
);
2827 // ----------------------------------------------------------------------------
2829 // ----------------------------------------------------------------------------
2831 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2832 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2835 virtual wxSize
GetSize() const { return m_size
; }
2837 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2838 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2840 wxCoord
GetItemHeight() const { return m_heightItem
; }
2843 // the total size of the menu
2846 // the offset of the start of the menu item label
2849 // the offset of the start of the accel label
2852 // the height of a normal (not separator) item
2853 wxCoord m_heightItem
;
2855 friend wxMenuGeometryInfo
*
2856 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2859 // FIXME: all constants are hardcoded but shouldn't be
2860 static const wxCoord MENU_LEFT_MARGIN
= 9;
2861 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2862 static const wxCoord MENU_VERT_MARGIN
= 3;
2864 // the margin around bitmap/check marks (on each side)
2865 static const wxCoord MENU_BMP_MARGIN
= 2;
2867 // the margin between the labels and accel strings
2868 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2870 // the separator height in pixels: in fact, strangely enough, the real height
2871 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2873 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2875 // the size of the standard checkmark bitmap
2876 static const wxCoord MENU_CHECK_SIZE
= 9;
2878 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2879 const wxRect
& rectOrig
,
2880 const wxString
& label
,
2884 wxRect rect
= rectOrig
;
2887 wxDCTextColourChanger
colChanger(dc
);
2889 if ( flags
& wxCONTROL_SELECTED
)
2891 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2893 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2894 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2895 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2896 dc
.DrawRectangle(rect
);
2899 // don't draw the focus rect around menu bar items
2900 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2901 wxALIGN_CENTRE
, indexAccel
);
2904 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2906 const wxMenuGeometryInfo
& gi
,
2907 const wxString
& label
,
2908 const wxString
& accel
,
2909 const wxBitmap
& bitmap
,
2913 const wxWin32MenuGeometryInfo
& geometryInfo
=
2914 (const wxWin32MenuGeometryInfo
&)gi
;
2919 rect
.width
= geometryInfo
.GetSize().x
;
2920 rect
.height
= geometryInfo
.GetItemHeight();
2922 // draw the selected item specially
2923 wxDCTextColourChanger
colChanger(dc
);
2924 if ( flags
& wxCONTROL_SELECTED
)
2926 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2928 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2929 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2930 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2931 dc
.DrawRectangle(rect
);
2934 // draw the bitmap: use the bitmap provided or the standard checkmark for
2935 // the checkable items
2936 wxBitmap bmp
= bitmap
;
2937 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2939 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2944 rect
.SetRight(geometryInfo
.GetLabelOffset());
2945 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2949 rect
.x
= geometryInfo
.GetLabelOffset();
2950 rect
.SetRight(geometryInfo
.GetAccelOffset());
2952 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2954 // draw the accel string
2955 rect
.x
= geometryInfo
.GetAccelOffset();
2956 rect
.SetRight(geometryInfo
.GetSize().x
);
2958 // NB: no accel index here
2959 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2961 // draw the submenu indicator
2962 if ( flags
& wxCONTROL_ISSUBMENU
)
2964 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2965 rect
.width
= MENU_RIGHT_MARGIN
;
2967 wxArrowStyle arrowStyle
;
2968 if ( flags
& wxCONTROL_DISABLED
)
2969 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
2971 else if ( flags
& wxCONTROL_SELECTED
)
2972 arrowStyle
= Arrow_Inversed
;
2974 arrowStyle
= Arrow_Normal
;
2976 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2980 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2982 const wxMenuGeometryInfo
& geomInfo
)
2984 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2987 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2989 wxSize size
= sizeText
;
2991 // FIXME: menubar height is configurable under Windows
2998 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2999 const wxMenu
& menu
) const
3001 // prepare the dc: for now we draw all the items with the system font
3003 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3005 // the height of a normal item
3006 wxCoord heightText
= dc
.GetCharHeight();
3011 // the max length of label and accel strings: the menu width is the sum of
3012 // them, even if they're for different items (as the accels should be
3015 // the max length of the bitmap is never 0 as Windows always leaves enough
3016 // space for a check mark indicator
3017 wxCoord widthLabelMax
= 0,
3019 widthBmpMax
= MENU_LEFT_MARGIN
;
3021 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
3023 node
= node
->GetNext() )
3025 // height of this item
3028 wxMenuItem
*item
= node
->GetData();
3029 if ( item
->IsSeparator() )
3031 h
= MENU_SEPARATOR_HEIGHT
;
3033 else // not separator
3038 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3039 if ( widthLabel
> widthLabelMax
)
3041 widthLabelMax
= widthLabel
;
3045 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3046 if ( widthAccel
> widthAccelMax
)
3048 widthAccelMax
= widthAccel
;
3051 const wxBitmap
& bmp
= item
->GetBitmap();
3054 wxCoord widthBmp
= bmp
.GetWidth();
3055 if ( widthBmp
> widthBmpMax
)
3056 widthBmpMax
= widthBmp
;
3058 //else if ( item->IsCheckable() ): no need to check for this as
3059 // MENU_LEFT_MARGIN is big enough to show the check mark
3062 h
+= 2*MENU_VERT_MARGIN
;
3064 // remember the item position and height
3065 item
->SetGeometry(height
, h
);
3070 // bundle the metrics into a struct and return it
3071 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3073 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3074 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3075 if ( widthAccelMax
> 0 )
3077 // if we actually have any accesl, add a margin
3078 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3081 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3083 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3084 gi
->m_size
.y
= height
;
3089 // ----------------------------------------------------------------------------
3091 // ----------------------------------------------------------------------------
3093 static const wxCoord STATBAR_BORDER_X
= 2;
3094 static const wxCoord STATBAR_BORDER_Y
= 2;
3096 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3098 if ( borderBetweenFields
)
3099 *borderBetweenFields
= 2;
3101 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3104 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3106 const wxString
& label
,
3111 if ( flags
& wxCONTROL_ISDEFAULT
)
3113 // draw the size grip: it is a normal rect except that in the lower
3114 // right corner we have several bands which may be used for dragging
3115 // the status bar corner
3117 // each band consists of 4 stripes: m_penHighlight, double
3118 // m_penDarkGrey and transparent one
3119 wxCoord x2
= rect
.GetRight(),
3120 y2
= rect
.GetBottom();
3122 // draw the upper left part of the rect normally
3123 dc
.SetPen(m_penDarkGrey
);
3124 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3125 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3127 // draw the grey stripes of the grip
3129 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3130 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3132 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3133 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3136 // draw the white stripes
3137 dc
.SetPen(m_penHighlight
);
3138 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3139 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3141 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3144 // draw the remaining rect boundaries
3145 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3146 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3147 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3152 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3156 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3159 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3161 wxDCClipper
clipper(dc
, rectIn
);
3162 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3165 // ----------------------------------------------------------------------------
3167 // ----------------------------------------------------------------------------
3169 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3171 wxBitmap
*bmpPressed
,
3172 wxBitmap
*bmpDisabled
)
3174 static const wxCoord widthCombo
= 16;
3175 static const wxCoord heightCombo
= 17;
3181 bmpNormal
->Create(widthCombo
, heightCombo
);
3182 dcMem
.SelectObject(*bmpNormal
);
3183 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3184 Arrow_Down
, Arrow_Normal
);
3189 bmpPressed
->Create(widthCombo
, heightCombo
);
3190 dcMem
.SelectObject(*bmpPressed
);
3191 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3192 Arrow_Down
, Arrow_Pressed
);
3197 bmpDisabled
->Create(widthCombo
, heightCombo
);
3198 dcMem
.SelectObject(*bmpDisabled
);
3199 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3200 Arrow_Down
, Arrow_Disabled
);
3204 // ----------------------------------------------------------------------------
3206 // ----------------------------------------------------------------------------
3208 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3209 const wxColour
& col
,
3213 wxBrush
brush(col
, wxSOLID
);
3215 dc
.SetPen(*wxTRANSPARENT_PEN
);
3216 dc
.DrawRectangle(rect
);
3219 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3220 const wxColour
& col
,
3225 // just fill it with the given or default bg colour
3226 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3227 DoDrawBackground(dc
, colBg
, rect
, window
);
3230 // ----------------------------------------------------------------------------
3232 // ----------------------------------------------------------------------------
3234 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3239 // get the bitmap for this arrow
3240 wxArrowDirection arrowDir
;
3243 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3244 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3245 case wxUP
: arrowDir
= Arrow_Up
; break;
3246 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3249 wxFAIL_MSG(_T("unknown arrow direction"));
3253 wxArrowStyle arrowStyle
;
3254 if ( flags
& wxCONTROL_PRESSED
)
3256 // can't be pressed and disabled
3257 arrowStyle
= Arrow_Pressed
;
3261 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3264 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3267 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3269 wxArrowDirection arrowDir
,
3270 wxArrowStyle arrowStyle
)
3272 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3274 // under Windows the arrows always have the same size so just centre it in
3275 // the provided rectangle
3276 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3277 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3279 // Windows does it like this...
3280 if ( arrowDir
== Arrow_Left
)
3284 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3287 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3288 const wxRect
& rectAll
,
3289 wxArrowDirection arrowDir
,
3290 wxArrowStyle arrowStyle
)
3292 wxRect rect
= rectAll
;
3293 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3294 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3295 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3298 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3299 wxOrientation orient
,
3303 // we don't use the flags, the thumb never changes appearance
3304 wxRect rectThumb
= rect
;
3305 DrawArrowBorder(dc
, &rectThumb
);
3306 DrawBackground(dc
, wxNullColour
, rectThumb
);
3309 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3310 wxOrientation orient
,
3311 const wxRect
& rectBar
,
3314 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3315 ? wxColourScheme::SCROLLBAR_PRESSED
3316 : wxColourScheme::SCROLLBAR
;
3317 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3320 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3322 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3325 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3326 wxScrollBar::Element elem
,
3329 return StandardGetScrollbarRect(scrollbar
, elem
,
3330 thumbPos
, m_sizeScrollbarArrow
);
3333 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3335 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3338 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3339 const wxPoint
& pt
) const
3341 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3344 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3347 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3350 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3353 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3356 // ----------------------------------------------------------------------------
3357 // top level windows
3358 // ----------------------------------------------------------------------------
3360 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3362 wxRect client
= GetFrameClientArea(rect
, flags
);
3364 if ( client
.Inside(pt
) )
3365 return wxHT_TOPLEVEL_CLIENT_AREA
;
3367 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3369 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3371 if ( flags
& wxTOPLEVEL_ICON
)
3373 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3374 return wxHT_TOPLEVEL_ICON
;
3377 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3378 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3379 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3381 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3383 if ( btnRect
.Inside(pt
) )
3384 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3385 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3387 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3389 if ( btnRect
.Inside(pt
) )
3390 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3391 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3393 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3395 if ( btnRect
.Inside(pt
) )
3396 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3397 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3399 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3401 if ( btnRect
.Inside(pt
) )
3402 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3403 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3405 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3407 if ( btnRect
.Inside(pt
) )
3408 return wxHT_TOPLEVEL_BUTTON_HELP
;
3409 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3412 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3413 return wxHT_TOPLEVEL_TITLEBAR
;
3416 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3418 // we are certainly at one of borders, lets decide which one:
3421 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3422 if ( pt
.x
< client
.x
)
3423 border
|= wxHT_TOPLEVEL_BORDER_W
;
3424 else if ( pt
.x
>= client
.width
+ client
.x
)
3425 border
|= wxHT_TOPLEVEL_BORDER_E
;
3426 if ( pt
.y
< client
.y
)
3427 border
|= wxHT_TOPLEVEL_BORDER_N
;
3428 else if ( pt
.y
>= client
.height
+ client
.y
)
3429 border
|= wxHT_TOPLEVEL_BORDER_S
;
3433 return wxHT_NOWHERE
;
3436 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3438 const wxString
& title
,
3442 int specialButtonFlags
)
3444 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3446 DrawFrameBorder(dc
, rect
, flags
);
3448 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3450 DrawFrameBackground(dc
, rect
, flags
);
3451 if ( flags
& wxTOPLEVEL_ICON
)
3452 DrawFrameIcon(dc
, rect
, icon
, flags
);
3453 DrawFrameTitle(dc
, rect
, title
, flags
);
3455 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3457 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3458 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3460 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3462 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3463 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3464 specialButtonFlags
: 0);
3465 x
-= FRAME_BUTTON_WIDTH
+ 2;
3467 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3469 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3470 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3471 specialButtonFlags
: 0);
3472 x
-= FRAME_BUTTON_WIDTH
;
3474 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3476 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3477 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3478 specialButtonFlags
: 0);
3479 x
-= FRAME_BUTTON_WIDTH
;
3481 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3483 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3484 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3485 specialButtonFlags
: 0);
3486 x
-= FRAME_BUTTON_WIDTH
;
3488 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3490 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3491 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3492 specialButtonFlags
: 0);
3493 x
-= FRAME_BUTTON_WIDTH
;
3498 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3502 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3506 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3507 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3508 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3509 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3510 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3513 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3517 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3519 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3520 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3521 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3523 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3524 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3526 DrawBackground(dc
, col
, r
);
3529 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3531 const wxString
& title
,
3534 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3535 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3536 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3538 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3539 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3540 if ( flags
& wxTOPLEVEL_ICON
)
3542 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3543 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3551 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3552 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3553 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3554 r
.width
-= FRAME_BUTTON_WIDTH
;
3555 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3556 r
.width
-= FRAME_BUTTON_WIDTH
;
3557 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3558 r
.width
-= FRAME_BUTTON_WIDTH
;
3559 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3560 r
.width
-= FRAME_BUTTON_WIDTH
;
3562 dc
.SetFont(m_titlebarFont
);
3563 dc
.SetTextForeground(col
);
3566 dc
.GetTextExtent(title
, &textW
, NULL
);
3567 if ( textW
> r
.width
)
3569 // text is too big, let's shorten it and add "..." after it:
3570 size_t len
= title
.length();
3571 wxCoord WSoFar
, letterW
;
3573 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3574 if ( WSoFar
> r
.width
)
3576 // not enough space to draw anything
3582 for (size_t i
= 0; i
< len
; i
++)
3584 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3585 if ( letterW
+ WSoFar
> r
.width
)
3591 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3592 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3595 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3596 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3599 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3606 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3607 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3611 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3612 wxCoord x
, wxCoord y
,
3616 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3621 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3622 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3623 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3624 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3625 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3627 wxFAIL_MSG(wxT("incorrect button specification"));
3630 if ( flags
& wxCONTROL_PRESSED
)
3632 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3633 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3634 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3635 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3639 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3640 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3641 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3642 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3647 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3652 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3654 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3655 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3656 FRAME_BORDER_THICKNESS
;
3659 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3661 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3662 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3668 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3671 wxSize
s(clientSize
);
3673 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3675 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3676 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3677 FRAME_BORDER_THICKNESS
;
3681 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3682 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3687 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3691 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3693 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3694 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3695 FRAME_BORDER_THICKNESS
;
3700 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3702 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3704 if ( flags
& wxTOPLEVEL_ICON
)
3705 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3706 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3707 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3708 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3709 s
.x
+= FRAME_BUTTON_WIDTH
;
3710 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3711 s
.x
+= FRAME_BUTTON_WIDTH
;
3712 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3713 s
.x
+= FRAME_BUTTON_WIDTH
;
3714 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3715 s
.x
+= FRAME_BUTTON_WIDTH
;
3721 wxSize
wxWin32Renderer::GetFrameIconSize() const
3723 return wxSize(16, 16);
3727 // ----------------------------------------------------------------------------
3729 // ----------------------------------------------------------------------------
3731 static char *error_xpm
[]={
3738 "...........########.............",
3739 "........###aaaaaaaa###..........",
3740 ".......#aaaaaaaaaaaaaa#.........",
3741 ".....##aaaaaaaaaaaaaaaa##.......",
3742 "....#aaaaaaaaaaaaaaaaaaaa#......",
3743 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3744 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3745 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3746 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3747 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3748 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3749 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3750 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3751 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3752 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3753 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3754 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3755 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3756 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3757 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3758 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3759 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3760 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3761 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3762 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3763 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3764 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3765 "......b#aaaaaaaaaaaaaa#bbbbb....",
3766 ".......b###aaaaaaaa###bbbbb.....",
3767 ".........bb########bbbbbb.......",
3768 "..........bbbbbbbbbbbbbb........",
3769 ".............bbbbbbbb..........."};
3771 static char *info_xpm
[]={
3779 "...........########.............",
3780 "........###abbbbbba###..........",
3781 "......##abbbbbbbbbbbba##........",
3782 ".....#abbbbbbbbbbbbbbbba#.......",
3783 "....#bbbbbbbaccccabbbbbbbd......",
3784 "...#bbbbbbbbccccccbbbbbbbbd.....",
3785 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3786 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3787 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3788 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3789 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3790 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3791 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3792 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3793 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3794 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3795 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3796 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3797 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3798 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3799 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3800 ".....dabbbbbbbbbbbbbbbbad####...",
3801 "......ddabbbbbbbbbbbbadd####....",
3802 ".......#dddabbbbbbaddd#####.....",
3803 "........###dddabbbd#######......",
3804 "..........####dbbbd#####........",
3805 ".............#dbbbd##...........",
3806 "...............dbbd##...........",
3807 "................dbd##...........",
3808 ".................dd##...........",
3809 "..................###...........",
3810 "...................##..........."};
3812 static char *question_xpm
[]={
3820 "...........########.............",
3821 "........###abbbbbba###..........",
3822 "......##abbbbbbbbbbbba##........",
3823 ".....#abbbbbbbbbbbbbbbba#.......",
3824 "....#bbbbbbbbbbbbbbbbbbbbc......",
3825 "...#bbbbbbbaddddddabbbbbbbc.....",
3826 "..#bbbbbbbadabbddddabbbbbbbc....",
3827 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3828 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3829 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3830 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3831 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3832 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3833 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3834 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3835 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3836 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3837 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3838 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3839 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3840 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3841 ".....cabbbbbbbbbbbbbbbbac####...",
3842 "......ccabbbbbbbbbbbbacc####....",
3843 ".......#cccabbbbbbaccc#####.....",
3844 "........###cccabbbc#######......",
3845 "..........####cbbbc#####........",
3846 ".............#cbbbc##...........",
3847 "...............cbbc##...........",
3848 "................cbc##...........",
3849 ".................cc##...........",
3850 "..................###...........",
3851 "...................##..........."};
3853 static char *warning_xpm
[]={
3861 ".............###................",
3862 "............#aabc...............",
3863 "...........#aaaabcd.............",
3864 "...........#aaaaacdd............",
3865 "..........#aaaaaabcdd...........",
3866 "..........#aaaaaaacdd...........",
3867 ".........#aaaaaaaabcdd..........",
3868 ".........#aaaaaaaaacdd..........",
3869 "........#aaaaaaaaaabcdd.........",
3870 "........#aaabcccbaaacdd.........",
3871 ".......#aaaacccccaaabcdd........",
3872 ".......#aaaacccccaaaacdd........",
3873 "......#aaaaacccccaaaabcdd.......",
3874 "......#aaaaacccccaaaaacdd.......",
3875 ".....#aaaaaacccccaaaaabcdd......",
3876 ".....#aaaaaa#ccc#aaaaaacdd......",
3877 "....#aaaaaaabcccbaaaaaabcdd.....",
3878 "....#aaaaaaaacccaaaaaaaacdd.....",
3879 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3880 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3881 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3882 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3883 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3884 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3885 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3886 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3887 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3888 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3889 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3890 "..#ccccccccccccccccccccccccddddd",
3891 "....ddddddddddddddddddddddddddd.",
3892 ".....ddddddddddddddddddddddddd.."};
3894 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3895 const wxArtClient
& WXUNUSED(client
),
3896 const wxSize
& WXUNUSED(size
))
3898 if ( id
== wxART_INFORMATION
)
3899 return wxBitmap(info_xpm
);
3900 if ( id
== wxART_ERROR
)
3901 return wxBitmap(error_xpm
);
3902 if ( id
== wxART_WARNING
)
3903 return wxBitmap(warning_xpm
);
3904 if ( id
== wxART_QUESTION
)
3905 return wxBitmap(question_xpm
);
3906 return wxNullBitmap
;
3910 // ----------------------------------------------------------------------------
3911 // text control geometry
3912 // ----------------------------------------------------------------------------
3914 static inline int GetTextBorderWidth()
3919 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3920 const wxRect
& rect
) const
3922 wxRect rectTotal
= rect
;
3924 wxCoord widthBorder
= GetTextBorderWidth();
3925 rectTotal
.Inflate(widthBorder
);
3927 // this is what Windows does
3933 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3935 wxCoord
*extraSpaceBeyond
) const
3937 wxRect rectText
= rect
;
3939 // undo GetTextTotalArea()
3940 if ( rectText
.height
> 0 )
3943 wxCoord widthBorder
= GetTextBorderWidth();
3944 rectText
.Inflate(-widthBorder
);
3946 if ( extraSpaceBeyond
)
3947 *extraSpaceBeyond
= 0;
3952 // ----------------------------------------------------------------------------
3954 // ----------------------------------------------------------------------------
3956 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3959 if ( wxDynamicCast(window
, wxScrollBar
) )
3961 // we only set the width of vert scrollbars and height of the
3963 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3964 size
->y
= m_sizeScrollbarArrow
.y
;
3966 size
->x
= m_sizeScrollbarArrow
.x
;
3968 // skip border width adjustments, they don't make sense for us
3971 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
3974 if ( wxDynamicCast(window
, wxButton
) )
3976 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3978 // TODO: don't harcode all this
3979 size
->x
+= 3*window
->GetCharWidth();
3981 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3982 if ( size
->y
< heightBtn
- 8 )
3983 size
->y
= heightBtn
;
3988 // no border width adjustments for buttons
3991 #endif // wxUSE_BUTTON
3993 // take into account the border width
3994 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3995 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3996 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3999 // ============================================================================
4001 // ============================================================================
4003 // ----------------------------------------------------------------------------
4004 // wxWin32InputHandler
4005 // ----------------------------------------------------------------------------
4007 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4009 m_renderer
= renderer
;
4012 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
4013 const wxKeyEvent
& event
,
4019 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4020 const wxMouseEvent
& event
)
4022 // clicking on the control gives it focus
4023 if ( event
.ButtonDown() )
4025 wxWindow
*win
= control
->GetInputWindow();
4027 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4028 ( win
->AcceptsFocus() ) )
4039 // ----------------------------------------------------------------------------
4040 // wxWin32ScrollBarInputHandler
4041 // ----------------------------------------------------------------------------
4043 wxWin32ScrollBarInputHandler::
4044 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4045 wxInputHandler
*handler
)
4046 : wxStdScrollBarInputHandler(renderer
, handler
)
4048 m_scrollPaused
= FALSE
;
4052 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4053 const wxControlAction
& action
)
4055 // stop if went beyond the position of the original click (this can only
4056 // happen when we scroll by pages)
4058 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4060 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4061 != wxHT_SCROLLBAR_BAR_2
;
4063 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4065 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4066 != wxHT_SCROLLBAR_BAR_1
;
4071 StopScrolling(scrollbar
);
4073 scrollbar
->Refresh();
4078 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4081 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4082 const wxMouseEvent
& event
)
4084 // remember the current state
4085 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4087 // do process the message
4088 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4090 // analyse the changes
4091 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4093 // we just started dragging the thumb, remember its initial position to
4094 // be able to restore it if the drag is cancelled later
4095 m_eventStartDrag
= event
;
4101 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4102 const wxMouseEvent
& event
)
4104 // we don't highlight scrollbar elements, so there is no need to process
4105 // mouse move events normally - only do it while mouse is captured (i.e.
4106 // when we're dragging the thumb or pressing on something)
4107 if ( !m_winCapture
)
4110 if ( event
.Entering() )
4112 // we're not interested in this at all
4116 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4118 if ( m_scrollPaused
)
4120 // check if the mouse returned to its original location
4122 if ( event
.Leaving() )
4128 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4129 if ( ht
== m_htLast
)
4131 // yes it did, resume scrolling
4132 m_scrollPaused
= FALSE
;
4133 if ( m_timerScroll
)
4135 // we were scrolling by line/page, restart timer
4136 m_timerScroll
->Start(m_interval
);
4138 Press(scrollbar
, TRUE
);
4140 else // we were dragging the thumb
4142 // restore its last location
4143 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4149 else // normal case, scrolling hasn't been paused
4151 // if we're scrolling the scrollbar because the arrow or the shaft was
4152 // pressed, check that the mouse stays on the same scrollbar element
4155 // Always let thumb jump back if we leave the scrollbar
4156 if ( event
.Moving() )
4158 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4160 else // event.Leaving()
4165 // Jump back only if we get far away from it
4166 wxPoint pos
= event
.GetPosition();
4167 if (scrollbar
->HasFlag( wxVERTICAL
))
4169 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4174 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4177 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4180 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4181 // is still ok - we only want to catch the case when the mouse leaves
4182 // the scrollbar here
4183 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4185 ht
= wxHT_SCROLLBAR_THUMB
;
4188 if ( ht
!= m_htLast
)
4190 // what were we doing? 2 possibilities: either an arrow/shaft was
4191 // pressed in which case we have a timer and so we just stop it or
4192 // we were dragging the thumb
4193 if ( m_timerScroll
)
4196 m_interval
= m_timerScroll
->GetInterval();
4197 m_timerScroll
->Stop();
4198 m_scrollPaused
= TRUE
;
4200 // unpress the arrow
4201 Press(scrollbar
, FALSE
);
4203 else // we were dragging the thumb
4205 // remember the current thumb position to be able to restore it
4206 // if the mouse returns to it later
4207 m_eventLastDrag
= event
;
4209 // and restore the original position (before dragging) of the
4211 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4218 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4221 // ----------------------------------------------------------------------------
4222 // wxWin32CheckboxInputHandler
4223 // ----------------------------------------------------------------------------
4225 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4226 const wxKeyEvent
& event
,
4231 wxControlAction action
;
4232 int keycode
= event
.GetKeyCode();
4236 action
= wxACTION_CHECKBOX_TOGGLE
;
4240 case WXK_NUMPAD_SUBTRACT
:
4241 action
= wxACTION_CHECKBOX_CHECK
;
4245 case WXK_NUMPAD_ADD
:
4246 case WXK_NUMPAD_EQUAL
:
4247 action
= wxACTION_CHECKBOX_CLEAR
;
4253 control
->PerformAction(action
);
4262 // ----------------------------------------------------------------------------
4263 // wxWin32TextCtrlInputHandler
4264 // ----------------------------------------------------------------------------
4266 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4267 const wxKeyEvent
& event
,
4270 // handle only MSW-specific text bindings here, the others are handled in
4274 int keycode
= event
.GetKeyCode();
4276 wxControlAction action
;
4277 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4279 action
= wxACTION_TEXT_CUT
;
4281 else if ( keycode
== WXK_INSERT
)
4283 if ( event
.ControlDown() )
4284 action
= wxACTION_TEXT_COPY
;
4285 else if ( event
.ShiftDown() )
4286 action
= wxACTION_TEXT_PASTE
;
4289 if ( action
!= wxACTION_NONE
)
4291 control
->PerformAction(action
);
4297 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4300 // ----------------------------------------------------------------------------
4301 // wxWin32StatusBarInputHandler
4302 // ----------------------------------------------------------------------------
4304 wxWin32StatusBarInputHandler::
4305 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4306 : wxStdInputHandler(handler
)
4311 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4312 const wxPoint
& pt
) const
4314 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4315 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4318 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4320 wxCHECK_MSG( parentTLW
, FALSE
,
4321 _T("the status bar should be a child of a TLW") );
4323 // a maximized window can't be resized anyhow
4324 if ( !parentTLW
->IsMaximized() )
4326 // VZ: I think that the standard Windows behaviour is to only
4327 // show the resizing cursor when the mouse is on top of the
4328 // grip itself but apparently different Windows versions behave
4329 // differently (?) and it seems a better UI to allow resizing
4330 // the status bar even when the mouse is above the grip
4331 wxSize sizeSbar
= statbar
->GetSize();
4333 int diff
= sizeSbar
.x
- pt
.x
;
4334 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4341 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4342 const wxMouseEvent
& event
)
4344 if ( event
.Button(1) )
4346 if ( event
.ButtonDown(1) )
4348 wxWindow
*statbar
= consumer
->GetInputWindow();
4350 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4352 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4356 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4357 wxHT_TOPLEVEL_BORDER_SE
);
4359 statbar
->SetCursor(m_cursorOld
);
4367 return wxStdInputHandler::HandleMouse(consumer
, event
);
4370 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4371 const wxMouseEvent
& event
)
4373 wxWindow
*statbar
= consumer
->GetInputWindow();
4375 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4376 if ( isOnGrip
!= m_isOnGrip
)
4378 m_isOnGrip
= isOnGrip
;
4381 m_cursorOld
= statbar
->GetCursor();
4382 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4386 statbar
->SetCursor(m_cursorOld
);
4390 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4393 // ----------------------------------------------------------------------------
4394 // wxWin32FrameInputHandler
4395 // ----------------------------------------------------------------------------
4397 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4400 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4402 void Attach(wxInputConsumer
*consumer
);
4406 DECLARE_EVENT_TABLE()
4407 void OnSystemMenu(wxCommandEvent
&event
);
4408 void OnCloseFrame(wxCommandEvent
&event
);
4409 void OnClose(wxCloseEvent
&event
);
4411 wxWin32FrameInputHandler
*m_inputHnd
;
4412 wxTopLevelWindow
*m_wnd
;
4413 wxAcceleratorTable m_oldAccelTable
;
4416 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4417 wxWin32FrameInputHandler
*handler
)
4419 m_inputHnd
= handler
;
4423 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4425 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4427 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4428 m_wnd
->PushEventHandler(this);
4430 // VS: This code relies on using generic implementation of
4431 // wxAcceleratorTable in wxUniv!
4432 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4433 m_oldAccelTable
= table
;
4434 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4435 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4436 m_wnd
->SetAcceleratorTable(table
);
4439 void wxWin32SystemMenuEvtHandler::Detach()
4443 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4444 m_wnd
->RemoveEventHandler(this);
4449 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4450 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4451 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4452 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4455 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4457 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4458 !m_wnd
->IsMaximized()) ?
4459 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4460 FRAME_BORDER_THICKNESS
;
4461 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4462 pt
.x
= -pt
.x
+ border
;
4463 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4465 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4466 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4467 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4468 m_wnd
->SetAcceleratorTable(table
);
4471 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4473 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4474 wxTOPLEVEL_BUTTON_CLOSE
);
4477 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4484 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4485 : wxStdFrameInputHandler(handler
)
4487 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4490 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4492 if ( m_menuHandler
)
4494 m_menuHandler
->Detach();
4495 delete m_menuHandler
;
4499 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4500 const wxMouseEvent
& event
)
4502 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4504 wxTopLevelWindow
*tlw
=
4505 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4507 long hit
= tlw
->HitTest(event
.GetPosition());
4509 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4511 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4512 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4513 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4516 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4518 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4519 (event
.RightDown() &&
4520 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4521 hit
== wxHT_TOPLEVEL_ICON
)) )
4523 PopupSystemMenu(tlw
, event
.GetPosition());
4529 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4532 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4533 const wxPoint
& pos
) const
4535 wxMenu
*menu
= new wxMenu
;
4537 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4538 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4539 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4540 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4541 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4542 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4543 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4544 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4545 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4546 menu
->AppendSeparator();
4547 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4549 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4551 if ( window
->IsMaximized() )
4553 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4554 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4555 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4556 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4559 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4562 window
->PopupMenu(menu
, pos
);
4566 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4569 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4571 // always detach if active frame changed:
4572 m_menuHandler
->Detach();
4576 m_menuHandler
->Attach(consumer
);
4580 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);