1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: univ/themes/win32.cpp
3 // Purpose: wxUniversal theme implementing Win32-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
31 #include "wx/window.h"
33 #include "wx/dcmemory.h"
35 #include "wx/button.h"
36 #include "wx/listbox.h"
37 #include "wx/checklst.h"
38 #include "wx/combobox.h"
39 #include "wx/scrolbar.h"
40 #include "wx/slider.h"
41 #include "wx/textctrl.h"
42 #include "wx/listbox.h"
43 #include "wx/toolbar.h"
44 #include "wx/statusbr.h"
47 // for COLOR_* constants
48 #include "wx/msw/private.h"
52 #include "wx/notebook.h"
53 #include "wx/spinbutt.h"
54 #include "wx/settings.h"
56 #include "wx/artprov.h"
57 #include "wx/toplevel.h"
60 #include "wx/univ/scrtimer.h"
61 #include "wx/univ/renderer.h"
62 #include "wx/univ/inphand.h"
63 #include "wx/univ/colschem.h"
64 #include "wx/univ/theme.h"
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 static const int BORDER_THICKNESS
= 2;
72 // the offset between the label and focus rect around it
73 static const int FOCUS_RECT_OFFSET_X
= 1;
74 static const int FOCUS_RECT_OFFSET_Y
= 1;
76 static const int FRAME_BORDER_THICKNESS
= 3;
77 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
78 static const int FRAME_TITLEBAR_HEIGHT
= 18;
79 static const int FRAME_BUTTON_WIDTH
= 16;
80 static const int FRAME_BUTTON_HEIGHT
= 14;
82 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
83 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
84 static const size_t STATUSBAR_GRIP_SIZE
=
85 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
87 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
88 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
89 static const wxCoord SLIDER_TICK_LENGTH
= 6;
101 IndicatorState_Normal
,
102 IndicatorState_Pressed
, // this one is for check/radioboxes
103 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
104 IndicatorState_Disabled
,
105 IndicatorState_SelectedDisabled
, // only for the menus
111 IndicatorStatus_Checked
,
112 IndicatorStatus_Unchecked
,
116 // wxWin32Renderer: draw the GUI elements in Win32 style
117 // ----------------------------------------------------------------------------
119 class wxWin32Renderer
: public wxRenderer
123 enum wxArrowDirection
138 Arrow_InversedDisabled
,
142 enum wxFrameButtonType
145 FrameButton_Minimize
,
146 FrameButton_Maximize
,
153 wxWin32Renderer(const wxColourScheme
*scheme
);
155 // implement the base class pure virtuals
156 virtual void DrawBackground(wxDC
& dc
,
160 wxWindow
*window
= NULL
);
161 virtual void DrawLabel(wxDC
& dc
,
162 const wxString
& label
,
165 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
167 wxRect
*rectBounds
= NULL
);
168 virtual void DrawButtonLabel(wxDC
& dc
,
169 const wxString
& label
,
170 const wxBitmap
& image
,
173 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
175 wxRect
*rectBounds
= NULL
);
176 virtual void DrawBorder(wxDC
& dc
,
180 wxRect
*rectIn
= (wxRect
*)NULL
);
181 virtual void DrawHorizontalLine(wxDC
& dc
,
182 wxCoord y
, wxCoord x1
, wxCoord x2
);
183 virtual void DrawVerticalLine(wxDC
& dc
,
184 wxCoord x
, wxCoord y1
, wxCoord y2
);
185 virtual void DrawFrame(wxDC
& dc
,
186 const wxString
& label
,
189 int alignment
= wxALIGN_LEFT
,
190 int indexAccel
= -1);
191 virtual void DrawTextBorder(wxDC
& dc
,
195 wxRect
*rectIn
= (wxRect
*)NULL
);
196 virtual void DrawButtonBorder(wxDC
& dc
,
199 wxRect
*rectIn
= (wxRect
*)NULL
);
200 virtual void DrawArrow(wxDC
& dc
,
204 virtual void DrawScrollbarArrow(wxDC
& dc
,
208 { DrawArrow(dc
, dir
, rect
, flags
); }
209 virtual void DrawScrollbarThumb(wxDC
& dc
,
210 wxOrientation orient
,
213 virtual void DrawScrollbarShaft(wxDC
& dc
,
214 wxOrientation orient
,
217 virtual void DrawScrollCorner(wxDC
& dc
,
219 virtual void DrawItem(wxDC
& dc
,
220 const wxString
& label
,
223 virtual void DrawCheckItem(wxDC
& dc
,
224 const wxString
& label
,
225 const wxBitmap
& bitmap
,
228 virtual void DrawCheckButton(wxDC
& dc
,
229 const wxString
& label
,
230 const wxBitmap
& bitmap
,
233 wxAlignment align
= wxALIGN_LEFT
,
234 int indexAccel
= -1);
235 virtual void DrawRadioButton(wxDC
& dc
,
236 const wxString
& label
,
237 const wxBitmap
& bitmap
,
240 wxAlignment align
= wxALIGN_LEFT
,
241 int indexAccel
= -1);
242 virtual void DrawToolBarButton(wxDC
& dc
,
243 const wxString
& label
,
244 const wxBitmap
& bitmap
,
248 virtual void DrawTextLine(wxDC
& dc
,
249 const wxString
& text
,
254 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
255 virtual void DrawTab(wxDC
& dc
,
258 const wxString
& label
,
259 const wxBitmap
& bitmap
= wxNullBitmap
,
261 int indexAccel
= -1);
263 virtual void DrawSliderShaft(wxDC
& dc
,
266 wxOrientation orient
,
269 wxRect
*rectShaft
= NULL
);
270 virtual void DrawSliderThumb(wxDC
& dc
,
272 wxOrientation orient
,
275 virtual void DrawSliderTicks(wxDC
& dc
,
278 wxOrientation orient
,
285 virtual void DrawMenuBarItem(wxDC
& dc
,
287 const wxString
& label
,
289 int indexAccel
= -1);
290 virtual void DrawMenuItem(wxDC
& dc
,
292 const wxMenuGeometryInfo
& geometryInfo
,
293 const wxString
& label
,
294 const wxString
& accel
,
295 const wxBitmap
& bitmap
= wxNullBitmap
,
297 int indexAccel
= -1);
298 virtual void DrawMenuSeparator(wxDC
& dc
,
300 const wxMenuGeometryInfo
& geomInfo
);
302 virtual void DrawStatusField(wxDC
& dc
,
304 const wxString
& label
,
305 int flags
= 0, int style
= 0);
308 virtual void DrawFrameTitleBar(wxDC
& dc
,
310 const wxString
& title
,
313 int specialButton
= 0,
314 int specialButtonFlags
= 0);
315 virtual void DrawFrameBorder(wxDC
& dc
,
318 virtual void DrawFrameBackground(wxDC
& dc
,
321 virtual void DrawFrameTitle(wxDC
& dc
,
323 const wxString
& title
,
325 virtual void DrawFrameIcon(wxDC
& dc
,
329 virtual void DrawFrameButton(wxDC
& dc
,
330 wxCoord x
, wxCoord y
,
333 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
334 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
335 virtual wxSize
GetFrameMinSize(int flags
) const;
336 virtual wxSize
GetFrameIconSize() const;
337 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
339 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
341 wxBitmap
*bmpPressed
,
342 wxBitmap
*bmpDisabled
);
344 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
345 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
346 virtual bool AreScrollbarsInsideBorder() const;
348 virtual wxSize
GetScrollbarArrowSize() const
349 { return m_sizeScrollbarArrow
; }
350 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
351 wxScrollBar::Element elem
,
352 int thumbPos
= -1) const;
353 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
354 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
355 const wxPoint
& pt
) const;
356 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
358 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
359 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
360 { return fontHeight
+ 2; }
361 virtual wxSize
GetCheckBitmapSize() const
362 { return wxSize(13, 13); }
363 virtual wxSize
GetRadioBitmapSize() const
364 { return wxSize(12, 12); }
365 virtual wxCoord
GetCheckItemMargin() const
368 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
369 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
370 virtual wxSize
GetToolBarMargin() const
371 { return wxSize(4, 4); }
373 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
374 const wxRect
& rect
) const;
375 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
377 wxCoord
*extraSpaceBeyond
) const;
379 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
380 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
382 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
383 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
384 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
386 wxOrientation orient
,
387 long style
= 0) const;
388 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
390 wxOrientation orient
) const;
391 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
393 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
394 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
395 const wxMenu
& menu
) const;
397 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
400 // helper of DrawLabel() and DrawCheckOrRadioButton()
401 void DoDrawLabel(wxDC
& dc
,
402 const wxString
& label
,
405 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
407 wxRect
*rectBounds
= NULL
,
408 const wxPoint
& focusOffset
409 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
411 // common part of DrawLabel() and DrawItem()
412 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
414 // DrawLabel() and DrawButtonLabel() helper
415 void DrawLabelShadow(wxDC
& dc
,
416 const wxString
& label
,
421 // DrawButtonBorder() helper
422 void DoDrawBackground(wxDC
& dc
,
425 wxWindow
*window
= NULL
);
427 // DrawBorder() helpers: all of them shift and clip the DC after drawing
430 // just draw a rectangle with the given pen
431 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
433 // draw the lower left part of rectangle
434 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
436 // draw the rectange using the first brush for the left and top sides and
437 // the second one for the bottom and right ones
438 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
439 const wxPen
& pen1
, const wxPen
& pen2
);
441 // draw the normal 3D border
442 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
444 // draw the sunken 3D border
445 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
447 // draw the border used for scrollbar arrows
448 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
450 // public DrawArrow()s helper
451 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
452 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
454 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
455 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
456 wxArrowDirection arrowDir
,
457 wxArrowStyle arrowStyle
);
459 // DrawCheckButton/DrawRadioButton helper
460 void DrawCheckOrRadioButton(wxDC
& dc
,
461 const wxString
& label
,
462 const wxBitmap
& bitmap
,
467 wxCoord focusOffsetY
);
469 // draw a normal or transposed line (useful for using the same code fo both
470 // horizontal and vertical widgets)
471 void DrawLine(wxDC
& dc
,
472 wxCoord x1
, wxCoord y1
,
473 wxCoord x2
, wxCoord y2
,
474 bool transpose
= false)
477 dc
.DrawLine(y1
, x1
, y2
, x2
);
479 dc
.DrawLine(x1
, y1
, x2
, y2
);
482 // get the standard check/radio button bitmap
483 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
484 wxBitmap
GetCheckBitmap(int flags
)
485 { return GetIndicator(IndicatorType_Check
, flags
); }
486 wxBitmap
GetRadioBitmap(int flags
)
487 { return GetIndicator(IndicatorType_Radio
, flags
); }
490 const wxColourScheme
*m_scheme
;
492 // the sizing parameters (TODO make them changeable)
493 wxSize m_sizeScrollbarArrow
;
495 // GDI objects we use for drawing
496 wxColour m_colDarkGrey
,
504 wxFont m_titlebarFont
;
506 // the checked and unchecked bitmaps for DrawCheckItem()
507 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
509 // the bitmaps returned by GetIndicator()
510 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
512 [IndicatorStatus_Max
];
515 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
517 // first row is for the normal state, second - for the disabled
518 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
521 // ----------------------------------------------------------------------------
522 // wxWin32InputHandler and derived classes: process the keyboard and mouse
523 // messages according to Windows standards
524 // ----------------------------------------------------------------------------
526 class wxWin32InputHandler
: public wxInputHandler
529 wxWin32InputHandler(wxWin32Renderer
*renderer
);
531 virtual bool HandleKey(wxInputConsumer
*control
,
532 const wxKeyEvent
& event
,
534 virtual bool HandleMouse(wxInputConsumer
*control
,
535 const wxMouseEvent
& event
);
538 wxWin32Renderer
*m_renderer
;
541 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
544 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
545 wxInputHandler
*handler
);
547 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
548 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
550 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
551 const wxControlAction
& action
);
554 virtual bool IsAllowedButton(int button
) { return button
== 1; }
556 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
559 // we don't highlight anything
562 // the first and last event which caused the thumb to move
563 wxMouseEvent m_eventStartDrag
,
566 // have we paused the scrolling because the mouse moved?
569 // we remember the interval of the timer to be able to restart it
573 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
576 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
577 : wxStdCheckboxInputHandler(handler
) { }
579 virtual bool HandleKey(wxInputConsumer
*control
,
580 const wxKeyEvent
& event
,
584 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
587 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
588 : wxStdTextCtrlInputHandler(handler
) { }
590 virtual bool HandleKey(wxInputConsumer
*control
,
591 const wxKeyEvent
& event
,
595 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
598 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
600 virtual bool HandleMouse(wxInputConsumer
*consumer
,
601 const wxMouseEvent
& event
);
603 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
604 const wxMouseEvent
& event
);
607 // is the given point over the statusbar grip?
608 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
611 // the cursor we had replaced with the resize one
612 wxCursor m_cursorOld
;
614 // was the mouse over the grip last time we checked?
618 class wxWin32SystemMenuEvtHandler
;
620 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
623 wxWin32FrameInputHandler(wxInputHandler
*handler
);
624 ~wxWin32FrameInputHandler();
626 virtual bool HandleMouse(wxInputConsumer
*control
,
627 const wxMouseEvent
& event
);
629 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
631 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
634 // was the mouse over the grip last time we checked?
635 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
638 // ----------------------------------------------------------------------------
639 // wxWin32ColourScheme: uses (default) Win32 colours
640 // ----------------------------------------------------------------------------
642 class wxWin32ColourScheme
: public wxColourScheme
645 virtual wxColour
Get(StdColour col
) const;
646 virtual wxColour
GetBackground(wxWindow
*win
) const;
649 // ----------------------------------------------------------------------------
650 // wxWin32ArtProvider
651 // ----------------------------------------------------------------------------
653 class wxWin32ArtProvider
: public wxArtProvider
656 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
657 const wxArtClient
& client
,
661 // ----------------------------------------------------------------------------
663 // ----------------------------------------------------------------------------
665 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
667 class wxWin32Theme
: public wxTheme
671 virtual ~wxWin32Theme();
673 virtual wxRenderer
*GetRenderer();
674 virtual wxArtProvider
*GetArtProvider();
675 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
676 virtual wxColourScheme
*GetColourScheme();
679 // get the default input handler
680 wxInputHandler
*GetDefaultInputHandler();
682 wxWin32Renderer
*m_renderer
;
684 wxWin32ArtProvider
*m_artProvider
;
686 // the names of the already created handlers and the handlers themselves
687 // (these arrays are synchronized)
688 wxSortedArrayString m_handlerNames
;
689 wxArrayHandlers m_handlers
;
691 wxWin32InputHandler
*m_handlerDefault
;
693 wxWin32ColourScheme
*m_scheme
;
695 WX_DECLARE_THEME(win32
)
698 // ----------------------------------------------------------------------------
700 // ----------------------------------------------------------------------------
702 // frame buttons bitmaps
704 static const char *frame_button_close_xpm
[] = {
719 static const char *frame_button_help_xpm
[] = {
734 static const char *frame_button_maximize_xpm
[] = {
749 static const char *frame_button_minimize_xpm
[] = {
764 static const char *frame_button_restore_xpm
[] = {
781 static const char *checked_menu_xpm
[] = {
782 /* columns rows colors chars-per-pixel */
798 static const char *selected_checked_menu_xpm
[] = {
799 /* columns rows colors chars-per-pixel */
815 static const char *disabled_checked_menu_xpm
[] = {
816 /* columns rows colors chars-per-pixel */
833 static const char *selected_disabled_checked_menu_xpm
[] = {
834 /* columns rows colors chars-per-pixel */
850 // checkbox and radiobox bitmaps below
852 static const char *checked_xpm
[] = {
853 /* columns rows colors chars-per-pixel */
876 static const char *pressed_checked_xpm
[] = {
877 /* columns rows colors chars-per-pixel */
899 static const char *pressed_disabled_checked_xpm
[] = {
900 /* columns rows colors chars-per-pixel */
922 static const char *checked_item_xpm
[] = {
923 /* columns rows colors chars-per-pixel */
944 static const char *unchecked_xpm
[] = {
945 /* columns rows colors chars-per-pixel */
968 static const char *pressed_unchecked_xpm
[] = {
969 /* columns rows colors chars-per-pixel */
991 static const char *unchecked_item_xpm
[] = {
992 /* columns rows colors chars-per-pixel */
1012 static const char *checked_radio_xpm
[] = {
1013 /* columns rows colors chars-per-pixel */
1036 static const char *pressed_checked_radio_xpm
[] = {
1037 /* columns rows colors chars-per-pixel */
1060 static const char *pressed_disabled_checked_radio_xpm
[] = {
1061 /* columns rows colors chars-per-pixel */
1084 static const char *unchecked_radio_xpm
[] = {
1085 /* columns rows colors chars-per-pixel */
1108 static const char *pressed_unchecked_radio_xpm
[] = {
1109 /* columns rows colors chars-per-pixel */
1132 static const char **
1133 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1138 { checked_xpm
, unchecked_xpm
},
1141 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1144 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1150 { checked_radio_xpm
, unchecked_radio_xpm
},
1153 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1156 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1162 { checked_menu_xpm
, NULL
},
1165 { selected_checked_menu_xpm
, NULL
},
1168 { disabled_checked_menu_xpm
, NULL
},
1170 // disabled selected state
1171 { selected_disabled_checked_menu_xpm
, NULL
},
1175 static const char **xpmChecked
[IndicatorStatus_Max
] =
1181 // ============================================================================
1183 // ============================================================================
1185 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1187 // ----------------------------------------------------------------------------
1189 // ----------------------------------------------------------------------------
1191 wxWin32Theme::wxWin32Theme()
1195 m_handlerDefault
= NULL
;
1196 m_artProvider
= NULL
;
1199 wxWin32Theme::~wxWin32Theme()
1201 size_t count
= m_handlers
.GetCount();
1202 for ( size_t n
= 0; n
< count
; n
++ )
1204 if ( m_handlers
[n
] != m_handlerDefault
)
1205 delete m_handlers
[n
];
1208 delete m_handlerDefault
;
1212 wxArtProvider::RemoveProvider(m_artProvider
);
1215 wxRenderer
*wxWin32Theme::GetRenderer()
1219 m_renderer
= new wxWin32Renderer(GetColourScheme());
1225 wxArtProvider
*wxWin32Theme::GetArtProvider()
1227 if ( !m_artProvider
)
1229 m_artProvider
= new wxWin32ArtProvider
;
1232 return m_artProvider
;
1235 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1237 if ( !m_handlerDefault
)
1239 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1242 return m_handlerDefault
;
1245 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1247 wxInputHandler
*handler
;
1248 int n
= m_handlerNames
.Index(control
);
1249 if ( n
== wxNOT_FOUND
)
1251 // create a new handler
1252 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1253 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1254 GetDefaultInputHandler());
1256 else if ( control
== wxINP_HANDLER_BUTTON
)
1257 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1258 #endif // wxUSE_BUTTON
1260 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1261 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1262 #endif // wxUSE_CHECKBOX
1264 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1265 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1266 #endif // wxUSE_COMBOBOX
1268 else if ( control
== wxINP_HANDLER_LISTBOX
)
1269 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1270 #endif // wxUSE_LISTBOX
1271 #if wxUSE_CHECKLISTBOX
1272 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1273 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1274 #endif // wxUSE_CHECKLISTBOX
1276 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1277 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1278 #endif // wxUSE_TEXTCTRL
1280 else if ( control
== wxINP_HANDLER_SLIDER
)
1281 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1282 #endif // wxUSE_SLIDER
1284 else if ( control
== wxINP_HANDLER_SPINBTN
)
1285 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1286 #endif // wxUSE_SPINBTN
1288 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1289 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1290 #endif // wxUSE_NOTEBOOK
1292 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1293 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1294 #endif // wxUSE_STATUSBAR
1296 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1297 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1298 #endif // wxUSE_TOOLBAR
1299 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1300 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1302 handler
= GetDefaultInputHandler();
1304 n
= m_handlerNames
.Add(control
);
1305 m_handlers
.Insert(handler
, n
);
1307 else // we already have it
1309 handler
= m_handlers
[n
];
1315 wxColourScheme
*wxWin32Theme::GetColourScheme()
1319 m_scheme
= new wxWin32ColourScheme
;
1324 // ============================================================================
1325 // wxWin32ColourScheme
1326 // ============================================================================
1328 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1331 if ( win
->UseBgCol() )
1333 // use the user specified colour
1334 col
= win
->GetBackgroundColour();
1337 if ( !win
->ShouldInheritColours() )
1339 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1341 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1349 if ( !win
->IsEnabled() ) // not IsEditable()
1355 // doesn't depend on the state
1362 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1366 int flags
= win
->GetStateFlags();
1368 // the colour set by the user should be used for the normal state
1369 // and for the states for which we don't have any specific colours
1370 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1372 if ( wxDynamicCast(win
, wxScrollBar
) )
1373 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1383 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1387 // use the system colours under Windows
1388 #if defined(__WXMSW__)
1389 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1391 case CONTROL_PRESSED
:
1392 case CONTROL_CURRENT
:
1393 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1395 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1397 #if defined(COLOR_3DLIGHT)
1398 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1400 case SCROLLBAR
: return wxColour(0xe0e0e0);
1402 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1404 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1405 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1407 #if defined(COLOR_3DDKSHADOW)
1408 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1410 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1413 case CONTROL_TEXT_DISABLED
:
1414 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1416 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1418 case CONTROL_TEXT_DISABLED_SHADOW
:
1419 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1421 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1422 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1423 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1424 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1426 case DESKTOP
: return wxColour(0x808000);
1428 // use the standard Windows colours elsewhere
1429 case WINDOW
: return *wxWHITE
;
1431 case CONTROL_PRESSED
:
1432 case CONTROL_CURRENT
:
1433 case CONTROL
: return wxColour(0xc0c0c0);
1435 case CONTROL_TEXT
: return *wxBLACK
;
1437 case SCROLLBAR
: return wxColour(0xe0e0e0);
1438 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1440 case HIGHLIGHT
: return wxColour(0x800000);
1441 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1443 case SHADOW_DARK
: return *wxBLACK
;
1445 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1446 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1448 case SHADOW_IN
: return wxColour(0xc0c0c0);
1450 case CONTROL_TEXT_DISABLED_SHADOW
:
1451 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1453 case TITLEBAR
: return wxColour(0xaeaaae);
1454 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1455 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1456 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1458 case DESKTOP
: return wxColour(0x808000);
1461 case GAUGE
: return Get(HIGHLIGHT
);
1465 wxFAIL_MSG(_T("invalid standard colour"));
1470 // ============================================================================
1472 // ============================================================================
1474 // ----------------------------------------------------------------------------
1476 // ----------------------------------------------------------------------------
1478 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1482 m_sizeScrollbarArrow
= wxSize(16, 16);
1484 // init colours and pens
1485 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1487 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1488 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1490 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1492 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1493 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1495 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1496 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1498 // init the arrow bitmaps
1499 static const size_t ARROW_WIDTH
= 7;
1500 static const size_t ARROW_LENGTH
= 4;
1503 wxMemoryDC dcNormal
,
1506 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1508 bool isVertical
= n
> Arrow_Right
;
1521 // disabled arrow is larger because of the shadow
1522 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1523 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1525 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1526 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1528 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1529 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1533 dcNormal
.SetPen(m_penBlack
);
1534 dcDisabled
.SetPen(m_penDarkGrey
);
1536 // calculate the position of the point of the arrow
1540 x1
= (ARROW_WIDTH
- 1)/2;
1541 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1545 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1546 y1
= (ARROW_WIDTH
- 1)/2;
1557 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1559 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1560 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1567 if ( n
== Arrow_Up
)
1578 else // left or right arrow
1583 if ( n
== Arrow_Left
)
1596 // draw the shadow for the disabled one
1597 dcDisabled
.SetPen(m_penHighlight
);
1602 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1606 x1
= ARROW_LENGTH
- 1;
1607 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1610 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1611 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1616 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1620 x1
= ARROW_WIDTH
- 1;
1622 x2
= (ARROW_WIDTH
- 1)/2;
1624 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1625 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1630 // create the inversed bitmap but only for the right arrow as we only
1631 // use it for the menus
1632 if ( n
== Arrow_Right
)
1634 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1635 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1637 dcInverse
.Blit(0, 0, w
, h
,
1640 dcInverse
.SelectObject(wxNullBitmap
);
1642 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1643 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1645 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1646 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1648 dcInverse
.Blit(0, 0, w
, h
,
1651 dcInverse
.SelectObject(wxNullBitmap
);
1653 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1654 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1657 dcNormal
.SelectObject(wxNullBitmap
);
1658 dcDisabled
.SelectObject(wxNullBitmap
);
1660 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1661 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1662 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1663 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1665 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1668 // init the frame buttons bitmaps
1669 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1670 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1671 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1672 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1673 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1676 // ----------------------------------------------------------------------------
1678 // ----------------------------------------------------------------------------
1681 The raised border in Win32 looks like this:
1683 IIIIIIIIIIIIIIIIIIIIIIB
1685 I GB I = white (HILIGHT)
1686 I GB H = light grey (LIGHT)
1687 I GB G = dark grey (SHADOI)
1688 I GB B = black (DKSHADOI)
1689 I GB I = hIghlight (COLOR_3DHILIGHT)
1691 IGGGGGGGGGGGGGGGGGGGGGB
1692 BBBBBBBBBBBBBBBBBBBBBBB
1694 The sunken border looks like this:
1696 GGGGGGGGGGGGGGGGGGGGGGI
1697 GBBBBBBBBBBBBBBBBBBBBHI
1704 GHHHHHHHHHHHHHHHHHHHHHI
1705 IIIIIIIIIIIIIIIIIIIIIII
1707 The static border (used for the controls which don't get focus) is like
1710 GGGGGGGGGGGGGGGGGGGGGGW
1718 WWWWWWWWWWWWWWWWWWWWWWW
1720 The most complicated is the double border:
1722 HHHHHHHHHHHHHHHHHHHHHHB
1723 HWWWWWWWWWWWWWWWWWWWWGB
1724 HWHHHHHHHHHHHHHHHHHHHGB
1729 HWHHHHHHHHHHHHHHHHHHHGB
1730 HGGGGGGGGGGGGGGGGGGGGGB
1731 BBBBBBBBBBBBBBBBBBBBBBB
1733 And the simple border is, well, simple:
1735 BBBBBBBBBBBBBBBBBBBBBBB
1744 BBBBBBBBBBBBBBBBBBBBBBB
1747 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1751 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1752 dc
.DrawRectangle(*rect
);
1758 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1760 // draw the bottom and right sides
1762 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1763 rect
->GetRight() + 1, rect
->GetBottom());
1764 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1765 rect
->GetRight(), rect
->GetBottom());
1771 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1772 const wxPen
& pen1
, const wxPen
& pen2
)
1774 // draw the rectangle
1776 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1777 rect
->GetLeft(), rect
->GetBottom());
1778 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1779 rect
->GetRight(), rect
->GetTop());
1781 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1782 rect
->GetRight(), rect
->GetBottom());
1783 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1784 rect
->GetRight() + 1, rect
->GetBottom());
1790 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1792 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1793 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1796 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1798 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1799 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1802 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1806 DrawRect(dc
, rect
, m_penDarkGrey
);
1808 // the arrow is usually drawn inside border of width 2 and is offset by
1809 // another pixel in both directions when it's pressed - as the border
1810 // in this case is more narrow as well, we have to adjust rect like
1818 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1819 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1823 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1825 const wxRect
& rectTotal
,
1826 int WXUNUSED(flags
),
1831 wxRect rect
= rectTotal
;
1835 case wxBORDER_SUNKEN
:
1836 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1838 DrawSunkenBorder(dc
, &rect
);
1842 case wxBORDER_STATIC
:
1843 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1846 case wxBORDER_RAISED
:
1847 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1849 DrawRaisedBorder(dc
, &rect
);
1853 case wxBORDER_DOUBLE
:
1854 DrawArrowBorder(dc
, &rect
);
1855 DrawRect(dc
, &rect
, m_penLightGrey
);
1858 case wxBORDER_SIMPLE
:
1859 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1861 DrawRect(dc
, &rect
, m_penBlack
);
1866 wxFAIL_MSG(_T("unknown border type"));
1869 case wxBORDER_DEFAULT
:
1878 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1883 case wxBORDER_RAISED
:
1884 case wxBORDER_SUNKEN
:
1885 width
= BORDER_THICKNESS
;
1888 case wxBORDER_SIMPLE
:
1889 case wxBORDER_STATIC
:
1893 case wxBORDER_DOUBLE
:
1899 // char *crash = NULL;
1901 wxFAIL_MSG(_T("unknown border type"));
1905 case wxBORDER_DEFAULT
:
1915 rect
.height
= width
;
1920 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1925 // ----------------------------------------------------------------------------
1927 // ----------------------------------------------------------------------------
1929 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1935 // text controls are not special under windows
1936 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1939 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1940 const wxRect
& rectTotal
,
1944 wxRect rect
= rectTotal
;
1946 if ( flags
& wxCONTROL_PRESSED
)
1948 // button pressed: draw a double border around it
1949 DrawRect(dc
, &rect
, m_penBlack
);
1950 DrawRect(dc
, &rect
, m_penDarkGrey
);
1954 // button not pressed
1956 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1958 // button either default or focused (or both): add an extra border around it
1959 DrawRect(dc
, &rect
, m_penBlack
);
1962 // now draw a normal button
1963 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1964 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1973 // ----------------------------------------------------------------------------
1975 // ----------------------------------------------------------------------------
1977 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1978 wxCoord y
, wxCoord x1
, wxCoord x2
)
1980 dc
.SetPen(m_penDarkGrey
);
1981 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1982 dc
.SetPen(m_penHighlight
);
1984 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1987 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1988 wxCoord x
, wxCoord y1
, wxCoord y2
)
1990 dc
.SetPen(m_penDarkGrey
);
1991 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1992 dc
.SetPen(m_penHighlight
);
1994 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1997 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1998 const wxString
& label
,
2004 wxCoord height
= 0; // of the label
2005 wxRect rectFrame
= rect
;
2006 if ( !label
.empty() )
2008 // the text should touch the top border of the rect, so the frame
2009 // itself should be lower
2010 dc
.GetTextExtent(label
, NULL
, &height
);
2011 rectFrame
.y
+= height
/ 2;
2012 rectFrame
.height
-= height
/ 2;
2014 // we have to draw each part of the frame individually as we can't
2015 // erase the background beyond the label as it might contain some
2016 // pixmap already, so drawing everything and then overwriting part of
2017 // the frame with label doesn't work
2019 // TODO: the +5 and space insertion should be customizable
2022 rectText
.x
= rectFrame
.x
+ 5;
2023 rectText
.y
= rect
.y
;
2024 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2025 rectText
.height
= height
;
2028 label2
<< _T(' ') << label
<< _T(' ');
2029 if ( indexAccel
!= -1 )
2031 // adjust it as we prepended a space
2036 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2038 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2042 // just draw the complete frame
2043 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2044 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2048 // ----------------------------------------------------------------------------
2050 // ----------------------------------------------------------------------------
2052 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2054 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2055 // pixels each while we really need dots here... PS_ALTERNATE might
2056 // work, but it is for NT 5 only
2058 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2060 // draw the pixels manually: note that to behave in the same manner as
2061 // DrawRect(), we must exclude the bottom and right borders from the
2063 wxCoord x1
= rect
.GetLeft(),
2065 x2
= rect
.GetRight(),
2066 y2
= rect
.GetBottom();
2068 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2070 // this seems to be closer than what Windows does than wxINVERT although
2071 // I'm still not sure if it's correct
2072 dc
.SetLogicalFunction(wxAND_REVERSE
);
2075 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2076 dc
.DrawPoint(z
, rect
.GetTop());
2078 wxCoord shift
= z
== x2
? 0 : 1;
2079 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2080 dc
.DrawPoint(x2
, z
);
2082 shift
= z
== y2
? 0 : 1;
2083 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2084 dc
.DrawPoint(z
, y2
);
2086 shift
= z
== x1
? 0 : 1;
2087 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2088 dc
.DrawPoint(x1
, z
);
2090 dc
.SetLogicalFunction(wxCOPY
);
2094 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2095 const wxString
& label
,
2100 // draw shadow of the text
2101 dc
.SetTextForeground(m_colHighlight
);
2102 wxRect rectShadow
= rect
;
2105 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2107 // make the text grey
2108 dc
.SetTextForeground(m_colDarkGrey
);
2111 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2112 const wxString
& label
,
2119 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2122 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2123 const wxString
& label
,
2129 const wxPoint
& focusOffset
)
2131 // the underscores are not drawn for focused controls in wxMSW
2132 if ( flags
& wxCONTROL_FOCUSED
)
2137 if ( flags
& wxCONTROL_DISABLED
)
2139 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2140 // currently only can happen for a menu item and it seems that Windows
2141 // doesn't draw the shadow in this case, so we don't do it neither
2142 if ( flags
& wxCONTROL_SELECTED
)
2144 // just make the label text greyed out
2145 dc
.SetTextForeground(m_colDarkGrey
);
2147 else // draw normal disabled label
2149 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2154 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2156 if ( flags
& wxCONTROL_DISABLED
)
2158 // restore the fg colour
2159 dc
.SetTextForeground(*wxBLACK
);
2162 if ( flags
& wxCONTROL_FOCUSED
)
2164 if ( focusOffset
.x
|| focusOffset
.y
)
2166 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2169 DrawFocusRect(dc
, rectLabel
);
2173 *rectBounds
= rectLabel
;
2176 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2177 const wxString
& label
,
2178 const wxBitmap
& image
,
2185 // the underscores are not drawn for focused controls in wxMSW
2186 if ( flags
& wxCONTROL_PRESSED
)
2191 wxRect rectLabel
= rect
;
2192 if ( !label
.empty() )
2194 // shift the label if a button is pressed
2195 if ( flags
& wxCONTROL_PRESSED
)
2201 if ( flags
& wxCONTROL_DISABLED
)
2203 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2206 // leave enough space for the focus rectangle
2207 if ( flags
& wxCONTROL_FOCUSED
)
2209 rectLabel
.Inflate(-2);
2213 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2215 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2217 if ( flags
& wxCONTROL_PRESSED
)
2219 // the focus rectangle is never pressed, so undo the shift done
2227 DrawFocusRect(dc
, rectLabel
);
2231 // ----------------------------------------------------------------------------
2232 // (check)listbox items
2233 // ----------------------------------------------------------------------------
2235 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2236 const wxString
& label
,
2240 wxDCTextColourChanger
colChanger(dc
);
2242 if ( flags
& wxCONTROL_SELECTED
)
2244 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2246 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2247 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2248 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2249 dc
.DrawRectangle(rect
);
2252 wxRect rectText
= rect
;
2254 rectText
.width
-= 2;
2255 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2257 if ( flags
& wxCONTROL_FOCUSED
)
2259 DrawFocusRect(dc
, rect
);
2263 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2264 const wxString
& label
,
2265 const wxBitmap
& bitmap
,
2274 else // use default bitmap
2276 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2277 ? IndicatorStatus_Checked
2278 : IndicatorStatus_Unchecked
;
2280 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2282 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2285 bmp
= m_bmpCheckBitmaps
[i
];
2288 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2289 true /* use mask */);
2291 wxRect rectLabel
= rect
;
2292 int bmpWidth
= bmp
.GetWidth();
2293 rectLabel
.x
+= bmpWidth
;
2294 rectLabel
.width
-= bmpWidth
;
2296 DrawItem(dc
, label
, rectLabel
, flags
);
2299 // ----------------------------------------------------------------------------
2300 // check/radio buttons
2301 // ----------------------------------------------------------------------------
2303 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2305 IndicatorState indState
;
2306 if ( flags
& wxCONTROL_SELECTED
)
2307 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2308 : IndicatorState_Selected
;
2309 else if ( flags
& wxCONTROL_DISABLED
)
2310 indState
= IndicatorState_Disabled
;
2311 else if ( flags
& wxCONTROL_PRESSED
)
2312 indState
= IndicatorState_Pressed
;
2314 indState
= IndicatorState_Normal
;
2316 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2317 ? IndicatorStatus_Checked
2318 : IndicatorStatus_Unchecked
;
2320 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2323 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2326 // create and cache it
2327 bmp
= wxBitmap(xpm
);
2328 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2335 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2336 const wxString
& label
,
2337 const wxBitmap
& bitmap
,
2342 wxCoord focusOffsetY
)
2344 // calculate the position of the bitmap and of the label
2345 wxCoord heightBmp
= bitmap
.GetHeight();
2347 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2350 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2351 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2353 // align label vertically with the bitmap - looks nicer like this
2354 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2356 // calc horz position
2357 if ( align
== wxALIGN_RIGHT
)
2359 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2360 rectLabel
.x
= rect
.x
+ 3;
2361 rectLabel
.SetRight(xBmp
);
2363 else // normal (checkbox to the left of the text) case
2366 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2367 rectLabel
.SetRight(rect
.GetRight());
2370 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2373 dc
, label
, rectLabel
,
2375 wxALIGN_LEFT
| wxALIGN_TOP
,
2377 NULL
, // we don't need bounding rect
2378 // use custom vert focus rect offset
2379 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2383 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2384 const wxString
& label
,
2385 const wxBitmap
& bitmap
,
2395 bmp
= GetRadioBitmap(flags
);
2397 DrawCheckOrRadioButton(dc
, label
,
2399 rect
, flags
, align
, indexAccel
,
2400 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2403 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2404 const wxString
& label
,
2405 const wxBitmap
& bitmap
,
2415 bmp
= GetCheckBitmap(flags
);
2417 DrawCheckOrRadioButton(dc
, label
,
2419 rect
, flags
, align
, indexAccel
,
2420 0); // no focus rect offset for checkboxes
2423 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2424 const wxString
& label
,
2425 const wxBitmap
& bitmap
,
2426 const wxRect
& rectOrig
,
2430 if (style
== wxTOOL_STYLE_BUTTON
)
2432 wxRect rect
= rectOrig
;
2433 rect
.Deflate(BORDER_THICKNESS
);
2435 if ( flags
& wxCONTROL_PRESSED
)
2437 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2439 else if ( flags
& wxCONTROL_CURRENT
)
2441 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2444 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2446 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2448 // leave a small gap aroudn the line, also account for the toolbar
2450 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2451 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2452 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2454 // don't draw wxTOOL_STYLE_CONTROL
2457 // ----------------------------------------------------------------------------
2459 // ----------------------------------------------------------------------------
2461 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2462 const wxString
& text
,
2468 // nothing special to do here
2469 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2473 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2474 const wxRect
& WXUNUSED(rect
))
2476 // we don't draw them
2479 // ----------------------------------------------------------------------------
2481 // ----------------------------------------------------------------------------
2483 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2484 const wxRect
& rectOrig
,
2486 const wxString
& label
,
2487 const wxBitmap
& bitmap
,
2491 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2492 #define REVERSE_FOR_VERTICAL(X,Y) \
2493 SELECT_FOR_VERTICAL(X,Y) \
2495 SELECT_FOR_VERTICAL(Y,X)
2497 wxRect rect
= rectOrig
;
2499 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2501 // the current tab is drawn indented (to the top for default case) and
2502 // bigger than the other ones
2503 const wxSize indent
= GetTabIndent();
2504 if ( flags
& wxCONTROL_SELECTED
)
2506 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
2507 SELECT_FOR_VERTICAL( 0, indent
.y
));
2511 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2518 rect
.height
+= indent
.y
;
2525 rect
.width
+= indent
.x
;
2530 // draw the text, image and the focus around them (if necessary)
2531 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2532 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2534 rectLabel
.Deflate(1, 1);
2537 // draw it horizontally into memory and rotate for screen
2539 wxBitmap bitmapRotated
,
2540 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2541 rectLabel
.y
+ rectLabel
.height
);
2542 dcMem
.SelectObject(bitmapMem
);
2543 dcMem
.SetBackground(dc
.GetBackground());
2544 dcMem
.SetFont(dc
.GetFont());
2545 dcMem
.SetTextForeground(dc
.GetTextForeground());
2547 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
2548 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2549 flags
, wxALIGN_CENTRE
, indexAccel
);
2550 dcMem
.SelectObject(wxNullBitmap
);
2551 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2552 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2553 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2557 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2558 flags
, wxALIGN_CENTRE
, indexAccel
);
2561 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2562 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2563 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2564 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2565 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2566 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2568 // FIXME: all this code will break if the tab indent or the border width,
2569 // it is tied to the fact that both of them are equal to 2
2575 // left orientation looks like top but IsVertical makes x and y reversed
2577 // top is not vertical so use coordinates in written order
2578 dc
.SetPen(m_penHighlight
);
2579 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2580 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2581 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2582 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2583 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2584 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2586 dc
.SetPen(m_penBlack
);
2587 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2588 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2589 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2590 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2592 dc
.SetPen(m_penDarkGrey
);
2593 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2594 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2596 if ( flags
& wxCONTROL_SELECTED
)
2598 dc
.SetPen(m_penLightGrey
);
2600 // overwrite the part of the border below this tab
2601 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2602 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2604 // and the shadow of the tab to the left of us
2605 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2606 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2611 // right orientation looks like bottom but IsVertical makes x and y reversed
2613 // bottom is not vertical so use coordinates in written order
2614 dc
.SetPen(m_penHighlight
);
2615 // we need to continue one pixel further to overwrite the corner of
2616 // the border for the selected tab
2617 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
2618 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2619 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2620 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2622 dc
.SetPen(m_penBlack
);
2623 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2624 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2625 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2626 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2627 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2628 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2630 dc
.SetPen(m_penDarkGrey
);
2631 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2632 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2633 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2634 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2636 if ( flags
& wxCONTROL_SELECTED
)
2638 dc
.SetPen(m_penLightGrey
);
2640 // overwrite the part of the (double!) border above this tab
2641 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2642 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2643 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2644 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2646 // and the shadow of the tab to the left of us
2647 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2648 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2653 #undef SELECT_FOR_VERTICAL
2654 #undef REVERSE_FOR_VERTICAL
2657 // ----------------------------------------------------------------------------
2659 // ----------------------------------------------------------------------------
2662 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2664 wxOrientation orient
) const
2667 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2668 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2670 if (orient
== wxHORIZONTAL
)
2684 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2686 wxOrientation orient
,
2689 bool transpose
= (orient
== wxVERTICAL
);
2690 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2691 (((style
& wxSL_TOP
) != 0) & !transpose
|
2692 ((style
& wxSL_LEFT
) != 0) & transpose
|
2693 ((style
& wxSL_BOTH
) != 0));
2694 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2695 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2696 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2697 ((style
& wxSL_BOTH
) != 0));
2699 wxRect rect
= rectOrig
;
2701 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2703 if (orient
== wxHORIZONTAL
) {
2704 rect
.x
+= SLIDER_MARGIN
;
2707 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2711 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2715 rect
.y
+= sizeThumb
.y
/2;
2717 rect
.width
-= 2*SLIDER_MARGIN
;
2718 rect
.height
= 2*BORDER_THICKNESS
;
2722 rect
.y
+= SLIDER_MARGIN
;
2725 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2729 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2733 rect
.x
+= sizeThumb
.x
/2;
2735 rect
.width
= 2*BORDER_THICKNESS
;
2736 rect
.height
-= 2*SLIDER_MARGIN
;
2742 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2743 const wxRect
& rectOrig
,
2745 wxOrientation orient
,
2750 /* show shaft geometry
2768 if (flags
& wxCONTROL_FOCUSED
) {
2769 DrawFocusRect(dc
, rectOrig
);
2772 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2774 if (rectShaft
) *rectShaft
= rect
;
2776 DrawSunkenBorder(dc
, &rect
);
2779 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2781 wxOrientation orient
,
2785 /* show thumb geometry
2794 H D B where H is hightlight colour
2808 The interior of this shape is filled with the hatched brush if the thumb
2812 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2814 bool transpose
= (orient
== wxVERTICAL
);
2815 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2816 (((style
& wxSL_TOP
) != 0) & !transpose
|
2817 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2818 ((style
& wxSL_BOTH
) == 0);
2819 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2820 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2821 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2822 ((style
& wxSL_BOTH
) == 0);
2824 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2825 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2827 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2828 x1
= (transpose
? rect
.y
: rect
.x
);
2829 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2830 x3
= (x1
-1+c
) + sizeArrow
;
2831 y1
= (transpose
? rect
.x
: rect
.y
);
2832 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2833 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2834 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2836 dc
.SetPen(m_penBlack
);
2838 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2840 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2843 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2847 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2850 dc
.SetPen(m_penDarkGrey
);
2851 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2853 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2857 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2860 dc
.SetPen(m_penHighlight
);
2863 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2864 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2868 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2870 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2873 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2876 if (flags
& wxCONTROL_PRESSED
) {
2877 // TODO: MSW fills the entire area inside, not just the rect
2878 wxRect rectInt
= rect
;
2881 rectInt
.SetLeft(y3
);
2882 rectInt
.SetRight(y4
);
2887 rectInt
.SetBottom(y4
);
2891 #if !defined(__WXMGL__)
2892 static const char *stipple_xpm
[] = {
2893 /* columns rows colors chars-per-pixel */
2902 // VS: MGL can only do 8x8 stipple brushes
2903 static const char *stipple_xpm
[] = {
2904 /* columns rows colors chars-per-pixel */
2919 dc
.SetBrush(wxBrush(stipple_xpm
));
2921 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2922 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2923 dc
.SetPen(*wxTRANSPARENT_PEN
);
2924 dc
.DrawRectangle(rectInt
);
2928 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2931 wxOrientation orient
,
2935 int WXUNUSED(flags
),
2938 /* show ticks geometry
2953 if (end
== start
) return;
2955 bool transpose
= (orient
== wxVERTICAL
);
2956 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2957 (((style
& wxSL_TOP
) != 0) & !transpose
|
2958 ((style
& wxSL_LEFT
) != 0) & transpose
|
2959 ((style
& wxSL_BOTH
) != 0));
2960 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2961 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2962 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2963 ((style
& wxSL_BOTH
) != 0));
2965 // default thumb size
2966 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2967 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
2969 // normal thumb size
2970 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2971 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
2973 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2975 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2976 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2977 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2978 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2979 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2980 y3
= (transpose
? rect
.x
: rect
.y
);
2981 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2984 dc
.SetPen(m_penBlack
);
2986 int range
= end
- start
;
2987 for ( int n
= 0; n
< range
; n
+= step
) {
2988 wxCoord x
= x1
+ (len
*n
) / range
;
2990 if (left
& (y1
> y3
)) {
2991 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2993 if (right
& (y4
> y2
)) {
2994 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2997 // always draw the line at the end position
2998 if (left
& (y1
> y3
)) {
2999 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3001 if (right
& (y4
> y2
)) {
3002 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3006 // ----------------------------------------------------------------------------
3008 // ----------------------------------------------------------------------------
3010 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3011 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3014 virtual wxSize
GetSize() const { return m_size
; }
3016 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3017 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3019 wxCoord
GetItemHeight() const { return m_heightItem
; }
3022 // the total size of the menu
3025 // the offset of the start of the menu item label
3028 // the offset of the start of the accel label
3031 // the height of a normal (not separator) item
3032 wxCoord m_heightItem
;
3034 friend wxMenuGeometryInfo
*
3035 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3038 // FIXME: all constants are hardcoded but shouldn't be
3039 static const wxCoord MENU_LEFT_MARGIN
= 9;
3040 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3041 static const wxCoord MENU_VERT_MARGIN
= 3;
3043 // the margin around bitmap/check marks (on each side)
3044 static const wxCoord MENU_BMP_MARGIN
= 2;
3046 // the margin between the labels and accel strings
3047 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3049 // the separator height in pixels: in fact, strangely enough, the real height
3050 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3052 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3054 // the size of the standard checkmark bitmap
3055 static const wxCoord MENU_CHECK_SIZE
= 9;
3057 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3058 const wxRect
& rectOrig
,
3059 const wxString
& label
,
3063 wxRect rect
= rectOrig
;
3066 wxDCTextColourChanger
colChanger(dc
);
3068 if ( flags
& wxCONTROL_SELECTED
)
3070 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3072 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3073 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3074 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3075 dc
.DrawRectangle(rect
);
3078 // don't draw the focus rect around menu bar items
3079 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3080 wxALIGN_CENTRE
, indexAccel
);
3083 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3085 const wxMenuGeometryInfo
& gi
,
3086 const wxString
& label
,
3087 const wxString
& accel
,
3088 const wxBitmap
& bitmap
,
3092 const wxWin32MenuGeometryInfo
& geometryInfo
=
3093 (const wxWin32MenuGeometryInfo
&)gi
;
3098 rect
.width
= geometryInfo
.GetSize().x
;
3099 rect
.height
= geometryInfo
.GetItemHeight();
3101 // draw the selected item specially
3102 wxDCTextColourChanger
colChanger(dc
);
3103 if ( flags
& wxCONTROL_SELECTED
)
3105 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3107 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3108 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3109 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3110 dc
.DrawRectangle(rect
);
3113 // draw the bitmap: use the bitmap provided or the standard checkmark for
3114 // the checkable items
3115 wxBitmap bmp
= bitmap
;
3116 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3118 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3123 rect
.SetRight(geometryInfo
.GetLabelOffset());
3124 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3128 rect
.x
= geometryInfo
.GetLabelOffset();
3129 rect
.SetRight(geometryInfo
.GetAccelOffset());
3131 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3133 // draw the accel string
3134 rect
.x
= geometryInfo
.GetAccelOffset();
3135 rect
.SetRight(geometryInfo
.GetSize().x
);
3137 // NB: no accel index here
3138 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3140 // draw the submenu indicator
3141 if ( flags
& wxCONTROL_ISSUBMENU
)
3143 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3144 rect
.width
= MENU_RIGHT_MARGIN
;
3146 wxArrowStyle arrowStyle
;
3147 if ( flags
& wxCONTROL_DISABLED
)
3148 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
3150 else if ( flags
& wxCONTROL_SELECTED
)
3151 arrowStyle
= Arrow_Inversed
;
3153 arrowStyle
= Arrow_Normal
;
3155 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3159 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3161 const wxMenuGeometryInfo
& geomInfo
)
3163 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3166 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3168 wxSize size
= sizeText
;
3170 // FIXME: menubar height is configurable under Windows
3177 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3178 const wxMenu
& menu
) const
3180 // prepare the dc: for now we draw all the items with the system font
3182 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3184 // the height of a normal item
3185 wxCoord heightText
= dc
.GetCharHeight();
3190 // the max length of label and accel strings: the menu width is the sum of
3191 // them, even if they're for different items (as the accels should be
3194 // the max length of the bitmap is never 0 as Windows always leaves enough
3195 // space for a check mark indicator
3196 wxCoord widthLabelMax
= 0,
3198 widthBmpMax
= MENU_LEFT_MARGIN
;
3200 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3202 node
= node
->GetNext() )
3204 // height of this item
3207 wxMenuItem
*item
= node
->GetData();
3208 if ( item
->IsSeparator() )
3210 h
= MENU_SEPARATOR_HEIGHT
;
3212 else // not separator
3217 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3218 if ( widthLabel
> widthLabelMax
)
3220 widthLabelMax
= widthLabel
;
3224 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3225 if ( widthAccel
> widthAccelMax
)
3227 widthAccelMax
= widthAccel
;
3230 const wxBitmap
& bmp
= item
->GetBitmap();
3233 wxCoord widthBmp
= bmp
.GetWidth();
3234 if ( widthBmp
> widthBmpMax
)
3235 widthBmpMax
= widthBmp
;
3237 //else if ( item->IsCheckable() ): no need to check for this as
3238 // MENU_LEFT_MARGIN is big enough to show the check mark
3241 h
+= 2*MENU_VERT_MARGIN
;
3243 // remember the item position and height
3244 item
->SetGeometry(height
, h
);
3249 // bundle the metrics into a struct and return it
3250 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3252 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3253 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3254 if ( widthAccelMax
> 0 )
3256 // if we actually have any accesl, add a margin
3257 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3260 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3262 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3263 gi
->m_size
.y
= height
;
3268 // ----------------------------------------------------------------------------
3270 // ----------------------------------------------------------------------------
3272 static const wxCoord STATBAR_BORDER_X
= 2;
3273 static const wxCoord STATBAR_BORDER_Y
= 2;
3275 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3277 if ( borderBetweenFields
)
3278 *borderBetweenFields
= 2;
3280 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3283 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3285 const wxString
& label
,
3286 int flags
, int style
/*=0*/)
3290 if ( flags
& wxCONTROL_ISDEFAULT
)
3292 // draw the size grip: it is a normal rect except that in the lower
3293 // right corner we have several bands which may be used for dragging
3294 // the status bar corner
3296 // each band consists of 4 stripes: m_penHighlight, double
3297 // m_penDarkGrey and transparent one
3298 wxCoord x2
= rect
.GetRight(),
3299 y2
= rect
.GetBottom();
3301 // draw the upper left part of the rect normally
3302 if (style
!= wxSB_FLAT
)
3304 if (style
== wxSB_RAISED
)
3305 dc
.SetPen(m_penHighlight
);
3307 dc
.SetPen(m_penDarkGrey
);
3308 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3309 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3312 // draw the grey stripes of the grip
3314 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3315 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3317 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3318 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3321 // draw the white stripes
3322 dc
.SetPen(m_penHighlight
);
3323 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3324 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3326 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3329 // draw the remaining rect boundaries
3330 if (style
!= wxSB_FLAT
)
3332 if (style
== wxSB_RAISED
)
3333 dc
.SetPen(m_penDarkGrey
);
3335 dc
.SetPen(m_penHighlight
);
3336 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3337 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3338 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3344 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3348 if (style
== wxSB_RAISED
)
3349 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3350 else if (style
!= wxSB_FLAT
)
3351 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3354 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3356 wxDCClipper
clipper(dc
, rectIn
);
3357 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3360 // ----------------------------------------------------------------------------
3362 // ----------------------------------------------------------------------------
3364 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3365 wxBitmap
* WXUNUSED(bmpFocus
),
3366 wxBitmap
*bmpPressed
,
3367 wxBitmap
*bmpDisabled
)
3369 static const wxCoord widthCombo
= 16;
3370 static const wxCoord heightCombo
= 17;
3376 bmpNormal
->Create(widthCombo
, heightCombo
);
3377 dcMem
.SelectObject(*bmpNormal
);
3378 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3379 Arrow_Down
, Arrow_Normal
);
3384 bmpPressed
->Create(widthCombo
, heightCombo
);
3385 dcMem
.SelectObject(*bmpPressed
);
3386 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3387 Arrow_Down
, Arrow_Pressed
);
3392 bmpDisabled
->Create(widthCombo
, heightCombo
);
3393 dcMem
.SelectObject(*bmpDisabled
);
3394 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3395 Arrow_Down
, Arrow_Disabled
);
3399 // ----------------------------------------------------------------------------
3401 // ----------------------------------------------------------------------------
3403 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3404 const wxColour
& col
,
3406 wxWindow
* WXUNUSED(window
))
3408 wxBrush
brush(col
, wxSOLID
);
3410 dc
.SetPen(*wxTRANSPARENT_PEN
);
3411 dc
.DrawRectangle(rect
);
3414 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3415 const wxColour
& col
,
3417 int WXUNUSED(flags
),
3420 // just fill it with the given or default bg colour
3421 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3422 DoDrawBackground(dc
, colBg
, rect
, window
);
3425 // ----------------------------------------------------------------------------
3427 // ----------------------------------------------------------------------------
3429 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3434 // get the bitmap for this arrow
3435 wxArrowDirection arrowDir
;
3438 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3439 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3440 case wxUP
: arrowDir
= Arrow_Up
; break;
3441 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3444 wxFAIL_MSG(_T("unknown arrow direction"));
3448 wxArrowStyle arrowStyle
;
3449 if ( flags
& wxCONTROL_PRESSED
)
3451 // can't be pressed and disabled
3452 arrowStyle
= Arrow_Pressed
;
3456 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3459 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3462 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3464 wxArrowDirection arrowDir
,
3465 wxArrowStyle arrowStyle
)
3467 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3469 // under Windows the arrows always have the same size so just centre it in
3470 // the provided rectangle
3471 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3472 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3474 // Windows does it like this...
3475 if ( arrowDir
== Arrow_Left
)
3479 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3482 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3483 const wxRect
& rectAll
,
3484 wxArrowDirection arrowDir
,
3485 wxArrowStyle arrowStyle
)
3487 wxRect rect
= rectAll
;
3488 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3489 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3490 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3493 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3494 wxOrientation
WXUNUSED(orient
),
3496 int WXUNUSED(flags
))
3498 // we don't use the flags, the thumb never changes appearance
3499 wxRect rectThumb
= rect
;
3500 DrawArrowBorder(dc
, &rectThumb
);
3501 DrawBackground(dc
, wxNullColour
, rectThumb
);
3504 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3505 wxOrientation
WXUNUSED(orient
),
3506 const wxRect
& rectBar
,
3509 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3510 ? wxColourScheme::SCROLLBAR_PRESSED
3511 : wxColourScheme::SCROLLBAR
;
3512 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3515 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3517 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3520 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3521 wxScrollBar::Element elem
,
3524 return StandardGetScrollbarRect(scrollbar
, elem
,
3525 thumbPos
, m_sizeScrollbarArrow
);
3528 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3530 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3533 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3534 const wxPoint
& pt
) const
3536 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3539 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3542 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3545 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3548 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3551 // ----------------------------------------------------------------------------
3552 // top level windows
3553 // ----------------------------------------------------------------------------
3555 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3557 wxRect client
= GetFrameClientArea(rect
, flags
);
3559 if ( client
.Inside(pt
) )
3560 return wxHT_TOPLEVEL_CLIENT_AREA
;
3562 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3564 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3566 if ( flags
& wxTOPLEVEL_ICON
)
3568 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3569 return wxHT_TOPLEVEL_ICON
;
3572 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3573 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3574 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3576 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3578 if ( btnRect
.Inside(pt
) )
3579 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3580 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3582 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3584 if ( btnRect
.Inside(pt
) )
3585 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3586 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3588 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3590 if ( btnRect
.Inside(pt
) )
3591 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3592 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3594 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3596 if ( btnRect
.Inside(pt
) )
3597 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3598 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3600 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3602 if ( btnRect
.Inside(pt
) )
3603 return wxHT_TOPLEVEL_BUTTON_HELP
;
3604 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3607 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3608 return wxHT_TOPLEVEL_TITLEBAR
;
3611 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3613 // we are certainly at one of borders, lets decide which one:
3616 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3617 if ( pt
.x
< client
.x
)
3618 border
|= wxHT_TOPLEVEL_BORDER_W
;
3619 else if ( pt
.x
>= client
.width
+ client
.x
)
3620 border
|= wxHT_TOPLEVEL_BORDER_E
;
3621 if ( pt
.y
< client
.y
)
3622 border
|= wxHT_TOPLEVEL_BORDER_N
;
3623 else if ( pt
.y
>= client
.height
+ client
.y
)
3624 border
|= wxHT_TOPLEVEL_BORDER_S
;
3628 return wxHT_NOWHERE
;
3631 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3633 const wxString
& title
,
3637 int specialButtonFlags
)
3639 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3641 DrawFrameBorder(dc
, rect
, flags
);
3643 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3645 DrawFrameBackground(dc
, rect
, flags
);
3646 if ( flags
& wxTOPLEVEL_ICON
)
3647 DrawFrameIcon(dc
, rect
, icon
, flags
);
3648 DrawFrameTitle(dc
, rect
, title
, flags
);
3650 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3652 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3653 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3655 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3657 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3658 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3659 specialButtonFlags
: 0);
3660 x
-= FRAME_BUTTON_WIDTH
+ 2;
3662 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3664 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3665 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3666 specialButtonFlags
: 0);
3667 x
-= FRAME_BUTTON_WIDTH
;
3669 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3671 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3672 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3673 specialButtonFlags
: 0);
3674 x
-= FRAME_BUTTON_WIDTH
;
3676 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3678 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3679 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3680 specialButtonFlags
: 0);
3681 x
-= FRAME_BUTTON_WIDTH
;
3683 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3685 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3686 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3687 specialButtonFlags
: 0);
3692 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3696 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3700 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3701 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3702 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3703 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3704 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3707 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3711 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3713 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3714 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3715 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3717 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3718 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3720 DrawBackground(dc
, col
, r
);
3723 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3725 const wxString
& title
,
3728 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3729 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3730 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3732 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3733 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3734 if ( flags
& wxTOPLEVEL_ICON
)
3736 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3737 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3745 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3746 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3747 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3748 r
.width
-= FRAME_BUTTON_WIDTH
;
3749 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3750 r
.width
-= FRAME_BUTTON_WIDTH
;
3751 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3752 r
.width
-= FRAME_BUTTON_WIDTH
;
3753 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3754 r
.width
-= FRAME_BUTTON_WIDTH
;
3756 dc
.SetFont(m_titlebarFont
);
3757 dc
.SetTextForeground(col
);
3760 dc
.GetTextExtent(title
, &textW
, NULL
);
3761 if ( textW
> r
.width
)
3763 // text is too big, let's shorten it and add "..." after it:
3764 size_t len
= title
.length();
3765 wxCoord WSoFar
, letterW
;
3767 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3768 if ( WSoFar
> r
.width
)
3770 // not enough space to draw anything
3776 for (size_t i
= 0; i
< len
; i
++)
3778 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3779 if ( letterW
+ WSoFar
> r
.width
)
3785 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3786 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3789 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3790 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3793 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3800 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3801 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3805 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3806 wxCoord x
, wxCoord y
,
3810 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3815 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3816 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3817 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3818 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3819 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3821 wxFAIL_MSG(wxT("incorrect button specification"));
3824 if ( flags
& wxCONTROL_PRESSED
)
3826 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3827 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3828 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3829 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3833 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3834 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3835 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3836 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3841 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3846 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3848 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3849 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3850 FRAME_BORDER_THICKNESS
;
3853 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3855 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3856 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3862 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3865 wxSize
s(clientSize
);
3867 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3869 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3870 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3871 FRAME_BORDER_THICKNESS
;
3875 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3876 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3881 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3885 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3887 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3888 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3889 FRAME_BORDER_THICKNESS
;
3894 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3896 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3898 if ( flags
& wxTOPLEVEL_ICON
)
3899 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3900 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3901 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3902 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3903 s
.x
+= FRAME_BUTTON_WIDTH
;
3904 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3905 s
.x
+= FRAME_BUTTON_WIDTH
;
3906 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3907 s
.x
+= FRAME_BUTTON_WIDTH
;
3908 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3909 s
.x
+= FRAME_BUTTON_WIDTH
;
3915 wxSize
wxWin32Renderer::GetFrameIconSize() const
3917 return wxSize(16, 16);
3921 // ----------------------------------------------------------------------------
3923 // ----------------------------------------------------------------------------
3925 static char *error_xpm
[]={
3932 "...........########.............",
3933 "........###aaaaaaaa###..........",
3934 ".......#aaaaaaaaaaaaaa#.........",
3935 ".....##aaaaaaaaaaaaaaaa##.......",
3936 "....#aaaaaaaaaaaaaaaaaaaa#......",
3937 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3938 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3939 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3940 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3941 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3942 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3943 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3944 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3945 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3946 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3947 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3948 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3949 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3950 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3951 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3952 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3953 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3954 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3955 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3956 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3957 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3958 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3959 "......b#aaaaaaaaaaaaaa#bbbbb....",
3960 ".......b###aaaaaaaa###bbbbb.....",
3961 ".........bb########bbbbbb.......",
3962 "..........bbbbbbbbbbbbbb........",
3963 ".............bbbbbbbb..........."};
3965 static char *info_xpm
[]={
3973 "...........########.............",
3974 "........###abbbbbba###..........",
3975 "......##abbbbbbbbbbbba##........",
3976 ".....#abbbbbbbbbbbbbbbba#.......",
3977 "....#bbbbbbbaccccabbbbbbbd......",
3978 "...#bbbbbbbbccccccbbbbbbbbd.....",
3979 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3980 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3981 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3982 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3983 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3984 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3985 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3986 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3987 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3988 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3989 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3990 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3991 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3992 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3993 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3994 ".....dabbbbbbbbbbbbbbbbad####...",
3995 "......ddabbbbbbbbbbbbadd####....",
3996 ".......#dddabbbbbbaddd#####.....",
3997 "........###dddabbbd#######......",
3998 "..........####dbbbd#####........",
3999 ".............#dbbbd##...........",
4000 "...............dbbd##...........",
4001 "................dbd##...........",
4002 ".................dd##...........",
4003 "..................###...........",
4004 "...................##..........."};
4006 static char *question_xpm
[]={
4014 "...........########.............",
4015 "........###abbbbbba###..........",
4016 "......##abbbbbbbbbbbba##........",
4017 ".....#abbbbbbbbbbbbbbbba#.......",
4018 "....#bbbbbbbbbbbbbbbbbbbbc......",
4019 "...#bbbbbbbaddddddabbbbbbbc.....",
4020 "..#bbbbbbbadabbddddabbbbbbbc....",
4021 ".#abbbbbbbddbbbbddddbbbbbbbac...",
4022 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
4023 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
4024 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
4025 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
4026 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
4027 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
4028 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
4029 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
4030 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
4031 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
4032 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
4033 "...cbbbbbbbbbaddabbbbbbbbbc####.",
4034 "....cbbbbbbbbbbbbbbbbbbbbc####..",
4035 ".....cabbbbbbbbbbbbbbbbac####...",
4036 "......ccabbbbbbbbbbbbacc####....",
4037 ".......#cccabbbbbbaccc#####.....",
4038 "........###cccabbbc#######......",
4039 "..........####cbbbc#####........",
4040 ".............#cbbbc##...........",
4041 "...............cbbc##...........",
4042 "................cbc##...........",
4043 ".................cc##...........",
4044 "..................###...........",
4045 "...................##..........."};
4047 static char *warning_xpm
[]={
4055 ".............###................",
4056 "............#aabc...............",
4057 "...........#aaaabcd.............",
4058 "...........#aaaaacdd............",
4059 "..........#aaaaaabcdd...........",
4060 "..........#aaaaaaacdd...........",
4061 ".........#aaaaaaaabcdd..........",
4062 ".........#aaaaaaaaacdd..........",
4063 "........#aaaaaaaaaabcdd.........",
4064 "........#aaabcccbaaacdd.........",
4065 ".......#aaaacccccaaabcdd........",
4066 ".......#aaaacccccaaaacdd........",
4067 "......#aaaaacccccaaaabcdd.......",
4068 "......#aaaaacccccaaaaacdd.......",
4069 ".....#aaaaaacccccaaaaabcdd......",
4070 ".....#aaaaaa#ccc#aaaaaacdd......",
4071 "....#aaaaaaabcccbaaaaaabcdd.....",
4072 "....#aaaaaaaacccaaaaaaaacdd.....",
4073 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
4074 "...#aaaaaaaaabcbaaaaaaaaacdd....",
4075 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
4076 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
4077 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
4078 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
4079 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
4080 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
4081 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
4082 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
4083 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
4084 "..#ccccccccccccccccccccccccddddd",
4085 "....ddddddddddddddddddddddddddd.",
4086 ".....ddddddddddddddddddddddddd.."};
4088 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4089 const wxArtClient
& WXUNUSED(client
),
4090 const wxSize
& WXUNUSED(size
))
4092 if ( id
== wxART_INFORMATION
)
4093 return wxBitmap(info_xpm
);
4094 if ( id
== wxART_ERROR
)
4095 return wxBitmap(error_xpm
);
4096 if ( id
== wxART_WARNING
)
4097 return wxBitmap(warning_xpm
);
4098 if ( id
== wxART_QUESTION
)
4099 return wxBitmap(question_xpm
);
4100 return wxNullBitmap
;
4104 // ----------------------------------------------------------------------------
4105 // text control geometry
4106 // ----------------------------------------------------------------------------
4108 static inline int GetTextBorderWidth()
4114 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4115 const wxRect
& rect
) const
4117 wxRect rectTotal
= rect
;
4119 wxCoord widthBorder
= GetTextBorderWidth();
4120 rectTotal
.Inflate(widthBorder
);
4122 // this is what Windows does
4129 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4131 wxCoord
*extraSpaceBeyond
) const
4133 wxRect rectText
= rect
;
4135 // undo GetTextTotalArea()
4136 if ( rectText
.height
> 0 )
4139 wxCoord widthBorder
= GetTextBorderWidth();
4140 rectText
.Inflate(-widthBorder
);
4142 if ( extraSpaceBeyond
)
4143 *extraSpaceBeyond
= 0;
4148 // ----------------------------------------------------------------------------
4150 // ----------------------------------------------------------------------------
4152 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4155 if ( wxDynamicCast(window
, wxScrollBar
) )
4157 // we only set the width of vert scrollbars and height of the
4159 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4160 size
->y
= m_sizeScrollbarArrow
.y
;
4162 size
->x
= m_sizeScrollbarArrow
.x
;
4164 // skip border width adjustments, they don't make sense for us
4167 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4170 if ( wxDynamicCast(window
, wxButton
) )
4172 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4174 // TODO: don't harcode all this
4175 size
->x
+= 3*window
->GetCharWidth();
4177 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4178 if ( size
->y
< heightBtn
- 8 )
4179 size
->y
= heightBtn
;
4184 // for compatibility with other ports, the buttons default size is never
4185 // less than the standard one, but not when display not PDAs.
4186 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4188 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4190 wxSize szDef
= wxButton::GetDefaultSize();
4191 if ( size
->x
< szDef
.x
)
4196 // no border width adjustments for buttons
4199 #endif // wxUSE_BUTTON
4201 // take into account the border width
4202 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4203 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4204 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4207 // ============================================================================
4209 // ============================================================================
4211 // ----------------------------------------------------------------------------
4212 // wxWin32InputHandler
4213 // ----------------------------------------------------------------------------
4215 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4217 m_renderer
= renderer
;
4220 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4221 const wxKeyEvent
& WXUNUSED(event
),
4222 bool WXUNUSED(pressed
))
4227 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4228 const wxMouseEvent
& event
)
4230 // clicking on the control gives it focus
4231 if ( event
.ButtonDown() )
4233 wxWindow
*win
= control
->GetInputWindow();
4235 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4236 ( win
->AcceptsFocus() ) )
4247 // ----------------------------------------------------------------------------
4248 // wxWin32ScrollBarInputHandler
4249 // ----------------------------------------------------------------------------
4251 wxWin32ScrollBarInputHandler::
4252 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4253 wxInputHandler
*handler
)
4254 : wxStdScrollBarInputHandler(renderer
, handler
)
4256 m_scrollPaused
= false;
4260 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4261 const wxControlAction
& action
)
4263 // stop if went beyond the position of the original click (this can only
4264 // happen when we scroll by pages)
4266 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4268 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4269 != wxHT_SCROLLBAR_BAR_2
;
4271 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4273 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4274 != wxHT_SCROLLBAR_BAR_1
;
4279 StopScrolling(scrollbar
);
4281 scrollbar
->Refresh();
4286 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4289 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4290 const wxMouseEvent
& event
)
4292 // remember the current state
4293 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4295 // do process the message
4296 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4298 // analyse the changes
4299 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4301 // we just started dragging the thumb, remember its initial position to
4302 // be able to restore it if the drag is cancelled later
4303 m_eventStartDrag
= event
;
4309 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4310 const wxMouseEvent
& event
)
4312 // we don't highlight scrollbar elements, so there is no need to process
4313 // mouse move events normally - only do it while mouse is captured (i.e.
4314 // when we're dragging the thumb or pressing on something)
4315 if ( !m_winCapture
)
4318 if ( event
.Entering() )
4320 // we're not interested in this at all
4324 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4326 if ( m_scrollPaused
)
4328 // check if the mouse returned to its original location
4330 if ( event
.Leaving() )
4336 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4337 if ( ht
== m_htLast
)
4339 // yes it did, resume scrolling
4340 m_scrollPaused
= false;
4341 if ( m_timerScroll
)
4343 // we were scrolling by line/page, restart timer
4344 m_timerScroll
->Start(m_interval
);
4346 Press(scrollbar
, true);
4348 else // we were dragging the thumb
4350 // restore its last location
4351 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4357 else // normal case, scrolling hasn't been paused
4359 // if we're scrolling the scrollbar because the arrow or the shaft was
4360 // pressed, check that the mouse stays on the same scrollbar element
4363 // Always let thumb jump back if we leave the scrollbar
4364 if ( event
.Moving() )
4366 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4368 else // event.Leaving()
4373 // Jump back only if we get far away from it
4374 wxPoint pos
= event
.GetPosition();
4375 if (scrollbar
->HasFlag( wxVERTICAL
))
4377 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4382 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4385 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4388 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4389 // is still ok - we only want to catch the case when the mouse leaves
4390 // the scrollbar here
4391 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4393 ht
= wxHT_SCROLLBAR_THUMB
;
4396 if ( ht
!= m_htLast
)
4398 // what were we doing? 2 possibilities: either an arrow/shaft was
4399 // pressed in which case we have a timer and so we just stop it or
4400 // we were dragging the thumb
4401 if ( m_timerScroll
)
4404 m_interval
= m_timerScroll
->GetInterval();
4405 m_timerScroll
->Stop();
4406 m_scrollPaused
= true;
4408 // unpress the arrow
4409 Press(scrollbar
, false);
4411 else // we were dragging the thumb
4413 // remember the current thumb position to be able to restore it
4414 // if the mouse returns to it later
4415 m_eventLastDrag
= event
;
4417 // and restore the original position (before dragging) of the
4419 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4426 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4429 // ----------------------------------------------------------------------------
4430 // wxWin32CheckboxInputHandler
4431 // ----------------------------------------------------------------------------
4433 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4434 const wxKeyEvent
& event
,
4439 wxControlAction action
;
4440 int keycode
= event
.GetKeyCode();
4444 action
= wxACTION_CHECKBOX_TOGGLE
;
4448 case WXK_NUMPAD_SUBTRACT
:
4449 action
= wxACTION_CHECKBOX_CHECK
;
4453 case WXK_NUMPAD_ADD
:
4454 case WXK_NUMPAD_EQUAL
:
4455 action
= wxACTION_CHECKBOX_CLEAR
;
4459 if ( !action
.IsEmpty() )
4461 control
->PerformAction(action
);
4470 // ----------------------------------------------------------------------------
4471 // wxWin32TextCtrlInputHandler
4472 // ----------------------------------------------------------------------------
4474 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4475 const wxKeyEvent
& event
,
4478 // handle only MSW-specific text bindings here, the others are handled in
4482 int keycode
= event
.GetKeyCode();
4484 wxControlAction action
;
4485 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4487 action
= wxACTION_TEXT_CUT
;
4489 else if ( keycode
== WXK_INSERT
)
4491 if ( event
.ControlDown() )
4492 action
= wxACTION_TEXT_COPY
;
4493 else if ( event
.ShiftDown() )
4494 action
= wxACTION_TEXT_PASTE
;
4497 if ( action
!= wxACTION_NONE
)
4499 control
->PerformAction(action
);
4505 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4508 // ----------------------------------------------------------------------------
4509 // wxWin32StatusBarInputHandler
4510 // ----------------------------------------------------------------------------
4512 wxWin32StatusBarInputHandler::
4513 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4514 : wxStdInputHandler(handler
)
4519 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4520 const wxPoint
& pt
) const
4522 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4523 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4526 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4528 wxCHECK_MSG( parentTLW
, false,
4529 _T("the status bar should be a child of a TLW") );
4531 // a maximized window can't be resized anyhow
4532 if ( !parentTLW
->IsMaximized() )
4534 // VZ: I think that the standard Windows behaviour is to only
4535 // show the resizing cursor when the mouse is on top of the
4536 // grip itself but apparently different Windows versions behave
4537 // differently (?) and it seems a better UI to allow resizing
4538 // the status bar even when the mouse is above the grip
4539 wxSize sizeSbar
= statbar
->GetSize();
4541 int diff
= sizeSbar
.x
- pt
.x
;
4542 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4549 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4550 const wxMouseEvent
& event
)
4552 if ( event
.Button(1) )
4554 if ( event
.ButtonDown(1) )
4556 wxWindow
*statbar
= consumer
->GetInputWindow();
4558 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4560 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4564 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4565 wxHT_TOPLEVEL_BORDER_SE
);
4567 statbar
->SetCursor(m_cursorOld
);
4575 return wxStdInputHandler::HandleMouse(consumer
, event
);
4578 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4579 const wxMouseEvent
& event
)
4581 wxWindow
*statbar
= consumer
->GetInputWindow();
4583 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4584 if ( isOnGrip
!= m_isOnGrip
)
4586 m_isOnGrip
= isOnGrip
;
4589 m_cursorOld
= statbar
->GetCursor();
4590 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4594 statbar
->SetCursor(m_cursorOld
);
4598 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4601 // ----------------------------------------------------------------------------
4602 // wxWin32FrameInputHandler
4603 // ----------------------------------------------------------------------------
4605 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4608 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4610 void Attach(wxInputConsumer
*consumer
);
4614 DECLARE_EVENT_TABLE()
4615 void OnSystemMenu(wxCommandEvent
&event
);
4616 void OnCloseFrame(wxCommandEvent
&event
);
4617 void OnClose(wxCloseEvent
&event
);
4619 wxWin32FrameInputHandler
*m_inputHnd
;
4620 wxTopLevelWindow
*m_wnd
;
4622 wxAcceleratorTable m_oldAccelTable
;
4626 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4627 wxWin32FrameInputHandler
*handler
)
4629 m_inputHnd
= handler
;
4633 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4635 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4637 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4638 m_wnd
->PushEventHandler(this);
4641 // VS: This code relies on using generic implementation of
4642 // wxAcceleratorTable in wxUniv!
4643 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4644 m_oldAccelTable
= table
;
4645 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4646 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4647 m_wnd
->SetAcceleratorTable(table
);
4651 void wxWin32SystemMenuEvtHandler::Detach()
4656 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4658 m_wnd
->RemoveEventHandler(this);
4663 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4664 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4665 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4666 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4669 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4671 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4672 !m_wnd
->IsMaximized()) ?
4673 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4674 FRAME_BORDER_THICKNESS
;
4675 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4676 pt
.x
= -pt
.x
+ border
;
4677 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4680 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4681 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4684 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4687 m_wnd
->SetAcceleratorTable(table
);
4691 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4693 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4694 wxTOPLEVEL_BUTTON_CLOSE
);
4697 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4704 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4705 : wxStdFrameInputHandler(handler
)
4707 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4710 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4712 if ( m_menuHandler
)
4714 m_menuHandler
->Detach();
4715 delete m_menuHandler
;
4719 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4720 const wxMouseEvent
& event
)
4722 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4724 wxTopLevelWindow
*tlw
=
4725 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4727 long hit
= tlw
->HitTest(event
.GetPosition());
4729 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4731 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4732 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4733 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4736 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4738 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4739 (event
.RightDown() &&
4740 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4741 hit
== wxHT_TOPLEVEL_ICON
)) )
4743 PopupSystemMenu(tlw
, event
.GetPosition());
4749 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4752 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4753 const wxPoint
& pos
) const
4755 wxMenu
*menu
= new wxMenu
;
4757 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4758 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4759 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4760 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4761 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4762 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4763 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4764 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4765 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4766 menu
->AppendSeparator();
4767 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4769 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4771 if ( window
->IsMaximized() )
4773 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4774 menu
->Enable(wxID_MOVE_FRAME
, false);
4775 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4776 menu
->Enable(wxID_RESIZE_FRAME
, false);
4779 menu
->Enable(wxID_RESTORE_FRAME
, false);
4782 window
->PopupMenu(menu
, pos
);
4786 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4789 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4791 // always detach if active frame changed:
4792 m_menuHandler
->Detach();
4796 m_menuHandler
->Attach(consumer
);
4800 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);