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 licence
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/listbox.h"
42 #include "wx/toolbar.h"
43 #include "wx/statusbr.h"
46 // for COLOR_* constants
47 #include "wx/msw/private.h"
51 #include "wx/notebook.h"
52 #include "wx/spinbutt.h"
53 #include "wx/settings.h"
55 #include "wx/artprov.h"
56 #include "wx/toplevel.h"
58 #include "wx/univ/scrtimer.h"
59 #include "wx/univ/renderer.h"
60 #include "wx/univ/inphand.h"
61 #include "wx/univ/colschem.h"
62 #include "wx/univ/theme.h"
64 // ----------------------------------------------------------------------------
66 // ----------------------------------------------------------------------------
68 static const int BORDER_THICKNESS
= 2;
70 // the offset between the label and focus rect around it
71 static const int FOCUS_RECT_OFFSET_X
= 1;
72 static const int FOCUS_RECT_OFFSET_Y
= 1;
74 static const int FRAME_BORDER_THICKNESS
= 3;
75 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
76 static const int FRAME_TITLEBAR_HEIGHT
= 18;
77 static const int FRAME_BUTTON_WIDTH
= 16;
78 static const int FRAME_BUTTON_HEIGHT
= 14;
80 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
81 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
82 static const size_t STATUSBAR_GRIP_SIZE
=
83 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
85 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
86 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
87 static const wxCoord SLIDER_TICK_LENGTH
= 6;
99 IndicatorState_Normal
,
100 IndicatorState_Pressed
, // this one is for check/radioboxes
101 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
102 IndicatorState_Disabled
,
103 IndicatorState_SelectedDisabled
, // only for the menus
109 IndicatorStatus_Checked
,
110 IndicatorStatus_Unchecked
,
114 // wxWin32Renderer: draw the GUI elements in Win32 style
115 // ----------------------------------------------------------------------------
117 class wxWin32Renderer
: public wxRenderer
121 enum wxArrowDirection
136 Arrow_InversedDisabled
,
140 enum wxFrameButtonType
143 FrameButton_Minimize
,
144 FrameButton_Maximize
,
151 wxWin32Renderer(const wxColourScheme
*scheme
);
153 // implement the base class pure virtuals
154 virtual void DrawBackground(wxDC
& dc
,
158 wxWindow
*window
= NULL
);
159 virtual void DrawLabel(wxDC
& dc
,
160 const wxString
& label
,
163 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
165 wxRect
*rectBounds
= NULL
);
166 virtual void DrawButtonLabel(wxDC
& dc
,
167 const wxString
& label
,
168 const wxBitmap
& image
,
171 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
173 wxRect
*rectBounds
= NULL
);
174 virtual void DrawBorder(wxDC
& dc
,
178 wxRect
*rectIn
= (wxRect
*)NULL
);
179 virtual void DrawHorizontalLine(wxDC
& dc
,
180 wxCoord y
, wxCoord x1
, wxCoord x2
);
181 virtual void DrawVerticalLine(wxDC
& dc
,
182 wxCoord x
, wxCoord y1
, wxCoord y2
);
183 virtual void DrawFrame(wxDC
& dc
,
184 const wxString
& label
,
187 int alignment
= wxALIGN_LEFT
,
188 int indexAccel
= -1);
189 virtual void DrawTextBorder(wxDC
& dc
,
193 wxRect
*rectIn
= (wxRect
*)NULL
);
194 virtual void DrawButtonBorder(wxDC
& dc
,
197 wxRect
*rectIn
= (wxRect
*)NULL
);
198 virtual void DrawArrow(wxDC
& dc
,
202 virtual void DrawScrollbarArrow(wxDC
& dc
,
206 { DrawArrow(dc
, dir
, rect
, flags
); }
207 virtual void DrawScrollbarThumb(wxDC
& dc
,
208 wxOrientation orient
,
211 virtual void DrawScrollbarShaft(wxDC
& dc
,
212 wxOrientation orient
,
215 virtual void DrawScrollCorner(wxDC
& dc
,
217 virtual void DrawItem(wxDC
& dc
,
218 const wxString
& label
,
221 virtual void DrawCheckItem(wxDC
& dc
,
222 const wxString
& label
,
223 const wxBitmap
& bitmap
,
226 virtual void DrawCheckButton(wxDC
& dc
,
227 const wxString
& label
,
228 const wxBitmap
& bitmap
,
231 wxAlignment align
= wxALIGN_LEFT
,
232 int indexAccel
= -1);
233 virtual void DrawRadioButton(wxDC
& dc
,
234 const wxString
& label
,
235 const wxBitmap
& bitmap
,
238 wxAlignment align
= wxALIGN_LEFT
,
239 int indexAccel
= -1);
240 virtual void DrawToolBarButton(wxDC
& dc
,
241 const wxString
& label
,
242 const wxBitmap
& bitmap
,
246 virtual void DrawTextLine(wxDC
& dc
,
247 const wxString
& text
,
252 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
253 virtual void DrawTab(wxDC
& dc
,
256 const wxString
& label
,
257 const wxBitmap
& bitmap
= wxNullBitmap
,
259 int indexAccel
= -1);
261 virtual void DrawSliderShaft(wxDC
& dc
,
264 wxOrientation orient
,
267 wxRect
*rectShaft
= NULL
);
268 virtual void DrawSliderThumb(wxDC
& dc
,
270 wxOrientation orient
,
273 virtual void DrawSliderTicks(wxDC
& dc
,
276 wxOrientation orient
,
283 virtual void DrawMenuBarItem(wxDC
& dc
,
285 const wxString
& label
,
287 int indexAccel
= -1);
288 virtual void DrawMenuItem(wxDC
& dc
,
290 const wxMenuGeometryInfo
& geometryInfo
,
291 const wxString
& label
,
292 const wxString
& accel
,
293 const wxBitmap
& bitmap
= wxNullBitmap
,
295 int indexAccel
= -1);
296 virtual void DrawMenuSeparator(wxDC
& dc
,
298 const wxMenuGeometryInfo
& geomInfo
);
300 virtual void DrawStatusField(wxDC
& dc
,
302 const wxString
& label
,
303 int flags
= 0, int style
= 0);
306 virtual void DrawFrameTitleBar(wxDC
& dc
,
308 const wxString
& title
,
311 int specialButton
= 0,
312 int specialButtonFlags
= 0);
313 virtual void DrawFrameBorder(wxDC
& dc
,
316 virtual void DrawFrameBackground(wxDC
& dc
,
319 virtual void DrawFrameTitle(wxDC
& dc
,
321 const wxString
& title
,
323 virtual void DrawFrameIcon(wxDC
& dc
,
327 virtual void DrawFrameButton(wxDC
& dc
,
328 wxCoord x
, wxCoord y
,
331 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
332 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
333 virtual wxSize
GetFrameMinSize(int flags
) const;
334 virtual wxSize
GetFrameIconSize() const;
335 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
337 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
339 wxBitmap
*bmpPressed
,
340 wxBitmap
*bmpDisabled
);
342 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
343 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
344 virtual bool AreScrollbarsInsideBorder() const;
346 virtual wxSize
GetScrollbarArrowSize() const
347 { return m_sizeScrollbarArrow
; }
348 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
349 wxScrollBar::Element elem
,
350 int thumbPos
= -1) const;
351 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
352 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
353 const wxPoint
& pt
) const;
354 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
356 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
357 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
358 { return fontHeight
+ 2; }
359 virtual wxSize
GetCheckBitmapSize() const
360 { return wxSize(13, 13); }
361 virtual wxSize
GetRadioBitmapSize() const
362 { return wxSize(12, 12); }
363 virtual wxCoord
GetCheckItemMargin() const
366 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
367 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
368 virtual wxSize
GetToolBarMargin() const
369 { return wxSize(4, 4); }
371 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
372 const wxRect
& rect
) const;
373 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
375 wxCoord
*extraSpaceBeyond
) const;
377 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
378 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
380 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
381 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
382 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
384 wxOrientation orient
,
385 long style
= 0) const;
386 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
388 wxOrientation orient
) const;
389 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
391 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
392 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
393 const wxMenu
& menu
) const;
395 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
398 // helper of DrawLabel() and DrawCheckOrRadioButton()
399 void DoDrawLabel(wxDC
& dc
,
400 const wxString
& label
,
403 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
405 wxRect
*rectBounds
= NULL
,
406 const wxPoint
& focusOffset
407 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
409 // common part of DrawLabel() and DrawItem()
410 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
412 // DrawLabel() and DrawButtonLabel() helper
413 void DrawLabelShadow(wxDC
& dc
,
414 const wxString
& label
,
419 // DrawButtonBorder() helper
420 void DoDrawBackground(wxDC
& dc
,
423 wxWindow
*window
= NULL
);
425 // DrawBorder() helpers: all of them shift and clip the DC after drawing
428 // just draw a rectangle with the given pen
429 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
431 // draw the lower left part of rectangle
432 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
434 // draw the rectange using the first brush for the left and top sides and
435 // the second one for the bottom and right ones
436 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
437 const wxPen
& pen1
, const wxPen
& pen2
);
439 // draw the normal 3D border
440 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
442 // draw the sunken 3D border
443 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
445 // draw the border used for scrollbar arrows
446 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
448 // public DrawArrow()s helper
449 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
450 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
452 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
453 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
454 wxArrowDirection arrowDir
,
455 wxArrowStyle arrowStyle
);
457 // DrawCheckButton/DrawRadioButton helper
458 void DrawCheckOrRadioButton(wxDC
& dc
,
459 const wxString
& label
,
460 const wxBitmap
& bitmap
,
465 wxCoord focusOffsetY
);
467 // draw a normal or transposed line (useful for using the same code fo both
468 // horizontal and vertical widgets)
469 void DrawLine(wxDC
& dc
,
470 wxCoord x1
, wxCoord y1
,
471 wxCoord x2
, wxCoord y2
,
472 bool transpose
= false)
475 dc
.DrawLine(y1
, x1
, y2
, x2
);
477 dc
.DrawLine(x1
, y1
, x2
, y2
);
480 // get the standard check/radio button bitmap
481 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
482 wxBitmap
GetCheckBitmap(int flags
)
483 { return GetIndicator(IndicatorType_Check
, flags
); }
484 wxBitmap
GetRadioBitmap(int flags
)
485 { return GetIndicator(IndicatorType_Radio
, flags
); }
488 const wxColourScheme
*m_scheme
;
490 // the sizing parameters (TODO make them changeable)
491 wxSize m_sizeScrollbarArrow
;
493 // GDI objects we use for drawing
494 wxColour m_colDarkGrey
,
502 wxFont m_titlebarFont
;
504 // the checked and unchecked bitmaps for DrawCheckItem()
505 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
507 // the bitmaps returned by GetIndicator()
508 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
510 [IndicatorStatus_Max
];
513 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
515 // first row is for the normal state, second - for the disabled
516 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
519 // ----------------------------------------------------------------------------
520 // wxWin32InputHandler and derived classes: process the keyboard and mouse
521 // messages according to Windows standards
522 // ----------------------------------------------------------------------------
524 class wxWin32InputHandler
: public wxInputHandler
527 wxWin32InputHandler(wxWin32Renderer
*renderer
);
529 virtual bool HandleKey(wxInputConsumer
*control
,
530 const wxKeyEvent
& event
,
532 virtual bool HandleMouse(wxInputConsumer
*control
,
533 const wxMouseEvent
& event
);
536 wxWin32Renderer
*m_renderer
;
539 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
542 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
543 wxInputHandler
*handler
);
545 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
546 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
548 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
549 const wxControlAction
& action
);
552 virtual bool IsAllowedButton(int button
) { return button
== 1; }
554 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
557 // we don't highlight anything
560 // the first and last event which caused the thumb to move
561 wxMouseEvent m_eventStartDrag
,
564 // have we paused the scrolling because the mouse moved?
567 // we remember the interval of the timer to be able to restart it
571 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
574 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
575 : wxStdCheckboxInputHandler(handler
) { }
577 virtual bool HandleKey(wxInputConsumer
*control
,
578 const wxKeyEvent
& event
,
582 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
585 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
586 : wxStdTextCtrlInputHandler(handler
) { }
588 virtual bool HandleKey(wxInputConsumer
*control
,
589 const wxKeyEvent
& event
,
593 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
596 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
598 virtual bool HandleMouse(wxInputConsumer
*consumer
,
599 const wxMouseEvent
& event
);
601 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
602 const wxMouseEvent
& event
);
605 // is the given point over the statusbar grip?
606 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
609 // the cursor we had replaced with the resize one
610 wxCursor m_cursorOld
;
612 // was the mouse over the grip last time we checked?
616 class wxWin32SystemMenuEvtHandler
;
618 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
621 wxWin32FrameInputHandler(wxInputHandler
*handler
);
622 ~wxWin32FrameInputHandler();
624 virtual bool HandleMouse(wxInputConsumer
*control
,
625 const wxMouseEvent
& event
);
627 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
629 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
632 // was the mouse over the grip last time we checked?
633 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
636 // ----------------------------------------------------------------------------
637 // wxWin32ColourScheme: uses (default) Win32 colours
638 // ----------------------------------------------------------------------------
640 class wxWin32ColourScheme
: public wxColourScheme
643 virtual wxColour
Get(StdColour col
) const;
644 virtual wxColour
GetBackground(wxWindow
*win
) const;
647 // ----------------------------------------------------------------------------
648 // wxWin32ArtProvider
649 // ----------------------------------------------------------------------------
651 class wxWin32ArtProvider
: public wxArtProvider
654 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
655 const wxArtClient
& client
,
659 // ----------------------------------------------------------------------------
661 // ----------------------------------------------------------------------------
663 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
665 class wxWin32Theme
: public wxTheme
669 virtual ~wxWin32Theme();
671 virtual wxRenderer
*GetRenderer();
672 virtual wxArtProvider
*GetArtProvider();
673 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
674 virtual wxColourScheme
*GetColourScheme();
677 // get the default input handler
678 wxInputHandler
*GetDefaultInputHandler();
680 wxWin32Renderer
*m_renderer
;
682 wxWin32ArtProvider
*m_artProvider
;
684 // the names of the already created handlers and the handlers themselves
685 // (these arrays are synchronized)
686 wxSortedArrayString m_handlerNames
;
687 wxArrayHandlers m_handlers
;
689 wxWin32InputHandler
*m_handlerDefault
;
691 wxWin32ColourScheme
*m_scheme
;
693 WX_DECLARE_THEME(win32
)
696 // ----------------------------------------------------------------------------
698 // ----------------------------------------------------------------------------
700 // frame buttons bitmaps
702 static const char *frame_button_close_xpm
[] = {
717 static const char *frame_button_help_xpm
[] = {
732 static const char *frame_button_maximize_xpm
[] = {
747 static const char *frame_button_minimize_xpm
[] = {
762 static const char *frame_button_restore_xpm
[] = {
779 static const char *checked_menu_xpm
[] = {
780 /* columns rows colors chars-per-pixel */
796 static const char *selected_checked_menu_xpm
[] = {
797 /* columns rows colors chars-per-pixel */
813 static const char *disabled_checked_menu_xpm
[] = {
814 /* columns rows colors chars-per-pixel */
831 static const char *selected_disabled_checked_menu_xpm
[] = {
832 /* columns rows colors chars-per-pixel */
848 // checkbox and radiobox bitmaps below
850 static const char *checked_xpm
[] = {
851 /* columns rows colors chars-per-pixel */
874 static const char *pressed_checked_xpm
[] = {
875 /* columns rows colors chars-per-pixel */
897 static const char *pressed_disabled_checked_xpm
[] = {
898 /* columns rows colors chars-per-pixel */
920 static const char *checked_item_xpm
[] = {
921 /* columns rows colors chars-per-pixel */
942 static const char *unchecked_xpm
[] = {
943 /* columns rows colors chars-per-pixel */
966 static const char *pressed_unchecked_xpm
[] = {
967 /* columns rows colors chars-per-pixel */
989 static const char *unchecked_item_xpm
[] = {
990 /* columns rows colors chars-per-pixel */
1010 static const char *checked_radio_xpm
[] = {
1011 /* columns rows colors chars-per-pixel */
1034 static const char *pressed_checked_radio_xpm
[] = {
1035 /* columns rows colors chars-per-pixel */
1058 static const char *pressed_disabled_checked_radio_xpm
[] = {
1059 /* columns rows colors chars-per-pixel */
1082 static const char *unchecked_radio_xpm
[] = {
1083 /* columns rows colors chars-per-pixel */
1106 static const char *pressed_unchecked_radio_xpm
[] = {
1107 /* columns rows colors chars-per-pixel */
1130 static const char **
1131 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1136 { checked_xpm
, unchecked_xpm
},
1139 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1142 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1148 { checked_radio_xpm
, unchecked_radio_xpm
},
1151 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1154 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1160 { checked_menu_xpm
, NULL
},
1163 { selected_checked_menu_xpm
, NULL
},
1166 { disabled_checked_menu_xpm
, NULL
},
1168 // disabled selected state
1169 { selected_disabled_checked_menu_xpm
, NULL
},
1173 static const char **xpmChecked
[IndicatorStatus_Max
] =
1179 // ============================================================================
1181 // ============================================================================
1183 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1185 // ----------------------------------------------------------------------------
1187 // ----------------------------------------------------------------------------
1189 wxWin32Theme::wxWin32Theme()
1193 m_handlerDefault
= NULL
;
1194 m_artProvider
= NULL
;
1197 wxWin32Theme::~wxWin32Theme()
1199 size_t count
= m_handlers
.GetCount();
1200 for ( size_t n
= 0; n
< count
; n
++ )
1202 if ( m_handlers
[n
] != m_handlerDefault
)
1203 delete m_handlers
[n
];
1206 delete m_handlerDefault
;
1210 wxArtProvider::RemoveProvider(m_artProvider
);
1213 wxRenderer
*wxWin32Theme::GetRenderer()
1217 m_renderer
= new wxWin32Renderer(GetColourScheme());
1223 wxArtProvider
*wxWin32Theme::GetArtProvider()
1225 if ( !m_artProvider
)
1227 m_artProvider
= new wxWin32ArtProvider
;
1230 return m_artProvider
;
1233 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1235 if ( !m_handlerDefault
)
1237 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1240 return m_handlerDefault
;
1243 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1245 wxInputHandler
*handler
;
1246 int n
= m_handlerNames
.Index(control
);
1247 if ( n
== wxNOT_FOUND
)
1249 // create a new handler
1250 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1251 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1252 GetDefaultInputHandler());
1254 else if ( control
== wxINP_HANDLER_BUTTON
)
1255 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1256 #endif // wxUSE_BUTTON
1258 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1259 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1260 #endif // wxUSE_CHECKBOX
1262 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1263 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1264 #endif // wxUSE_COMBOBOX
1266 else if ( control
== wxINP_HANDLER_LISTBOX
)
1267 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1268 #endif // wxUSE_LISTBOX
1269 #if wxUSE_CHECKLISTBOX
1270 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1271 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1272 #endif // wxUSE_CHECKLISTBOX
1274 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1275 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1276 #endif // wxUSE_TEXTCTRL
1278 else if ( control
== wxINP_HANDLER_SLIDER
)
1279 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1280 #endif // wxUSE_SLIDER
1282 else if ( control
== wxINP_HANDLER_SPINBTN
)
1283 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1284 #endif // wxUSE_SPINBTN
1286 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1287 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1288 #endif // wxUSE_NOTEBOOK
1290 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1291 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1292 #endif // wxUSE_STATUSBAR
1294 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1295 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1296 #endif // wxUSE_TOOLBAR
1297 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1298 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1300 handler
= GetDefaultInputHandler();
1302 n
= m_handlerNames
.Add(control
);
1303 m_handlers
.Insert(handler
, n
);
1305 else // we already have it
1307 handler
= m_handlers
[n
];
1313 wxColourScheme
*wxWin32Theme::GetColourScheme()
1317 m_scheme
= new wxWin32ColourScheme
;
1322 // ============================================================================
1323 // wxWin32ColourScheme
1324 // ============================================================================
1326 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1329 if ( win
->UseBgCol() )
1331 // use the user specified colour
1332 col
= win
->GetBackgroundColour();
1335 if ( !win
->ShouldInheritColours() )
1337 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1339 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1347 if ( !win
->IsEnabled() ) // not IsEditable()
1353 // doesn't depend on the state
1360 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1364 int flags
= win
->GetStateFlags();
1366 // the colour set by the user should be used for the normal state
1367 // and for the states for which we don't have any specific colours
1368 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1370 if ( wxDynamicCast(win
, wxScrollBar
) )
1371 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1381 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1385 // use the system colours under Windows
1386 #if defined(__WXMSW__)
1387 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1389 case CONTROL_PRESSED
:
1390 case CONTROL_CURRENT
:
1391 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1393 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1395 #if defined(COLOR_3DLIGHT)
1396 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1398 case SCROLLBAR
: return wxColour(0xe0e0e0);
1400 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1402 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1403 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1405 #if defined(COLOR_3DDKSHADOW)
1406 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1408 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1411 case CONTROL_TEXT_DISABLED
:
1412 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1414 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1416 case CONTROL_TEXT_DISABLED_SHADOW
:
1417 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1419 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1420 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1421 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1422 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1424 case DESKTOP
: return wxColour(0x808000);
1426 // use the standard Windows colours elsewhere
1427 case WINDOW
: return *wxWHITE
;
1429 case CONTROL_PRESSED
:
1430 case CONTROL_CURRENT
:
1431 case CONTROL
: return wxColour(0xc0c0c0);
1433 case CONTROL_TEXT
: return *wxBLACK
;
1435 case SCROLLBAR
: return wxColour(0xe0e0e0);
1436 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1438 case HIGHLIGHT
: return wxColour(0x800000);
1439 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1441 case SHADOW_DARK
: return *wxBLACK
;
1443 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1444 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1446 case SHADOW_IN
: return wxColour(0xc0c0c0);
1448 case CONTROL_TEXT_DISABLED_SHADOW
:
1449 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1451 case TITLEBAR
: return wxColour(0xaeaaae);
1452 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1453 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1454 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1456 case DESKTOP
: return wxColour(0x808000);
1459 case GAUGE
: return Get(HIGHLIGHT
);
1463 wxFAIL_MSG(_T("invalid standard colour"));
1468 // ============================================================================
1470 // ============================================================================
1472 // ----------------------------------------------------------------------------
1474 // ----------------------------------------------------------------------------
1476 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1480 m_sizeScrollbarArrow
= wxSize(16, 16);
1482 // init colours and pens
1483 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1485 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1486 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1488 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1490 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1491 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1493 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1494 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1496 // init the arrow bitmaps
1497 static const size_t ARROW_WIDTH
= 7;
1498 static const size_t ARROW_LENGTH
= 4;
1501 wxMemoryDC dcNormal
,
1504 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1506 bool isVertical
= n
> Arrow_Right
;
1519 // disabled arrow is larger because of the shadow
1520 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1521 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1523 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1524 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1526 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1527 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1531 dcNormal
.SetPen(m_penBlack
);
1532 dcDisabled
.SetPen(m_penDarkGrey
);
1534 // calculate the position of the point of the arrow
1538 x1
= (ARROW_WIDTH
- 1)/2;
1539 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1543 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1544 y1
= (ARROW_WIDTH
- 1)/2;
1555 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1557 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1558 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1565 if ( n
== Arrow_Up
)
1576 else // left or right arrow
1581 if ( n
== Arrow_Left
)
1594 // draw the shadow for the disabled one
1595 dcDisabled
.SetPen(m_penHighlight
);
1600 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1604 x1
= ARROW_LENGTH
- 1;
1605 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1608 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1609 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1614 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1618 x1
= ARROW_WIDTH
- 1;
1620 x2
= (ARROW_WIDTH
- 1)/2;
1622 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1623 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1628 // create the inversed bitmap but only for the right arrow as we only
1629 // use it for the menus
1630 if ( n
== Arrow_Right
)
1632 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1633 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1635 dcInverse
.Blit(0, 0, w
, h
,
1638 dcInverse
.SelectObject(wxNullBitmap
);
1640 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1641 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1643 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1644 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1646 dcInverse
.Blit(0, 0, w
, h
,
1649 dcInverse
.SelectObject(wxNullBitmap
);
1651 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1652 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1655 dcNormal
.SelectObject(wxNullBitmap
);
1656 dcDisabled
.SelectObject(wxNullBitmap
);
1658 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1659 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1660 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1661 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1663 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1666 // init the frame buttons bitmaps
1667 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1668 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1669 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1670 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1671 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1674 // ----------------------------------------------------------------------------
1676 // ----------------------------------------------------------------------------
1679 The raised border in Win32 looks like this:
1681 IIIIIIIIIIIIIIIIIIIIIIB
1683 I GB I = white (HILIGHT)
1684 I GB H = light grey (LIGHT)
1685 I GB G = dark grey (SHADOI)
1686 I GB B = black (DKSHADOI)
1687 I GB I = hIghlight (COLOR_3DHILIGHT)
1689 IGGGGGGGGGGGGGGGGGGGGGB
1690 BBBBBBBBBBBBBBBBBBBBBBB
1692 The sunken border looks like this:
1694 GGGGGGGGGGGGGGGGGGGGGGI
1695 GBBBBBBBBBBBBBBBBBBBBHI
1702 GHHHHHHHHHHHHHHHHHHHHHI
1703 IIIIIIIIIIIIIIIIIIIIIII
1705 The static border (used for the controls which don't get focus) is like
1708 GGGGGGGGGGGGGGGGGGGGGGW
1716 WWWWWWWWWWWWWWWWWWWWWWW
1718 The most complicated is the double border:
1720 HHHHHHHHHHHHHHHHHHHHHHB
1721 HWWWWWWWWWWWWWWWWWWWWGB
1722 HWHHHHHHHHHHHHHHHHHHHGB
1727 HWHHHHHHHHHHHHHHHHHHHGB
1728 HGGGGGGGGGGGGGGGGGGGGGB
1729 BBBBBBBBBBBBBBBBBBBBBBB
1731 And the simple border is, well, simple:
1733 BBBBBBBBBBBBBBBBBBBBBBB
1742 BBBBBBBBBBBBBBBBBBBBBBB
1745 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1749 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1750 dc
.DrawRectangle(*rect
);
1756 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1758 // draw the bottom and right sides
1760 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1761 rect
->GetRight() + 1, rect
->GetBottom());
1762 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1763 rect
->GetRight(), rect
->GetBottom());
1769 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1770 const wxPen
& pen1
, const wxPen
& pen2
)
1772 // draw the rectangle
1774 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1775 rect
->GetLeft(), rect
->GetBottom());
1776 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1777 rect
->GetRight(), rect
->GetTop());
1779 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1780 rect
->GetRight(), rect
->GetBottom());
1781 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1782 rect
->GetRight() + 1, rect
->GetBottom());
1788 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1790 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1791 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1794 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1796 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1797 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1800 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1804 DrawRect(dc
, rect
, m_penDarkGrey
);
1806 // the arrow is usually drawn inside border of width 2 and is offset by
1807 // another pixel in both directions when it's pressed - as the border
1808 // in this case is more narrow as well, we have to adjust rect like
1816 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1817 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1821 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1823 const wxRect
& rectTotal
,
1824 int WXUNUSED(flags
),
1829 wxRect rect
= rectTotal
;
1833 case wxBORDER_SUNKEN
:
1834 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1836 DrawSunkenBorder(dc
, &rect
);
1840 case wxBORDER_STATIC
:
1841 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1844 case wxBORDER_RAISED
:
1845 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1847 DrawRaisedBorder(dc
, &rect
);
1851 case wxBORDER_DOUBLE
:
1852 DrawArrowBorder(dc
, &rect
);
1853 DrawRect(dc
, &rect
, m_penLightGrey
);
1856 case wxBORDER_SIMPLE
:
1857 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1859 DrawRect(dc
, &rect
, m_penBlack
);
1864 wxFAIL_MSG(_T("unknown border type"));
1867 case wxBORDER_DEFAULT
:
1876 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1881 case wxBORDER_RAISED
:
1882 case wxBORDER_SUNKEN
:
1883 width
= BORDER_THICKNESS
;
1886 case wxBORDER_SIMPLE
:
1887 case wxBORDER_STATIC
:
1891 case wxBORDER_DOUBLE
:
1897 // char *crash = NULL;
1899 wxFAIL_MSG(_T("unknown border type"));
1903 case wxBORDER_DEFAULT
:
1913 rect
.height
= width
;
1918 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1923 // ----------------------------------------------------------------------------
1925 // ----------------------------------------------------------------------------
1927 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1933 // text controls are not special under windows
1934 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1937 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1938 const wxRect
& rectTotal
,
1942 wxRect rect
= rectTotal
;
1944 if ( flags
& wxCONTROL_PRESSED
)
1946 // button pressed: draw a double border around it
1947 DrawRect(dc
, &rect
, m_penBlack
);
1948 DrawRect(dc
, &rect
, m_penDarkGrey
);
1952 // button not pressed
1954 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1956 // button either default or focused (or both): add an extra border around it
1957 DrawRect(dc
, &rect
, m_penBlack
);
1960 // now draw a normal button
1961 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1962 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1971 // ----------------------------------------------------------------------------
1973 // ----------------------------------------------------------------------------
1975 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1976 wxCoord y
, wxCoord x1
, wxCoord x2
)
1978 dc
.SetPen(m_penDarkGrey
);
1979 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1980 dc
.SetPen(m_penHighlight
);
1982 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1985 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1986 wxCoord x
, wxCoord y1
, wxCoord y2
)
1988 dc
.SetPen(m_penDarkGrey
);
1989 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1990 dc
.SetPen(m_penHighlight
);
1992 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1995 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1996 const wxString
& label
,
2002 wxCoord height
= 0; // of the label
2003 wxRect rectFrame
= rect
;
2004 if ( !label
.empty() )
2006 // the text should touch the top border of the rect, so the frame
2007 // itself should be lower
2008 dc
.GetTextExtent(label
, NULL
, &height
);
2009 rectFrame
.y
+= height
/ 2;
2010 rectFrame
.height
-= height
/ 2;
2012 // we have to draw each part of the frame individually as we can't
2013 // erase the background beyond the label as it might contain some
2014 // pixmap already, so drawing everything and then overwriting part of
2015 // the frame with label doesn't work
2017 // TODO: the +5 and space insertion should be customizable
2020 rectText
.x
= rectFrame
.x
+ 5;
2021 rectText
.y
= rect
.y
;
2022 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2023 rectText
.height
= height
;
2026 label2
<< _T(' ') << label
<< _T(' ');
2027 if ( indexAccel
!= -1 )
2029 // adjust it as we prepended a space
2034 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2036 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2040 // just draw the complete frame
2041 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2042 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2046 // ----------------------------------------------------------------------------
2048 // ----------------------------------------------------------------------------
2050 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2052 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2053 // pixels each while we really need dots here... PS_ALTERNATE might
2054 // work, but it is for NT 5 only
2056 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2058 // draw the pixels manually: note that to behave in the same manner as
2059 // DrawRect(), we must exclude the bottom and right borders from the
2061 wxCoord x1
= rect
.GetLeft(),
2063 x2
= rect
.GetRight(),
2064 y2
= rect
.GetBottom();
2066 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2068 // this seems to be closer than what Windows does than wxINVERT although
2069 // I'm still not sure if it's correct
2070 dc
.SetLogicalFunction(wxAND_REVERSE
);
2073 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2074 dc
.DrawPoint(z
, rect
.GetTop());
2076 wxCoord shift
= z
== x2
? 0 : 1;
2077 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2078 dc
.DrawPoint(x2
, z
);
2080 shift
= z
== y2
? 0 : 1;
2081 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2082 dc
.DrawPoint(z
, y2
);
2084 shift
= z
== x1
? 0 : 1;
2085 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2086 dc
.DrawPoint(x1
, z
);
2088 dc
.SetLogicalFunction(wxCOPY
);
2092 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2093 const wxString
& label
,
2098 // draw shadow of the text
2099 dc
.SetTextForeground(m_colHighlight
);
2100 wxRect rectShadow
= rect
;
2103 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2105 // make the text grey
2106 dc
.SetTextForeground(m_colDarkGrey
);
2109 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2110 const wxString
& label
,
2117 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2120 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2121 const wxString
& label
,
2127 const wxPoint
& focusOffset
)
2129 // the underscores are not drawn for focused controls in wxMSW
2130 if ( flags
& wxCONTROL_FOCUSED
)
2135 if ( flags
& wxCONTROL_DISABLED
)
2137 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2138 // currently only can happen for a menu item and it seems that Windows
2139 // doesn't draw the shadow in this case, so we don't do it neither
2140 if ( flags
& wxCONTROL_SELECTED
)
2142 // just make the label text greyed out
2143 dc
.SetTextForeground(m_colDarkGrey
);
2145 else // draw normal disabled label
2147 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2152 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2154 if ( flags
& wxCONTROL_DISABLED
)
2156 // restore the fg colour
2157 dc
.SetTextForeground(*wxBLACK
);
2160 if ( flags
& wxCONTROL_FOCUSED
)
2162 if ( focusOffset
.x
|| focusOffset
.y
)
2164 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2167 DrawFocusRect(dc
, rectLabel
);
2171 *rectBounds
= rectLabel
;
2174 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2175 const wxString
& label
,
2176 const wxBitmap
& image
,
2183 // the underscores are not drawn for focused controls in wxMSW
2184 if ( flags
& wxCONTROL_PRESSED
)
2189 wxRect rectLabel
= rect
;
2190 if ( !label
.empty() )
2192 // shift the label if a button is pressed
2193 if ( flags
& wxCONTROL_PRESSED
)
2199 if ( flags
& wxCONTROL_DISABLED
)
2201 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2204 // leave enough space for the focus rectangle
2205 if ( flags
& wxCONTROL_FOCUSED
)
2207 rectLabel
.Inflate(-2);
2211 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2213 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2215 if ( flags
& wxCONTROL_PRESSED
)
2217 // the focus rectangle is never pressed, so undo the shift done
2225 DrawFocusRect(dc
, rectLabel
);
2229 // ----------------------------------------------------------------------------
2230 // (check)listbox items
2231 // ----------------------------------------------------------------------------
2233 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2234 const wxString
& label
,
2238 wxDCTextColourChanger
colChanger(dc
);
2240 if ( flags
& wxCONTROL_SELECTED
)
2242 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2244 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2245 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2246 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2247 dc
.DrawRectangle(rect
);
2250 wxRect rectText
= rect
;
2252 rectText
.width
-= 2;
2253 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2255 if ( flags
& wxCONTROL_FOCUSED
)
2257 DrawFocusRect(dc
, rect
);
2261 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2262 const wxString
& label
,
2263 const wxBitmap
& bitmap
,
2272 else // use default bitmap
2274 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2275 ? IndicatorStatus_Checked
2276 : IndicatorStatus_Unchecked
;
2278 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2280 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2283 bmp
= m_bmpCheckBitmaps
[i
];
2286 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2287 true /* use mask */);
2289 wxRect rectLabel
= rect
;
2290 int bmpWidth
= bmp
.GetWidth();
2291 rectLabel
.x
+= bmpWidth
;
2292 rectLabel
.width
-= bmpWidth
;
2294 DrawItem(dc
, label
, rectLabel
, flags
);
2297 // ----------------------------------------------------------------------------
2298 // check/radio buttons
2299 // ----------------------------------------------------------------------------
2301 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2303 IndicatorState indState
;
2304 if ( flags
& wxCONTROL_SELECTED
)
2305 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2306 : IndicatorState_Selected
;
2307 else if ( flags
& wxCONTROL_DISABLED
)
2308 indState
= IndicatorState_Disabled
;
2309 else if ( flags
& wxCONTROL_PRESSED
)
2310 indState
= IndicatorState_Pressed
;
2312 indState
= IndicatorState_Normal
;
2314 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2315 ? IndicatorStatus_Checked
2316 : IndicatorStatus_Unchecked
;
2318 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2321 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2324 // create and cache it
2325 bmp
= wxBitmap(xpm
);
2326 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2333 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2334 const wxString
& label
,
2335 const wxBitmap
& bitmap
,
2340 wxCoord focusOffsetY
)
2342 // calculate the position of the bitmap and of the label
2343 wxCoord heightBmp
= bitmap
.GetHeight();
2345 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2348 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2349 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2351 // align label vertically with the bitmap - looks nicer like this
2352 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2354 // calc horz position
2355 if ( align
== wxALIGN_RIGHT
)
2357 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2358 rectLabel
.x
= rect
.x
+ 3;
2359 rectLabel
.SetRight(xBmp
);
2361 else // normal (checkbox to the left of the text) case
2364 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2365 rectLabel
.SetRight(rect
.GetRight());
2368 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2371 dc
, label
, rectLabel
,
2373 wxALIGN_LEFT
| wxALIGN_TOP
,
2375 NULL
, // we don't need bounding rect
2376 // use custom vert focus rect offset
2377 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2381 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2382 const wxString
& label
,
2383 const wxBitmap
& bitmap
,
2393 bmp
= GetRadioBitmap(flags
);
2395 DrawCheckOrRadioButton(dc
, label
,
2397 rect
, flags
, align
, indexAccel
,
2398 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2401 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2402 const wxString
& label
,
2403 const wxBitmap
& bitmap
,
2413 bmp
= GetCheckBitmap(flags
);
2415 DrawCheckOrRadioButton(dc
, label
,
2417 rect
, flags
, align
, indexAccel
,
2418 0); // no focus rect offset for checkboxes
2421 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2422 const wxString
& label
,
2423 const wxBitmap
& bitmap
,
2424 const wxRect
& rectOrig
,
2428 if (style
== wxTOOL_STYLE_BUTTON
)
2430 wxRect rect
= rectOrig
;
2431 rect
.Deflate(BORDER_THICKNESS
);
2433 if ( flags
& wxCONTROL_PRESSED
)
2435 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2437 else if ( flags
& wxCONTROL_CURRENT
)
2439 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2442 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2444 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2446 // leave a small gap aroudn the line, also account for the toolbar
2448 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2449 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2450 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2452 // don't draw wxTOOL_STYLE_CONTROL
2455 // ----------------------------------------------------------------------------
2457 // ----------------------------------------------------------------------------
2459 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2460 const wxString
& text
,
2466 // nothing special to do here
2467 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2471 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2472 const wxRect
& WXUNUSED(rect
))
2474 // we don't draw them
2477 // ----------------------------------------------------------------------------
2479 // ----------------------------------------------------------------------------
2481 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2482 const wxRect
& rectOrig
,
2484 const wxString
& label
,
2485 const wxBitmap
& bitmap
,
2489 wxRect rect
= rectOrig
;
2491 // the current tab is drawn indented (to the top for default case) and
2492 // bigger than the other ones
2493 const wxSize indent
= GetTabIndent();
2494 if ( flags
& wxCONTROL_SELECTED
)
2499 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2503 rect
.Inflate(indent
.x
, 0);
2505 rect
.height
+= indent
.y
;
2509 rect
.Inflate(indent
.x
, 0);
2510 rect
.height
+= indent
.y
;
2515 wxFAIL_MSG(_T("TODO"));
2520 // draw the text, image and the focus around them (if necessary)
2521 wxRect rectLabel
= rect
;
2522 rectLabel
.Deflate(1, 1);
2523 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2524 flags
, wxALIGN_CENTRE
, indexAccel
);
2526 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2527 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2530 x2
= rect
.GetRight(),
2531 y2
= rect
.GetBottom();
2533 // FIXME: all this code will break if the tab indent or the border width,
2534 // it is tied to the fact that both of them are equal to 2
2539 dc
.SetPen(m_penHighlight
);
2540 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2541 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2542 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2544 dc
.SetPen(m_penBlack
);
2545 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2546 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2548 dc
.SetPen(m_penDarkGrey
);
2549 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2551 if ( flags
& wxCONTROL_SELECTED
)
2553 dc
.SetPen(m_penLightGrey
);
2555 // overwrite the part of the border below this tab
2556 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2558 // and the shadow of the tab to the left of us
2559 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2564 dc
.SetPen(m_penHighlight
);
2565 // we need to continue one pixel further to overwrite the corner of
2566 // the border for the selected tab
2567 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2569 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2571 dc
.SetPen(m_penBlack
);
2572 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2573 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2574 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2576 dc
.SetPen(m_penDarkGrey
);
2577 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2578 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2580 if ( flags
& wxCONTROL_SELECTED
)
2582 dc
.SetPen(m_penLightGrey
);
2584 // overwrite the part of the (double!) border above this tab
2585 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2586 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2588 // and the shadow of the tab to the left of us
2589 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2595 wxFAIL_MSG(_T("TODO"));
2599 // ----------------------------------------------------------------------------
2601 // ----------------------------------------------------------------------------
2604 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2606 wxOrientation orient
) const
2609 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2610 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2612 if (orient
== wxHORIZONTAL
)
2626 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2628 wxOrientation orient
,
2631 bool transpose
= (orient
== wxVERTICAL
);
2632 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2633 (((style
& wxSL_TOP
) != 0) & !transpose
|
2634 ((style
& wxSL_LEFT
) != 0) & transpose
|
2635 ((style
& wxSL_BOTH
) != 0));
2636 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2637 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2638 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2639 ((style
& wxSL_BOTH
) != 0));
2641 wxRect rect
= rectOrig
;
2643 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2645 if (orient
== wxHORIZONTAL
) {
2646 rect
.x
+= SLIDER_MARGIN
;
2649 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2653 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2657 rect
.y
+= sizeThumb
.y
/2;
2659 rect
.width
-= 2*SLIDER_MARGIN
;
2660 rect
.height
= 2*BORDER_THICKNESS
;
2664 rect
.y
+= SLIDER_MARGIN
;
2667 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2671 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2675 rect
.x
+= sizeThumb
.x
/2;
2677 rect
.width
= 2*BORDER_THICKNESS
;
2678 rect
.height
-= 2*SLIDER_MARGIN
;
2684 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2685 const wxRect
& rectOrig
,
2687 wxOrientation orient
,
2692 /* show shaft geometry
2710 if (flags
& wxCONTROL_FOCUSED
) {
2711 DrawFocusRect(dc
, rectOrig
);
2714 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2716 if (rectShaft
) *rectShaft
= rect
;
2718 DrawSunkenBorder(dc
, &rect
);
2721 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2723 wxOrientation orient
,
2727 /* show thumb geometry
2736 H D B where H is hightlight colour
2750 The interior of this shape is filled with the hatched brush if the thumb
2754 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2756 bool transpose
= (orient
== wxVERTICAL
);
2757 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2758 (((style
& wxSL_TOP
) != 0) & !transpose
|
2759 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2760 ((style
& wxSL_BOTH
) == 0);
2761 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2762 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2763 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2764 ((style
& wxSL_BOTH
) == 0);
2766 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2767 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2769 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2770 x1
= (transpose
? rect
.y
: rect
.x
);
2771 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2772 x3
= (x1
-1+c
) + sizeArrow
;
2773 y1
= (transpose
? rect
.x
: rect
.y
);
2774 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2775 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2776 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2778 dc
.SetPen(m_penBlack
);
2780 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2782 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2785 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2789 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2792 dc
.SetPen(m_penDarkGrey
);
2793 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2795 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2799 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2802 dc
.SetPen(m_penHighlight
);
2805 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2806 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2810 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2812 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2815 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2818 if (flags
& wxCONTROL_PRESSED
) {
2819 // TODO: MSW fills the entire area inside, not just the rect
2820 wxRect rectInt
= rect
;
2823 rectInt
.SetLeft(y3
);
2824 rectInt
.SetRight(y4
);
2829 rectInt
.SetBottom(y4
);
2833 #if !defined(__WXMGL__)
2834 static const char *stipple_xpm
[] = {
2835 /* columns rows colors chars-per-pixel */
2844 // VS: MGL can only do 8x8 stipple brushes
2845 static const char *stipple_xpm
[] = {
2846 /* columns rows colors chars-per-pixel */
2861 dc
.SetBrush(wxBrush(stipple_xpm
));
2863 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2864 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2865 dc
.SetPen(*wxTRANSPARENT_PEN
);
2866 dc
.DrawRectangle(rectInt
);
2870 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2873 wxOrientation orient
,
2877 int WXUNUSED(flags
),
2880 /* show ticks geometry
2895 if (end
== start
) return;
2897 bool transpose
= (orient
== wxVERTICAL
);
2898 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2899 (((style
& wxSL_TOP
) != 0) & !transpose
|
2900 ((style
& wxSL_LEFT
) != 0) & transpose
|
2901 ((style
& wxSL_BOTH
) != 0));
2902 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2903 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2904 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2905 ((style
& wxSL_BOTH
) != 0));
2907 // default thumb size
2908 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2909 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
2911 // normal thumb size
2912 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2913 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
2915 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2917 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2918 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2919 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2920 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2921 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2922 y3
= (transpose
? rect
.x
: rect
.y
);
2923 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2926 dc
.SetPen(m_penBlack
);
2928 int range
= end
- start
;
2929 for ( int n
= 0; n
< range
; n
+= step
) {
2930 wxCoord x
= x1
+ (len
*n
) / range
;
2932 if (left
& (y1
> y3
)) {
2933 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2935 if (right
& (y4
> y2
)) {
2936 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2939 // always draw the line at the end position
2940 if (left
& (y1
> y3
)) {
2941 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2943 if (right
& (y4
> y2
)) {
2944 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2948 // ----------------------------------------------------------------------------
2950 // ----------------------------------------------------------------------------
2952 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2953 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2956 virtual wxSize
GetSize() const { return m_size
; }
2958 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2959 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2961 wxCoord
GetItemHeight() const { return m_heightItem
; }
2964 // the total size of the menu
2967 // the offset of the start of the menu item label
2970 // the offset of the start of the accel label
2973 // the height of a normal (not separator) item
2974 wxCoord m_heightItem
;
2976 friend wxMenuGeometryInfo
*
2977 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2980 // FIXME: all constants are hardcoded but shouldn't be
2981 static const wxCoord MENU_LEFT_MARGIN
= 9;
2982 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2983 static const wxCoord MENU_VERT_MARGIN
= 3;
2985 // the margin around bitmap/check marks (on each side)
2986 static const wxCoord MENU_BMP_MARGIN
= 2;
2988 // the margin between the labels and accel strings
2989 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2991 // the separator height in pixels: in fact, strangely enough, the real height
2992 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2994 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2996 // the size of the standard checkmark bitmap
2997 static const wxCoord MENU_CHECK_SIZE
= 9;
2999 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3000 const wxRect
& rectOrig
,
3001 const wxString
& label
,
3005 wxRect rect
= rectOrig
;
3008 wxDCTextColourChanger
colChanger(dc
);
3010 if ( flags
& wxCONTROL_SELECTED
)
3012 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3014 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3015 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3016 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3017 dc
.DrawRectangle(rect
);
3020 // don't draw the focus rect around menu bar items
3021 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3022 wxALIGN_CENTRE
, indexAccel
);
3025 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3027 const wxMenuGeometryInfo
& gi
,
3028 const wxString
& label
,
3029 const wxString
& accel
,
3030 const wxBitmap
& bitmap
,
3034 const wxWin32MenuGeometryInfo
& geometryInfo
=
3035 (const wxWin32MenuGeometryInfo
&)gi
;
3040 rect
.width
= geometryInfo
.GetSize().x
;
3041 rect
.height
= geometryInfo
.GetItemHeight();
3043 // draw the selected item specially
3044 wxDCTextColourChanger
colChanger(dc
);
3045 if ( flags
& wxCONTROL_SELECTED
)
3047 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3049 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3050 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3051 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3052 dc
.DrawRectangle(rect
);
3055 // draw the bitmap: use the bitmap provided or the standard checkmark for
3056 // the checkable items
3057 wxBitmap bmp
= bitmap
;
3058 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3060 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3065 rect
.SetRight(geometryInfo
.GetLabelOffset());
3066 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3070 rect
.x
= geometryInfo
.GetLabelOffset();
3071 rect
.SetRight(geometryInfo
.GetAccelOffset());
3073 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3075 // draw the accel string
3076 rect
.x
= geometryInfo
.GetAccelOffset();
3077 rect
.SetRight(geometryInfo
.GetSize().x
);
3079 // NB: no accel index here
3080 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3082 // draw the submenu indicator
3083 if ( flags
& wxCONTROL_ISSUBMENU
)
3085 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3086 rect
.width
= MENU_RIGHT_MARGIN
;
3088 wxArrowStyle arrowStyle
;
3089 if ( flags
& wxCONTROL_DISABLED
)
3090 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
3092 else if ( flags
& wxCONTROL_SELECTED
)
3093 arrowStyle
= Arrow_Inversed
;
3095 arrowStyle
= Arrow_Normal
;
3097 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3101 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3103 const wxMenuGeometryInfo
& geomInfo
)
3105 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3108 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3110 wxSize size
= sizeText
;
3112 // FIXME: menubar height is configurable under Windows
3119 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3120 const wxMenu
& menu
) const
3122 // prepare the dc: for now we draw all the items with the system font
3124 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3126 // the height of a normal item
3127 wxCoord heightText
= dc
.GetCharHeight();
3132 // the max length of label and accel strings: the menu width is the sum of
3133 // them, even if they're for different items (as the accels should be
3136 // the max length of the bitmap is never 0 as Windows always leaves enough
3137 // space for a check mark indicator
3138 wxCoord widthLabelMax
= 0,
3140 widthBmpMax
= MENU_LEFT_MARGIN
;
3142 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3144 node
= node
->GetNext() )
3146 // height of this item
3149 wxMenuItem
*item
= node
->GetData();
3150 if ( item
->IsSeparator() )
3152 h
= MENU_SEPARATOR_HEIGHT
;
3154 else // not separator
3159 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3160 if ( widthLabel
> widthLabelMax
)
3162 widthLabelMax
= widthLabel
;
3166 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3167 if ( widthAccel
> widthAccelMax
)
3169 widthAccelMax
= widthAccel
;
3172 const wxBitmap
& bmp
= item
->GetBitmap();
3175 wxCoord widthBmp
= bmp
.GetWidth();
3176 if ( widthBmp
> widthBmpMax
)
3177 widthBmpMax
= widthBmp
;
3179 //else if ( item->IsCheckable() ): no need to check for this as
3180 // MENU_LEFT_MARGIN is big enough to show the check mark
3183 h
+= 2*MENU_VERT_MARGIN
;
3185 // remember the item position and height
3186 item
->SetGeometry(height
, h
);
3191 // bundle the metrics into a struct and return it
3192 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3194 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3195 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3196 if ( widthAccelMax
> 0 )
3198 // if we actually have any accesl, add a margin
3199 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3202 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3204 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3205 gi
->m_size
.y
= height
;
3210 // ----------------------------------------------------------------------------
3212 // ----------------------------------------------------------------------------
3214 static const wxCoord STATBAR_BORDER_X
= 2;
3215 static const wxCoord STATBAR_BORDER_Y
= 2;
3217 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3219 if ( borderBetweenFields
)
3220 *borderBetweenFields
= 2;
3222 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3225 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3227 const wxString
& label
,
3228 int flags
, int style
/*=0*/)
3232 if ( flags
& wxCONTROL_ISDEFAULT
)
3234 // draw the size grip: it is a normal rect except that in the lower
3235 // right corner we have several bands which may be used for dragging
3236 // the status bar corner
3238 // each band consists of 4 stripes: m_penHighlight, double
3239 // m_penDarkGrey and transparent one
3240 wxCoord x2
= rect
.GetRight(),
3241 y2
= rect
.GetBottom();
3243 // draw the upper left part of the rect normally
3244 if (style
!= wxSB_FLAT
)
3246 if (style
== wxSB_RAISED
)
3247 dc
.SetPen(m_penHighlight
);
3249 dc
.SetPen(m_penDarkGrey
);
3250 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3251 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3254 // draw the grey stripes of the grip
3256 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3257 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3259 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3260 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3263 // draw the white stripes
3264 dc
.SetPen(m_penHighlight
);
3265 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3266 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3268 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3271 // draw the remaining rect boundaries
3272 if (style
!= wxSB_FLAT
)
3274 if (style
== wxSB_RAISED
)
3275 dc
.SetPen(m_penDarkGrey
);
3277 dc
.SetPen(m_penHighlight
);
3278 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3279 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3280 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3286 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3290 if (style
== wxSB_RAISED
)
3291 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3292 else if (style
!= wxSB_FLAT
)
3293 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3296 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3298 wxDCClipper
clipper(dc
, rectIn
);
3299 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3302 // ----------------------------------------------------------------------------
3304 // ----------------------------------------------------------------------------
3306 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3307 wxBitmap
* WXUNUSED(bmpFocus
),
3308 wxBitmap
*bmpPressed
,
3309 wxBitmap
*bmpDisabled
)
3311 static const wxCoord widthCombo
= 16;
3312 static const wxCoord heightCombo
= 17;
3318 bmpNormal
->Create(widthCombo
, heightCombo
);
3319 dcMem
.SelectObject(*bmpNormal
);
3320 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3321 Arrow_Down
, Arrow_Normal
);
3326 bmpPressed
->Create(widthCombo
, heightCombo
);
3327 dcMem
.SelectObject(*bmpPressed
);
3328 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3329 Arrow_Down
, Arrow_Pressed
);
3334 bmpDisabled
->Create(widthCombo
, heightCombo
);
3335 dcMem
.SelectObject(*bmpDisabled
);
3336 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3337 Arrow_Down
, Arrow_Disabled
);
3341 // ----------------------------------------------------------------------------
3343 // ----------------------------------------------------------------------------
3345 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3346 const wxColour
& col
,
3348 wxWindow
* WXUNUSED(window
))
3350 wxBrush
brush(col
, wxSOLID
);
3352 dc
.SetPen(*wxTRANSPARENT_PEN
);
3353 dc
.DrawRectangle(rect
);
3356 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3357 const wxColour
& col
,
3359 int WXUNUSED(flags
),
3362 // just fill it with the given or default bg colour
3363 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3364 DoDrawBackground(dc
, colBg
, rect
, window
);
3367 // ----------------------------------------------------------------------------
3369 // ----------------------------------------------------------------------------
3371 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3376 // get the bitmap for this arrow
3377 wxArrowDirection arrowDir
;
3380 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3381 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3382 case wxUP
: arrowDir
= Arrow_Up
; break;
3383 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3386 wxFAIL_MSG(_T("unknown arrow direction"));
3390 wxArrowStyle arrowStyle
;
3391 if ( flags
& wxCONTROL_PRESSED
)
3393 // can't be pressed and disabled
3394 arrowStyle
= Arrow_Pressed
;
3398 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3401 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3404 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3406 wxArrowDirection arrowDir
,
3407 wxArrowStyle arrowStyle
)
3409 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3411 // under Windows the arrows always have the same size so just centre it in
3412 // the provided rectangle
3413 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3414 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3416 // Windows does it like this...
3417 if ( arrowDir
== Arrow_Left
)
3421 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3424 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3425 const wxRect
& rectAll
,
3426 wxArrowDirection arrowDir
,
3427 wxArrowStyle arrowStyle
)
3429 wxRect rect
= rectAll
;
3430 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3431 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3432 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3435 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3436 wxOrientation
WXUNUSED(orient
),
3438 int WXUNUSED(flags
))
3440 // we don't use the flags, the thumb never changes appearance
3441 wxRect rectThumb
= rect
;
3442 DrawArrowBorder(dc
, &rectThumb
);
3443 DrawBackground(dc
, wxNullColour
, rectThumb
);
3446 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3447 wxOrientation
WXUNUSED(orient
),
3448 const wxRect
& rectBar
,
3451 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3452 ? wxColourScheme::SCROLLBAR_PRESSED
3453 : wxColourScheme::SCROLLBAR
;
3454 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3457 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3459 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3462 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3463 wxScrollBar::Element elem
,
3466 return StandardGetScrollbarRect(scrollbar
, elem
,
3467 thumbPos
, m_sizeScrollbarArrow
);
3470 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3472 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3475 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3476 const wxPoint
& pt
) const
3478 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3481 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3484 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3487 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3490 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3493 // ----------------------------------------------------------------------------
3494 // top level windows
3495 // ----------------------------------------------------------------------------
3497 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3499 wxRect client
= GetFrameClientArea(rect
, flags
);
3501 if ( client
.Inside(pt
) )
3502 return wxHT_TOPLEVEL_CLIENT_AREA
;
3504 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3506 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3508 if ( flags
& wxTOPLEVEL_ICON
)
3510 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3511 return wxHT_TOPLEVEL_ICON
;
3514 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3515 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3516 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3518 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3520 if ( btnRect
.Inside(pt
) )
3521 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3522 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3524 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3526 if ( btnRect
.Inside(pt
) )
3527 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3528 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3530 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3532 if ( btnRect
.Inside(pt
) )
3533 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3534 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3536 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3538 if ( btnRect
.Inside(pt
) )
3539 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3540 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3542 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3544 if ( btnRect
.Inside(pt
) )
3545 return wxHT_TOPLEVEL_BUTTON_HELP
;
3546 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3549 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3550 return wxHT_TOPLEVEL_TITLEBAR
;
3553 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3555 // we are certainly at one of borders, lets decide which one:
3558 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3559 if ( pt
.x
< client
.x
)
3560 border
|= wxHT_TOPLEVEL_BORDER_W
;
3561 else if ( pt
.x
>= client
.width
+ client
.x
)
3562 border
|= wxHT_TOPLEVEL_BORDER_E
;
3563 if ( pt
.y
< client
.y
)
3564 border
|= wxHT_TOPLEVEL_BORDER_N
;
3565 else if ( pt
.y
>= client
.height
+ client
.y
)
3566 border
|= wxHT_TOPLEVEL_BORDER_S
;
3570 return wxHT_NOWHERE
;
3573 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3575 const wxString
& title
,
3579 int specialButtonFlags
)
3581 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3583 DrawFrameBorder(dc
, rect
, flags
);
3585 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3587 DrawFrameBackground(dc
, rect
, flags
);
3588 if ( flags
& wxTOPLEVEL_ICON
)
3589 DrawFrameIcon(dc
, rect
, icon
, flags
);
3590 DrawFrameTitle(dc
, rect
, title
, flags
);
3592 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3594 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3595 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3597 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3599 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3600 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3601 specialButtonFlags
: 0);
3602 x
-= FRAME_BUTTON_WIDTH
+ 2;
3604 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3606 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3607 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3608 specialButtonFlags
: 0);
3609 x
-= FRAME_BUTTON_WIDTH
;
3611 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3613 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3614 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3615 specialButtonFlags
: 0);
3616 x
-= FRAME_BUTTON_WIDTH
;
3618 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3620 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3621 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3622 specialButtonFlags
: 0);
3623 x
-= FRAME_BUTTON_WIDTH
;
3625 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3627 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3628 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3629 specialButtonFlags
: 0);
3634 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3638 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3642 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3643 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3644 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3645 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3646 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3649 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3653 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3655 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3656 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3657 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3659 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3660 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3662 DrawBackground(dc
, col
, r
);
3665 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3667 const wxString
& title
,
3670 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3671 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3672 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3674 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3675 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3676 if ( flags
& wxTOPLEVEL_ICON
)
3678 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3679 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3687 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3688 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3689 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3690 r
.width
-= FRAME_BUTTON_WIDTH
;
3691 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3692 r
.width
-= FRAME_BUTTON_WIDTH
;
3693 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3694 r
.width
-= FRAME_BUTTON_WIDTH
;
3695 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3696 r
.width
-= FRAME_BUTTON_WIDTH
;
3698 dc
.SetFont(m_titlebarFont
);
3699 dc
.SetTextForeground(col
);
3702 dc
.GetTextExtent(title
, &textW
, NULL
);
3703 if ( textW
> r
.width
)
3705 // text is too big, let's shorten it and add "..." after it:
3706 size_t len
= title
.length();
3707 wxCoord WSoFar
, letterW
;
3709 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3710 if ( WSoFar
> r
.width
)
3712 // not enough space to draw anything
3718 for (size_t i
= 0; i
< len
; i
++)
3720 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3721 if ( letterW
+ WSoFar
> r
.width
)
3727 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3728 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3731 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3732 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3735 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3742 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3743 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3747 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3748 wxCoord x
, wxCoord y
,
3752 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3757 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3758 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3759 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3760 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3761 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3763 wxFAIL_MSG(wxT("incorrect button specification"));
3766 if ( flags
& wxCONTROL_PRESSED
)
3768 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3769 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3770 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3771 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3775 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3776 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3777 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3778 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3783 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3788 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3790 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3791 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3792 FRAME_BORDER_THICKNESS
;
3795 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3797 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3798 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3804 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3807 wxSize
s(clientSize
);
3809 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3811 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3812 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3813 FRAME_BORDER_THICKNESS
;
3817 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3818 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3823 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3827 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3829 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3830 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3831 FRAME_BORDER_THICKNESS
;
3836 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3838 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3840 if ( flags
& wxTOPLEVEL_ICON
)
3841 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3842 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3843 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3844 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3845 s
.x
+= FRAME_BUTTON_WIDTH
;
3846 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3847 s
.x
+= FRAME_BUTTON_WIDTH
;
3848 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3849 s
.x
+= FRAME_BUTTON_WIDTH
;
3850 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3851 s
.x
+= FRAME_BUTTON_WIDTH
;
3857 wxSize
wxWin32Renderer::GetFrameIconSize() const
3859 return wxSize(16, 16);
3863 // ----------------------------------------------------------------------------
3865 // ----------------------------------------------------------------------------
3867 static char *error_xpm
[]={
3874 "...........########.............",
3875 "........###aaaaaaaa###..........",
3876 ".......#aaaaaaaaaaaaaa#.........",
3877 ".....##aaaaaaaaaaaaaaaa##.......",
3878 "....#aaaaaaaaaaaaaaaaaaaa#......",
3879 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3880 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3881 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3882 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3883 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3884 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3885 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3886 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3887 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3888 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3889 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3890 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3891 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3892 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3893 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3894 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3895 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3896 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3897 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3898 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3899 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3900 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3901 "......b#aaaaaaaaaaaaaa#bbbbb....",
3902 ".......b###aaaaaaaa###bbbbb.....",
3903 ".........bb########bbbbbb.......",
3904 "..........bbbbbbbbbbbbbb........",
3905 ".............bbbbbbbb..........."};
3907 static char *info_xpm
[]={
3915 "...........########.............",
3916 "........###abbbbbba###..........",
3917 "......##abbbbbbbbbbbba##........",
3918 ".....#abbbbbbbbbbbbbbbba#.......",
3919 "....#bbbbbbbaccccabbbbbbbd......",
3920 "...#bbbbbbbbccccccbbbbbbbbd.....",
3921 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3922 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3923 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3924 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3925 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3926 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3927 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3928 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3929 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3930 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3931 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3932 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3933 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3934 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3935 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3936 ".....dabbbbbbbbbbbbbbbbad####...",
3937 "......ddabbbbbbbbbbbbadd####....",
3938 ".......#dddabbbbbbaddd#####.....",
3939 "........###dddabbbd#######......",
3940 "..........####dbbbd#####........",
3941 ".............#dbbbd##...........",
3942 "...............dbbd##...........",
3943 "................dbd##...........",
3944 ".................dd##...........",
3945 "..................###...........",
3946 "...................##..........."};
3948 static char *question_xpm
[]={
3956 "...........########.............",
3957 "........###abbbbbba###..........",
3958 "......##abbbbbbbbbbbba##........",
3959 ".....#abbbbbbbbbbbbbbbba#.......",
3960 "....#bbbbbbbbbbbbbbbbbbbbc......",
3961 "...#bbbbbbbaddddddabbbbbbbc.....",
3962 "..#bbbbbbbadabbddddabbbbbbbc....",
3963 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3964 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3965 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3966 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3967 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3968 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3969 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3970 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3971 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3972 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3973 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3974 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3975 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3976 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3977 ".....cabbbbbbbbbbbbbbbbac####...",
3978 "......ccabbbbbbbbbbbbacc####....",
3979 ".......#cccabbbbbbaccc#####.....",
3980 "........###cccabbbc#######......",
3981 "..........####cbbbc#####........",
3982 ".............#cbbbc##...........",
3983 "...............cbbc##...........",
3984 "................cbc##...........",
3985 ".................cc##...........",
3986 "..................###...........",
3987 "...................##..........."};
3989 static char *warning_xpm
[]={
3997 ".............###................",
3998 "............#aabc...............",
3999 "...........#aaaabcd.............",
4000 "...........#aaaaacdd............",
4001 "..........#aaaaaabcdd...........",
4002 "..........#aaaaaaacdd...........",
4003 ".........#aaaaaaaabcdd..........",
4004 ".........#aaaaaaaaacdd..........",
4005 "........#aaaaaaaaaabcdd.........",
4006 "........#aaabcccbaaacdd.........",
4007 ".......#aaaacccccaaabcdd........",
4008 ".......#aaaacccccaaaacdd........",
4009 "......#aaaaacccccaaaabcdd.......",
4010 "......#aaaaacccccaaaaacdd.......",
4011 ".....#aaaaaacccccaaaaabcdd......",
4012 ".....#aaaaaa#ccc#aaaaaacdd......",
4013 "....#aaaaaaabcccbaaaaaabcdd.....",
4014 "....#aaaaaaaacccaaaaaaaacdd.....",
4015 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
4016 "...#aaaaaaaaabcbaaaaaaaaacdd....",
4017 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
4018 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
4019 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
4020 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
4021 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
4022 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
4023 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
4024 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
4025 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
4026 "..#ccccccccccccccccccccccccddddd",
4027 "....ddddddddddddddddddddddddddd.",
4028 ".....ddddddddddddddddddddddddd.."};
4030 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4031 const wxArtClient
& WXUNUSED(client
),
4032 const wxSize
& WXUNUSED(size
))
4034 if ( id
== wxART_INFORMATION
)
4035 return wxBitmap(info_xpm
);
4036 if ( id
== wxART_ERROR
)
4037 return wxBitmap(error_xpm
);
4038 if ( id
== wxART_WARNING
)
4039 return wxBitmap(warning_xpm
);
4040 if ( id
== wxART_QUESTION
)
4041 return wxBitmap(question_xpm
);
4042 return wxNullBitmap
;
4046 // ----------------------------------------------------------------------------
4047 // text control geometry
4048 // ----------------------------------------------------------------------------
4050 static inline int GetTextBorderWidth()
4056 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4057 const wxRect
& rect
) const
4059 wxRect rectTotal
= rect
;
4061 wxCoord widthBorder
= GetTextBorderWidth();
4062 rectTotal
.Inflate(widthBorder
);
4064 // this is what Windows does
4071 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4073 wxCoord
*extraSpaceBeyond
) const
4075 wxRect rectText
= rect
;
4077 // undo GetTextTotalArea()
4078 if ( rectText
.height
> 0 )
4081 wxCoord widthBorder
= GetTextBorderWidth();
4082 rectText
.Inflate(-widthBorder
);
4084 if ( extraSpaceBeyond
)
4085 *extraSpaceBeyond
= 0;
4090 // ----------------------------------------------------------------------------
4092 // ----------------------------------------------------------------------------
4094 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4097 if ( wxDynamicCast(window
, wxScrollBar
) )
4099 // we only set the width of vert scrollbars and height of the
4101 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4102 size
->y
= m_sizeScrollbarArrow
.y
;
4104 size
->x
= m_sizeScrollbarArrow
.x
;
4106 // skip border width adjustments, they don't make sense for us
4109 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4112 if ( wxDynamicCast(window
, wxButton
) )
4114 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4116 // TODO: don't harcode all this
4117 size
->x
+= 3*window
->GetCharWidth();
4119 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4120 if ( size
->y
< heightBtn
- 8 )
4121 size
->y
= heightBtn
;
4126 // for compatibility with other ports, the buttons default size is never
4127 // less than the standard one, but not when display not PDAs.
4128 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4130 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4132 wxSize szDef
= wxButton::GetDefaultSize();
4133 if ( size
->x
< szDef
.x
)
4138 // no border width adjustments for buttons
4141 #endif // wxUSE_BUTTON
4143 // take into account the border width
4144 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4145 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4146 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4149 // ============================================================================
4151 // ============================================================================
4153 // ----------------------------------------------------------------------------
4154 // wxWin32InputHandler
4155 // ----------------------------------------------------------------------------
4157 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4159 m_renderer
= renderer
;
4162 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4163 const wxKeyEvent
& WXUNUSED(event
),
4164 bool WXUNUSED(pressed
))
4169 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4170 const wxMouseEvent
& event
)
4172 // clicking on the control gives it focus
4173 if ( event
.ButtonDown() )
4175 wxWindow
*win
= control
->GetInputWindow();
4177 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4178 ( win
->AcceptsFocus() ) )
4189 // ----------------------------------------------------------------------------
4190 // wxWin32ScrollBarInputHandler
4191 // ----------------------------------------------------------------------------
4193 wxWin32ScrollBarInputHandler::
4194 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4195 wxInputHandler
*handler
)
4196 : wxStdScrollBarInputHandler(renderer
, handler
)
4198 m_scrollPaused
= false;
4202 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4203 const wxControlAction
& action
)
4205 // stop if went beyond the position of the original click (this can only
4206 // happen when we scroll by pages)
4208 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4210 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4211 != wxHT_SCROLLBAR_BAR_2
;
4213 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4215 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4216 != wxHT_SCROLLBAR_BAR_1
;
4221 StopScrolling(scrollbar
);
4223 scrollbar
->Refresh();
4228 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4231 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4232 const wxMouseEvent
& event
)
4234 // remember the current state
4235 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4237 // do process the message
4238 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4240 // analyse the changes
4241 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4243 // we just started dragging the thumb, remember its initial position to
4244 // be able to restore it if the drag is cancelled later
4245 m_eventStartDrag
= event
;
4251 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4252 const wxMouseEvent
& event
)
4254 // we don't highlight scrollbar elements, so there is no need to process
4255 // mouse move events normally - only do it while mouse is captured (i.e.
4256 // when we're dragging the thumb or pressing on something)
4257 if ( !m_winCapture
)
4260 if ( event
.Entering() )
4262 // we're not interested in this at all
4266 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4268 if ( m_scrollPaused
)
4270 // check if the mouse returned to its original location
4272 if ( event
.Leaving() )
4278 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4279 if ( ht
== m_htLast
)
4281 // yes it did, resume scrolling
4282 m_scrollPaused
= false;
4283 if ( m_timerScroll
)
4285 // we were scrolling by line/page, restart timer
4286 m_timerScroll
->Start(m_interval
);
4288 Press(scrollbar
, true);
4290 else // we were dragging the thumb
4292 // restore its last location
4293 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4299 else // normal case, scrolling hasn't been paused
4301 // if we're scrolling the scrollbar because the arrow or the shaft was
4302 // pressed, check that the mouse stays on the same scrollbar element
4305 // Always let thumb jump back if we leave the scrollbar
4306 if ( event
.Moving() )
4308 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4310 else // event.Leaving()
4315 // Jump back only if we get far away from it
4316 wxPoint pos
= event
.GetPosition();
4317 if (scrollbar
->HasFlag( wxVERTICAL
))
4319 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4324 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4327 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4330 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4331 // is still ok - we only want to catch the case when the mouse leaves
4332 // the scrollbar here
4333 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4335 ht
= wxHT_SCROLLBAR_THUMB
;
4338 if ( ht
!= m_htLast
)
4340 // what were we doing? 2 possibilities: either an arrow/shaft was
4341 // pressed in which case we have a timer and so we just stop it or
4342 // we were dragging the thumb
4343 if ( m_timerScroll
)
4346 m_interval
= m_timerScroll
->GetInterval();
4347 m_timerScroll
->Stop();
4348 m_scrollPaused
= true;
4350 // unpress the arrow
4351 Press(scrollbar
, false);
4353 else // we were dragging the thumb
4355 // remember the current thumb position to be able to restore it
4356 // if the mouse returns to it later
4357 m_eventLastDrag
= event
;
4359 // and restore the original position (before dragging) of the
4361 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4368 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4371 // ----------------------------------------------------------------------------
4372 // wxWin32CheckboxInputHandler
4373 // ----------------------------------------------------------------------------
4375 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4376 const wxKeyEvent
& event
,
4381 wxControlAction action
;
4382 int keycode
= event
.GetKeyCode();
4386 action
= wxACTION_CHECKBOX_TOGGLE
;
4390 case WXK_NUMPAD_SUBTRACT
:
4391 action
= wxACTION_CHECKBOX_CHECK
;
4395 case WXK_NUMPAD_ADD
:
4396 case WXK_NUMPAD_EQUAL
:
4397 action
= wxACTION_CHECKBOX_CLEAR
;
4401 if ( !action
.IsEmpty() )
4403 control
->PerformAction(action
);
4412 // ----------------------------------------------------------------------------
4413 // wxWin32TextCtrlInputHandler
4414 // ----------------------------------------------------------------------------
4416 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4417 const wxKeyEvent
& event
,
4420 // handle only MSW-specific text bindings here, the others are handled in
4424 int keycode
= event
.GetKeyCode();
4426 wxControlAction action
;
4427 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4429 action
= wxACTION_TEXT_CUT
;
4431 else if ( keycode
== WXK_INSERT
)
4433 if ( event
.ControlDown() )
4434 action
= wxACTION_TEXT_COPY
;
4435 else if ( event
.ShiftDown() )
4436 action
= wxACTION_TEXT_PASTE
;
4439 if ( action
!= wxACTION_NONE
)
4441 control
->PerformAction(action
);
4447 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4450 // ----------------------------------------------------------------------------
4451 // wxWin32StatusBarInputHandler
4452 // ----------------------------------------------------------------------------
4454 wxWin32StatusBarInputHandler::
4455 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4456 : wxStdInputHandler(handler
)
4461 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4462 const wxPoint
& pt
) const
4464 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4465 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4468 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4470 wxCHECK_MSG( parentTLW
, false,
4471 _T("the status bar should be a child of a TLW") );
4473 // a maximized window can't be resized anyhow
4474 if ( !parentTLW
->IsMaximized() )
4476 // VZ: I think that the standard Windows behaviour is to only
4477 // show the resizing cursor when the mouse is on top of the
4478 // grip itself but apparently different Windows versions behave
4479 // differently (?) and it seems a better UI to allow resizing
4480 // the status bar even when the mouse is above the grip
4481 wxSize sizeSbar
= statbar
->GetSize();
4483 int diff
= sizeSbar
.x
- pt
.x
;
4484 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4491 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4492 const wxMouseEvent
& event
)
4494 if ( event
.Button(1) )
4496 if ( event
.ButtonDown(1) )
4498 wxWindow
*statbar
= consumer
->GetInputWindow();
4500 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4502 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4506 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4507 wxHT_TOPLEVEL_BORDER_SE
);
4509 statbar
->SetCursor(m_cursorOld
);
4517 return wxStdInputHandler::HandleMouse(consumer
, event
);
4520 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4521 const wxMouseEvent
& event
)
4523 wxWindow
*statbar
= consumer
->GetInputWindow();
4525 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4526 if ( isOnGrip
!= m_isOnGrip
)
4528 m_isOnGrip
= isOnGrip
;
4531 m_cursorOld
= statbar
->GetCursor();
4532 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4536 statbar
->SetCursor(m_cursorOld
);
4540 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4543 // ----------------------------------------------------------------------------
4544 // wxWin32FrameInputHandler
4545 // ----------------------------------------------------------------------------
4547 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4550 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4552 void Attach(wxInputConsumer
*consumer
);
4556 DECLARE_EVENT_TABLE()
4557 void OnSystemMenu(wxCommandEvent
&event
);
4558 void OnCloseFrame(wxCommandEvent
&event
);
4559 void OnClose(wxCloseEvent
&event
);
4561 wxWin32FrameInputHandler
*m_inputHnd
;
4562 wxTopLevelWindow
*m_wnd
;
4564 wxAcceleratorTable m_oldAccelTable
;
4568 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4569 wxWin32FrameInputHandler
*handler
)
4571 m_inputHnd
= handler
;
4575 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4577 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4579 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4580 m_wnd
->PushEventHandler(this);
4583 // VS: This code relies on using generic implementation of
4584 // wxAcceleratorTable in wxUniv!
4585 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4586 m_oldAccelTable
= table
;
4587 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4588 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4589 m_wnd
->SetAcceleratorTable(table
);
4593 void wxWin32SystemMenuEvtHandler::Detach()
4598 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4600 m_wnd
->RemoveEventHandler(this);
4605 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4606 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4607 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4608 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4611 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4613 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4614 !m_wnd
->IsMaximized()) ?
4615 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4616 FRAME_BORDER_THICKNESS
;
4617 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4618 pt
.x
= -pt
.x
+ border
;
4619 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4622 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4623 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4626 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4629 m_wnd
->SetAcceleratorTable(table
);
4633 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4635 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4636 wxTOPLEVEL_BUTTON_CLOSE
);
4639 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4646 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4647 : wxStdFrameInputHandler(handler
)
4649 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4652 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4654 if ( m_menuHandler
)
4656 m_menuHandler
->Detach();
4657 delete m_menuHandler
;
4661 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4662 const wxMouseEvent
& event
)
4664 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4666 wxTopLevelWindow
*tlw
=
4667 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4669 long hit
= tlw
->HitTest(event
.GetPosition());
4671 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4673 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4674 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4675 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4678 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4680 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4681 (event
.RightDown() &&
4682 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4683 hit
== wxHT_TOPLEVEL_ICON
)) )
4685 PopupSystemMenu(tlw
, event
.GetPosition());
4691 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4694 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4695 const wxPoint
& pos
) const
4697 wxMenu
*menu
= new wxMenu
;
4699 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4700 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4701 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4702 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4703 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4704 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4705 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4706 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4707 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4708 menu
->AppendSeparator();
4709 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4711 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4713 if ( window
->IsMaximized() )
4715 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4716 menu
->Enable(wxID_MOVE_FRAME
, false);
4717 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4718 menu
->Enable(wxID_RESIZE_FRAME
, false);
4721 menu
->Enable(wxID_RESTORE_FRAME
, false);
4724 window
->PopupMenu(menu
, pos
);
4728 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4731 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4733 // always detach if active frame changed:
4734 m_menuHandler
->Detach();
4738 m_menuHandler
->Attach(consumer
);
4742 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);