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
;
83 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
84 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
85 static const wxCoord SLIDER_TICK_LENGTH
= 6;
97 IndicatorState_Normal
,
98 IndicatorState_Pressed
, // this one is for check/radioboxes
99 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
100 IndicatorState_Disabled
,
101 IndicatorState_SelectedDisabled
, // only for the menus
107 IndicatorStatus_Checked
,
108 IndicatorStatus_Unchecked
,
112 // wxWin32Renderer: draw the GUI elements in Win32 style
113 // ----------------------------------------------------------------------------
115 class wxWin32Renderer
: public wxRenderer
119 enum wxArrowDirection
134 Arrow_InversedDisabled
,
138 enum wxFrameButtonType
141 FrameButton_Minimize
,
142 FrameButton_Maximize
,
149 wxWin32Renderer(const wxColourScheme
*scheme
);
151 // implement the base class pure virtuals
152 virtual void DrawBackground(wxDC
& dc
,
156 wxWindow
*window
= NULL
);
157 virtual void DrawLabel(wxDC
& dc
,
158 const wxString
& label
,
161 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
163 wxRect
*rectBounds
= NULL
);
164 virtual void DrawButtonLabel(wxDC
& dc
,
165 const wxString
& label
,
166 const wxBitmap
& image
,
169 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
171 wxRect
*rectBounds
= NULL
);
172 virtual void DrawBorder(wxDC
& dc
,
176 wxRect
*rectIn
= (wxRect
*)NULL
);
177 virtual void DrawHorizontalLine(wxDC
& dc
,
178 wxCoord y
, wxCoord x1
, wxCoord x2
);
179 virtual void DrawVerticalLine(wxDC
& dc
,
180 wxCoord x
, wxCoord y1
, wxCoord y2
);
181 virtual void DrawFrame(wxDC
& dc
,
182 const wxString
& label
,
185 int alignment
= wxALIGN_LEFT
,
186 int indexAccel
= -1);
187 virtual void DrawTextBorder(wxDC
& dc
,
191 wxRect
*rectIn
= (wxRect
*)NULL
);
192 virtual void DrawButtonBorder(wxDC
& dc
,
195 wxRect
*rectIn
= (wxRect
*)NULL
);
196 virtual void DrawArrow(wxDC
& dc
,
200 virtual void DrawScrollbarArrow(wxDC
& dc
,
204 { DrawArrow(dc
, dir
, rect
, flags
); }
205 virtual void DrawScrollbarThumb(wxDC
& dc
,
206 wxOrientation orient
,
209 virtual void DrawScrollbarShaft(wxDC
& dc
,
210 wxOrientation orient
,
213 virtual void DrawScrollCorner(wxDC
& dc
,
215 virtual void DrawItem(wxDC
& dc
,
216 const wxString
& label
,
219 virtual void DrawCheckItem(wxDC
& dc
,
220 const wxString
& label
,
221 const wxBitmap
& bitmap
,
224 virtual void DrawCheckButton(wxDC
& dc
,
225 const wxString
& label
,
226 const wxBitmap
& bitmap
,
229 wxAlignment align
= wxALIGN_LEFT
,
230 int indexAccel
= -1);
231 virtual void DrawRadioButton(wxDC
& dc
,
232 const wxString
& label
,
233 const wxBitmap
& bitmap
,
236 wxAlignment align
= wxALIGN_LEFT
,
237 int indexAccel
= -1);
238 virtual void DrawToolBarButton(wxDC
& dc
,
239 const wxString
& label
,
240 const wxBitmap
& bitmap
,
243 virtual void DrawTextLine(wxDC
& dc
,
244 const wxString
& text
,
249 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
250 virtual void DrawTab(wxDC
& dc
,
253 const wxString
& label
,
254 const wxBitmap
& bitmap
= wxNullBitmap
,
256 int indexAccel
= -1);
258 virtual void DrawSliderShaft(wxDC
& dc
,
261 wxOrientation orient
,
264 wxRect
*rectShaft
= NULL
);
265 virtual void DrawSliderThumb(wxDC
& dc
,
267 wxOrientation orient
,
270 virtual void DrawSliderTicks(wxDC
& dc
,
273 wxOrientation orient
,
280 virtual void DrawMenuBarItem(wxDC
& dc
,
282 const wxString
& label
,
284 int indexAccel
= -1);
285 virtual void DrawMenuItem(wxDC
& dc
,
287 const wxMenuGeometryInfo
& geometryInfo
,
288 const wxString
& label
,
289 const wxString
& accel
,
290 const wxBitmap
& bitmap
= wxNullBitmap
,
292 int indexAccel
= -1);
293 virtual void DrawMenuSeparator(wxDC
& dc
,
295 const wxMenuGeometryInfo
& geomInfo
);
297 virtual void DrawStatusField(wxDC
& dc
,
299 const wxString
& label
,
303 virtual void DrawFrameTitleBar(wxDC
& dc
,
305 const wxString
& title
,
308 int specialButton
= 0,
309 int specialButtonFlags
= 0);
310 virtual void DrawFrameBorder(wxDC
& dc
,
313 virtual void DrawFrameBackground(wxDC
& dc
,
316 virtual void DrawFrameTitle(wxDC
& dc
,
318 const wxString
& title
,
320 virtual void DrawFrameIcon(wxDC
& dc
,
324 virtual void DrawFrameButton(wxDC
& dc
,
325 wxCoord x
, wxCoord y
,
328 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
329 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
330 virtual wxSize
GetFrameMinSize(int flags
) const;
331 virtual wxSize
GetFrameIconSize() const;
332 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
334 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
336 wxBitmap
*bmpPressed
,
337 wxBitmap
*bmpDisabled
);
339 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
340 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
341 virtual bool AreScrollbarsInsideBorder() const;
343 virtual wxSize
GetScrollbarArrowSize() const
344 { return m_sizeScrollbarArrow
; }
345 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
346 wxScrollBar::Element elem
,
347 int thumbPos
= -1) const;
348 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
349 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
350 const wxPoint
& pt
) const;
351 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
353 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
354 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
355 { return fontHeight
+ 2; }
356 virtual wxSize
GetCheckBitmapSize() const
357 { return wxSize(13, 13); }
358 virtual wxSize
GetRadioBitmapSize() const
359 { return wxSize(12, 12); }
360 virtual wxCoord
GetCheckItemMargin() const
363 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
364 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
365 virtual wxSize
GetToolBarMargin() const
366 { return wxSize(4, 4); }
368 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
369 const wxRect
& rect
) const;
370 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
372 wxCoord
*extraSpaceBeyond
) const;
374 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
375 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
377 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
378 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
379 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
381 wxOrientation orient
,
382 long style
= 0) const;
383 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
385 wxOrientation orient
) const;
386 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
388 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
389 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
390 const wxMenu
& menu
) const;
392 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
395 // helper of DrawLabel() and DrawCheckOrRadioButton()
396 void DoDrawLabel(wxDC
& dc
,
397 const wxString
& label
,
400 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
402 wxRect
*rectBounds
= NULL
,
403 const wxPoint
& focusOffset
404 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
406 // common part of DrawLabel() and DrawItem()
407 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
409 // DrawLabel() and DrawButtonLabel() helper
410 void DrawLabelShadow(wxDC
& dc
,
411 const wxString
& label
,
416 // DrawButtonBorder() helper
417 void DoDrawBackground(wxDC
& dc
,
420 wxWindow
*window
= NULL
);
422 // DrawBorder() helpers: all of them shift and clip the DC after drawing
425 // just draw a rectangle with the given pen
426 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
428 // draw the lower left part of rectangle
429 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
431 // draw the rectange using the first brush for the left and top sides and
432 // the second one for the bottom and right ones
433 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
434 const wxPen
& pen1
, const wxPen
& pen2
);
436 // draw the normal 3D border
437 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
439 // draw the sunken 3D border
440 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
442 // draw the border used for scrollbar arrows
443 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
445 // public DrawArrow()s helper
446 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
447 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
449 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
450 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
451 wxArrowDirection arrowDir
,
452 wxArrowStyle arrowStyle
);
454 // DrawCheckButton/DrawRadioButton helper
455 void DrawCheckOrRadioButton(wxDC
& dc
,
456 const wxString
& label
,
457 const wxBitmap
& bitmap
,
462 wxCoord focusOffsetY
);
464 // draw a normal or transposed line (useful for using the same code fo both
465 // horizontal and vertical widgets)
466 void DrawLine(wxDC
& dc
,
467 wxCoord x1
, wxCoord y1
,
468 wxCoord x2
, wxCoord y2
,
469 bool transpose
= FALSE
)
472 dc
.DrawLine(y1
, x1
, y2
, x2
);
474 dc
.DrawLine(x1
, y1
, x2
, y2
);
477 // get the standard check/radio button bitmap
478 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
479 wxBitmap
GetCheckBitmap(int flags
)
480 { return GetIndicator(IndicatorType_Check
, flags
); }
481 wxBitmap
GetRadioBitmap(int flags
)
482 { return GetIndicator(IndicatorType_Radio
, flags
); }
485 const wxColourScheme
*m_scheme
;
487 // the sizing parameters (TODO make them changeable)
488 wxSize m_sizeScrollbarArrow
;
490 // GDI objects we use for drawing
491 wxColour m_colDarkGrey
,
499 wxFont m_titlebarFont
;
501 // the checked and unchecked bitmaps for DrawCheckItem()
502 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
504 // the bitmaps returned by GetIndicator()
505 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
507 [IndicatorStatus_Max
];
510 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
512 // first row is for the normal state, second - for the disabled
513 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
516 // ----------------------------------------------------------------------------
517 // wxWin32InputHandler and derived classes: process the keyboard and mouse
518 // messages according to Windows standards
519 // ----------------------------------------------------------------------------
521 class wxWin32InputHandler
: public wxInputHandler
524 wxWin32InputHandler(wxWin32Renderer
*renderer
);
526 virtual bool HandleKey(wxInputConsumer
*control
,
527 const wxKeyEvent
& event
,
529 virtual bool HandleMouse(wxInputConsumer
*control
,
530 const wxMouseEvent
& event
);
533 wxWin32Renderer
*m_renderer
;
536 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
539 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
540 wxInputHandler
*handler
);
542 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
543 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
545 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
546 const wxControlAction
& action
);
549 virtual bool IsAllowedButton(int button
) { return button
== 1; }
551 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
553 // we don't highlight anything
556 // the first and last event which caused the thumb to move
557 wxMouseEvent m_eventStartDrag
,
560 // have we paused the scrolling because the mouse moved?
563 // we remember the interval of the timer to be able to restart it
567 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
570 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
571 : wxStdCheckboxInputHandler(handler
) { }
573 virtual bool HandleKey(wxInputConsumer
*control
,
574 const wxKeyEvent
& event
,
578 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
581 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
582 : wxStdTextCtrlInputHandler(handler
) { }
584 virtual bool HandleKey(wxInputConsumer
*control
,
585 const wxKeyEvent
& event
,
589 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
592 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
594 virtual bool HandleMouse(wxInputConsumer
*consumer
,
595 const wxMouseEvent
& event
);
597 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
598 const wxMouseEvent
& event
);
601 // is the given point over the statusbar grip?
602 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
605 // the cursor we had replaced with the resize one
606 wxCursor m_cursorOld
;
608 // was the mouse over the grip last time we checked?
612 class wxWin32SystemMenuEvtHandler
;
614 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
617 wxWin32FrameInputHandler(wxInputHandler
*handler
);
618 ~wxWin32FrameInputHandler();
620 virtual bool HandleMouse(wxInputConsumer
*control
,
621 const wxMouseEvent
& event
);
623 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
625 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
628 // was the mouse over the grip last time we checked?
629 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
632 // ----------------------------------------------------------------------------
633 // wxWin32ColourScheme: uses (default) Win32 colours
634 // ----------------------------------------------------------------------------
636 class wxWin32ColourScheme
: public wxColourScheme
639 virtual wxColour
Get(StdColour col
) const;
640 virtual wxColour
GetBackground(wxWindow
*win
) const;
643 // ----------------------------------------------------------------------------
644 // wxWin32ArtProvider
645 // ----------------------------------------------------------------------------
647 class wxWin32ArtProvider
: public wxArtProvider
650 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
651 const wxArtClient
& client
,
655 // ----------------------------------------------------------------------------
657 // ----------------------------------------------------------------------------
659 WX_DEFINE_ARRAY(wxInputHandler
*, wxArrayHandlers
);
661 class wxWin32Theme
: public wxTheme
665 virtual ~wxWin32Theme();
667 virtual wxRenderer
*GetRenderer();
668 virtual wxArtProvider
*GetArtProvider();
669 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
670 virtual wxColourScheme
*GetColourScheme();
673 // get the default input handler
674 wxInputHandler
*GetDefaultInputHandler();
676 wxWin32Renderer
*m_renderer
;
678 wxWin32ArtProvider
*m_artProvider
;
680 // the names of the already created handlers and the handlers themselves
681 // (these arrays are synchronized)
682 wxSortedArrayString m_handlerNames
;
683 wxArrayHandlers m_handlers
;
685 wxWin32InputHandler
*m_handlerDefault
;
687 wxWin32ColourScheme
*m_scheme
;
689 WX_DECLARE_THEME(win32
)
692 // ----------------------------------------------------------------------------
694 // ----------------------------------------------------------------------------
696 // frame buttons bitmaps
698 static const char *frame_button_close_xpm
[] = {
713 static const char *frame_button_help_xpm
[] = {
728 static const char *frame_button_maximize_xpm
[] = {
743 static const char *frame_button_minimize_xpm
[] = {
758 static const char *frame_button_restore_xpm
[] = {
775 static const char *checked_menu_xpm
[] = {
776 /* columns rows colors chars-per-pixel */
792 static const char *selected_checked_menu_xpm
[] = {
793 /* columns rows colors chars-per-pixel */
809 static const char *disabled_checked_menu_xpm
[] = {
810 /* columns rows colors chars-per-pixel */
827 static const char *selected_disabled_checked_menu_xpm
[] = {
828 /* columns rows colors chars-per-pixel */
844 // checkbox and radiobox bitmaps below
846 static const char *checked_xpm
[] = {
847 /* columns rows colors chars-per-pixel */
870 static const char *pressed_checked_xpm
[] = {
871 /* columns rows colors chars-per-pixel */
893 static const char *pressed_disabled_checked_xpm
[] = {
894 /* columns rows colors chars-per-pixel */
916 static const char *checked_item_xpm
[] = {
917 /* columns rows colors chars-per-pixel */
938 static const char *unchecked_xpm
[] = {
939 /* columns rows colors chars-per-pixel */
962 static const char *pressed_unchecked_xpm
[] = {
963 /* columns rows colors chars-per-pixel */
985 static const char *unchecked_item_xpm
[] = {
986 /* columns rows colors chars-per-pixel */
1006 static const char *checked_radio_xpm
[] = {
1007 /* columns rows colors chars-per-pixel */
1030 static const char *pressed_checked_radio_xpm
[] = {
1031 /* columns rows colors chars-per-pixel */
1054 static const char *pressed_disabled_checked_radio_xpm
[] = {
1055 /* columns rows colors chars-per-pixel */
1078 static const char *unchecked_radio_xpm
[] = {
1079 /* columns rows colors chars-per-pixel */
1102 static const char *pressed_unchecked_radio_xpm
[] = {
1103 /* columns rows colors chars-per-pixel */
1126 static const char **
1127 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1132 { checked_xpm
, unchecked_xpm
},
1135 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1138 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1144 { checked_radio_xpm
, unchecked_radio_xpm
},
1147 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1150 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1156 { checked_menu_xpm
, NULL
},
1159 { selected_checked_menu_xpm
, NULL
},
1162 { disabled_checked_menu_xpm
, NULL
},
1164 // disabled selected state
1165 { selected_disabled_checked_menu_xpm
, NULL
},
1169 static const char **xpmChecked
[IndicatorStatus_Max
] =
1175 // ============================================================================
1177 // ============================================================================
1179 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1181 // ----------------------------------------------------------------------------
1183 // ----------------------------------------------------------------------------
1185 wxWin32Theme::wxWin32Theme()
1189 m_handlerDefault
= NULL
;
1190 m_artProvider
= NULL
;
1193 wxWin32Theme::~wxWin32Theme()
1195 size_t count
= m_handlers
.GetCount();
1196 for ( size_t n
= 0; n
< count
; n
++ )
1198 if ( m_handlers
[n
] != m_handlerDefault
)
1199 delete m_handlers
[n
];
1202 delete m_handlerDefault
;
1206 wxArtProvider::RemoveProvider(m_artProvider
);
1209 wxRenderer
*wxWin32Theme::GetRenderer()
1213 m_renderer
= new wxWin32Renderer(GetColourScheme());
1219 wxArtProvider
*wxWin32Theme::GetArtProvider()
1221 if ( !m_artProvider
)
1223 m_artProvider
= new wxWin32ArtProvider
;
1226 return m_artProvider
;
1229 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1231 if ( !m_handlerDefault
)
1233 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1236 return m_handlerDefault
;
1239 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1241 wxInputHandler
*handler
;
1242 int n
= m_handlerNames
.Index(control
);
1243 if ( n
== wxNOT_FOUND
)
1245 // create a new handler
1246 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1247 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1248 GetDefaultInputHandler());
1250 else if ( control
== wxINP_HANDLER_BUTTON
)
1251 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1252 #endif // wxUSE_BUTTON
1254 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1255 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1256 #endif // wxUSE_CHECKBOX
1258 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1259 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1260 #endif // wxUSE_COMBOBOX
1262 else if ( control
== wxINP_HANDLER_LISTBOX
)
1263 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1264 #endif // wxUSE_LISTBOX
1265 #if wxUSE_CHECKLISTBOX
1266 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1267 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1268 #endif // wxUSE_CHECKLISTBOX
1270 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1271 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1272 #endif // wxUSE_TEXTCTRL
1274 else if ( control
== wxINP_HANDLER_SLIDER
)
1275 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1276 #endif // wxUSE_SLIDER
1278 else if ( control
== wxINP_HANDLER_SPINBTN
)
1279 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1280 #endif // wxUSE_SPINBTN
1282 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1283 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1284 #endif // wxUSE_NOTEBOOK
1286 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1287 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1288 #endif // wxUSE_STATUSBAR
1290 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1291 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1292 #endif // wxUSE_TOOLBAR
1293 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1294 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1296 handler
= GetDefaultInputHandler();
1298 n
= m_handlerNames
.Add(control
);
1299 m_handlers
.Insert(handler
, n
);
1301 else // we already have it
1303 handler
= m_handlers
[n
];
1309 wxColourScheme
*wxWin32Theme::GetColourScheme()
1313 m_scheme
= new wxWin32ColourScheme
;
1318 // ============================================================================
1319 // wxWin32ColourScheme
1320 // ============================================================================
1322 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1325 if ( win
->UseBgCol() )
1327 // use the user specified colour
1328 col
= win
->GetBackgroundColour();
1331 if ( win
->IsContainerWindow() )
1333 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1336 if ( !text
->IsEnabled() ) // not IsEditable()
1338 //else: execute code below
1343 // doesn't depend on the state
1349 int flags
= win
->GetStateFlags();
1351 // the colour set by the user should be used for the normal state
1352 // and for the states for which we don't have any specific colours
1353 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1355 if ( wxDynamicCast(win
, wxScrollBar
) )
1356 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1366 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1370 // use the system colours under Windows
1371 #if defined(__WXMSW__)
1372 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1374 case CONTROL_PRESSED
:
1375 case CONTROL_CURRENT
:
1376 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1378 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1380 #if defined(COLOR_3DLIGHT)
1381 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1383 case SCROLLBAR
: return wxColour(0xe0e0e0);
1385 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1387 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1388 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1390 #if defined(COLOR_3DDKSHADOW)
1391 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1393 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1396 case CONTROL_TEXT_DISABLED
:
1397 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1399 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1401 case CONTROL_TEXT_DISABLED_SHADOW
:
1402 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1404 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1405 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1406 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1407 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1409 case DESKTOP
: return wxColour(0x808000);
1411 // use the standard Windows colours elsewhere
1412 case WINDOW
: return *wxWHITE
;
1414 case CONTROL_PRESSED
:
1415 case CONTROL_CURRENT
:
1416 case CONTROL
: return wxColour(0xc0c0c0);
1418 case CONTROL_TEXT
: return *wxBLACK
;
1420 case SCROLLBAR
: return wxColour(0xe0e0e0);
1421 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1423 case HIGHLIGHT
: return wxColour(0x800000);
1424 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1426 case SHADOW_DARK
: return *wxBLACK
;
1428 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1429 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1431 case SHADOW_IN
: return wxColour(0xc0c0c0);
1433 case CONTROL_TEXT_DISABLED_SHADOW
:
1434 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1436 case TITLEBAR
: return wxColour(0xaeaaae);
1437 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1438 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1439 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1441 case DESKTOP
: return wxColour(0x808000);
1444 case GAUGE
: return Get(HIGHLIGHT
);
1448 wxFAIL_MSG(_T("invalid standard colour"));
1453 // ============================================================================
1455 // ============================================================================
1457 // ----------------------------------------------------------------------------
1459 // ----------------------------------------------------------------------------
1461 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1465 m_sizeScrollbarArrow
= wxSize(16, 16);
1467 // init colours and pens
1468 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1470 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1471 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1473 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1475 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1476 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1478 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1479 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1481 // init the arrow bitmaps
1482 static const size_t ARROW_WIDTH
= 7;
1483 static const size_t ARROW_LENGTH
= 4;
1486 wxMemoryDC dcNormal
,
1489 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1491 bool isVertical
= n
> Arrow_Right
;
1504 // disabled arrow is larger because of the shadow
1505 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1506 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1508 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1509 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1511 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1512 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1516 dcNormal
.SetPen(m_penBlack
);
1517 dcDisabled
.SetPen(m_penDarkGrey
);
1519 // calculate the position of the point of the arrow
1523 x1
= (ARROW_WIDTH
- 1)/2;
1524 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1528 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1529 y1
= (ARROW_WIDTH
- 1)/2;
1540 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1542 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1543 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1550 if ( n
== Arrow_Up
)
1561 else // left or right arrow
1566 if ( n
== Arrow_Left
)
1579 // draw the shadow for the disabled one
1580 dcDisabled
.SetPen(m_penHighlight
);
1585 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1589 x1
= ARROW_LENGTH
- 1;
1590 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1593 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1594 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1599 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1603 x1
= ARROW_WIDTH
- 1;
1605 x2
= (ARROW_WIDTH
- 1)/2;
1607 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1608 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1613 // create the inversed bitmap but only for the right arrow as we only
1614 // use it for the menus
1615 if ( n
== Arrow_Right
)
1617 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1618 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1620 dcInverse
.Blit(0, 0, w
, h
,
1623 dcInverse
.SelectObject(wxNullBitmap
);
1625 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1626 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1628 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1629 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1631 dcInverse
.Blit(0, 0, w
, h
,
1634 dcInverse
.SelectObject(wxNullBitmap
);
1636 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1637 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1640 dcNormal
.SelectObject(wxNullBitmap
);
1641 dcDisabled
.SelectObject(wxNullBitmap
);
1643 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1644 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1645 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1646 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1648 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1651 // init the frame buttons bitmaps
1652 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1653 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1654 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1655 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1656 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1659 // ----------------------------------------------------------------------------
1661 // ----------------------------------------------------------------------------
1664 The raised border in Win32 looks like this:
1666 IIIIIIIIIIIIIIIIIIIIIIB
1668 I GB I = white (HILIGHT)
1669 I GB H = light grey (LIGHT)
1670 I GB G = dark grey (SHADOI)
1671 I GB B = black (DKSHADOI)
1672 I GB I = hIghlight (COLOR_3DHILIGHT)
1674 IGGGGGGGGGGGGGGGGGGGGGB
1675 BBBBBBBBBBBBBBBBBBBBBBB
1677 The sunken border looks like this:
1679 GGGGGGGGGGGGGGGGGGGGGGI
1680 GBBBBBBBBBBBBBBBBBBBBHI
1687 GHHHHHHHHHHHHHHHHHHHHHI
1688 IIIIIIIIIIIIIIIIIIIIIII
1690 The static border (used for the controls which don't get focus) is like
1693 GGGGGGGGGGGGGGGGGGGGGGW
1701 WWWWWWWWWWWWWWWWWWWWWWW
1703 The most complicated is the double border:
1705 HHHHHHHHHHHHHHHHHHHHHHB
1706 HWWWWWWWWWWWWWWWWWWWWGB
1707 HWHHHHHHHHHHHHHHHHHHHGB
1712 HWHHHHHHHHHHHHHHHHHHHGB
1713 HGGGGGGGGGGGGGGGGGGGGGB
1714 BBBBBBBBBBBBBBBBBBBBBBB
1716 And the simple border is, well, simple:
1718 BBBBBBBBBBBBBBBBBBBBBBB
1727 BBBBBBBBBBBBBBBBBBBBBBB
1730 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1734 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1735 dc
.DrawRectangle(*rect
);
1741 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1743 // draw the bottom and right sides
1745 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1746 rect
->GetRight() + 1, rect
->GetBottom());
1747 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1748 rect
->GetRight(), rect
->GetBottom());
1754 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1755 const wxPen
& pen1
, const wxPen
& pen2
)
1757 // draw the rectangle
1759 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1760 rect
->GetLeft(), rect
->GetBottom());
1761 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1762 rect
->GetRight(), rect
->GetTop());
1764 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1765 rect
->GetRight(), rect
->GetBottom());
1766 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1767 rect
->GetRight() + 1, rect
->GetBottom());
1773 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1775 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1776 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1779 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1781 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1782 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1785 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1789 DrawRect(dc
, rect
, m_penDarkGrey
);
1791 // the arrow is usually drawn inside border of width 2 and is offset by
1792 // another pixel in both directions when it's pressed - as the border
1793 // in this case is more narrow as well, we have to adjust rect like
1801 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1802 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1806 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1808 const wxRect
& rectTotal
,
1809 int WXUNUSED(flags
),
1814 wxRect rect
= rectTotal
;
1818 case wxBORDER_SUNKEN
:
1819 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1821 DrawSunkenBorder(dc
, &rect
);
1825 case wxBORDER_STATIC
:
1826 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1829 case wxBORDER_RAISED
:
1830 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1832 DrawRaisedBorder(dc
, &rect
);
1836 case wxBORDER_DOUBLE
:
1837 DrawArrowBorder(dc
, &rect
);
1838 DrawRect(dc
, &rect
, m_penLightGrey
);
1841 case wxBORDER_SIMPLE
:
1842 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1844 DrawRect(dc
, &rect
, m_penBlack
);
1849 wxFAIL_MSG(_T("unknown border type"));
1852 case wxBORDER_DEFAULT
:
1861 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1866 case wxBORDER_RAISED
:
1867 case wxBORDER_SUNKEN
:
1868 width
= BORDER_THICKNESS
;
1871 case wxBORDER_SIMPLE
:
1872 case wxBORDER_STATIC
:
1876 case wxBORDER_DOUBLE
:
1882 // char *crash = NULL;
1884 wxFAIL_MSG(_T("unknown border type"));
1888 case wxBORDER_DEFAULT
:
1898 rect
.height
= width
;
1903 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1908 // ----------------------------------------------------------------------------
1910 // ----------------------------------------------------------------------------
1912 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1918 // text controls are not special under windows
1919 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1922 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1923 const wxRect
& rectTotal
,
1927 wxRect rect
= rectTotal
;
1929 if ( flags
& wxCONTROL_PRESSED
)
1931 // button pressed: draw a double border around it
1932 DrawRect(dc
, &rect
, m_penBlack
);
1933 DrawRect(dc
, &rect
, m_penDarkGrey
);
1937 // button not pressed
1939 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1941 // button either default or focused (or both): add an extra border around it
1942 DrawRect(dc
, &rect
, m_penBlack
);
1945 // now draw a normal button
1946 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1947 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1956 // ----------------------------------------------------------------------------
1958 // ----------------------------------------------------------------------------
1960 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1961 wxCoord y
, wxCoord x1
, wxCoord x2
)
1963 dc
.SetPen(m_penDarkGrey
);
1964 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1965 dc
.SetPen(m_penHighlight
);
1967 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1970 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1971 wxCoord x
, wxCoord y1
, wxCoord y2
)
1973 dc
.SetPen(m_penDarkGrey
);
1974 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1975 dc
.SetPen(m_penHighlight
);
1977 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1980 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1981 const wxString
& label
,
1987 wxCoord height
= 0; // of the label
1988 wxRect rectFrame
= rect
;
1989 if ( !label
.empty() )
1991 // the text should touch the top border of the rect, so the frame
1992 // itself should be lower
1993 dc
.GetTextExtent(label
, NULL
, &height
);
1994 rectFrame
.y
+= height
/ 2;
1995 rectFrame
.height
-= height
/ 2;
1997 // we have to draw each part of the frame individually as we can't
1998 // erase the background beyond the label as it might contain some
1999 // pixmap already, so drawing everything and then overwriting part of
2000 // the frame with label doesn't work
2002 // TODO: the +5 and space insertion should be customizable
2005 rectText
.x
= rectFrame
.x
+ 5;
2006 rectText
.y
= rect
.y
;
2007 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2008 rectText
.height
= height
;
2011 label2
<< _T(' ') << label
<< _T(' ');
2012 if ( indexAccel
!= -1 )
2014 // adjust it as we prepended a space
2019 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2021 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2025 // just draw the complete frame
2026 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2027 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2031 // ----------------------------------------------------------------------------
2033 // ----------------------------------------------------------------------------
2035 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2037 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2038 // pixels each while we really need dots here... PS_ALTERNATE might
2039 // work, but it is for NT 5 only
2041 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2043 // draw the pixels manually: note that to behave in the same manner as
2044 // DrawRect(), we must exclude the bottom and right borders from the
2046 wxCoord x1
= rect
.GetLeft(),
2048 x2
= rect
.GetRight(),
2049 y2
= rect
.GetBottom();
2051 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2053 // this seems to be closer than what Windows does than wxINVERT although
2054 // I'm still not sure if it's correct
2055 dc
.SetLogicalFunction(wxAND_REVERSE
);
2058 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2059 dc
.DrawPoint(z
, rect
.GetTop());
2061 wxCoord shift
= z
== x2
? 0 : 1;
2062 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2063 dc
.DrawPoint(x2
, z
);
2065 shift
= z
== y2
? 0 : 1;
2066 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2067 dc
.DrawPoint(z
, y2
);
2069 shift
= z
== x1
? 0 : 1;
2070 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2071 dc
.DrawPoint(x1
, z
);
2073 dc
.SetLogicalFunction(wxCOPY
);
2077 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2078 const wxString
& label
,
2083 // draw shadow of the text
2084 dc
.SetTextForeground(m_colHighlight
);
2085 wxRect rectShadow
= rect
;
2088 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2090 // make the text grey
2091 dc
.SetTextForeground(m_colDarkGrey
);
2094 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2095 const wxString
& label
,
2102 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2105 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2106 const wxString
& label
,
2112 const wxPoint
& focusOffset
)
2114 // the underscores are not drawn for focused controls in wxMSW
2115 if ( flags
& wxCONTROL_FOCUSED
)
2120 if ( flags
& wxCONTROL_DISABLED
)
2122 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2123 // currently only can happen for a menu item and it seems that Windows
2124 // doesn't draw the shadow in this case, so we don't do it neither
2125 if ( flags
& wxCONTROL_SELECTED
)
2127 // just make the label text greyed out
2128 dc
.SetTextForeground(m_colDarkGrey
);
2130 else // draw normal disabled label
2132 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2137 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2139 if ( flags
& wxCONTROL_DISABLED
)
2141 // restore the fg colour
2142 dc
.SetTextForeground(*wxBLACK
);
2145 if ( flags
& wxCONTROL_FOCUSED
)
2147 if ( focusOffset
.x
|| focusOffset
.y
)
2149 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2152 DrawFocusRect(dc
, rectLabel
);
2156 *rectBounds
= rectLabel
;
2159 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2160 const wxString
& label
,
2161 const wxBitmap
& image
,
2168 // the underscores are not drawn for focused controls in wxMSW
2169 if ( flags
& wxCONTROL_PRESSED
)
2174 wxRect rectLabel
= rect
;
2175 if ( !label
.empty() )
2177 // shift the label if a button is pressed
2178 if ( flags
& wxCONTROL_PRESSED
)
2184 if ( flags
& wxCONTROL_DISABLED
)
2186 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2189 // leave enough space for the focus rectangle
2190 if ( flags
& wxCONTROL_FOCUSED
)
2192 rectLabel
.Inflate(-2);
2196 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2198 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2200 if ( flags
& wxCONTROL_PRESSED
)
2202 // the focus rectangle is never pressed, so undo the shift done
2210 DrawFocusRect(dc
, rectLabel
);
2214 // ----------------------------------------------------------------------------
2215 // (check)listbox items
2216 // ----------------------------------------------------------------------------
2218 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2219 const wxString
& label
,
2223 wxDCTextColourChanger
colChanger(dc
);
2225 if ( flags
& wxCONTROL_SELECTED
)
2227 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2229 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2230 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2231 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2232 dc
.DrawRectangle(rect
);
2235 wxRect rectText
= rect
;
2237 rectText
.width
-= 2;
2238 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2240 if ( flags
& wxCONTROL_FOCUSED
)
2242 DrawFocusRect(dc
, rect
);
2246 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2247 const wxString
& label
,
2248 const wxBitmap
& bitmap
,
2257 else // use default bitmap
2259 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2260 ? IndicatorStatus_Checked
2261 : IndicatorStatus_Unchecked
;
2263 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2265 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2268 bmp
= m_bmpCheckBitmaps
[i
];
2271 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2272 TRUE
/* use mask */);
2274 wxRect rectLabel
= rect
;
2275 int bmpWidth
= bmp
.GetWidth();
2276 rectLabel
.x
+= bmpWidth
;
2277 rectLabel
.width
-= bmpWidth
;
2279 DrawItem(dc
, label
, rectLabel
, flags
);
2282 // ----------------------------------------------------------------------------
2283 // check/radio buttons
2284 // ----------------------------------------------------------------------------
2286 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2288 IndicatorState indState
;
2289 if ( flags
& wxCONTROL_SELECTED
)
2290 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2291 : IndicatorState_Selected
;
2292 else if ( flags
& wxCONTROL_DISABLED
)
2293 indState
= IndicatorState_Disabled
;
2294 else if ( flags
& wxCONTROL_PRESSED
)
2295 indState
= IndicatorState_Pressed
;
2297 indState
= IndicatorState_Normal
;
2299 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2300 ? IndicatorStatus_Checked
2301 : IndicatorStatus_Unchecked
;
2303 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2306 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2309 // create and cache it
2310 bmp
= wxBitmap(xpm
);
2311 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2318 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2319 const wxString
& label
,
2320 const wxBitmap
& bitmap
,
2325 wxCoord focusOffsetY
)
2327 // calculate the position of the bitmap and of the label
2328 wxCoord heightBmp
= bitmap
.GetHeight();
2330 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2333 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2334 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2336 // align label vertically with the bitmap - looks nicer like this
2337 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2339 // calc horz position
2340 if ( align
== wxALIGN_RIGHT
)
2342 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2343 rectLabel
.x
= rect
.x
+ 3;
2344 rectLabel
.SetRight(xBmp
);
2346 else // normal (checkbox to the left of the text) case
2349 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2350 rectLabel
.SetRight(rect
.GetRight());
2353 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2356 dc
, label
, rectLabel
,
2358 wxALIGN_LEFT
| wxALIGN_TOP
,
2360 NULL
, // we don't need bounding rect
2361 // use custom vert focus rect offset
2362 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2366 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2367 const wxString
& label
,
2368 const wxBitmap
& bitmap
,
2378 bmp
= GetRadioBitmap(flags
);
2380 DrawCheckOrRadioButton(dc
, label
,
2382 rect
, flags
, align
, indexAccel
,
2383 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2386 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2387 const wxString
& label
,
2388 const wxBitmap
& bitmap
,
2398 bmp
= GetCheckBitmap(flags
);
2400 DrawCheckOrRadioButton(dc
, label
,
2402 rect
, flags
, align
, indexAccel
,
2403 0); // no focus rect offset for checkboxes
2406 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2407 const wxString
& label
,
2408 const wxBitmap
& bitmap
,
2409 const wxRect
& rectOrig
,
2412 if ( !label
.empty() || bitmap
.Ok() )
2414 wxRect rect
= rectOrig
;
2415 rect
.Deflate(BORDER_THICKNESS
);
2417 if ( flags
& wxCONTROL_PRESSED
)
2419 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2421 else if ( flags
& wxCONTROL_CURRENT
)
2423 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2426 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2430 // leave a small gap aroudn the line, also account for the toolbar
2432 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2433 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2434 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2438 // ----------------------------------------------------------------------------
2440 // ----------------------------------------------------------------------------
2442 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2443 const wxString
& text
,
2449 // nothing special to do here
2450 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2453 void wxWin32Renderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
2455 // we don't draw them
2458 // ----------------------------------------------------------------------------
2460 // ----------------------------------------------------------------------------
2462 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2463 const wxRect
& rectOrig
,
2465 const wxString
& label
,
2466 const wxBitmap
& bitmap
,
2470 wxRect rect
= rectOrig
;
2472 // the current tab is drawn indented (to the top for default case) and
2473 // bigger than the other ones
2474 const wxSize indent
= GetTabIndent();
2475 if ( flags
& wxCONTROL_SELECTED
)
2480 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2484 rect
.Inflate(indent
.x
, 0);
2486 rect
.height
+= indent
.y
;
2490 rect
.Inflate(indent
.x
, 0);
2491 rect
.height
+= indent
.y
;
2496 wxFAIL_MSG(_T("TODO"));
2501 // draw the text, image and the focus around them (if necessary)
2502 wxRect rectLabel
= rect
;
2503 rectLabel
.Deflate(1, 1);
2504 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2505 flags
, wxALIGN_CENTRE
, indexAccel
);
2507 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2508 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2511 x2
= rect
.GetRight(),
2512 y2
= rect
.GetBottom();
2514 // FIXME: all this code will break if the tab indent or the border width,
2515 // it is tied to the fact that both of them are equal to 2
2520 dc
.SetPen(m_penHighlight
);
2521 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2522 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2523 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2525 dc
.SetPen(m_penBlack
);
2526 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2527 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2529 dc
.SetPen(m_penDarkGrey
);
2530 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2532 if ( flags
& wxCONTROL_SELECTED
)
2534 dc
.SetPen(m_penLightGrey
);
2536 // overwrite the part of the border below this tab
2537 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2539 // and the shadow of the tab to the left of us
2540 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2545 dc
.SetPen(m_penHighlight
);
2546 // we need to continue one pixel further to overwrite the corner of
2547 // the border for the selected tab
2548 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2550 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2552 dc
.SetPen(m_penBlack
);
2553 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2554 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2555 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2557 dc
.SetPen(m_penDarkGrey
);
2558 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2559 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2561 if ( flags
& wxCONTROL_SELECTED
)
2563 dc
.SetPen(m_penLightGrey
);
2565 // overwrite the part of the (double!) border above this tab
2566 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2567 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2569 // and the shadow of the tab to the left of us
2570 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2576 wxFAIL_MSG(_T("TODO"));
2580 // ----------------------------------------------------------------------------
2582 // ----------------------------------------------------------------------------
2584 wxSize
wxWin32Renderer::GetSliderThumbSize(const wxRect
& rect
,
2586 wxOrientation orient
) const
2589 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2590 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2592 if (orient
== wxHORIZONTAL
)
2606 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2608 wxOrientation orient
,
2611 bool transpose
= (orient
== wxVERTICAL
);
2612 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2613 (((style
& wxSL_TOP
) != 0) & !transpose
|
2614 ((style
& wxSL_LEFT
) != 0) & transpose
|
2615 ((style
& wxSL_BOTH
) != 0));
2616 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2617 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2618 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2619 ((style
& wxSL_BOTH
) != 0));
2621 wxRect rect
= rectOrig
;
2623 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2625 if (orient
== wxHORIZONTAL
) {
2626 rect
.x
+= SLIDER_MARGIN
;
2629 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2633 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2637 rect
.y
+= sizeThumb
.y
/2;
2639 rect
.width
-= 2*SLIDER_MARGIN
;
2640 rect
.height
= 2*BORDER_THICKNESS
;
2644 rect
.y
+= SLIDER_MARGIN
;
2647 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2651 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2655 rect
.x
+= sizeThumb
.x
/2;
2657 rect
.width
= 2*BORDER_THICKNESS
;
2658 rect
.height
-= 2*SLIDER_MARGIN
;
2664 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2665 const wxRect
& rectOrig
,
2667 wxOrientation orient
,
2672 /* show shaft geometry
2690 if (flags
& wxCONTROL_FOCUSED
) {
2691 DrawFocusRect(dc
, rectOrig
);
2694 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2696 if (rectShaft
) *rectShaft
= rect
;
2698 DrawSunkenBorder(dc
, &rect
);
2701 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2703 wxOrientation orient
,
2707 /* show thumb geometry
2716 H D B where H is hightlight colour
2730 The interior of this shape is filled with the hatched brush if the thumb
2734 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2736 bool transpose
= (orient
== wxVERTICAL
);
2737 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2738 (((style
& wxSL_TOP
) != 0) & !transpose
|
2739 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2740 ((style
& wxSL_BOTH
) == 0);
2741 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2742 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2743 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2744 ((style
& wxSL_BOTH
) == 0);
2746 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2747 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2749 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2750 x1
= (transpose
? rect
.y
: rect
.x
);
2751 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2752 x3
= (x1
-1+c
) + sizeArrow
;
2753 y1
= (transpose
? rect
.x
: rect
.y
);
2754 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2755 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2756 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2758 dc
.SetPen(m_penBlack
);
2760 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2762 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2765 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2769 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2772 dc
.SetPen(m_penDarkGrey
);
2773 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2775 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2779 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2782 dc
.SetPen(m_penHighlight
);
2785 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2786 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2790 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2792 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2795 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2798 if (flags
& wxCONTROL_PRESSED
) {
2799 // TODO: MSW fills the entire area inside, not just the rect
2800 wxRect rectInt
= rect
;
2803 rectInt
.SetLeft(y3
);
2804 rectInt
.SetRight(y4
);
2809 rectInt
.SetBottom(y4
);
2813 #if !defined(__WXMGL__)
2814 static const char *stipple_xpm
[] = {
2815 /* columns rows colors chars-per-pixel */
2824 // VS: MGL can only do 8x8 stipple brushes
2825 static const char *stipple_xpm
[] = {
2826 /* columns rows colors chars-per-pixel */
2841 dc
.SetBrush(wxBrush(stipple_xpm
));
2843 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2844 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2845 dc
.SetPen(*wxTRANSPARENT_PEN
);
2846 dc
.DrawRectangle(rectInt
);
2850 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2853 wxOrientation orient
,
2860 /* show ticks geometry
2875 if (end
== start
) return;
2877 bool transpose
= (orient
== wxVERTICAL
);
2878 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2879 (((style
& wxSL_TOP
) != 0) & !transpose
|
2880 ((style
& wxSL_LEFT
) != 0) & transpose
|
2881 ((style
& wxSL_BOTH
) != 0));
2882 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2883 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2884 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2885 ((style
& wxSL_BOTH
) != 0));
2887 // default thumb size
2888 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2889 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
2891 // normal thumb size
2892 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2893 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
2895 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2897 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2898 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2899 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2900 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2901 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2902 y3
= (transpose
? rect
.x
: rect
.y
);
2903 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2906 dc
.SetPen(m_penBlack
);
2908 int range
= end
- start
;
2909 for ( int n
= 0; n
< range
; n
+= step
) {
2910 wxCoord x
= x1
+ (len
*n
) / range
;
2912 if (left
& (y1
> y3
)) {
2913 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2915 if (right
& (y4
> y2
)) {
2916 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2919 // always draw the line at the end position
2920 if (left
& (y1
> y3
)) {
2921 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2923 if (right
& (y4
> y2
)) {
2924 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2928 // ----------------------------------------------------------------------------
2930 // ----------------------------------------------------------------------------
2932 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2933 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2936 virtual wxSize
GetSize() const { return m_size
; }
2938 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2939 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2941 wxCoord
GetItemHeight() const { return m_heightItem
; }
2944 // the total size of the menu
2947 // the offset of the start of the menu item label
2950 // the offset of the start of the accel label
2953 // the height of a normal (not separator) item
2954 wxCoord m_heightItem
;
2956 friend wxMenuGeometryInfo
*
2957 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2960 // FIXME: all constants are hardcoded but shouldn't be
2961 static const wxCoord MENU_LEFT_MARGIN
= 9;
2962 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2963 static const wxCoord MENU_VERT_MARGIN
= 3;
2965 // the margin around bitmap/check marks (on each side)
2966 static const wxCoord MENU_BMP_MARGIN
= 2;
2968 // the margin between the labels and accel strings
2969 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2971 // the separator height in pixels: in fact, strangely enough, the real height
2972 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2974 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2976 // the size of the standard checkmark bitmap
2977 static const wxCoord MENU_CHECK_SIZE
= 9;
2979 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2980 const wxRect
& rectOrig
,
2981 const wxString
& label
,
2985 wxRect rect
= rectOrig
;
2988 wxDCTextColourChanger
colChanger(dc
);
2990 if ( flags
& wxCONTROL_SELECTED
)
2992 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2994 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2995 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2996 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2997 dc
.DrawRectangle(rect
);
3000 // don't draw the focus rect around menu bar items
3001 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3002 wxALIGN_CENTRE
, indexAccel
);
3005 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3007 const wxMenuGeometryInfo
& gi
,
3008 const wxString
& label
,
3009 const wxString
& accel
,
3010 const wxBitmap
& bitmap
,
3014 const wxWin32MenuGeometryInfo
& geometryInfo
=
3015 (const wxWin32MenuGeometryInfo
&)gi
;
3020 rect
.width
= geometryInfo
.GetSize().x
;
3021 rect
.height
= geometryInfo
.GetItemHeight();
3023 // draw the selected item specially
3024 wxDCTextColourChanger
colChanger(dc
);
3025 if ( flags
& wxCONTROL_SELECTED
)
3027 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3029 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3030 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3031 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3032 dc
.DrawRectangle(rect
);
3035 // draw the bitmap: use the bitmap provided or the standard checkmark for
3036 // the checkable items
3037 wxBitmap bmp
= bitmap
;
3038 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3040 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3045 rect
.SetRight(geometryInfo
.GetLabelOffset());
3046 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3050 rect
.x
= geometryInfo
.GetLabelOffset();
3051 rect
.SetRight(geometryInfo
.GetAccelOffset());
3053 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3055 // draw the accel string
3056 rect
.x
= geometryInfo
.GetAccelOffset();
3057 rect
.SetRight(geometryInfo
.GetSize().x
);
3059 // NB: no accel index here
3060 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3062 // draw the submenu indicator
3063 if ( flags
& wxCONTROL_ISSUBMENU
)
3065 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3066 rect
.width
= MENU_RIGHT_MARGIN
;
3068 wxArrowStyle arrowStyle
;
3069 if ( flags
& wxCONTROL_DISABLED
)
3070 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
3072 else if ( flags
& wxCONTROL_SELECTED
)
3073 arrowStyle
= Arrow_Inversed
;
3075 arrowStyle
= Arrow_Normal
;
3077 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3081 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3083 const wxMenuGeometryInfo
& geomInfo
)
3085 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3088 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3090 wxSize size
= sizeText
;
3092 // FIXME: menubar height is configurable under Windows
3099 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3100 const wxMenu
& menu
) const
3102 // prepare the dc: for now we draw all the items with the system font
3104 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3106 // the height of a normal item
3107 wxCoord heightText
= dc
.GetCharHeight();
3112 // the max length of label and accel strings: the menu width is the sum of
3113 // them, even if they're for different items (as the accels should be
3116 // the max length of the bitmap is never 0 as Windows always leaves enough
3117 // space for a check mark indicator
3118 wxCoord widthLabelMax
= 0,
3120 widthBmpMax
= MENU_LEFT_MARGIN
;
3122 for ( wxMenuItemList::Node
*node
= menu
.GetMenuItems().GetFirst();
3124 node
= node
->GetNext() )
3126 // height of this item
3129 wxMenuItem
*item
= node
->GetData();
3130 if ( item
->IsSeparator() )
3132 h
= MENU_SEPARATOR_HEIGHT
;
3134 else // not separator
3139 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3140 if ( widthLabel
> widthLabelMax
)
3142 widthLabelMax
= widthLabel
;
3146 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3147 if ( widthAccel
> widthAccelMax
)
3149 widthAccelMax
= widthAccel
;
3152 const wxBitmap
& bmp
= item
->GetBitmap();
3155 wxCoord widthBmp
= bmp
.GetWidth();
3156 if ( widthBmp
> widthBmpMax
)
3157 widthBmpMax
= widthBmp
;
3159 //else if ( item->IsCheckable() ): no need to check for this as
3160 // MENU_LEFT_MARGIN is big enough to show the check mark
3163 h
+= 2*MENU_VERT_MARGIN
;
3165 // remember the item position and height
3166 item
->SetGeometry(height
, h
);
3171 // bundle the metrics into a struct and return it
3172 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3174 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3175 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3176 if ( widthAccelMax
> 0 )
3178 // if we actually have any accesl, add a margin
3179 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3182 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3184 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3185 gi
->m_size
.y
= height
;
3190 // ----------------------------------------------------------------------------
3192 // ----------------------------------------------------------------------------
3194 static const wxCoord STATBAR_BORDER_X
= 2;
3195 static const wxCoord STATBAR_BORDER_Y
= 2;
3197 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3199 if ( borderBetweenFields
)
3200 *borderBetweenFields
= 2;
3202 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3205 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3207 const wxString
& label
,
3212 if ( flags
& wxCONTROL_ISDEFAULT
)
3214 // draw the size grip: it is a normal rect except that in the lower
3215 // right corner we have several bands which may be used for dragging
3216 // the status bar corner
3218 // each band consists of 4 stripes: m_penHighlight, double
3219 // m_penDarkGrey and transparent one
3220 wxCoord x2
= rect
.GetRight(),
3221 y2
= rect
.GetBottom();
3223 // draw the upper left part of the rect normally
3224 dc
.SetPen(m_penDarkGrey
);
3225 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3226 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3228 // draw the grey stripes of the grip
3230 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3231 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3233 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3234 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3237 // draw the white stripes
3238 dc
.SetPen(m_penHighlight
);
3239 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3240 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3242 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3245 // draw the remaining rect boundaries
3246 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3247 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3248 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3253 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3257 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3260 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3262 wxDCClipper
clipper(dc
, rectIn
);
3263 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3266 // ----------------------------------------------------------------------------
3268 // ----------------------------------------------------------------------------
3270 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3272 wxBitmap
*bmpPressed
,
3273 wxBitmap
*bmpDisabled
)
3275 static const wxCoord widthCombo
= 16;
3276 static const wxCoord heightCombo
= 17;
3282 bmpNormal
->Create(widthCombo
, heightCombo
);
3283 dcMem
.SelectObject(*bmpNormal
);
3284 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3285 Arrow_Down
, Arrow_Normal
);
3290 bmpPressed
->Create(widthCombo
, heightCombo
);
3291 dcMem
.SelectObject(*bmpPressed
);
3292 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3293 Arrow_Down
, Arrow_Pressed
);
3298 bmpDisabled
->Create(widthCombo
, heightCombo
);
3299 dcMem
.SelectObject(*bmpDisabled
);
3300 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3301 Arrow_Down
, Arrow_Disabled
);
3305 // ----------------------------------------------------------------------------
3307 // ----------------------------------------------------------------------------
3309 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3310 const wxColour
& col
,
3314 wxBrush
brush(col
, wxSOLID
);
3316 dc
.SetPen(*wxTRANSPARENT_PEN
);
3317 dc
.DrawRectangle(rect
);
3320 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3321 const wxColour
& col
,
3326 // just fill it with the given or default bg colour
3327 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3328 DoDrawBackground(dc
, colBg
, rect
, window
);
3331 // ----------------------------------------------------------------------------
3333 // ----------------------------------------------------------------------------
3335 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3340 // get the bitmap for this arrow
3341 wxArrowDirection arrowDir
;
3344 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3345 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3346 case wxUP
: arrowDir
= Arrow_Up
; break;
3347 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3350 wxFAIL_MSG(_T("unknown arrow direction"));
3354 wxArrowStyle arrowStyle
;
3355 if ( flags
& wxCONTROL_PRESSED
)
3357 // can't be pressed and disabled
3358 arrowStyle
= Arrow_Pressed
;
3362 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3365 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3368 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3370 wxArrowDirection arrowDir
,
3371 wxArrowStyle arrowStyle
)
3373 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3375 // under Windows the arrows always have the same size so just centre it in
3376 // the provided rectangle
3377 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3378 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3380 // Windows does it like this...
3381 if ( arrowDir
== Arrow_Left
)
3385 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3388 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3389 const wxRect
& rectAll
,
3390 wxArrowDirection arrowDir
,
3391 wxArrowStyle arrowStyle
)
3393 wxRect rect
= rectAll
;
3394 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3395 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3396 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3399 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3400 wxOrientation orient
,
3404 // we don't use the flags, the thumb never changes appearance
3405 wxRect rectThumb
= rect
;
3406 DrawArrowBorder(dc
, &rectThumb
);
3407 DrawBackground(dc
, wxNullColour
, rectThumb
);
3410 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3411 wxOrientation orient
,
3412 const wxRect
& rectBar
,
3415 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3416 ? wxColourScheme::SCROLLBAR_PRESSED
3417 : wxColourScheme::SCROLLBAR
;
3418 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3421 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3423 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3426 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3427 wxScrollBar::Element elem
,
3430 return StandardGetScrollbarRect(scrollbar
, elem
,
3431 thumbPos
, m_sizeScrollbarArrow
);
3434 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3436 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3439 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3440 const wxPoint
& pt
) const
3442 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3445 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3448 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3451 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3454 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3457 // ----------------------------------------------------------------------------
3458 // top level windows
3459 // ----------------------------------------------------------------------------
3461 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3463 wxRect client
= GetFrameClientArea(rect
, flags
);
3465 if ( client
.Inside(pt
) )
3466 return wxHT_TOPLEVEL_CLIENT_AREA
;
3468 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3470 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3472 if ( flags
& wxTOPLEVEL_ICON
)
3474 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3475 return wxHT_TOPLEVEL_ICON
;
3478 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3479 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3480 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3482 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3484 if ( btnRect
.Inside(pt
) )
3485 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3486 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3488 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3490 if ( btnRect
.Inside(pt
) )
3491 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3492 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3494 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3496 if ( btnRect
.Inside(pt
) )
3497 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3498 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3500 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3502 if ( btnRect
.Inside(pt
) )
3503 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3504 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3506 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3508 if ( btnRect
.Inside(pt
) )
3509 return wxHT_TOPLEVEL_BUTTON_HELP
;
3510 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3513 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3514 return wxHT_TOPLEVEL_TITLEBAR
;
3517 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3519 // we are certainly at one of borders, lets decide which one:
3522 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3523 if ( pt
.x
< client
.x
)
3524 border
|= wxHT_TOPLEVEL_BORDER_W
;
3525 else if ( pt
.x
>= client
.width
+ client
.x
)
3526 border
|= wxHT_TOPLEVEL_BORDER_E
;
3527 if ( pt
.y
< client
.y
)
3528 border
|= wxHT_TOPLEVEL_BORDER_N
;
3529 else if ( pt
.y
>= client
.height
+ client
.y
)
3530 border
|= wxHT_TOPLEVEL_BORDER_S
;
3534 return wxHT_NOWHERE
;
3537 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3539 const wxString
& title
,
3543 int specialButtonFlags
)
3545 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3547 DrawFrameBorder(dc
, rect
, flags
);
3549 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3551 DrawFrameBackground(dc
, rect
, flags
);
3552 if ( flags
& wxTOPLEVEL_ICON
)
3553 DrawFrameIcon(dc
, rect
, icon
, flags
);
3554 DrawFrameTitle(dc
, rect
, title
, flags
);
3556 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3558 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3559 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3561 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3563 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3564 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3565 specialButtonFlags
: 0);
3566 x
-= FRAME_BUTTON_WIDTH
+ 2;
3568 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3570 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3571 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3572 specialButtonFlags
: 0);
3573 x
-= FRAME_BUTTON_WIDTH
;
3575 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3577 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3578 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3579 specialButtonFlags
: 0);
3580 x
-= FRAME_BUTTON_WIDTH
;
3582 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3584 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3585 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3586 specialButtonFlags
: 0);
3587 x
-= FRAME_BUTTON_WIDTH
;
3589 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3591 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3592 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3593 specialButtonFlags
: 0);
3594 x
-= FRAME_BUTTON_WIDTH
;
3599 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3603 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3607 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3608 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3609 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3610 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3611 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3614 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3618 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3620 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3621 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3622 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3624 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3625 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3627 DrawBackground(dc
, col
, r
);
3630 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3632 const wxString
& title
,
3635 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3636 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3637 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3639 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3640 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3641 if ( flags
& wxTOPLEVEL_ICON
)
3643 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3644 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3652 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3653 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3654 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3655 r
.width
-= FRAME_BUTTON_WIDTH
;
3656 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3657 r
.width
-= FRAME_BUTTON_WIDTH
;
3658 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3659 r
.width
-= FRAME_BUTTON_WIDTH
;
3660 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3661 r
.width
-= FRAME_BUTTON_WIDTH
;
3663 dc
.SetFont(m_titlebarFont
);
3664 dc
.SetTextForeground(col
);
3667 dc
.GetTextExtent(title
, &textW
, NULL
);
3668 if ( textW
> r
.width
)
3670 // text is too big, let's shorten it and add "..." after it:
3671 size_t len
= title
.length();
3672 wxCoord WSoFar
, letterW
;
3674 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3675 if ( WSoFar
> r
.width
)
3677 // not enough space to draw anything
3683 for (size_t i
= 0; i
< len
; i
++)
3685 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3686 if ( letterW
+ WSoFar
> r
.width
)
3692 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3693 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3696 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3697 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3700 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3707 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3708 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3712 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3713 wxCoord x
, wxCoord y
,
3717 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3722 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3723 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3724 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3725 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3726 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3728 wxFAIL_MSG(wxT("incorrect button specification"));
3731 if ( flags
& wxCONTROL_PRESSED
)
3733 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3734 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3735 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3736 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3740 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3741 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3742 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3743 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3748 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3753 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3755 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3756 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3757 FRAME_BORDER_THICKNESS
;
3760 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3762 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3763 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3769 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3772 wxSize
s(clientSize
);
3774 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3776 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3777 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3778 FRAME_BORDER_THICKNESS
;
3782 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3783 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3788 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3792 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3794 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3795 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3796 FRAME_BORDER_THICKNESS
;
3801 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3803 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3805 if ( flags
& wxTOPLEVEL_ICON
)
3806 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3807 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3808 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3809 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3810 s
.x
+= FRAME_BUTTON_WIDTH
;
3811 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3812 s
.x
+= FRAME_BUTTON_WIDTH
;
3813 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3814 s
.x
+= FRAME_BUTTON_WIDTH
;
3815 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3816 s
.x
+= FRAME_BUTTON_WIDTH
;
3822 wxSize
wxWin32Renderer::GetFrameIconSize() const
3824 return wxSize(16, 16);
3828 // ----------------------------------------------------------------------------
3830 // ----------------------------------------------------------------------------
3832 static char *error_xpm
[]={
3839 "...........########.............",
3840 "........###aaaaaaaa###..........",
3841 ".......#aaaaaaaaaaaaaa#.........",
3842 ".....##aaaaaaaaaaaaaaaa##.......",
3843 "....#aaaaaaaaaaaaaaaaaaaa#......",
3844 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3845 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3846 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3847 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3848 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3849 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3850 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3851 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3852 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3853 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3854 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3855 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3856 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3857 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3858 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3859 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3860 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3861 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3862 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3863 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3864 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3865 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3866 "......b#aaaaaaaaaaaaaa#bbbbb....",
3867 ".......b###aaaaaaaa###bbbbb.....",
3868 ".........bb########bbbbbb.......",
3869 "..........bbbbbbbbbbbbbb........",
3870 ".............bbbbbbbb..........."};
3872 static char *info_xpm
[]={
3880 "...........########.............",
3881 "........###abbbbbba###..........",
3882 "......##abbbbbbbbbbbba##........",
3883 ".....#abbbbbbbbbbbbbbbba#.......",
3884 "....#bbbbbbbaccccabbbbbbbd......",
3885 "...#bbbbbbbbccccccbbbbbbbbd.....",
3886 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3887 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3888 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3889 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3890 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3891 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3892 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3893 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3894 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3895 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3896 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3897 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3898 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3899 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3900 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3901 ".....dabbbbbbbbbbbbbbbbad####...",
3902 "......ddabbbbbbbbbbbbadd####....",
3903 ".......#dddabbbbbbaddd#####.....",
3904 "........###dddabbbd#######......",
3905 "..........####dbbbd#####........",
3906 ".............#dbbbd##...........",
3907 "...............dbbd##...........",
3908 "................dbd##...........",
3909 ".................dd##...........",
3910 "..................###...........",
3911 "...................##..........."};
3913 static char *question_xpm
[]={
3921 "...........########.............",
3922 "........###abbbbbba###..........",
3923 "......##abbbbbbbbbbbba##........",
3924 ".....#abbbbbbbbbbbbbbbba#.......",
3925 "....#bbbbbbbbbbbbbbbbbbbbc......",
3926 "...#bbbbbbbaddddddabbbbbbbc.....",
3927 "..#bbbbbbbadabbddddabbbbbbbc....",
3928 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3929 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3930 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3931 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3932 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3933 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3934 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3935 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3936 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3937 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3938 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3939 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3940 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3941 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3942 ".....cabbbbbbbbbbbbbbbbac####...",
3943 "......ccabbbbbbbbbbbbacc####....",
3944 ".......#cccabbbbbbaccc#####.....",
3945 "........###cccabbbc#######......",
3946 "..........####cbbbc#####........",
3947 ".............#cbbbc##...........",
3948 "...............cbbc##...........",
3949 "................cbc##...........",
3950 ".................cc##...........",
3951 "..................###...........",
3952 "...................##..........."};
3954 static char *warning_xpm
[]={
3962 ".............###................",
3963 "............#aabc...............",
3964 "...........#aaaabcd.............",
3965 "...........#aaaaacdd............",
3966 "..........#aaaaaabcdd...........",
3967 "..........#aaaaaaacdd...........",
3968 ".........#aaaaaaaabcdd..........",
3969 ".........#aaaaaaaaacdd..........",
3970 "........#aaaaaaaaaabcdd.........",
3971 "........#aaabcccbaaacdd.........",
3972 ".......#aaaacccccaaabcdd........",
3973 ".......#aaaacccccaaaacdd........",
3974 "......#aaaaacccccaaaabcdd.......",
3975 "......#aaaaacccccaaaaacdd.......",
3976 ".....#aaaaaacccccaaaaabcdd......",
3977 ".....#aaaaaa#ccc#aaaaaacdd......",
3978 "....#aaaaaaabcccbaaaaaabcdd.....",
3979 "....#aaaaaaaacccaaaaaaaacdd.....",
3980 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3981 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3982 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3983 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3984 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3985 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3986 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3987 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3988 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3989 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3990 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3991 "..#ccccccccccccccccccccccccddddd",
3992 "....ddddddddddddddddddddddddddd.",
3993 ".....ddddddddddddddddddddddddd.."};
3995 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3996 const wxArtClient
& WXUNUSED(client
),
3997 const wxSize
& WXUNUSED(size
))
3999 if ( id
== wxART_INFORMATION
)
4000 return wxBitmap(info_xpm
);
4001 if ( id
== wxART_ERROR
)
4002 return wxBitmap(error_xpm
);
4003 if ( id
== wxART_WARNING
)
4004 return wxBitmap(warning_xpm
);
4005 if ( id
== wxART_QUESTION
)
4006 return wxBitmap(question_xpm
);
4007 return wxNullBitmap
;
4011 // ----------------------------------------------------------------------------
4012 // text control geometry
4013 // ----------------------------------------------------------------------------
4015 static inline int GetTextBorderWidth()
4020 wxRect
wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
4021 const wxRect
& rect
) const
4023 wxRect rectTotal
= rect
;
4025 wxCoord widthBorder
= GetTextBorderWidth();
4026 rectTotal
.Inflate(widthBorder
);
4028 // this is what Windows does
4034 wxRect
wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
4036 wxCoord
*extraSpaceBeyond
) const
4038 wxRect rectText
= rect
;
4040 // undo GetTextTotalArea()
4041 if ( rectText
.height
> 0 )
4044 wxCoord widthBorder
= GetTextBorderWidth();
4045 rectText
.Inflate(-widthBorder
);
4047 if ( extraSpaceBeyond
)
4048 *extraSpaceBeyond
= 0;
4053 // ----------------------------------------------------------------------------
4055 // ----------------------------------------------------------------------------
4057 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4060 if ( wxDynamicCast(window
, wxScrollBar
) )
4062 // we only set the width of vert scrollbars and height of the
4064 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4065 size
->y
= m_sizeScrollbarArrow
.y
;
4067 size
->x
= m_sizeScrollbarArrow
.x
;
4069 // skip border width adjustments, they don't make sense for us
4072 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4075 if ( wxDynamicCast(window
, wxButton
) )
4077 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4079 // TODO: don't harcode all this
4080 size
->x
+= 3*window
->GetCharWidth();
4082 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4083 if ( size
->y
< heightBtn
- 8 )
4084 size
->y
= heightBtn
;
4089 // for compatibility with other ports, the buttons default size is never
4090 // less than the standard one, but not when display not PDAs.
4091 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4093 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4095 wxSize szDef
= wxButton::GetDefaultSize();
4096 if ( size
->x
< szDef
.x
)
4101 // no border width adjustments for buttons
4104 #endif // wxUSE_BUTTON
4106 // take into account the border width
4107 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4108 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4109 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4112 // ============================================================================
4114 // ============================================================================
4116 // ----------------------------------------------------------------------------
4117 // wxWin32InputHandler
4118 // ----------------------------------------------------------------------------
4120 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4122 m_renderer
= renderer
;
4125 bool wxWin32InputHandler::HandleKey(wxInputConsumer
*control
,
4126 const wxKeyEvent
& event
,
4132 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4133 const wxMouseEvent
& event
)
4135 // clicking on the control gives it focus
4136 if ( event
.ButtonDown() )
4138 wxWindow
*win
= control
->GetInputWindow();
4140 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4141 ( win
->AcceptsFocus() ) )
4152 // ----------------------------------------------------------------------------
4153 // wxWin32ScrollBarInputHandler
4154 // ----------------------------------------------------------------------------
4156 wxWin32ScrollBarInputHandler::
4157 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4158 wxInputHandler
*handler
)
4159 : wxStdScrollBarInputHandler(renderer
, handler
)
4161 m_scrollPaused
= FALSE
;
4165 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4166 const wxControlAction
& action
)
4168 // stop if went beyond the position of the original click (this can only
4169 // happen when we scroll by pages)
4171 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4173 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4174 != wxHT_SCROLLBAR_BAR_2
;
4176 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4178 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4179 != wxHT_SCROLLBAR_BAR_1
;
4184 StopScrolling(scrollbar
);
4186 scrollbar
->Refresh();
4191 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4194 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4195 const wxMouseEvent
& event
)
4197 // remember the current state
4198 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4200 // do process the message
4201 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4203 // analyse the changes
4204 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4206 // we just started dragging the thumb, remember its initial position to
4207 // be able to restore it if the drag is cancelled later
4208 m_eventStartDrag
= event
;
4214 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4215 const wxMouseEvent
& event
)
4217 // we don't highlight scrollbar elements, so there is no need to process
4218 // mouse move events normally - only do it while mouse is captured (i.e.
4219 // when we're dragging the thumb or pressing on something)
4220 if ( !m_winCapture
)
4223 if ( event
.Entering() )
4225 // we're not interested in this at all
4229 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4231 if ( m_scrollPaused
)
4233 // check if the mouse returned to its original location
4235 if ( event
.Leaving() )
4241 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4242 if ( ht
== m_htLast
)
4244 // yes it did, resume scrolling
4245 m_scrollPaused
= FALSE
;
4246 if ( m_timerScroll
)
4248 // we were scrolling by line/page, restart timer
4249 m_timerScroll
->Start(m_interval
);
4251 Press(scrollbar
, TRUE
);
4253 else // we were dragging the thumb
4255 // restore its last location
4256 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4262 else // normal case, scrolling hasn't been paused
4264 // if we're scrolling the scrollbar because the arrow or the shaft was
4265 // pressed, check that the mouse stays on the same scrollbar element
4268 // Always let thumb jump back if we leave the scrollbar
4269 if ( event
.Moving() )
4271 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4273 else // event.Leaving()
4278 // Jump back only if we get far away from it
4279 wxPoint pos
= event
.GetPosition();
4280 if (scrollbar
->HasFlag( wxVERTICAL
))
4282 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4287 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4290 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4293 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4294 // is still ok - we only want to catch the case when the mouse leaves
4295 // the scrollbar here
4296 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4298 ht
= wxHT_SCROLLBAR_THUMB
;
4301 if ( ht
!= m_htLast
)
4303 // what were we doing? 2 possibilities: either an arrow/shaft was
4304 // pressed in which case we have a timer and so we just stop it or
4305 // we were dragging the thumb
4306 if ( m_timerScroll
)
4309 m_interval
= m_timerScroll
->GetInterval();
4310 m_timerScroll
->Stop();
4311 m_scrollPaused
= TRUE
;
4313 // unpress the arrow
4314 Press(scrollbar
, FALSE
);
4316 else // we were dragging the thumb
4318 // remember the current thumb position to be able to restore it
4319 // if the mouse returns to it later
4320 m_eventLastDrag
= event
;
4322 // and restore the original position (before dragging) of the
4324 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4331 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4334 // ----------------------------------------------------------------------------
4335 // wxWin32CheckboxInputHandler
4336 // ----------------------------------------------------------------------------
4338 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4339 const wxKeyEvent
& event
,
4344 wxControlAction action
;
4345 int keycode
= event
.GetKeyCode();
4349 action
= wxACTION_CHECKBOX_TOGGLE
;
4353 case WXK_NUMPAD_SUBTRACT
:
4354 action
= wxACTION_CHECKBOX_CHECK
;
4358 case WXK_NUMPAD_ADD
:
4359 case WXK_NUMPAD_EQUAL
:
4360 action
= wxACTION_CHECKBOX_CLEAR
;
4366 control
->PerformAction(action
);
4375 // ----------------------------------------------------------------------------
4376 // wxWin32TextCtrlInputHandler
4377 // ----------------------------------------------------------------------------
4379 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4380 const wxKeyEvent
& event
,
4383 // handle only MSW-specific text bindings here, the others are handled in
4387 int keycode
= event
.GetKeyCode();
4389 wxControlAction action
;
4390 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4392 action
= wxACTION_TEXT_CUT
;
4394 else if ( keycode
== WXK_INSERT
)
4396 if ( event
.ControlDown() )
4397 action
= wxACTION_TEXT_COPY
;
4398 else if ( event
.ShiftDown() )
4399 action
= wxACTION_TEXT_PASTE
;
4402 if ( action
!= wxACTION_NONE
)
4404 control
->PerformAction(action
);
4410 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4413 // ----------------------------------------------------------------------------
4414 // wxWin32StatusBarInputHandler
4415 // ----------------------------------------------------------------------------
4417 wxWin32StatusBarInputHandler::
4418 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4419 : wxStdInputHandler(handler
)
4424 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4425 const wxPoint
& pt
) const
4427 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4428 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4431 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4433 wxCHECK_MSG( parentTLW
, FALSE
,
4434 _T("the status bar should be a child of a TLW") );
4436 // a maximized window can't be resized anyhow
4437 if ( !parentTLW
->IsMaximized() )
4439 // VZ: I think that the standard Windows behaviour is to only
4440 // show the resizing cursor when the mouse is on top of the
4441 // grip itself but apparently different Windows versions behave
4442 // differently (?) and it seems a better UI to allow resizing
4443 // the status bar even when the mouse is above the grip
4444 wxSize sizeSbar
= statbar
->GetSize();
4446 int diff
= sizeSbar
.x
- pt
.x
;
4447 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4454 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4455 const wxMouseEvent
& event
)
4457 if ( event
.Button(1) )
4459 if ( event
.ButtonDown(1) )
4461 wxWindow
*statbar
= consumer
->GetInputWindow();
4463 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4465 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4469 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4470 wxHT_TOPLEVEL_BORDER_SE
);
4472 statbar
->SetCursor(m_cursorOld
);
4480 return wxStdInputHandler::HandleMouse(consumer
, event
);
4483 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4484 const wxMouseEvent
& event
)
4486 wxWindow
*statbar
= consumer
->GetInputWindow();
4488 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4489 if ( isOnGrip
!= m_isOnGrip
)
4491 m_isOnGrip
= isOnGrip
;
4494 m_cursorOld
= statbar
->GetCursor();
4495 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4499 statbar
->SetCursor(m_cursorOld
);
4503 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4506 // ----------------------------------------------------------------------------
4507 // wxWin32FrameInputHandler
4508 // ----------------------------------------------------------------------------
4510 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4513 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4515 void Attach(wxInputConsumer
*consumer
);
4519 DECLARE_EVENT_TABLE()
4520 void OnSystemMenu(wxCommandEvent
&event
);
4521 void OnCloseFrame(wxCommandEvent
&event
);
4522 void OnClose(wxCloseEvent
&event
);
4524 wxWin32FrameInputHandler
*m_inputHnd
;
4525 wxTopLevelWindow
*m_wnd
;
4526 wxAcceleratorTable m_oldAccelTable
;
4529 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4530 wxWin32FrameInputHandler
*handler
)
4532 m_inputHnd
= handler
;
4536 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4538 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4540 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4541 m_wnd
->PushEventHandler(this);
4543 // VS: This code relies on using generic implementation of
4544 // wxAcceleratorTable in wxUniv!
4545 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4546 m_oldAccelTable
= table
;
4547 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4548 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4549 m_wnd
->SetAcceleratorTable(table
);
4552 void wxWin32SystemMenuEvtHandler::Detach()
4556 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4557 m_wnd
->RemoveEventHandler(this);
4562 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4563 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4564 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4565 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4568 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4570 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4571 !m_wnd
->IsMaximized()) ?
4572 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4573 FRAME_BORDER_THICKNESS
;
4574 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4575 pt
.x
= -pt
.x
+ border
;
4576 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4578 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4579 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4580 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4581 m_wnd
->SetAcceleratorTable(table
);
4584 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4586 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4587 wxTOPLEVEL_BUTTON_CLOSE
);
4590 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4597 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4598 : wxStdFrameInputHandler(handler
)
4600 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4603 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4605 if ( m_menuHandler
)
4607 m_menuHandler
->Detach();
4608 delete m_menuHandler
;
4612 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4613 const wxMouseEvent
& event
)
4615 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4617 wxTopLevelWindow
*tlw
=
4618 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4620 long hit
= tlw
->HitTest(event
.GetPosition());
4622 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4624 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4625 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4626 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4629 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4631 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4632 (event
.RightDown() &&
4633 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4634 hit
== wxHT_TOPLEVEL_ICON
)) )
4636 PopupSystemMenu(tlw
, event
.GetPosition());
4642 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4645 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4646 const wxPoint
& pos
) const
4648 wxMenu
*menu
= new wxMenu
;
4650 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4651 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4652 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4653 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4654 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4655 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4656 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4657 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4658 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4659 menu
->AppendSeparator();
4660 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4662 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4664 if ( window
->IsMaximized() )
4666 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4667 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4668 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4669 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4672 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4675 window
->PopupMenu(menu
, pos
);
4679 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4682 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4684 // always detach if active frame changed:
4685 m_menuHandler
->Detach();
4689 m_menuHandler
->Attach(consumer
);
4693 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);