1 // Name: univ/themes/win32.cpp
2 // Purpose: wxUniversal theme implementing Win32-like LNF
3 // Author: Vadim Zeitlin
7 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
30 #include "wx/window.h"
32 #include "wx/dcmemory.h"
34 #include "wx/button.h"
35 #include "wx/listbox.h"
36 #include "wx/checklst.h"
37 #include "wx/combobox.h"
38 #include "wx/scrolbar.h"
39 #include "wx/slider.h"
40 #include "wx/textctrl.h"
41 #include "wx/listbox.h"
42 #include "wx/toolbar.h"
45 // for COLOR_* constants
46 #include "wx/msw/private.h"
50 #include "wx/notebook.h"
51 #include "wx/spinbutt.h"
52 #include "wx/settings.h"
54 #include "wx/artprov.h"
55 #include "wx/toplevel.h"
57 #include "wx/univ/scrtimer.h"
58 #include "wx/univ/renderer.h"
59 #include "wx/univ/inphand.h"
60 #include "wx/univ/colschem.h"
61 #include "wx/univ/theme.h"
63 // ----------------------------------------------------------------------------
65 // ----------------------------------------------------------------------------
67 static const int BORDER_THICKNESS
= 2;
69 // the offset between the label and focus rect around it
70 static const int FOCUS_RECT_OFFSET_X
= 1;
71 static const int FOCUS_RECT_OFFSET_Y
= 1;
73 static const int FRAME_BORDER_THICKNESS
= 3;
74 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
75 static const int FRAME_TITLEBAR_HEIGHT
= 18;
76 static const int FRAME_BUTTON_WIDTH
= 16;
77 static const int FRAME_BUTTON_HEIGHT
= 14;
79 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
80 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
81 static const size_t STATUSBAR_GRIP_SIZE
=
82 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
84 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
85 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
86 static const wxCoord SLIDER_TICK_LENGTH
= 6;
98 IndicatorState_Normal
,
99 IndicatorState_Pressed
, // this one is for check/radioboxes
100 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
101 IndicatorState_Disabled
,
102 IndicatorState_SelectedDisabled
, // only for the menus
108 IndicatorStatus_Checked
,
109 IndicatorStatus_Unchecked
,
113 // wxWin32Renderer: draw the GUI elements in Win32 style
114 // ----------------------------------------------------------------------------
116 class wxWin32Renderer
: public wxRenderer
120 enum wxArrowDirection
135 Arrow_InversedDisabled
,
139 enum wxFrameButtonType
142 FrameButton_Minimize
,
143 FrameButton_Maximize
,
150 wxWin32Renderer(const wxColourScheme
*scheme
);
152 // implement the base class pure virtuals
153 virtual void DrawBackground(wxDC
& dc
,
157 wxWindow
*window
= NULL
);
158 virtual void DrawLabel(wxDC
& dc
,
159 const wxString
& label
,
162 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
164 wxRect
*rectBounds
= NULL
);
165 virtual void DrawButtonLabel(wxDC
& dc
,
166 const wxString
& label
,
167 const wxBitmap
& image
,
170 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
172 wxRect
*rectBounds
= NULL
);
173 virtual void DrawBorder(wxDC
& dc
,
177 wxRect
*rectIn
= (wxRect
*)NULL
);
178 virtual void DrawHorizontalLine(wxDC
& dc
,
179 wxCoord y
, wxCoord x1
, wxCoord x2
);
180 virtual void DrawVerticalLine(wxDC
& dc
,
181 wxCoord x
, wxCoord y1
, wxCoord y2
);
182 virtual void DrawFrame(wxDC
& dc
,
183 const wxString
& label
,
186 int alignment
= wxALIGN_LEFT
,
187 int indexAccel
= -1);
188 virtual void DrawTextBorder(wxDC
& dc
,
192 wxRect
*rectIn
= (wxRect
*)NULL
);
193 virtual void DrawButtonBorder(wxDC
& dc
,
196 wxRect
*rectIn
= (wxRect
*)NULL
);
197 virtual void DrawArrow(wxDC
& dc
,
201 virtual void DrawScrollbarArrow(wxDC
& dc
,
205 { DrawArrow(dc
, dir
, rect
, flags
); }
206 virtual void DrawScrollbarThumb(wxDC
& dc
,
207 wxOrientation orient
,
210 virtual void DrawScrollbarShaft(wxDC
& dc
,
211 wxOrientation orient
,
214 virtual void DrawScrollCorner(wxDC
& dc
,
216 virtual void DrawItem(wxDC
& dc
,
217 const wxString
& label
,
220 virtual void DrawCheckItem(wxDC
& dc
,
221 const wxString
& label
,
222 const wxBitmap
& bitmap
,
225 virtual void DrawCheckButton(wxDC
& dc
,
226 const wxString
& label
,
227 const wxBitmap
& bitmap
,
230 wxAlignment align
= wxALIGN_LEFT
,
231 int indexAccel
= -1);
232 virtual void DrawRadioButton(wxDC
& dc
,
233 const wxString
& label
,
234 const wxBitmap
& bitmap
,
237 wxAlignment align
= wxALIGN_LEFT
,
238 int indexAccel
= -1);
239 virtual void DrawToolBarButton(wxDC
& dc
,
240 const wxString
& label
,
241 const wxBitmap
& bitmap
,
245 virtual void DrawTextLine(wxDC
& dc
,
246 const wxString
& text
,
251 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
252 virtual void DrawTab(wxDC
& dc
,
255 const wxString
& label
,
256 const wxBitmap
& bitmap
= wxNullBitmap
,
258 int indexAccel
= -1);
260 virtual void DrawSliderShaft(wxDC
& dc
,
263 wxOrientation orient
,
266 wxRect
*rectShaft
= NULL
);
267 virtual void DrawSliderThumb(wxDC
& dc
,
269 wxOrientation orient
,
272 virtual void DrawSliderTicks(wxDC
& dc
,
275 wxOrientation orient
,
282 virtual void DrawMenuBarItem(wxDC
& dc
,
284 const wxString
& label
,
286 int indexAccel
= -1);
287 virtual void DrawMenuItem(wxDC
& dc
,
289 const wxMenuGeometryInfo
& geometryInfo
,
290 const wxString
& label
,
291 const wxString
& accel
,
292 const wxBitmap
& bitmap
= wxNullBitmap
,
294 int indexAccel
= -1);
295 virtual void DrawMenuSeparator(wxDC
& dc
,
297 const wxMenuGeometryInfo
& geomInfo
);
299 virtual void DrawStatusField(wxDC
& dc
,
301 const wxString
& label
,
305 virtual void DrawFrameTitleBar(wxDC
& dc
,
307 const wxString
& title
,
310 int specialButton
= 0,
311 int specialButtonFlags
= 0);
312 virtual void DrawFrameBorder(wxDC
& dc
,
315 virtual void DrawFrameBackground(wxDC
& dc
,
318 virtual void DrawFrameTitle(wxDC
& dc
,
320 const wxString
& title
,
322 virtual void DrawFrameIcon(wxDC
& dc
,
326 virtual void DrawFrameButton(wxDC
& dc
,
327 wxCoord x
, wxCoord y
,
330 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
331 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
332 virtual wxSize
GetFrameMinSize(int flags
) const;
333 virtual wxSize
GetFrameIconSize() const;
334 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
336 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
338 wxBitmap
*bmpPressed
,
339 wxBitmap
*bmpDisabled
);
341 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
342 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
343 virtual bool AreScrollbarsInsideBorder() const;
345 virtual wxSize
GetScrollbarArrowSize() const
346 { return m_sizeScrollbarArrow
; }
347 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
348 wxScrollBar::Element elem
,
349 int thumbPos
= -1) const;
350 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
351 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
352 const wxPoint
& pt
) const;
353 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
355 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
356 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
357 { return fontHeight
+ 2; }
358 virtual wxSize
GetCheckBitmapSize() const
359 { return wxSize(13, 13); }
360 virtual wxSize
GetRadioBitmapSize() const
361 { return wxSize(12, 12); }
362 virtual wxCoord
GetCheckItemMargin() const
365 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
366 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
367 virtual wxSize
GetToolBarMargin() const
368 { return wxSize(4, 4); }
370 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
371 const wxRect
& rect
) const;
372 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
374 wxCoord
*extraSpaceBeyond
) const;
376 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
377 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
379 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
380 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
381 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
383 wxOrientation orient
,
384 long style
= 0) const;
385 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
387 wxOrientation orient
) const;
388 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
390 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
391 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
392 const wxMenu
& menu
) const;
394 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
397 // helper of DrawLabel() and DrawCheckOrRadioButton()
398 void DoDrawLabel(wxDC
& dc
,
399 const wxString
& label
,
402 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
404 wxRect
*rectBounds
= NULL
,
405 const wxPoint
& focusOffset
406 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
408 // common part of DrawLabel() and DrawItem()
409 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
411 // DrawLabel() and DrawButtonLabel() helper
412 void DrawLabelShadow(wxDC
& dc
,
413 const wxString
& label
,
418 // DrawButtonBorder() helper
419 void DoDrawBackground(wxDC
& dc
,
422 wxWindow
*window
= NULL
);
424 // DrawBorder() helpers: all of them shift and clip the DC after drawing
427 // just draw a rectangle with the given pen
428 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
430 // draw the lower left part of rectangle
431 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
433 // draw the rectange using the first brush for the left and top sides and
434 // the second one for the bottom and right ones
435 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
436 const wxPen
& pen1
, const wxPen
& pen2
);
438 // draw the normal 3D border
439 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
441 // draw the sunken 3D border
442 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
444 // draw the border used for scrollbar arrows
445 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
447 // public DrawArrow()s helper
448 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
449 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
451 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
452 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
453 wxArrowDirection arrowDir
,
454 wxArrowStyle arrowStyle
);
456 // DrawCheckButton/DrawRadioButton helper
457 void DrawCheckOrRadioButton(wxDC
& dc
,
458 const wxString
& label
,
459 const wxBitmap
& bitmap
,
464 wxCoord focusOffsetY
);
466 // draw a normal or transposed line (useful for using the same code fo both
467 // horizontal and vertical widgets)
468 void DrawLine(wxDC
& dc
,
469 wxCoord x1
, wxCoord y1
,
470 wxCoord x2
, wxCoord y2
,
471 bool transpose
= FALSE
)
474 dc
.DrawLine(y1
, x1
, y2
, x2
);
476 dc
.DrawLine(x1
, y1
, x2
, y2
);
479 // get the standard check/radio button bitmap
480 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
481 wxBitmap
GetCheckBitmap(int flags
)
482 { return GetIndicator(IndicatorType_Check
, flags
); }
483 wxBitmap
GetRadioBitmap(int flags
)
484 { return GetIndicator(IndicatorType_Radio
, flags
); }
487 const wxColourScheme
*m_scheme
;
489 // the sizing parameters (TODO make them changeable)
490 wxSize m_sizeScrollbarArrow
;
492 // GDI objects we use for drawing
493 wxColour m_colDarkGrey
,
501 wxFont m_titlebarFont
;
503 // the checked and unchecked bitmaps for DrawCheckItem()
504 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
506 // the bitmaps returned by GetIndicator()
507 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
509 [IndicatorStatus_Max
];
512 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
514 // first row is for the normal state, second - for the disabled
515 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
518 // ----------------------------------------------------------------------------
519 // wxWin32InputHandler and derived classes: process the keyboard and mouse
520 // messages according to Windows standards
521 // ----------------------------------------------------------------------------
523 class wxWin32InputHandler
: public wxInputHandler
526 wxWin32InputHandler(wxWin32Renderer
*renderer
);
528 virtual bool HandleKey(wxInputConsumer
*control
,
529 const wxKeyEvent
& event
,
531 virtual bool HandleMouse(wxInputConsumer
*control
,
532 const wxMouseEvent
& event
);
535 wxWin32Renderer
*m_renderer
;
538 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
541 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
542 wxInputHandler
*handler
);
544 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
545 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
547 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
548 const wxControlAction
& action
);
551 virtual bool IsAllowedButton(int button
) { return button
== 1; }
553 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
556 // we don't highlight anything
559 // the first and last event which caused the thumb to move
560 wxMouseEvent m_eventStartDrag
,
563 // have we paused the scrolling because the mouse moved?
566 // we remember the interval of the timer to be able to restart it
570 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
573 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
574 : wxStdCheckboxInputHandler(handler
) { }
576 virtual bool HandleKey(wxInputConsumer
*control
,
577 const wxKeyEvent
& event
,
581 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
584 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
585 : wxStdTextCtrlInputHandler(handler
) { }
587 virtual bool HandleKey(wxInputConsumer
*control
,
588 const wxKeyEvent
& event
,
592 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
595 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
597 virtual bool HandleMouse(wxInputConsumer
*consumer
,
598 const wxMouseEvent
& event
);
600 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
601 const wxMouseEvent
& event
);
604 // is the given point over the statusbar grip?
605 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
608 // the cursor we had replaced with the resize one
609 wxCursor m_cursorOld
;
611 // was the mouse over the grip last time we checked?
615 class wxWin32SystemMenuEvtHandler
;
617 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
620 wxWin32FrameInputHandler(wxInputHandler
*handler
);
621 ~wxWin32FrameInputHandler();
623 virtual bool HandleMouse(wxInputConsumer
*control
,
624 const wxMouseEvent
& event
);
626 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
628 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
631 // was the mouse over the grip last time we checked?
632 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
635 // ----------------------------------------------------------------------------
636 // wxWin32ColourScheme: uses (default) Win32 colours
637 // ----------------------------------------------------------------------------
639 class wxWin32ColourScheme
: public wxColourScheme
642 virtual wxColour
Get(StdColour col
) const;
643 virtual wxColour
GetBackground(wxWindow
*win
) const;
646 // ----------------------------------------------------------------------------
647 // wxWin32ArtProvider
648 // ----------------------------------------------------------------------------
650 class wxWin32ArtProvider
: public wxArtProvider
653 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
654 const wxArtClient
& client
,
658 // ----------------------------------------------------------------------------
660 // ----------------------------------------------------------------------------
662 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
664 class wxWin32Theme
: public wxTheme
668 virtual ~wxWin32Theme();
670 virtual wxRenderer
*GetRenderer();
671 virtual wxArtProvider
*GetArtProvider();
672 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
673 virtual wxColourScheme
*GetColourScheme();
676 // get the default input handler
677 wxInputHandler
*GetDefaultInputHandler();
679 wxWin32Renderer
*m_renderer
;
681 wxWin32ArtProvider
*m_artProvider
;
683 // the names of the already created handlers and the handlers themselves
684 // (these arrays are synchronized)
685 wxSortedArrayString m_handlerNames
;
686 wxArrayHandlers m_handlers
;
688 wxWin32InputHandler
*m_handlerDefault
;
690 wxWin32ColourScheme
*m_scheme
;
692 WX_DECLARE_THEME(win32
)
695 // ----------------------------------------------------------------------------
697 // ----------------------------------------------------------------------------
699 // frame buttons bitmaps
701 static const char *frame_button_close_xpm
[] = {
716 static const char *frame_button_help_xpm
[] = {
731 static const char *frame_button_maximize_xpm
[] = {
746 static const char *frame_button_minimize_xpm
[] = {
761 static const char *frame_button_restore_xpm
[] = {
778 static const char *checked_menu_xpm
[] = {
779 /* columns rows colors chars-per-pixel */
795 static const char *selected_checked_menu_xpm
[] = {
796 /* columns rows colors chars-per-pixel */
812 static const char *disabled_checked_menu_xpm
[] = {
813 /* columns rows colors chars-per-pixel */
830 static const char *selected_disabled_checked_menu_xpm
[] = {
831 /* columns rows colors chars-per-pixel */
847 // checkbox and radiobox bitmaps below
849 static const char *checked_xpm
[] = {
850 /* columns rows colors chars-per-pixel */
873 static const char *pressed_checked_xpm
[] = {
874 /* columns rows colors chars-per-pixel */
896 static const char *pressed_disabled_checked_xpm
[] = {
897 /* columns rows colors chars-per-pixel */
919 static const char *checked_item_xpm
[] = {
920 /* columns rows colors chars-per-pixel */
941 static const char *unchecked_xpm
[] = {
942 /* columns rows colors chars-per-pixel */
965 static const char *pressed_unchecked_xpm
[] = {
966 /* columns rows colors chars-per-pixel */
988 static const char *unchecked_item_xpm
[] = {
989 /* columns rows colors chars-per-pixel */
1009 static const char *checked_radio_xpm
[] = {
1010 /* columns rows colors chars-per-pixel */
1033 static const char *pressed_checked_radio_xpm
[] = {
1034 /* columns rows colors chars-per-pixel */
1057 static const char *pressed_disabled_checked_radio_xpm
[] = {
1058 /* columns rows colors chars-per-pixel */
1081 static const char *unchecked_radio_xpm
[] = {
1082 /* columns rows colors chars-per-pixel */
1105 static const char *pressed_unchecked_radio_xpm
[] = {
1106 /* columns rows colors chars-per-pixel */
1129 static const char **
1130 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1135 { checked_xpm
, unchecked_xpm
},
1138 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1141 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1147 { checked_radio_xpm
, unchecked_radio_xpm
},
1150 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1153 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1159 { checked_menu_xpm
, NULL
},
1162 { selected_checked_menu_xpm
, NULL
},
1165 { disabled_checked_menu_xpm
, NULL
},
1167 // disabled selected state
1168 { selected_disabled_checked_menu_xpm
, NULL
},
1172 static const char **xpmChecked
[IndicatorStatus_Max
] =
1178 // ============================================================================
1180 // ============================================================================
1182 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1184 // ----------------------------------------------------------------------------
1186 // ----------------------------------------------------------------------------
1188 wxWin32Theme::wxWin32Theme()
1192 m_handlerDefault
= NULL
;
1193 m_artProvider
= NULL
;
1196 wxWin32Theme::~wxWin32Theme()
1198 size_t count
= m_handlers
.GetCount();
1199 for ( size_t n
= 0; n
< count
; n
++ )
1201 if ( m_handlers
[n
] != m_handlerDefault
)
1202 delete m_handlers
[n
];
1205 delete m_handlerDefault
;
1209 wxArtProvider::RemoveProvider(m_artProvider
);
1212 wxRenderer
*wxWin32Theme::GetRenderer()
1216 m_renderer
= new wxWin32Renderer(GetColourScheme());
1222 wxArtProvider
*wxWin32Theme::GetArtProvider()
1224 if ( !m_artProvider
)
1226 m_artProvider
= new wxWin32ArtProvider
;
1229 return m_artProvider
;
1232 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1234 if ( !m_handlerDefault
)
1236 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1239 return m_handlerDefault
;
1242 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1244 wxInputHandler
*handler
;
1245 int n
= m_handlerNames
.Index(control
);
1246 if ( n
== wxNOT_FOUND
)
1248 // create a new handler
1249 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1250 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1251 GetDefaultInputHandler());
1253 else if ( control
== wxINP_HANDLER_BUTTON
)
1254 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1255 #endif // wxUSE_BUTTON
1257 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1258 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1259 #endif // wxUSE_CHECKBOX
1261 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1262 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1263 #endif // wxUSE_COMBOBOX
1265 else if ( control
== wxINP_HANDLER_LISTBOX
)
1266 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1267 #endif // wxUSE_LISTBOX
1268 #if wxUSE_CHECKLISTBOX
1269 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1270 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1271 #endif // wxUSE_CHECKLISTBOX
1273 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1274 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1275 #endif // wxUSE_TEXTCTRL
1277 else if ( control
== wxINP_HANDLER_SLIDER
)
1278 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1279 #endif // wxUSE_SLIDER
1281 else if ( control
== wxINP_HANDLER_SPINBTN
)
1282 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1283 #endif // wxUSE_SPINBTN
1285 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1286 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1287 #endif // wxUSE_NOTEBOOK
1289 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1290 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1291 #endif // wxUSE_STATUSBAR
1293 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1294 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1295 #endif // wxUSE_TOOLBAR
1296 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1297 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1299 handler
= GetDefaultInputHandler();
1301 n
= m_handlerNames
.Add(control
);
1302 m_handlers
.Insert(handler
, n
);
1304 else // we already have it
1306 handler
= m_handlers
[n
];
1312 wxColourScheme
*wxWin32Theme::GetColourScheme()
1316 m_scheme
= new wxWin32ColourScheme
;
1321 // ============================================================================
1322 // wxWin32ColourScheme
1323 // ============================================================================
1325 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1328 if ( win
->UseBgCol() )
1330 // use the user specified colour
1331 col
= win
->GetBackgroundColour();
1334 if ( !win
->ShouldInheritColours() )
1336 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1338 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1346 if ( !win
->IsEnabled() ) // not IsEditable()
1352 // doesn't depend on the state
1359 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1363 int flags
= win
->GetStateFlags();
1365 // the colour set by the user should be used for the normal state
1366 // and for the states for which we don't have any specific colours
1367 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1369 if ( wxDynamicCast(win
, wxScrollBar
) )
1370 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1380 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1384 // use the system colours under Windows
1385 #if defined(__WXMSW__)
1386 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1388 case CONTROL_PRESSED
:
1389 case CONTROL_CURRENT
:
1390 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1392 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1394 #if defined(COLOR_3DLIGHT)
1395 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1397 case SCROLLBAR
: return wxColour(0xe0e0e0);
1399 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1401 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1402 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1404 #if defined(COLOR_3DDKSHADOW)
1405 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1407 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1410 case CONTROL_TEXT_DISABLED
:
1411 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1413 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1415 case CONTROL_TEXT_DISABLED_SHADOW
:
1416 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1418 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1419 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1420 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1421 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1423 case DESKTOP
: return wxColour(0x808000);
1425 // use the standard Windows colours elsewhere
1426 case WINDOW
: return *wxWHITE
;
1428 case CONTROL_PRESSED
:
1429 case CONTROL_CURRENT
:
1430 case CONTROL
: return wxColour(0xc0c0c0);
1432 case CONTROL_TEXT
: return *wxBLACK
;
1434 case SCROLLBAR
: return wxColour(0xe0e0e0);
1435 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1437 case HIGHLIGHT
: return wxColour(0x800000);
1438 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1440 case SHADOW_DARK
: return *wxBLACK
;
1442 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1443 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1445 case SHADOW_IN
: return wxColour(0xc0c0c0);
1447 case CONTROL_TEXT_DISABLED_SHADOW
:
1448 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1450 case TITLEBAR
: return wxColour(0xaeaaae);
1451 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1452 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1453 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1455 case DESKTOP
: return wxColour(0x808000);
1458 case GAUGE
: return Get(HIGHLIGHT
);
1462 wxFAIL_MSG(_T("invalid standard colour"));
1467 // ============================================================================
1469 // ============================================================================
1471 // ----------------------------------------------------------------------------
1473 // ----------------------------------------------------------------------------
1475 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1479 m_sizeScrollbarArrow
= wxSize(16, 16);
1481 // init colours and pens
1482 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1484 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1485 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1487 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1489 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1490 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1492 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1493 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1495 // init the arrow bitmaps
1496 static const size_t ARROW_WIDTH
= 7;
1497 static const size_t ARROW_LENGTH
= 4;
1500 wxMemoryDC dcNormal
,
1503 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1505 bool isVertical
= n
> Arrow_Right
;
1518 // disabled arrow is larger because of the shadow
1519 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1520 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1522 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1523 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1525 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1526 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1530 dcNormal
.SetPen(m_penBlack
);
1531 dcDisabled
.SetPen(m_penDarkGrey
);
1533 // calculate the position of the point of the arrow
1537 x1
= (ARROW_WIDTH
- 1)/2;
1538 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1542 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1543 y1
= (ARROW_WIDTH
- 1)/2;
1554 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1556 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1557 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1564 if ( n
== Arrow_Up
)
1575 else // left or right arrow
1580 if ( n
== Arrow_Left
)
1593 // draw the shadow for the disabled one
1594 dcDisabled
.SetPen(m_penHighlight
);
1599 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1603 x1
= ARROW_LENGTH
- 1;
1604 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1607 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1608 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1613 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1617 x1
= ARROW_WIDTH
- 1;
1619 x2
= (ARROW_WIDTH
- 1)/2;
1621 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1622 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1627 // create the inversed bitmap but only for the right arrow as we only
1628 // use it for the menus
1629 if ( n
== Arrow_Right
)
1631 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1632 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1634 dcInverse
.Blit(0, 0, w
, h
,
1637 dcInverse
.SelectObject(wxNullBitmap
);
1639 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1640 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1642 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1643 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1645 dcInverse
.Blit(0, 0, w
, h
,
1648 dcInverse
.SelectObject(wxNullBitmap
);
1650 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1651 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1654 dcNormal
.SelectObject(wxNullBitmap
);
1655 dcDisabled
.SelectObject(wxNullBitmap
);
1657 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1658 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1659 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1660 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1662 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1665 // init the frame buttons bitmaps
1666 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1667 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1668 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1669 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1670 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1673 // ----------------------------------------------------------------------------
1675 // ----------------------------------------------------------------------------
1678 The raised border in Win32 looks like this:
1680 IIIIIIIIIIIIIIIIIIIIIIB
1682 I GB I = white (HILIGHT)
1683 I GB H = light grey (LIGHT)
1684 I GB G = dark grey (SHADOI)
1685 I GB B = black (DKSHADOI)
1686 I GB I = hIghlight (COLOR_3DHILIGHT)
1688 IGGGGGGGGGGGGGGGGGGGGGB
1689 BBBBBBBBBBBBBBBBBBBBBBB
1691 The sunken border looks like this:
1693 GGGGGGGGGGGGGGGGGGGGGGI
1694 GBBBBBBBBBBBBBBBBBBBBHI
1701 GHHHHHHHHHHHHHHHHHHHHHI
1702 IIIIIIIIIIIIIIIIIIIIIII
1704 The static border (used for the controls which don't get focus) is like
1707 GGGGGGGGGGGGGGGGGGGGGGW
1715 WWWWWWWWWWWWWWWWWWWWWWW
1717 The most complicated is the double border:
1719 HHHHHHHHHHHHHHHHHHHHHHB
1720 HWWWWWWWWWWWWWWWWWWWWGB
1721 HWHHHHHHHHHHHHHHHHHHHGB
1726 HWHHHHHHHHHHHHHHHHHHHGB
1727 HGGGGGGGGGGGGGGGGGGGGGB
1728 BBBBBBBBBBBBBBBBBBBBBBB
1730 And the simple border is, well, simple:
1732 BBBBBBBBBBBBBBBBBBBBBBB
1741 BBBBBBBBBBBBBBBBBBBBBBB
1744 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1748 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1749 dc
.DrawRectangle(*rect
);
1755 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1757 // draw the bottom and right sides
1759 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1760 rect
->GetRight() + 1, rect
->GetBottom());
1761 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1762 rect
->GetRight(), rect
->GetBottom());
1768 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1769 const wxPen
& pen1
, const wxPen
& pen2
)
1771 // draw the rectangle
1773 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1774 rect
->GetLeft(), rect
->GetBottom());
1775 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1776 rect
->GetRight(), rect
->GetTop());
1778 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1779 rect
->GetRight(), rect
->GetBottom());
1780 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1781 rect
->GetRight() + 1, rect
->GetBottom());
1787 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1789 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1790 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1793 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1795 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1796 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1799 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1803 DrawRect(dc
, rect
, m_penDarkGrey
);
1805 // the arrow is usually drawn inside border of width 2 and is offset by
1806 // another pixel in both directions when it's pressed - as the border
1807 // in this case is more narrow as well, we have to adjust rect like
1815 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1816 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1820 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1822 const wxRect
& rectTotal
,
1823 int WXUNUSED(flags
),
1828 wxRect rect
= rectTotal
;
1832 case wxBORDER_SUNKEN
:
1833 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1835 DrawSunkenBorder(dc
, &rect
);
1839 case wxBORDER_STATIC
:
1840 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1843 case wxBORDER_RAISED
:
1844 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1846 DrawRaisedBorder(dc
, &rect
);
1850 case wxBORDER_DOUBLE
:
1851 DrawArrowBorder(dc
, &rect
);
1852 DrawRect(dc
, &rect
, m_penLightGrey
);
1855 case wxBORDER_SIMPLE
:
1856 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1858 DrawRect(dc
, &rect
, m_penBlack
);
1863 wxFAIL_MSG(_T("unknown border type"));
1866 case wxBORDER_DEFAULT
:
1875 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1880 case wxBORDER_RAISED
:
1881 case wxBORDER_SUNKEN
:
1882 width
= BORDER_THICKNESS
;
1885 case wxBORDER_SIMPLE
:
1886 case wxBORDER_STATIC
:
1890 case wxBORDER_DOUBLE
:
1896 // char *crash = NULL;
1898 wxFAIL_MSG(_T("unknown border type"));
1902 case wxBORDER_DEFAULT
:
1912 rect
.height
= width
;
1917 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1922 // ----------------------------------------------------------------------------
1924 // ----------------------------------------------------------------------------
1926 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1932 // text controls are not special under windows
1933 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1936 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1937 const wxRect
& rectTotal
,
1941 wxRect rect
= rectTotal
;
1943 if ( flags
& wxCONTROL_PRESSED
)
1945 // button pressed: draw a double border around it
1946 DrawRect(dc
, &rect
, m_penBlack
);
1947 DrawRect(dc
, &rect
, m_penDarkGrey
);
1951 // button not pressed
1953 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1955 // button either default or focused (or both): add an extra border around it
1956 DrawRect(dc
, &rect
, m_penBlack
);
1959 // now draw a normal button
1960 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1961 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1970 // ----------------------------------------------------------------------------
1972 // ----------------------------------------------------------------------------
1974 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1975 wxCoord y
, wxCoord x1
, wxCoord x2
)
1977 dc
.SetPen(m_penDarkGrey
);
1978 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1979 dc
.SetPen(m_penHighlight
);
1981 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1984 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1985 wxCoord x
, wxCoord y1
, wxCoord y2
)
1987 dc
.SetPen(m_penDarkGrey
);
1988 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1989 dc
.SetPen(m_penHighlight
);
1991 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1994 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1995 const wxString
& label
,
2001 wxCoord height
= 0; // of the label
2002 wxRect rectFrame
= rect
;
2003 if ( !label
.empty() )
2005 // the text should touch the top border of the rect, so the frame
2006 // itself should be lower
2007 dc
.GetTextExtent(label
, NULL
, &height
);
2008 rectFrame
.y
+= height
/ 2;
2009 rectFrame
.height
-= height
/ 2;
2011 // we have to draw each part of the frame individually as we can't
2012 // erase the background beyond the label as it might contain some
2013 // pixmap already, so drawing everything and then overwriting part of
2014 // the frame with label doesn't work
2016 // TODO: the +5 and space insertion should be customizable
2019 rectText
.x
= rectFrame
.x
+ 5;
2020 rectText
.y
= rect
.y
;
2021 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2022 rectText
.height
= height
;
2025 label2
<< _T(' ') << label
<< _T(' ');
2026 if ( indexAccel
!= -1 )
2028 // adjust it as we prepended a space
2033 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2035 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2039 // just draw the complete frame
2040 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2041 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2045 // ----------------------------------------------------------------------------
2047 // ----------------------------------------------------------------------------
2049 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2051 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2052 // pixels each while we really need dots here... PS_ALTERNATE might
2053 // work, but it is for NT 5 only
2055 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2057 // draw the pixels manually: note that to behave in the same manner as
2058 // DrawRect(), we must exclude the bottom and right borders from the
2060 wxCoord x1
= rect
.GetLeft(),
2062 x2
= rect
.GetRight(),
2063 y2
= rect
.GetBottom();
2065 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2067 // this seems to be closer than what Windows does than wxINVERT although
2068 // I'm still not sure if it's correct
2069 dc
.SetLogicalFunction(wxAND_REVERSE
);
2072 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2073 dc
.DrawPoint(z
, rect
.GetTop());
2075 wxCoord shift
= z
== x2
? 0 : 1;
2076 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2077 dc
.DrawPoint(x2
, z
);
2079 shift
= z
== y2
? 0 : 1;
2080 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2081 dc
.DrawPoint(z
, y2
);
2083 shift
= z
== x1
? 0 : 1;
2084 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2085 dc
.DrawPoint(x1
, z
);
2087 dc
.SetLogicalFunction(wxCOPY
);
2091 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2092 const wxString
& label
,
2097 // draw shadow of the text
2098 dc
.SetTextForeground(m_colHighlight
);
2099 wxRect rectShadow
= rect
;
2102 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2104 // make the text grey
2105 dc
.SetTextForeground(m_colDarkGrey
);
2108 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2109 const wxString
& label
,
2116 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2119 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2120 const wxString
& label
,
2126 const wxPoint
& focusOffset
)
2128 // the underscores are not drawn for focused controls in wxMSW
2129 if ( flags
& wxCONTROL_FOCUSED
)
2134 if ( flags
& wxCONTROL_DISABLED
)
2136 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2137 // currently only can happen for a menu item and it seems that Windows
2138 // doesn't draw the shadow in this case, so we don't do it neither
2139 if ( flags
& wxCONTROL_SELECTED
)
2141 // just make the label text greyed out
2142 dc
.SetTextForeground(m_colDarkGrey
);
2144 else // draw normal disabled label
2146 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2151 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2153 if ( flags
& wxCONTROL_DISABLED
)
2155 // restore the fg colour
2156 dc
.SetTextForeground(*wxBLACK
);
2159 if ( flags
& wxCONTROL_FOCUSED
)
2161 if ( focusOffset
.x
|| focusOffset
.y
)
2163 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2166 DrawFocusRect(dc
, rectLabel
);
2170 *rectBounds
= rectLabel
;
2173 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2174 const wxString
& label
,
2175 const wxBitmap
& image
,
2182 // the underscores are not drawn for focused controls in wxMSW
2183 if ( flags
& wxCONTROL_PRESSED
)
2188 wxRect rectLabel
= rect
;
2189 if ( !label
.empty() )
2191 // shift the label if a button is pressed
2192 if ( flags
& wxCONTROL_PRESSED
)
2198 if ( flags
& wxCONTROL_DISABLED
)
2200 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2203 // leave enough space for the focus rectangle
2204 if ( flags
& wxCONTROL_FOCUSED
)
2206 rectLabel
.Inflate(-2);
2210 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2212 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2214 if ( flags
& wxCONTROL_PRESSED
)
2216 // the focus rectangle is never pressed, so undo the shift done
2224 DrawFocusRect(dc
, rectLabel
);
2228 // ----------------------------------------------------------------------------
2229 // (check)listbox items
2230 // ----------------------------------------------------------------------------
2232 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2233 const wxString
& label
,
2237 wxDCTextColourChanger
colChanger(dc
);
2239 if ( flags
& wxCONTROL_SELECTED
)
2241 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2243 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2244 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2245 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2246 dc
.DrawRectangle(rect
);
2249 wxRect rectText
= rect
;
2251 rectText
.width
-= 2;
2252 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2254 if ( flags
& wxCONTROL_FOCUSED
)
2256 DrawFocusRect(dc
, rect
);
2260 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2261 const wxString
& label
,
2262 const wxBitmap
& bitmap
,
2271 else // use default bitmap
2273 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2274 ? IndicatorStatus_Checked
2275 : IndicatorStatus_Unchecked
;
2277 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2279 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2282 bmp
= m_bmpCheckBitmaps
[i
];
2285 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2286 TRUE
/* use mask */);
2288 wxRect rectLabel
= rect
;
2289 int bmpWidth
= bmp
.GetWidth();
2290 rectLabel
.x
+= bmpWidth
;
2291 rectLabel
.width
-= bmpWidth
;
2293 DrawItem(dc
, label
, rectLabel
, flags
);
2296 // ----------------------------------------------------------------------------
2297 // check/radio buttons
2298 // ----------------------------------------------------------------------------
2300 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2302 IndicatorState indState
;
2303 if ( flags
& wxCONTROL_SELECTED
)
2304 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2305 : IndicatorState_Selected
;
2306 else if ( flags
& wxCONTROL_DISABLED
)
2307 indState
= IndicatorState_Disabled
;
2308 else if ( flags
& wxCONTROL_PRESSED
)
2309 indState
= IndicatorState_Pressed
;
2311 indState
= IndicatorState_Normal
;
2313 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2314 ? IndicatorStatus_Checked
2315 : IndicatorStatus_Unchecked
;
2317 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2320 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2323 // create and cache it
2324 bmp
= wxBitmap(xpm
);
2325 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2332 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2333 const wxString
& label
,
2334 const wxBitmap
& bitmap
,
2339 wxCoord focusOffsetY
)
2341 // calculate the position of the bitmap and of the label
2342 wxCoord heightBmp
= bitmap
.GetHeight();
2344 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2347 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2348 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2350 // align label vertically with the bitmap - looks nicer like this
2351 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2353 // calc horz position
2354 if ( align
== wxALIGN_RIGHT
)
2356 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2357 rectLabel
.x
= rect
.x
+ 3;
2358 rectLabel
.SetRight(xBmp
);
2360 else // normal (checkbox to the left of the text) case
2363 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2364 rectLabel
.SetRight(rect
.GetRight());
2367 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2370 dc
, label
, rectLabel
,
2372 wxALIGN_LEFT
| wxALIGN_TOP
,
2374 NULL
, // we don't need bounding rect
2375 // use custom vert focus rect offset
2376 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2380 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2381 const wxString
& label
,
2382 const wxBitmap
& bitmap
,
2392 bmp
= GetRadioBitmap(flags
);
2394 DrawCheckOrRadioButton(dc
, label
,
2396 rect
, flags
, align
, indexAccel
,
2397 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2400 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2401 const wxString
& label
,
2402 const wxBitmap
& bitmap
,
2412 bmp
= GetCheckBitmap(flags
);
2414 DrawCheckOrRadioButton(dc
, label
,
2416 rect
, flags
, align
, indexAccel
,
2417 0); // no focus rect offset for checkboxes
2420 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2421 const wxString
& label
,
2422 const wxBitmap
& bitmap
,
2423 const wxRect
& rectOrig
,
2427 if (style
== wxTOOL_STYLE_BUTTON
)
2429 wxRect rect
= rectOrig
;
2430 rect
.Deflate(BORDER_THICKNESS
);
2432 if ( flags
& wxCONTROL_PRESSED
)
2434 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2436 else if ( flags
& wxCONTROL_CURRENT
)
2438 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2441 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2443 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2445 // leave a small gap aroudn the line, also account for the toolbar
2447 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2448 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2449 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2451 // don't draw wxTOOL_STYLE_CONTROL
2454 // ----------------------------------------------------------------------------
2456 // ----------------------------------------------------------------------------
2458 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2459 const wxString
& text
,
2465 // nothing special to do here
2466 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2470 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2471 const wxRect
& WXUNUSED(rect
))
2473 // we don't draw them
2476 // ----------------------------------------------------------------------------
2478 // ----------------------------------------------------------------------------
2480 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2481 const wxRect
& rectOrig
,
2483 const wxString
& label
,
2484 const wxBitmap
& bitmap
,
2488 wxRect rect
= rectOrig
;
2490 // the current tab is drawn indented (to the top for default case) and
2491 // bigger than the other ones
2492 const wxSize indent
= GetTabIndent();
2493 if ( flags
& wxCONTROL_SELECTED
)
2498 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2502 rect
.Inflate(indent
.x
, 0);
2504 rect
.height
+= indent
.y
;
2508 rect
.Inflate(indent
.x
, 0);
2509 rect
.height
+= indent
.y
;
2514 wxFAIL_MSG(_T("TODO"));
2519 // draw the text, image and the focus around them (if necessary)
2520 wxRect rectLabel
= rect
;
2521 rectLabel
.Deflate(1, 1);
2522 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2523 flags
, wxALIGN_CENTRE
, indexAccel
);
2525 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2526 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2529 x2
= rect
.GetRight(),
2530 y2
= rect
.GetBottom();
2532 // FIXME: all this code will break if the tab indent or the border width,
2533 // it is tied to the fact that both of them are equal to 2
2538 dc
.SetPen(m_penHighlight
);
2539 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2540 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2541 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2543 dc
.SetPen(m_penBlack
);
2544 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2545 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2547 dc
.SetPen(m_penDarkGrey
);
2548 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2550 if ( flags
& wxCONTROL_SELECTED
)
2552 dc
.SetPen(m_penLightGrey
);
2554 // overwrite the part of the border below this tab
2555 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2557 // and the shadow of the tab to the left of us
2558 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2563 dc
.SetPen(m_penHighlight
);
2564 // we need to continue one pixel further to overwrite the corner of
2565 // the border for the selected tab
2566 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2568 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2570 dc
.SetPen(m_penBlack
);
2571 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2572 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2573 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2575 dc
.SetPen(m_penDarkGrey
);
2576 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2577 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2579 if ( flags
& wxCONTROL_SELECTED
)
2581 dc
.SetPen(m_penLightGrey
);
2583 // overwrite the part of the (double!) border above this tab
2584 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2585 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2587 // and the shadow of the tab to the left of us
2588 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2594 wxFAIL_MSG(_T("TODO"));
2598 // ----------------------------------------------------------------------------
2600 // ----------------------------------------------------------------------------
2603 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2605 wxOrientation orient
) const
2608 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2609 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2611 if (orient
== wxHORIZONTAL
)
2625 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2627 wxOrientation orient
,
2630 bool transpose
= (orient
== wxVERTICAL
);
2631 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2632 (((style
& wxSL_TOP
) != 0) & !transpose
|
2633 ((style
& wxSL_LEFT
) != 0) & transpose
|
2634 ((style
& wxSL_BOTH
) != 0));
2635 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2636 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2637 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2638 ((style
& wxSL_BOTH
) != 0));
2640 wxRect rect
= rectOrig
;
2642 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2644 if (orient
== wxHORIZONTAL
) {
2645 rect
.x
+= SLIDER_MARGIN
;
2648 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2652 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2656 rect
.y
+= sizeThumb
.y
/2;
2658 rect
.width
-= 2*SLIDER_MARGIN
;
2659 rect
.height
= 2*BORDER_THICKNESS
;
2663 rect
.y
+= SLIDER_MARGIN
;
2666 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2670 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2674 rect
.x
+= sizeThumb
.x
/2;
2676 rect
.width
= 2*BORDER_THICKNESS
;
2677 rect
.height
-= 2*SLIDER_MARGIN
;
2683 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2684 const wxRect
& rectOrig
,
2686 wxOrientation orient
,
2691 /* show shaft geometry
2709 if (flags
& wxCONTROL_FOCUSED
) {
2710 DrawFocusRect(dc
, rectOrig
);
2713 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2715 if (rectShaft
) *rectShaft
= rect
;
2717 DrawSunkenBorder(dc
, &rect
);
2720 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2722 wxOrientation orient
,
2726 /* show thumb geometry
2735 H D B where H is hightlight colour
2749 The interior of this shape is filled with the hatched brush if the thumb
2753 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2755 bool transpose
= (orient
== wxVERTICAL
);
2756 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2757 (((style
& wxSL_TOP
) != 0) & !transpose
|
2758 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2759 ((style
& wxSL_BOTH
) == 0);
2760 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2761 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2762 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2763 ((style
& wxSL_BOTH
) == 0);
2765 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2766 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2768 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2769 x1
= (transpose
? rect
.y
: rect
.x
);
2770 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2771 x3
= (x1
-1+c
) + sizeArrow
;
2772 y1
= (transpose
? rect
.x
: rect
.y
);
2773 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2774 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2775 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2777 dc
.SetPen(m_penBlack
);
2779 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2781 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2784 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2788 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2791 dc
.SetPen(m_penDarkGrey
);
2792 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2794 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2798 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2801 dc
.SetPen(m_penHighlight
);
2804 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2805 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2809 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2811 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2814 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2817 if (flags
& wxCONTROL_PRESSED
) {
2818 // TODO: MSW fills the entire area inside, not just the rect
2819 wxRect rectInt
= rect
;
2822 rectInt
.SetLeft(y3
);
2823 rectInt
.SetRight(y4
);
2828 rectInt
.SetBottom(y4
);
2832 #if !defined(__WXMGL__)
2833 static const char *stipple_xpm
[] = {
2834 /* columns rows colors chars-per-pixel */
2843 // VS: MGL can only do 8x8 stipple brushes
2844 static const char *stipple_xpm
[] = {
2845 /* columns rows colors chars-per-pixel */
2860 dc
.SetBrush(wxBrush(stipple_xpm
));
2862 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2863 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2864 dc
.SetPen(*wxTRANSPARENT_PEN
);
2865 dc
.DrawRectangle(rectInt
);
2869 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2872 wxOrientation orient
,
2876 int WXUNUSED(flags
),
2879 /* show ticks geometry
2894 if (end
== start
) return;
2896 bool transpose
= (orient
== wxVERTICAL
);
2897 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2898 (((style
& wxSL_TOP
) != 0) & !transpose
|
2899 ((style
& wxSL_LEFT
) != 0) & transpose
|
2900 ((style
& wxSL_BOTH
) != 0));
2901 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2902 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2903 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2904 ((style
& wxSL_BOTH
) != 0));
2906 // default thumb size
2907 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2908 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
2910 // normal thumb size
2911 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2912 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
2914 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2916 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2917 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2918 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2919 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2920 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2921 y3
= (transpose
? rect
.x
: rect
.y
);
2922 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2925 dc
.SetPen(m_penBlack
);
2927 int range
= end
- start
;
2928 for ( int n
= 0; n
< range
; n
+= step
) {
2929 wxCoord x
= x1
+ (len
*n
) / range
;
2931 if (left
& (y1
> y3
)) {
2932 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2934 if (right
& (y4
> y2
)) {
2935 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2938 // always draw the line at the end position
2939 if (left
& (y1
> y3
)) {
2940 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2942 if (right
& (y4
> y2
)) {
2943 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2947 // ----------------------------------------------------------------------------
2949 // ----------------------------------------------------------------------------
2951 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2952 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2955 virtual wxSize
GetSize() const { return m_size
; }
2957 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2958 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2960 wxCoord
GetItemHeight() const { return m_heightItem
; }
2963 // the total size of the menu
2966 // the offset of the start of the menu item label
2969 // the offset of the start of the accel label
2972 // the height of a normal (not separator) item
2973 wxCoord m_heightItem
;
2975 friend wxMenuGeometryInfo
*
2976 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2979 // FIXME: all constants are hardcoded but shouldn't be
2980 static const wxCoord MENU_LEFT_MARGIN
= 9;
2981 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2982 static const wxCoord MENU_VERT_MARGIN
= 3;
2984 // the margin around bitmap/check marks (on each side)
2985 static const wxCoord MENU_BMP_MARGIN
= 2;
2987 // the margin between the labels and accel strings
2988 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2990 // the separator height in pixels: in fact, strangely enough, the real height
2991 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2993 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2995 // the size of the standard checkmark bitmap
2996 static const wxCoord MENU_CHECK_SIZE
= 9;
2998 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2999 const wxRect
& rectOrig
,
3000 const wxString
& label
,
3004 wxRect rect
= rectOrig
;
3007 wxDCTextColourChanger
colChanger(dc
);
3009 if ( flags
& wxCONTROL_SELECTED
)
3011 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3013 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3014 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3015 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3016 dc
.DrawRectangle(rect
);
3019 // don't draw the focus rect around menu bar items
3020 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3021 wxALIGN_CENTRE
, indexAccel
);
3024 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3026 const wxMenuGeometryInfo
& gi
,
3027 const wxString
& label
,
3028 const wxString
& accel
,
3029 const wxBitmap
& bitmap
,
3033 const wxWin32MenuGeometryInfo
& geometryInfo
=
3034 (const wxWin32MenuGeometryInfo
&)gi
;
3039 rect
.width
= geometryInfo
.GetSize().x
;
3040 rect
.height
= geometryInfo
.GetItemHeight();
3042 // draw the selected item specially
3043 wxDCTextColourChanger
colChanger(dc
);
3044 if ( flags
& wxCONTROL_SELECTED
)
3046 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3048 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3049 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3050 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3051 dc
.DrawRectangle(rect
);
3054 // draw the bitmap: use the bitmap provided or the standard checkmark for
3055 // the checkable items
3056 wxBitmap bmp
= bitmap
;
3057 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3059 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3064 rect
.SetRight(geometryInfo
.GetLabelOffset());
3065 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3069 rect
.x
= geometryInfo
.GetLabelOffset();
3070 rect
.SetRight(geometryInfo
.GetAccelOffset());
3072 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3074 // draw the accel string
3075 rect
.x
= geometryInfo
.GetAccelOffset();
3076 rect
.SetRight(geometryInfo
.GetSize().x
);
3078 // NB: no accel index here
3079 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3081 // draw the submenu indicator
3082 if ( flags
& wxCONTROL_ISSUBMENU
)
3084 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3085 rect
.width
= MENU_RIGHT_MARGIN
;
3087 wxArrowStyle arrowStyle
;
3088 if ( flags
& wxCONTROL_DISABLED
)
3089 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
3091 else if ( flags
& wxCONTROL_SELECTED
)
3092 arrowStyle
= Arrow_Inversed
;
3094 arrowStyle
= Arrow_Normal
;
3096 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3100 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3102 const wxMenuGeometryInfo
& geomInfo
)
3104 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3107 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3109 wxSize size
= sizeText
;
3111 // FIXME: menubar height is configurable under Windows
3118 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3119 const wxMenu
& menu
) const
3121 // prepare the dc: for now we draw all the items with the system font
3123 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3125 // the height of a normal item
3126 wxCoord heightText
= dc
.GetCharHeight();
3131 // the max length of label and accel strings: the menu width is the sum of
3132 // them, even if they're for different items (as the accels should be
3135 // the max length of the bitmap is never 0 as Windows always leaves enough
3136 // space for a check mark indicator
3137 wxCoord widthLabelMax
= 0,
3139 widthBmpMax
= MENU_LEFT_MARGIN
;
3141 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3143 node
= node
->GetNext() )
3145 // height of this item
3148 wxMenuItem
*item
= node
->GetData();
3149 if ( item
->IsSeparator() )
3151 h
= MENU_SEPARATOR_HEIGHT
;
3153 else // not separator
3158 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3159 if ( widthLabel
> widthLabelMax
)
3161 widthLabelMax
= widthLabel
;
3165 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3166 if ( widthAccel
> widthAccelMax
)
3168 widthAccelMax
= widthAccel
;
3171 const wxBitmap
& bmp
= item
->GetBitmap();
3174 wxCoord widthBmp
= bmp
.GetWidth();
3175 if ( widthBmp
> widthBmpMax
)
3176 widthBmpMax
= widthBmp
;
3178 //else if ( item->IsCheckable() ): no need to check for this as
3179 // MENU_LEFT_MARGIN is big enough to show the check mark
3182 h
+= 2*MENU_VERT_MARGIN
;
3184 // remember the item position and height
3185 item
->SetGeometry(height
, h
);
3190 // bundle the metrics into a struct and return it
3191 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3193 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3194 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3195 if ( widthAccelMax
> 0 )
3197 // if we actually have any accesl, add a margin
3198 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3201 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3203 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3204 gi
->m_size
.y
= height
;
3209 // ----------------------------------------------------------------------------
3211 // ----------------------------------------------------------------------------
3213 static const wxCoord STATBAR_BORDER_X
= 2;
3214 static const wxCoord STATBAR_BORDER_Y
= 2;
3216 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3218 if ( borderBetweenFields
)
3219 *borderBetweenFields
= 2;
3221 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3224 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3226 const wxString
& label
,
3231 if ( flags
& wxCONTROL_ISDEFAULT
)
3233 // draw the size grip: it is a normal rect except that in the lower
3234 // right corner we have several bands which may be used for dragging
3235 // the status bar corner
3237 // each band consists of 4 stripes: m_penHighlight, double
3238 // m_penDarkGrey and transparent one
3239 wxCoord x2
= rect
.GetRight(),
3240 y2
= rect
.GetBottom();
3242 // draw the upper left part of the rect normally
3243 dc
.SetPen(m_penDarkGrey
);
3244 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3245 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3247 // draw the grey stripes of the grip
3249 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3250 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3252 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3253 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3256 // draw the white stripes
3257 dc
.SetPen(m_penHighlight
);
3258 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3259 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3261 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3264 // draw the remaining rect boundaries
3265 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3266 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3267 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3272 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3276 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3279 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3281 wxDCClipper
clipper(dc
, rectIn
);
3282 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3285 // ----------------------------------------------------------------------------
3287 // ----------------------------------------------------------------------------
3289 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3290 wxBitmap
* WXUNUSED(bmpFocus
),
3291 wxBitmap
*bmpPressed
,
3292 wxBitmap
*bmpDisabled
)
3294 static const wxCoord widthCombo
= 16;
3295 static const wxCoord heightCombo
= 17;
3301 bmpNormal
->Create(widthCombo
, heightCombo
);
3302 dcMem
.SelectObject(*bmpNormal
);
3303 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3304 Arrow_Down
, Arrow_Normal
);
3309 bmpPressed
->Create(widthCombo
, heightCombo
);
3310 dcMem
.SelectObject(*bmpPressed
);
3311 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3312 Arrow_Down
, Arrow_Pressed
);
3317 bmpDisabled
->Create(widthCombo
, heightCombo
);
3318 dcMem
.SelectObject(*bmpDisabled
);
3319 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3320 Arrow_Down
, Arrow_Disabled
);
3324 // ----------------------------------------------------------------------------
3326 // ----------------------------------------------------------------------------
3328 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3329 const wxColour
& col
,
3331 wxWindow
* WXUNUSED(window
))
3333 wxBrush
brush(col
, wxSOLID
);
3335 dc
.SetPen(*wxTRANSPARENT_PEN
);
3336 dc
.DrawRectangle(rect
);
3339 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3340 const wxColour
& col
,
3342 int WXUNUSED(flags
),
3345 // just fill it with the given or default bg colour
3346 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3347 DoDrawBackground(dc
, colBg
, rect
, window
);
3350 // ----------------------------------------------------------------------------
3352 // ----------------------------------------------------------------------------
3354 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3359 // get the bitmap for this arrow
3360 wxArrowDirection arrowDir
;
3363 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3364 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3365 case wxUP
: arrowDir
= Arrow_Up
; break;
3366 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3369 wxFAIL_MSG(_T("unknown arrow direction"));
3373 wxArrowStyle arrowStyle
;
3374 if ( flags
& wxCONTROL_PRESSED
)
3376 // can't be pressed and disabled
3377 arrowStyle
= Arrow_Pressed
;
3381 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3384 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3387 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3389 wxArrowDirection arrowDir
,
3390 wxArrowStyle arrowStyle
)
3392 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3394 // under Windows the arrows always have the same size so just centre it in
3395 // the provided rectangle
3396 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3397 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3399 // Windows does it like this...
3400 if ( arrowDir
== Arrow_Left
)
3404 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3407 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3408 const wxRect
& rectAll
,
3409 wxArrowDirection arrowDir
,
3410 wxArrowStyle arrowStyle
)
3412 wxRect rect
= rectAll
;
3413 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3414 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3415 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3418 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3419 wxOrientation
WXUNUSED(orient
),
3421 int WXUNUSED(flags
))
3423 // we don't use the flags, the thumb never changes appearance
3424 wxRect rectThumb
= rect
;
3425 DrawArrowBorder(dc
, &rectThumb
);
3426 DrawBackground(dc
, wxNullColour
, rectThumb
);
3429 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3430 wxOrientation
WXUNUSED(orient
),
3431 const wxRect
& rectBar
,
3434 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3435 ? wxColourScheme::SCROLLBAR_PRESSED
3436 : wxColourScheme::SCROLLBAR
;
3437 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3440 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3442 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3445 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3446 wxScrollBar::Element elem
,
3449 return StandardGetScrollbarRect(scrollbar
, elem
,
3450 thumbPos
, m_sizeScrollbarArrow
);
3453 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3455 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3458 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3459 const wxPoint
& pt
) const
3461 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3464 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3467 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3470 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3473 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3476 // ----------------------------------------------------------------------------
3477 // top level windows
3478 // ----------------------------------------------------------------------------
3480 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3482 wxRect client
= GetFrameClientArea(rect
, flags
);
3484 if ( client
.Inside(pt
) )
3485 return wxHT_TOPLEVEL_CLIENT_AREA
;
3487 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3489 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3491 if ( flags
& wxTOPLEVEL_ICON
)
3493 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3494 return wxHT_TOPLEVEL_ICON
;
3497 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3498 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3499 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3501 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3503 if ( btnRect
.Inside(pt
) )
3504 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3505 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3507 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3509 if ( btnRect
.Inside(pt
) )
3510 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3511 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3513 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3515 if ( btnRect
.Inside(pt
) )
3516 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3517 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3519 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3521 if ( btnRect
.Inside(pt
) )
3522 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3523 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3525 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3527 if ( btnRect
.Inside(pt
) )
3528 return wxHT_TOPLEVEL_BUTTON_HELP
;
3529 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3532 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3533 return wxHT_TOPLEVEL_TITLEBAR
;
3536 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3538 // we are certainly at one of borders, lets decide which one:
3541 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3542 if ( pt
.x
< client
.x
)
3543 border
|= wxHT_TOPLEVEL_BORDER_W
;
3544 else if ( pt
.x
>= client
.width
+ client
.x
)
3545 border
|= wxHT_TOPLEVEL_BORDER_E
;
3546 if ( pt
.y
< client
.y
)
3547 border
|= wxHT_TOPLEVEL_BORDER_N
;
3548 else if ( pt
.y
>= client
.height
+ client
.y
)
3549 border
|= wxHT_TOPLEVEL_BORDER_S
;
3553 return wxHT_NOWHERE
;
3556 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3558 const wxString
& title
,
3562 int specialButtonFlags
)
3564 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3566 DrawFrameBorder(dc
, rect
, flags
);
3568 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3570 DrawFrameBackground(dc
, rect
, flags
);
3571 if ( flags
& wxTOPLEVEL_ICON
)
3572 DrawFrameIcon(dc
, rect
, icon
, flags
);
3573 DrawFrameTitle(dc
, rect
, title
, flags
);
3575 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3577 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3578 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3580 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3582 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3583 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3584 specialButtonFlags
: 0);
3585 x
-= FRAME_BUTTON_WIDTH
+ 2;
3587 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3589 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3590 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3591 specialButtonFlags
: 0);
3592 x
-= FRAME_BUTTON_WIDTH
;
3594 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3596 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3597 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3598 specialButtonFlags
: 0);
3599 x
-= FRAME_BUTTON_WIDTH
;
3601 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3603 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3604 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3605 specialButtonFlags
: 0);
3606 x
-= FRAME_BUTTON_WIDTH
;
3608 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3610 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3611 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3612 specialButtonFlags
: 0);
3617 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3621 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3625 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3626 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3627 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3628 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3629 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3632 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3636 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3638 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3639 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3640 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3642 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3643 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3645 DrawBackground(dc
, col
, r
);
3648 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3650 const wxString
& title
,
3653 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3654 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3655 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3657 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3658 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3659 if ( flags
& wxTOPLEVEL_ICON
)
3661 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3662 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3670 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3671 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3672 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3673 r
.width
-= FRAME_BUTTON_WIDTH
;
3674 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3675 r
.width
-= FRAME_BUTTON_WIDTH
;
3676 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3677 r
.width
-= FRAME_BUTTON_WIDTH
;
3678 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3679 r
.width
-= FRAME_BUTTON_WIDTH
;
3681 dc
.SetFont(m_titlebarFont
);
3682 dc
.SetTextForeground(col
);
3685 dc
.GetTextExtent(title
, &textW
, NULL
);
3686 if ( textW
> r
.width
)
3688 // text is too big, let's shorten it and add "..." after it:
3689 size_t len
= title
.length();
3690 wxCoord WSoFar
, letterW
;
3692 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3693 if ( WSoFar
> r
.width
)
3695 // not enough space to draw anything
3701 for (size_t i
= 0; i
< len
; i
++)
3703 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3704 if ( letterW
+ WSoFar
> r
.width
)
3710 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3711 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3714 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3715 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3718 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3725 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3726 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3730 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3731 wxCoord x
, wxCoord y
,
3735 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3740 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3741 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3742 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3743 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3744 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3746 wxFAIL_MSG(wxT("incorrect button specification"));
3749 if ( flags
& wxCONTROL_PRESSED
)
3751 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3752 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3753 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3754 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3758 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3759 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3760 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3761 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3766 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3771 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3773 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3774 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3775 FRAME_BORDER_THICKNESS
;
3778 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3780 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3781 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3787 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3790 wxSize
s(clientSize
);
3792 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3794 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3795 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3796 FRAME_BORDER_THICKNESS
;
3800 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3801 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3806 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3810 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3812 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3813 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3814 FRAME_BORDER_THICKNESS
;
3819 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3821 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3823 if ( flags
& wxTOPLEVEL_ICON
)
3824 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3825 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3826 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3827 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3828 s
.x
+= FRAME_BUTTON_WIDTH
;
3829 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3830 s
.x
+= FRAME_BUTTON_WIDTH
;
3831 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3832 s
.x
+= FRAME_BUTTON_WIDTH
;
3833 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3834 s
.x
+= FRAME_BUTTON_WIDTH
;
3840 wxSize
wxWin32Renderer::GetFrameIconSize() const
3842 return wxSize(16, 16);
3846 // ----------------------------------------------------------------------------
3848 // ----------------------------------------------------------------------------
3850 static char *error_xpm
[]={
3857 "...........########.............",
3858 "........###aaaaaaaa###..........",
3859 ".......#aaaaaaaaaaaaaa#.........",
3860 ".....##aaaaaaaaaaaaaaaa##.......",
3861 "....#aaaaaaaaaaaaaaaaaaaa#......",
3862 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3863 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3864 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3865 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3866 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3867 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3868 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3869 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3870 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3871 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3872 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3873 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3874 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3875 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3876 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3877 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3878 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3879 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3880 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3881 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3882 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3883 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3884 "......b#aaaaaaaaaaaaaa#bbbbb....",
3885 ".......b###aaaaaaaa###bbbbb.....",
3886 ".........bb########bbbbbb.......",
3887 "..........bbbbbbbbbbbbbb........",
3888 ".............bbbbbbbb..........."};
3890 static char *info_xpm
[]={
3898 "...........########.............",
3899 "........###abbbbbba###..........",
3900 "......##abbbbbbbbbbbba##........",
3901 ".....#abbbbbbbbbbbbbbbba#.......",
3902 "....#bbbbbbbaccccabbbbbbbd......",
3903 "...#bbbbbbbbccccccbbbbbbbbd.....",
3904 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3905 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3906 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3907 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3908 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3909 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3910 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3911 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3912 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3913 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3914 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3915 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3916 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3917 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3918 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3919 ".....dabbbbbbbbbbbbbbbbad####...",
3920 "......ddabbbbbbbbbbbbadd####....",
3921 ".......#dddabbbbbbaddd#####.....",
3922 "........###dddabbbd#######......",
3923 "..........####dbbbd#####........",
3924 ".............#dbbbd##...........",
3925 "...............dbbd##...........",
3926 "................dbd##...........",
3927 ".................dd##...........",
3928 "..................###...........",
3929 "...................##..........."};
3931 static char *question_xpm
[]={
3939 "...........########.............",
3940 "........###abbbbbba###..........",
3941 "......##abbbbbbbbbbbba##........",
3942 ".....#abbbbbbbbbbbbbbbba#.......",
3943 "....#bbbbbbbbbbbbbbbbbbbbc......",
3944 "...#bbbbbbbaddddddabbbbbbbc.....",
3945 "..#bbbbbbbadabbddddabbbbbbbc....",
3946 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3947 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3948 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3949 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3950 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3951 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3952 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3953 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3954 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3955 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3956 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3957 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3958 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3959 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3960 ".....cabbbbbbbbbbbbbbbbac####...",
3961 "......ccabbbbbbbbbbbbacc####....",
3962 ".......#cccabbbbbbaccc#####.....",
3963 "........###cccabbbc#######......",
3964 "..........####cbbbc#####........",
3965 ".............#cbbbc##...........",
3966 "...............cbbc##...........",
3967 "................cbc##...........",
3968 ".................cc##...........",
3969 "..................###...........",
3970 "...................##..........."};
3972 static char *warning_xpm
[]={
3980 ".............###................",
3981 "............#aabc...............",
3982 "...........#aaaabcd.............",
3983 "...........#aaaaacdd............",
3984 "..........#aaaaaabcdd...........",
3985 "..........#aaaaaaacdd...........",
3986 ".........#aaaaaaaabcdd..........",
3987 ".........#aaaaaaaaacdd..........",
3988 "........#aaaaaaaaaabcdd.........",
3989 "........#aaabcccbaaacdd.........",
3990 ".......#aaaacccccaaabcdd........",
3991 ".......#aaaacccccaaaacdd........",
3992 "......#aaaaacccccaaaabcdd.......",
3993 "......#aaaaacccccaaaaacdd.......",
3994 ".....#aaaaaacccccaaaaabcdd......",
3995 ".....#aaaaaa#ccc#aaaaaacdd......",
3996 "....#aaaaaaabcccbaaaaaabcdd.....",
3997 "....#aaaaaaaacccaaaaaaaacdd.....",
3998 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3999 "...#aaaaaaaaabcbaaaaaaaaacdd....",
4000 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
4001 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
4002 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
4003 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
4004 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
4005 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
4006 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
4007 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
4008 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
4009 "..#ccccccccccccccccccccccccddddd",
4010 "....ddddddddddddddddddddddddddd.",
4011 ".....ddddddddddddddddddddddddd.."};
4013 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4014 const wxArtClient
& WXUNUSED(client
),
4015 const wxSize
& WXUNUSED(size
))
4017 if ( id
== wxART_INFORMATION
)
4018 return wxBitmap(info_xpm
);
4019 if ( id
== wxART_ERROR
)
4020 return wxBitmap(error_xpm
);
4021 if ( id
== wxART_WARNING
)
4022 return wxBitmap(warning_xpm
);
4023 if ( id
== wxART_QUESTION
)
4024 return wxBitmap(question_xpm
);
4025 return wxNullBitmap
;
4029 // ----------------------------------------------------------------------------
4030 // text control geometry
4031 // ----------------------------------------------------------------------------
4033 static inline int GetTextBorderWidth()
4039 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4040 const wxRect
& rect
) const
4042 wxRect rectTotal
= rect
;
4044 wxCoord widthBorder
= GetTextBorderWidth();
4045 rectTotal
.Inflate(widthBorder
);
4047 // this is what Windows does
4054 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4056 wxCoord
*extraSpaceBeyond
) const
4058 wxRect rectText
= rect
;
4060 // undo GetTextTotalArea()
4061 if ( rectText
.height
> 0 )
4064 wxCoord widthBorder
= GetTextBorderWidth();
4065 rectText
.Inflate(-widthBorder
);
4067 if ( extraSpaceBeyond
)
4068 *extraSpaceBeyond
= 0;
4073 // ----------------------------------------------------------------------------
4075 // ----------------------------------------------------------------------------
4077 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4080 if ( wxDynamicCast(window
, wxScrollBar
) )
4082 // we only set the width of vert scrollbars and height of the
4084 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4085 size
->y
= m_sizeScrollbarArrow
.y
;
4087 size
->x
= m_sizeScrollbarArrow
.x
;
4089 // skip border width adjustments, they don't make sense for us
4092 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4095 if ( wxDynamicCast(window
, wxButton
) )
4097 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4099 // TODO: don't harcode all this
4100 size
->x
+= 3*window
->GetCharWidth();
4102 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4103 if ( size
->y
< heightBtn
- 8 )
4104 size
->y
= heightBtn
;
4109 // for compatibility with other ports, the buttons default size is never
4110 // less than the standard one, but not when display not PDAs.
4111 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4113 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4115 wxSize szDef
= wxButton::GetDefaultSize();
4116 if ( size
->x
< szDef
.x
)
4121 // no border width adjustments for buttons
4124 #endif // wxUSE_BUTTON
4126 // take into account the border width
4127 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4128 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4129 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4132 // ============================================================================
4134 // ============================================================================
4136 // ----------------------------------------------------------------------------
4137 // wxWin32InputHandler
4138 // ----------------------------------------------------------------------------
4140 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4142 m_renderer
= renderer
;
4145 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4146 const wxKeyEvent
& WXUNUSED(event
),
4147 bool WXUNUSED(pressed
))
4152 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4153 const wxMouseEvent
& event
)
4155 // clicking on the control gives it focus
4156 if ( event
.ButtonDown() )
4158 wxWindow
*win
= control
->GetInputWindow();
4160 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4161 ( win
->AcceptsFocus() ) )
4172 // ----------------------------------------------------------------------------
4173 // wxWin32ScrollBarInputHandler
4174 // ----------------------------------------------------------------------------
4176 wxWin32ScrollBarInputHandler::
4177 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4178 wxInputHandler
*handler
)
4179 : wxStdScrollBarInputHandler(renderer
, handler
)
4181 m_scrollPaused
= FALSE
;
4185 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4186 const wxControlAction
& action
)
4188 // stop if went beyond the position of the original click (this can only
4189 // happen when we scroll by pages)
4191 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4193 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4194 != wxHT_SCROLLBAR_BAR_2
;
4196 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4198 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4199 != wxHT_SCROLLBAR_BAR_1
;
4204 StopScrolling(scrollbar
);
4206 scrollbar
->Refresh();
4211 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4214 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4215 const wxMouseEvent
& event
)
4217 // remember the current state
4218 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4220 // do process the message
4221 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4223 // analyse the changes
4224 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4226 // we just started dragging the thumb, remember its initial position to
4227 // be able to restore it if the drag is cancelled later
4228 m_eventStartDrag
= event
;
4234 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4235 const wxMouseEvent
& event
)
4237 // we don't highlight scrollbar elements, so there is no need to process
4238 // mouse move events normally - only do it while mouse is captured (i.e.
4239 // when we're dragging the thumb or pressing on something)
4240 if ( !m_winCapture
)
4243 if ( event
.Entering() )
4245 // we're not interested in this at all
4249 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4251 if ( m_scrollPaused
)
4253 // check if the mouse returned to its original location
4255 if ( event
.Leaving() )
4261 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4262 if ( ht
== m_htLast
)
4264 // yes it did, resume scrolling
4265 m_scrollPaused
= FALSE
;
4266 if ( m_timerScroll
)
4268 // we were scrolling by line/page, restart timer
4269 m_timerScroll
->Start(m_interval
);
4271 Press(scrollbar
, TRUE
);
4273 else // we were dragging the thumb
4275 // restore its last location
4276 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4282 else // normal case, scrolling hasn't been paused
4284 // if we're scrolling the scrollbar because the arrow or the shaft was
4285 // pressed, check that the mouse stays on the same scrollbar element
4288 // Always let thumb jump back if we leave the scrollbar
4289 if ( event
.Moving() )
4291 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4293 else // event.Leaving()
4298 // Jump back only if we get far away from it
4299 wxPoint pos
= event
.GetPosition();
4300 if (scrollbar
->HasFlag( wxVERTICAL
))
4302 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4307 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4310 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4313 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4314 // is still ok - we only want to catch the case when the mouse leaves
4315 // the scrollbar here
4316 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4318 ht
= wxHT_SCROLLBAR_THUMB
;
4321 if ( ht
!= m_htLast
)
4323 // what were we doing? 2 possibilities: either an arrow/shaft was
4324 // pressed in which case we have a timer and so we just stop it or
4325 // we were dragging the thumb
4326 if ( m_timerScroll
)
4329 m_interval
= m_timerScroll
->GetInterval();
4330 m_timerScroll
->Stop();
4331 m_scrollPaused
= TRUE
;
4333 // unpress the arrow
4334 Press(scrollbar
, FALSE
);
4336 else // we were dragging the thumb
4338 // remember the current thumb position to be able to restore it
4339 // if the mouse returns to it later
4340 m_eventLastDrag
= event
;
4342 // and restore the original position (before dragging) of the
4344 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4351 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4354 // ----------------------------------------------------------------------------
4355 // wxWin32CheckboxInputHandler
4356 // ----------------------------------------------------------------------------
4358 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4359 const wxKeyEvent
& event
,
4364 wxControlAction action
;
4365 int keycode
= event
.GetKeyCode();
4369 action
= wxACTION_CHECKBOX_TOGGLE
;
4373 case WXK_NUMPAD_SUBTRACT
:
4374 action
= wxACTION_CHECKBOX_CHECK
;
4378 case WXK_NUMPAD_ADD
:
4379 case WXK_NUMPAD_EQUAL
:
4380 action
= wxACTION_CHECKBOX_CLEAR
;
4386 control
->PerformAction(action
);
4395 // ----------------------------------------------------------------------------
4396 // wxWin32TextCtrlInputHandler
4397 // ----------------------------------------------------------------------------
4399 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4400 const wxKeyEvent
& event
,
4403 // handle only MSW-specific text bindings here, the others are handled in
4407 int keycode
= event
.GetKeyCode();
4409 wxControlAction action
;
4410 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4412 action
= wxACTION_TEXT_CUT
;
4414 else if ( keycode
== WXK_INSERT
)
4416 if ( event
.ControlDown() )
4417 action
= wxACTION_TEXT_COPY
;
4418 else if ( event
.ShiftDown() )
4419 action
= wxACTION_TEXT_PASTE
;
4422 if ( action
!= wxACTION_NONE
)
4424 control
->PerformAction(action
);
4430 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4433 // ----------------------------------------------------------------------------
4434 // wxWin32StatusBarInputHandler
4435 // ----------------------------------------------------------------------------
4437 wxWin32StatusBarInputHandler::
4438 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4439 : wxStdInputHandler(handler
)
4444 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4445 const wxPoint
& pt
) const
4447 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4448 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4451 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4453 wxCHECK_MSG( parentTLW
, FALSE
,
4454 _T("the status bar should be a child of a TLW") );
4456 // a maximized window can't be resized anyhow
4457 if ( !parentTLW
->IsMaximized() )
4459 // VZ: I think that the standard Windows behaviour is to only
4460 // show the resizing cursor when the mouse is on top of the
4461 // grip itself but apparently different Windows versions behave
4462 // differently (?) and it seems a better UI to allow resizing
4463 // the status bar even when the mouse is above the grip
4464 wxSize sizeSbar
= statbar
->GetSize();
4466 int diff
= sizeSbar
.x
- pt
.x
;
4467 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4474 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4475 const wxMouseEvent
& event
)
4477 if ( event
.Button(1) )
4479 if ( event
.ButtonDown(1) )
4481 wxWindow
*statbar
= consumer
->GetInputWindow();
4483 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4485 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4489 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4490 wxHT_TOPLEVEL_BORDER_SE
);
4492 statbar
->SetCursor(m_cursorOld
);
4500 return wxStdInputHandler::HandleMouse(consumer
, event
);
4503 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4504 const wxMouseEvent
& event
)
4506 wxWindow
*statbar
= consumer
->GetInputWindow();
4508 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4509 if ( isOnGrip
!= m_isOnGrip
)
4511 m_isOnGrip
= isOnGrip
;
4514 m_cursorOld
= statbar
->GetCursor();
4515 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4519 statbar
->SetCursor(m_cursorOld
);
4523 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4526 // ----------------------------------------------------------------------------
4527 // wxWin32FrameInputHandler
4528 // ----------------------------------------------------------------------------
4530 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4533 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4535 void Attach(wxInputConsumer
*consumer
);
4539 DECLARE_EVENT_TABLE()
4540 void OnSystemMenu(wxCommandEvent
&event
);
4541 void OnCloseFrame(wxCommandEvent
&event
);
4542 void OnClose(wxCloseEvent
&event
);
4544 wxWin32FrameInputHandler
*m_inputHnd
;
4545 wxTopLevelWindow
*m_wnd
;
4546 wxAcceleratorTable m_oldAccelTable
;
4549 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4550 wxWin32FrameInputHandler
*handler
)
4552 m_inputHnd
= handler
;
4556 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4558 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4560 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4561 m_wnd
->PushEventHandler(this);
4563 // VS: This code relies on using generic implementation of
4564 // wxAcceleratorTable in wxUniv!
4565 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4566 m_oldAccelTable
= table
;
4567 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4568 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4569 m_wnd
->SetAcceleratorTable(table
);
4572 void wxWin32SystemMenuEvtHandler::Detach()
4576 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4577 m_wnd
->RemoveEventHandler(this);
4582 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4583 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4584 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4585 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4588 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4590 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4591 !m_wnd
->IsMaximized()) ?
4592 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4593 FRAME_BORDER_THICKNESS
;
4594 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4595 pt
.x
= -pt
.x
+ border
;
4596 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4598 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4599 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4600 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4601 m_wnd
->SetAcceleratorTable(table
);
4604 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4606 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4607 wxTOPLEVEL_BUTTON_CLOSE
);
4610 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4617 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4618 : wxStdFrameInputHandler(handler
)
4620 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4623 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4625 if ( m_menuHandler
)
4627 m_menuHandler
->Detach();
4628 delete m_menuHandler
;
4632 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4633 const wxMouseEvent
& event
)
4635 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4637 wxTopLevelWindow
*tlw
=
4638 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4640 long hit
= tlw
->HitTest(event
.GetPosition());
4642 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4644 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4645 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4646 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4649 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4651 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4652 (event
.RightDown() &&
4653 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4654 hit
== wxHT_TOPLEVEL_ICON
)) )
4656 PopupSystemMenu(tlw
, event
.GetPosition());
4662 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4665 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4666 const wxPoint
& pos
) const
4668 wxMenu
*menu
= new wxMenu
;
4670 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4671 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4672 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4673 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4674 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4675 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4676 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4677 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4678 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4679 menu
->AppendSeparator();
4680 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4682 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4684 if ( window
->IsMaximized() )
4686 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4687 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4688 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4689 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4692 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4695 window
->PopupMenu(menu
, pos
);
4699 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4702 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4704 // always detach if active frame changed:
4705 m_menuHandler
->Detach();
4709 m_menuHandler
->Attach(consumer
);
4713 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);