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/toolbar.h"
44 // for COLOR_* constants
45 #include "wx/msw/private.h"
49 #include "wx/notebook.h"
50 #include "wx/spinbutt.h"
51 #include "wx/settings.h"
53 #include "wx/artprov.h"
54 #include "wx/toplevel.h"
56 #include "wx/univ/scrtimer.h"
57 #include "wx/univ/renderer.h"
58 #include "wx/univ/inphand.h"
59 #include "wx/univ/colschem.h"
60 #include "wx/univ/theme.h"
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 static const int BORDER_THICKNESS
= 2;
68 // the offset between the label and focus rect around it
69 static const int FOCUS_RECT_OFFSET_X
= 1;
70 static const int FOCUS_RECT_OFFSET_Y
= 1;
72 static const int FRAME_BORDER_THICKNESS
= 3;
73 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
74 static const int FRAME_TITLEBAR_HEIGHT
= 18;
75 static const int FRAME_BUTTON_WIDTH
= 16;
76 static const int FRAME_BUTTON_HEIGHT
= 14;
78 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
79 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
80 static const size_t STATUSBAR_GRIP_SIZE
=
81 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
83 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
84 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
85 static const wxCoord SLIDER_TICK_LENGTH
= 6;
97 IndicatorState_Normal
,
98 IndicatorState_Pressed
, // this one is for check/radioboxes
99 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
100 IndicatorState_Disabled
,
101 IndicatorState_SelectedDisabled
, // only for the menus
107 IndicatorStatus_Checked
,
108 IndicatorStatus_Unchecked
,
112 // wxWin32Renderer: draw the GUI elements in Win32 style
113 // ----------------------------------------------------------------------------
115 class wxWin32Renderer
: public wxRenderer
119 enum wxArrowDirection
134 Arrow_InversedDisabled
,
138 enum wxFrameButtonType
141 FrameButton_Minimize
,
142 FrameButton_Maximize
,
149 wxWin32Renderer(const wxColourScheme
*scheme
);
151 // implement the base class pure virtuals
152 virtual void DrawBackground(wxDC
& dc
,
156 wxWindow
*window
= NULL
);
157 virtual void DrawLabel(wxDC
& dc
,
158 const wxString
& label
,
161 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
163 wxRect
*rectBounds
= NULL
);
164 virtual void DrawButtonLabel(wxDC
& dc
,
165 const wxString
& label
,
166 const wxBitmap
& image
,
169 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
171 wxRect
*rectBounds
= NULL
);
172 virtual void DrawBorder(wxDC
& dc
,
176 wxRect
*rectIn
= (wxRect
*)NULL
);
177 virtual void DrawHorizontalLine(wxDC
& dc
,
178 wxCoord y
, wxCoord x1
, wxCoord x2
);
179 virtual void DrawVerticalLine(wxDC
& dc
,
180 wxCoord x
, wxCoord y1
, wxCoord y2
);
181 virtual void DrawFrame(wxDC
& dc
,
182 const wxString
& label
,
185 int alignment
= wxALIGN_LEFT
,
186 int indexAccel
= -1);
187 virtual void DrawTextBorder(wxDC
& dc
,
191 wxRect
*rectIn
= (wxRect
*)NULL
);
192 virtual void DrawButtonBorder(wxDC
& dc
,
195 wxRect
*rectIn
= (wxRect
*)NULL
);
196 virtual void DrawArrow(wxDC
& dc
,
200 virtual void DrawScrollbarArrow(wxDC
& dc
,
204 { DrawArrow(dc
, dir
, rect
, flags
); }
205 virtual void DrawScrollbarThumb(wxDC
& dc
,
206 wxOrientation orient
,
209 virtual void DrawScrollbarShaft(wxDC
& dc
,
210 wxOrientation orient
,
213 virtual void DrawScrollCorner(wxDC
& dc
,
215 virtual void DrawItem(wxDC
& dc
,
216 const wxString
& label
,
219 virtual void DrawCheckItem(wxDC
& dc
,
220 const wxString
& label
,
221 const wxBitmap
& bitmap
,
224 virtual void DrawCheckButton(wxDC
& dc
,
225 const wxString
& label
,
226 const wxBitmap
& bitmap
,
229 wxAlignment align
= wxALIGN_LEFT
,
230 int indexAccel
= -1);
231 virtual void DrawRadioButton(wxDC
& dc
,
232 const wxString
& label
,
233 const wxBitmap
& bitmap
,
236 wxAlignment align
= wxALIGN_LEFT
,
237 int indexAccel
= -1);
238 virtual void DrawToolBarButton(wxDC
& dc
,
239 const wxString
& label
,
240 const wxBitmap
& bitmap
,
244 virtual void DrawTextLine(wxDC
& dc
,
245 const wxString
& text
,
250 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
251 virtual void DrawTab(wxDC
& dc
,
254 const wxString
& label
,
255 const wxBitmap
& bitmap
= wxNullBitmap
,
257 int indexAccel
= -1);
259 virtual void DrawSliderShaft(wxDC
& dc
,
262 wxOrientation orient
,
265 wxRect
*rectShaft
= NULL
);
266 virtual void DrawSliderThumb(wxDC
& dc
,
268 wxOrientation orient
,
271 virtual void DrawSliderTicks(wxDC
& dc
,
274 wxOrientation orient
,
281 virtual void DrawMenuBarItem(wxDC
& dc
,
283 const wxString
& label
,
285 int indexAccel
= -1);
286 virtual void DrawMenuItem(wxDC
& dc
,
288 const wxMenuGeometryInfo
& geometryInfo
,
289 const wxString
& label
,
290 const wxString
& accel
,
291 const wxBitmap
& bitmap
= wxNullBitmap
,
293 int indexAccel
= -1);
294 virtual void DrawMenuSeparator(wxDC
& dc
,
296 const wxMenuGeometryInfo
& geomInfo
);
298 virtual void DrawStatusField(wxDC
& dc
,
300 const wxString
& label
,
304 virtual void DrawFrameTitleBar(wxDC
& dc
,
306 const wxString
& title
,
309 int specialButton
= 0,
310 int specialButtonFlags
= 0);
311 virtual void DrawFrameBorder(wxDC
& dc
,
314 virtual void DrawFrameBackground(wxDC
& dc
,
317 virtual void DrawFrameTitle(wxDC
& dc
,
319 const wxString
& title
,
321 virtual void DrawFrameIcon(wxDC
& dc
,
325 virtual void DrawFrameButton(wxDC
& dc
,
326 wxCoord x
, wxCoord y
,
329 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
330 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
331 virtual wxSize
GetFrameMinSize(int flags
) const;
332 virtual wxSize
GetFrameIconSize() const;
333 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
335 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
337 wxBitmap
*bmpPressed
,
338 wxBitmap
*bmpDisabled
);
340 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
341 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
342 virtual bool AreScrollbarsInsideBorder() const;
344 virtual wxSize
GetScrollbarArrowSize() const
345 { return m_sizeScrollbarArrow
; }
346 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
347 wxScrollBar::Element elem
,
348 int thumbPos
= -1) const;
349 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
350 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
351 const wxPoint
& pt
) const;
352 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
354 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
355 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
356 { return fontHeight
+ 2; }
357 virtual wxSize
GetCheckBitmapSize() const
358 { return wxSize(13, 13); }
359 virtual wxSize
GetRadioBitmapSize() const
360 { return wxSize(12, 12); }
361 virtual wxCoord
GetCheckItemMargin() const
364 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
365 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
366 virtual wxSize
GetToolBarMargin() const
367 { return wxSize(4, 4); }
369 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
370 const wxRect
& rect
) const;
371 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
373 wxCoord
*extraSpaceBeyond
) const;
375 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
376 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
378 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
379 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
380 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
382 wxOrientation orient
,
383 long style
= 0) const;
384 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
386 wxOrientation orient
) const;
387 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
389 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
390 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
391 const wxMenu
& menu
) const;
393 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
396 // helper of DrawLabel() and DrawCheckOrRadioButton()
397 void DoDrawLabel(wxDC
& dc
,
398 const wxString
& label
,
401 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
403 wxRect
*rectBounds
= NULL
,
404 const wxPoint
& focusOffset
405 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
407 // common part of DrawLabel() and DrawItem()
408 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
410 // DrawLabel() and DrawButtonLabel() helper
411 void DrawLabelShadow(wxDC
& dc
,
412 const wxString
& label
,
417 // DrawButtonBorder() helper
418 void DoDrawBackground(wxDC
& dc
,
421 wxWindow
*window
= NULL
);
423 // DrawBorder() helpers: all of them shift and clip the DC after drawing
426 // just draw a rectangle with the given pen
427 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
429 // draw the lower left part of rectangle
430 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
432 // draw the rectange using the first brush for the left and top sides and
433 // the second one for the bottom and right ones
434 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
435 const wxPen
& pen1
, const wxPen
& pen2
);
437 // draw the normal 3D border
438 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
440 // draw the sunken 3D border
441 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
443 // draw the border used for scrollbar arrows
444 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= FALSE
);
446 // public DrawArrow()s helper
447 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
448 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
450 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
451 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
452 wxArrowDirection arrowDir
,
453 wxArrowStyle arrowStyle
);
455 // DrawCheckButton/DrawRadioButton helper
456 void DrawCheckOrRadioButton(wxDC
& dc
,
457 const wxString
& label
,
458 const wxBitmap
& bitmap
,
463 wxCoord focusOffsetY
);
465 // draw a normal or transposed line (useful for using the same code fo both
466 // horizontal and vertical widgets)
467 void DrawLine(wxDC
& dc
,
468 wxCoord x1
, wxCoord y1
,
469 wxCoord x2
, wxCoord y2
,
470 bool transpose
= FALSE
)
473 dc
.DrawLine(y1
, x1
, y2
, x2
);
475 dc
.DrawLine(x1
, y1
, x2
, y2
);
478 // get the standard check/radio button bitmap
479 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
480 wxBitmap
GetCheckBitmap(int flags
)
481 { return GetIndicator(IndicatorType_Check
, flags
); }
482 wxBitmap
GetRadioBitmap(int flags
)
483 { return GetIndicator(IndicatorType_Radio
, flags
); }
486 const wxColourScheme
*m_scheme
;
488 // the sizing parameters (TODO make them changeable)
489 wxSize m_sizeScrollbarArrow
;
491 // GDI objects we use for drawing
492 wxColour m_colDarkGrey
,
500 wxFont m_titlebarFont
;
502 // the checked and unchecked bitmaps for DrawCheckItem()
503 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
505 // the bitmaps returned by GetIndicator()
506 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
508 [IndicatorStatus_Max
];
511 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
513 // first row is for the normal state, second - for the disabled
514 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
517 // ----------------------------------------------------------------------------
518 // wxWin32InputHandler and derived classes: process the keyboard and mouse
519 // messages according to Windows standards
520 // ----------------------------------------------------------------------------
522 class wxWin32InputHandler
: public wxInputHandler
525 wxWin32InputHandler(wxWin32Renderer
*renderer
);
527 virtual bool HandleKey(wxInputConsumer
*control
,
528 const wxKeyEvent
& event
,
530 virtual bool HandleMouse(wxInputConsumer
*control
,
531 const wxMouseEvent
& event
);
534 wxWin32Renderer
*m_renderer
;
537 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
540 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
541 wxInputHandler
*handler
);
543 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
544 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
546 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
547 const wxControlAction
& action
);
550 virtual bool IsAllowedButton(int button
) { return button
== 1; }
552 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
555 // we don't highlight anything
558 // the first and last event which caused the thumb to move
559 wxMouseEvent m_eventStartDrag
,
562 // have we paused the scrolling because the mouse moved?
565 // we remember the interval of the timer to be able to restart it
569 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
572 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
573 : wxStdCheckboxInputHandler(handler
) { }
575 virtual bool HandleKey(wxInputConsumer
*control
,
576 const wxKeyEvent
& event
,
580 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
583 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
584 : wxStdTextCtrlInputHandler(handler
) { }
586 virtual bool HandleKey(wxInputConsumer
*control
,
587 const wxKeyEvent
& event
,
591 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
594 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
596 virtual bool HandleMouse(wxInputConsumer
*consumer
,
597 const wxMouseEvent
& event
);
599 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
600 const wxMouseEvent
& event
);
603 // is the given point over the statusbar grip?
604 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
607 // the cursor we had replaced with the resize one
608 wxCursor m_cursorOld
;
610 // was the mouse over the grip last time we checked?
614 class wxWin32SystemMenuEvtHandler
;
616 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
619 wxWin32FrameInputHandler(wxInputHandler
*handler
);
620 ~wxWin32FrameInputHandler();
622 virtual bool HandleMouse(wxInputConsumer
*control
,
623 const wxMouseEvent
& event
);
625 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
627 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
630 // was the mouse over the grip last time we checked?
631 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
634 // ----------------------------------------------------------------------------
635 // wxWin32ColourScheme: uses (default) Win32 colours
636 // ----------------------------------------------------------------------------
638 class wxWin32ColourScheme
: public wxColourScheme
641 virtual wxColour
Get(StdColour col
) const;
642 virtual wxColour
GetBackground(wxWindow
*win
) const;
645 // ----------------------------------------------------------------------------
646 // wxWin32ArtProvider
647 // ----------------------------------------------------------------------------
649 class wxWin32ArtProvider
: public wxArtProvider
652 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
653 const wxArtClient
& client
,
657 // ----------------------------------------------------------------------------
659 // ----------------------------------------------------------------------------
661 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
663 class wxWin32Theme
: public wxTheme
667 virtual ~wxWin32Theme();
669 virtual wxRenderer
*GetRenderer();
670 virtual wxArtProvider
*GetArtProvider();
671 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
672 virtual wxColourScheme
*GetColourScheme();
675 // get the default input handler
676 wxInputHandler
*GetDefaultInputHandler();
678 wxWin32Renderer
*m_renderer
;
680 wxWin32ArtProvider
*m_artProvider
;
682 // the names of the already created handlers and the handlers themselves
683 // (these arrays are synchronized)
684 wxSortedArrayString m_handlerNames
;
685 wxArrayHandlers m_handlers
;
687 wxWin32InputHandler
*m_handlerDefault
;
689 wxWin32ColourScheme
*m_scheme
;
691 WX_DECLARE_THEME(win32
)
694 // ----------------------------------------------------------------------------
696 // ----------------------------------------------------------------------------
698 // frame buttons bitmaps
700 static const char *frame_button_close_xpm
[] = {
715 static const char *frame_button_help_xpm
[] = {
730 static const char *frame_button_maximize_xpm
[] = {
745 static const char *frame_button_minimize_xpm
[] = {
760 static const char *frame_button_restore_xpm
[] = {
777 static const char *checked_menu_xpm
[] = {
778 /* columns rows colors chars-per-pixel */
794 static const char *selected_checked_menu_xpm
[] = {
795 /* columns rows colors chars-per-pixel */
811 static const char *disabled_checked_menu_xpm
[] = {
812 /* columns rows colors chars-per-pixel */
829 static const char *selected_disabled_checked_menu_xpm
[] = {
830 /* columns rows colors chars-per-pixel */
846 // checkbox and radiobox bitmaps below
848 static const char *checked_xpm
[] = {
849 /* columns rows colors chars-per-pixel */
872 static const char *pressed_checked_xpm
[] = {
873 /* columns rows colors chars-per-pixel */
895 static const char *pressed_disabled_checked_xpm
[] = {
896 /* columns rows colors chars-per-pixel */
918 static const char *checked_item_xpm
[] = {
919 /* columns rows colors chars-per-pixel */
940 static const char *unchecked_xpm
[] = {
941 /* columns rows colors chars-per-pixel */
964 static const char *pressed_unchecked_xpm
[] = {
965 /* columns rows colors chars-per-pixel */
987 static const char *unchecked_item_xpm
[] = {
988 /* columns rows colors chars-per-pixel */
1008 static const char *checked_radio_xpm
[] = {
1009 /* columns rows colors chars-per-pixel */
1032 static const char *pressed_checked_radio_xpm
[] = {
1033 /* columns rows colors chars-per-pixel */
1056 static const char *pressed_disabled_checked_radio_xpm
[] = {
1057 /* columns rows colors chars-per-pixel */
1080 static const char *unchecked_radio_xpm
[] = {
1081 /* columns rows colors chars-per-pixel */
1104 static const char *pressed_unchecked_radio_xpm
[] = {
1105 /* columns rows colors chars-per-pixel */
1128 static const char **
1129 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1134 { checked_xpm
, unchecked_xpm
},
1137 { pressed_checked_xpm
, pressed_unchecked_xpm
},
1140 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
},
1146 { checked_radio_xpm
, unchecked_radio_xpm
},
1149 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1152 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
},
1158 { checked_menu_xpm
, NULL
},
1161 { selected_checked_menu_xpm
, NULL
},
1164 { disabled_checked_menu_xpm
, NULL
},
1166 // disabled selected state
1167 { selected_disabled_checked_menu_xpm
, NULL
},
1171 static const char **xpmChecked
[IndicatorStatus_Max
] =
1177 // ============================================================================
1179 // ============================================================================
1181 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1183 // ----------------------------------------------------------------------------
1185 // ----------------------------------------------------------------------------
1187 wxWin32Theme::wxWin32Theme()
1191 m_handlerDefault
= NULL
;
1192 m_artProvider
= NULL
;
1195 wxWin32Theme::~wxWin32Theme()
1197 size_t count
= m_handlers
.GetCount();
1198 for ( size_t n
= 0; n
< count
; n
++ )
1200 if ( m_handlers
[n
] != m_handlerDefault
)
1201 delete m_handlers
[n
];
1204 delete m_handlerDefault
;
1208 wxArtProvider::RemoveProvider(m_artProvider
);
1211 wxRenderer
*wxWin32Theme::GetRenderer()
1215 m_renderer
= new wxWin32Renderer(GetColourScheme());
1221 wxArtProvider
*wxWin32Theme::GetArtProvider()
1223 if ( !m_artProvider
)
1225 m_artProvider
= new wxWin32ArtProvider
;
1228 return m_artProvider
;
1231 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1233 if ( !m_handlerDefault
)
1235 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1238 return m_handlerDefault
;
1241 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1243 wxInputHandler
*handler
;
1244 int n
= m_handlerNames
.Index(control
);
1245 if ( n
== wxNOT_FOUND
)
1247 // create a new handler
1248 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1249 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1250 GetDefaultInputHandler());
1252 else if ( control
== wxINP_HANDLER_BUTTON
)
1253 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1254 #endif // wxUSE_BUTTON
1256 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1257 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1258 #endif // wxUSE_CHECKBOX
1260 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1261 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1262 #endif // wxUSE_COMBOBOX
1264 else if ( control
== wxINP_HANDLER_LISTBOX
)
1265 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1266 #endif // wxUSE_LISTBOX
1267 #if wxUSE_CHECKLISTBOX
1268 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1269 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1270 #endif // wxUSE_CHECKLISTBOX
1272 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1273 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1274 #endif // wxUSE_TEXTCTRL
1276 else if ( control
== wxINP_HANDLER_SLIDER
)
1277 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1278 #endif // wxUSE_SLIDER
1280 else if ( control
== wxINP_HANDLER_SPINBTN
)
1281 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1282 #endif // wxUSE_SPINBTN
1284 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1285 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1286 #endif // wxUSE_NOTEBOOK
1288 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1289 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1290 #endif // wxUSE_STATUSBAR
1292 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1293 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1294 #endif // wxUSE_TOOLBAR
1295 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1296 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1298 handler
= GetDefaultInputHandler();
1300 n
= m_handlerNames
.Add(control
);
1301 m_handlers
.Insert(handler
, n
);
1303 else // we already have it
1305 handler
= m_handlers
[n
];
1311 wxColourScheme
*wxWin32Theme::GetColourScheme()
1315 m_scheme
= new wxWin32ColourScheme
;
1320 // ============================================================================
1321 // wxWin32ColourScheme
1322 // ============================================================================
1324 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1327 if ( win
->UseBgCol() )
1329 // use the user specified colour
1330 col
= win
->GetBackgroundColour();
1333 if ( !win
->ShouldInheritColours() )
1335 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1338 if ( !text
->IsEnabled() ) // not IsEditable()
1340 //else: execute code below
1345 // doesn't depend on the state
1351 int flags
= win
->GetStateFlags();
1353 // the colour set by the user should be used for the normal state
1354 // and for the states for which we don't have any specific colours
1355 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1357 if ( wxDynamicCast(win
, wxScrollBar
) )
1358 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1368 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1372 // use the system colours under Windows
1373 #if defined(__WXMSW__)
1374 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1376 case CONTROL_PRESSED
:
1377 case CONTROL_CURRENT
:
1378 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1380 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1382 #if defined(COLOR_3DLIGHT)
1383 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1385 case SCROLLBAR
: return wxColour(0xe0e0e0);
1387 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1389 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1390 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1392 #if defined(COLOR_3DDKSHADOW)
1393 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1395 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1398 case CONTROL_TEXT_DISABLED
:
1399 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1401 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1403 case CONTROL_TEXT_DISABLED_SHADOW
:
1404 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1406 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1407 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1408 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1409 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1411 case DESKTOP
: return wxColour(0x808000);
1413 // use the standard Windows colours elsewhere
1414 case WINDOW
: return *wxWHITE
;
1416 case CONTROL_PRESSED
:
1417 case CONTROL_CURRENT
:
1418 case CONTROL
: return wxColour(0xc0c0c0);
1420 case CONTROL_TEXT
: return *wxBLACK
;
1422 case SCROLLBAR
: return wxColour(0xe0e0e0);
1423 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1425 case HIGHLIGHT
: return wxColour(0x800000);
1426 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1428 case SHADOW_DARK
: return *wxBLACK
;
1430 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1431 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1433 case SHADOW_IN
: return wxColour(0xc0c0c0);
1435 case CONTROL_TEXT_DISABLED_SHADOW
:
1436 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1438 case TITLEBAR
: return wxColour(0xaeaaae);
1439 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1440 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1441 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1443 case DESKTOP
: return wxColour(0x808000);
1446 case GAUGE
: return Get(HIGHLIGHT
);
1450 wxFAIL_MSG(_T("invalid standard colour"));
1455 // ============================================================================
1457 // ============================================================================
1459 // ----------------------------------------------------------------------------
1461 // ----------------------------------------------------------------------------
1463 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1467 m_sizeScrollbarArrow
= wxSize(16, 16);
1469 // init colours and pens
1470 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1472 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1473 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1475 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1477 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1478 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1480 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1481 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1483 // init the arrow bitmaps
1484 static const size_t ARROW_WIDTH
= 7;
1485 static const size_t ARROW_LENGTH
= 4;
1488 wxMemoryDC dcNormal
,
1491 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1493 bool isVertical
= n
> Arrow_Right
;
1506 // disabled arrow is larger because of the shadow
1507 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1508 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1510 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1511 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1513 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1514 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1518 dcNormal
.SetPen(m_penBlack
);
1519 dcDisabled
.SetPen(m_penDarkGrey
);
1521 // calculate the position of the point of the arrow
1525 x1
= (ARROW_WIDTH
- 1)/2;
1526 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1530 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1531 y1
= (ARROW_WIDTH
- 1)/2;
1542 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1544 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1545 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1552 if ( n
== Arrow_Up
)
1563 else // left or right arrow
1568 if ( n
== Arrow_Left
)
1581 // draw the shadow for the disabled one
1582 dcDisabled
.SetPen(m_penHighlight
);
1587 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1591 x1
= ARROW_LENGTH
- 1;
1592 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1595 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1596 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1601 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1605 x1
= ARROW_WIDTH
- 1;
1607 x2
= (ARROW_WIDTH
- 1)/2;
1609 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1610 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1615 // create the inversed bitmap but only for the right arrow as we only
1616 // use it for the menus
1617 if ( n
== Arrow_Right
)
1619 m_bmpArrows
[Arrow_Inversed
][n
].Create(w
, h
);
1620 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inversed
][n
]);
1622 dcInverse
.Blit(0, 0, w
, h
,
1625 dcInverse
.SelectObject(wxNullBitmap
);
1627 mask
= new wxMask(m_bmpArrows
[Arrow_Inversed
][n
], *wxBLACK
);
1628 m_bmpArrows
[Arrow_Inversed
][n
].SetMask(mask
);
1630 m_bmpArrows
[Arrow_InversedDisabled
][n
].Create(w
, h
);
1631 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InversedDisabled
][n
]);
1633 dcInverse
.Blit(0, 0, w
, h
,
1636 dcInverse
.SelectObject(wxNullBitmap
);
1638 mask
= new wxMask(m_bmpArrows
[Arrow_InversedDisabled
][n
], *wxBLACK
);
1639 m_bmpArrows
[Arrow_InversedDisabled
][n
].SetMask(mask
);
1642 dcNormal
.SelectObject(wxNullBitmap
);
1643 dcDisabled
.SelectObject(wxNullBitmap
);
1645 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1646 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1647 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1648 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1650 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1653 // init the frame buttons bitmaps
1654 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1655 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1656 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1657 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1658 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1661 // ----------------------------------------------------------------------------
1663 // ----------------------------------------------------------------------------
1666 The raised border in Win32 looks like this:
1668 IIIIIIIIIIIIIIIIIIIIIIB
1670 I GB I = white (HILIGHT)
1671 I GB H = light grey (LIGHT)
1672 I GB G = dark grey (SHADOI)
1673 I GB B = black (DKSHADOI)
1674 I GB I = hIghlight (COLOR_3DHILIGHT)
1676 IGGGGGGGGGGGGGGGGGGGGGB
1677 BBBBBBBBBBBBBBBBBBBBBBB
1679 The sunken border looks like this:
1681 GGGGGGGGGGGGGGGGGGGGGGI
1682 GBBBBBBBBBBBBBBBBBBBBHI
1689 GHHHHHHHHHHHHHHHHHHHHHI
1690 IIIIIIIIIIIIIIIIIIIIIII
1692 The static border (used for the controls which don't get focus) is like
1695 GGGGGGGGGGGGGGGGGGGGGGW
1703 WWWWWWWWWWWWWWWWWWWWWWW
1705 The most complicated is the double border:
1707 HHHHHHHHHHHHHHHHHHHHHHB
1708 HWWWWWWWWWWWWWWWWWWWWGB
1709 HWHHHHHHHHHHHHHHHHHHHGB
1714 HWHHHHHHHHHHHHHHHHHHHGB
1715 HGGGGGGGGGGGGGGGGGGGGGB
1716 BBBBBBBBBBBBBBBBBBBBBBB
1718 And the simple border is, well, simple:
1720 BBBBBBBBBBBBBBBBBBBBBBB
1729 BBBBBBBBBBBBBBBBBBBBBBB
1732 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1736 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1737 dc
.DrawRectangle(*rect
);
1743 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1745 // draw the bottom and right sides
1747 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1748 rect
->GetRight() + 1, rect
->GetBottom());
1749 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1750 rect
->GetRight(), rect
->GetBottom());
1756 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1757 const wxPen
& pen1
, const wxPen
& pen2
)
1759 // draw the rectangle
1761 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1762 rect
->GetLeft(), rect
->GetBottom());
1763 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1764 rect
->GetRight(), rect
->GetTop());
1766 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1767 rect
->GetRight(), rect
->GetBottom());
1768 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1769 rect
->GetRight() + 1, rect
->GetBottom());
1775 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1777 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1778 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1781 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1783 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1784 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1787 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1791 DrawRect(dc
, rect
, m_penDarkGrey
);
1793 // the arrow is usually drawn inside border of width 2 and is offset by
1794 // another pixel in both directions when it's pressed - as the border
1795 // in this case is more narrow as well, we have to adjust rect like
1803 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1804 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1808 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1810 const wxRect
& rectTotal
,
1811 int WXUNUSED(flags
),
1816 wxRect rect
= rectTotal
;
1820 case wxBORDER_SUNKEN
:
1821 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1823 DrawSunkenBorder(dc
, &rect
);
1827 case wxBORDER_STATIC
:
1828 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1831 case wxBORDER_RAISED
:
1832 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1834 DrawRaisedBorder(dc
, &rect
);
1838 case wxBORDER_DOUBLE
:
1839 DrawArrowBorder(dc
, &rect
);
1840 DrawRect(dc
, &rect
, m_penLightGrey
);
1843 case wxBORDER_SIMPLE
:
1844 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1846 DrawRect(dc
, &rect
, m_penBlack
);
1851 wxFAIL_MSG(_T("unknown border type"));
1854 case wxBORDER_DEFAULT
:
1863 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1868 case wxBORDER_RAISED
:
1869 case wxBORDER_SUNKEN
:
1870 width
= BORDER_THICKNESS
;
1873 case wxBORDER_SIMPLE
:
1874 case wxBORDER_STATIC
:
1878 case wxBORDER_DOUBLE
:
1884 // char *crash = NULL;
1886 wxFAIL_MSG(_T("unknown border type"));
1890 case wxBORDER_DEFAULT
:
1900 rect
.height
= width
;
1905 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1910 // ----------------------------------------------------------------------------
1912 // ----------------------------------------------------------------------------
1914 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1920 // text controls are not special under windows
1921 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1924 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1925 const wxRect
& rectTotal
,
1929 wxRect rect
= rectTotal
;
1931 if ( flags
& wxCONTROL_PRESSED
)
1933 // button pressed: draw a double border around it
1934 DrawRect(dc
, &rect
, m_penBlack
);
1935 DrawRect(dc
, &rect
, m_penDarkGrey
);
1939 // button not pressed
1941 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1943 // button either default or focused (or both): add an extra border around it
1944 DrawRect(dc
, &rect
, m_penBlack
);
1947 // now draw a normal button
1948 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
1949 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
1958 // ----------------------------------------------------------------------------
1960 // ----------------------------------------------------------------------------
1962 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
1963 wxCoord y
, wxCoord x1
, wxCoord x2
)
1965 dc
.SetPen(m_penDarkGrey
);
1966 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1967 dc
.SetPen(m_penHighlight
);
1969 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
1972 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
1973 wxCoord x
, wxCoord y1
, wxCoord y2
)
1975 dc
.SetPen(m_penDarkGrey
);
1976 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1977 dc
.SetPen(m_penHighlight
);
1979 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
1982 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
1983 const wxString
& label
,
1989 wxCoord height
= 0; // of the label
1990 wxRect rectFrame
= rect
;
1991 if ( !label
.empty() )
1993 // the text should touch the top border of the rect, so the frame
1994 // itself should be lower
1995 dc
.GetTextExtent(label
, NULL
, &height
);
1996 rectFrame
.y
+= height
/ 2;
1997 rectFrame
.height
-= height
/ 2;
1999 // we have to draw each part of the frame individually as we can't
2000 // erase the background beyond the label as it might contain some
2001 // pixmap already, so drawing everything and then overwriting part of
2002 // the frame with label doesn't work
2004 // TODO: the +5 and space insertion should be customizable
2007 rectText
.x
= rectFrame
.x
+ 5;
2008 rectText
.y
= rect
.y
;
2009 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2010 rectText
.height
= height
;
2013 label2
<< _T(' ') << label
<< _T(' ');
2014 if ( indexAccel
!= -1 )
2016 // adjust it as we prepended a space
2021 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2023 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2027 // just draw the complete frame
2028 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2029 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2033 // ----------------------------------------------------------------------------
2035 // ----------------------------------------------------------------------------
2037 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2039 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2040 // pixels each while we really need dots here... PS_ALTERNATE might
2041 // work, but it is for NT 5 only
2043 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2045 // draw the pixels manually: note that to behave in the same manner as
2046 // DrawRect(), we must exclude the bottom and right borders from the
2048 wxCoord x1
= rect
.GetLeft(),
2050 x2
= rect
.GetRight(),
2051 y2
= rect
.GetBottom();
2053 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2055 // this seems to be closer than what Windows does than wxINVERT although
2056 // I'm still not sure if it's correct
2057 dc
.SetLogicalFunction(wxAND_REVERSE
);
2060 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2061 dc
.DrawPoint(z
, rect
.GetTop());
2063 wxCoord shift
= z
== x2
? 0 : 1;
2064 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2065 dc
.DrawPoint(x2
, z
);
2067 shift
= z
== y2
? 0 : 1;
2068 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2069 dc
.DrawPoint(z
, y2
);
2071 shift
= z
== x1
? 0 : 1;
2072 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2073 dc
.DrawPoint(x1
, z
);
2075 dc
.SetLogicalFunction(wxCOPY
);
2079 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2080 const wxString
& label
,
2085 // draw shadow of the text
2086 dc
.SetTextForeground(m_colHighlight
);
2087 wxRect rectShadow
= rect
;
2090 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2092 // make the text grey
2093 dc
.SetTextForeground(m_colDarkGrey
);
2096 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2097 const wxString
& label
,
2104 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2107 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2108 const wxString
& label
,
2114 const wxPoint
& focusOffset
)
2116 // the underscores are not drawn for focused controls in wxMSW
2117 if ( flags
& wxCONTROL_FOCUSED
)
2122 if ( flags
& wxCONTROL_DISABLED
)
2124 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2125 // currently only can happen for a menu item and it seems that Windows
2126 // doesn't draw the shadow in this case, so we don't do it neither
2127 if ( flags
& wxCONTROL_SELECTED
)
2129 // just make the label text greyed out
2130 dc
.SetTextForeground(m_colDarkGrey
);
2132 else // draw normal disabled label
2134 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2139 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2141 if ( flags
& wxCONTROL_DISABLED
)
2143 // restore the fg colour
2144 dc
.SetTextForeground(*wxBLACK
);
2147 if ( flags
& wxCONTROL_FOCUSED
)
2149 if ( focusOffset
.x
|| focusOffset
.y
)
2151 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2154 DrawFocusRect(dc
, rectLabel
);
2158 *rectBounds
= rectLabel
;
2161 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2162 const wxString
& label
,
2163 const wxBitmap
& image
,
2170 // the underscores are not drawn for focused controls in wxMSW
2171 if ( flags
& wxCONTROL_PRESSED
)
2176 wxRect rectLabel
= rect
;
2177 if ( !label
.empty() )
2179 // shift the label if a button is pressed
2180 if ( flags
& wxCONTROL_PRESSED
)
2186 if ( flags
& wxCONTROL_DISABLED
)
2188 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2191 // leave enough space for the focus rectangle
2192 if ( flags
& wxCONTROL_FOCUSED
)
2194 rectLabel
.Inflate(-2);
2198 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2200 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2202 if ( flags
& wxCONTROL_PRESSED
)
2204 // the focus rectangle is never pressed, so undo the shift done
2212 DrawFocusRect(dc
, rectLabel
);
2216 // ----------------------------------------------------------------------------
2217 // (check)listbox items
2218 // ----------------------------------------------------------------------------
2220 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2221 const wxString
& label
,
2225 wxDCTextColourChanger
colChanger(dc
);
2227 if ( flags
& wxCONTROL_SELECTED
)
2229 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2231 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2232 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2233 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2234 dc
.DrawRectangle(rect
);
2237 wxRect rectText
= rect
;
2239 rectText
.width
-= 2;
2240 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2242 if ( flags
& wxCONTROL_FOCUSED
)
2244 DrawFocusRect(dc
, rect
);
2248 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2249 const wxString
& label
,
2250 const wxBitmap
& bitmap
,
2259 else // use default bitmap
2261 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2262 ? IndicatorStatus_Checked
2263 : IndicatorStatus_Unchecked
;
2265 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2267 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2270 bmp
= m_bmpCheckBitmaps
[i
];
2273 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2274 TRUE
/* use mask */);
2276 wxRect rectLabel
= rect
;
2277 int bmpWidth
= bmp
.GetWidth();
2278 rectLabel
.x
+= bmpWidth
;
2279 rectLabel
.width
-= bmpWidth
;
2281 DrawItem(dc
, label
, rectLabel
, flags
);
2284 // ----------------------------------------------------------------------------
2285 // check/radio buttons
2286 // ----------------------------------------------------------------------------
2288 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2290 IndicatorState indState
;
2291 if ( flags
& wxCONTROL_SELECTED
)
2292 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2293 : IndicatorState_Selected
;
2294 else if ( flags
& wxCONTROL_DISABLED
)
2295 indState
= IndicatorState_Disabled
;
2296 else if ( flags
& wxCONTROL_PRESSED
)
2297 indState
= IndicatorState_Pressed
;
2299 indState
= IndicatorState_Normal
;
2301 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2302 ? IndicatorStatus_Checked
2303 : IndicatorStatus_Unchecked
;
2305 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2308 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2311 // create and cache it
2312 bmp
= wxBitmap(xpm
);
2313 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2320 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2321 const wxString
& label
,
2322 const wxBitmap
& bitmap
,
2327 wxCoord focusOffsetY
)
2329 // calculate the position of the bitmap and of the label
2330 wxCoord heightBmp
= bitmap
.GetHeight();
2332 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2335 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2336 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2338 // align label vertically with the bitmap - looks nicer like this
2339 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2341 // calc horz position
2342 if ( align
== wxALIGN_RIGHT
)
2344 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2345 rectLabel
.x
= rect
.x
+ 3;
2346 rectLabel
.SetRight(xBmp
);
2348 else // normal (checkbox to the left of the text) case
2351 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2352 rectLabel
.SetRight(rect
.GetRight());
2355 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, TRUE
/* use mask */);
2358 dc
, label
, rectLabel
,
2360 wxALIGN_LEFT
| wxALIGN_TOP
,
2362 NULL
, // we don't need bounding rect
2363 // use custom vert focus rect offset
2364 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2368 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2369 const wxString
& label
,
2370 const wxBitmap
& bitmap
,
2380 bmp
= GetRadioBitmap(flags
);
2382 DrawCheckOrRadioButton(dc
, label
,
2384 rect
, flags
, align
, indexAccel
,
2385 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2388 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2389 const wxString
& label
,
2390 const wxBitmap
& bitmap
,
2400 bmp
= GetCheckBitmap(flags
);
2402 DrawCheckOrRadioButton(dc
, label
,
2404 rect
, flags
, align
, indexAccel
,
2405 0); // no focus rect offset for checkboxes
2408 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2409 const wxString
& label
,
2410 const wxBitmap
& bitmap
,
2411 const wxRect
& rectOrig
,
2415 if (style
== wxTOOL_STYLE_BUTTON
)
2417 wxRect rect
= rectOrig
;
2418 rect
.Deflate(BORDER_THICKNESS
);
2420 if ( flags
& wxCONTROL_PRESSED
)
2422 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2424 else if ( flags
& wxCONTROL_CURRENT
)
2426 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2429 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2431 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2433 // leave a small gap aroudn the line, also account for the toolbar
2435 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2436 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2437 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2439 // don't draw wxTOOL_STYLE_CONTROL
2442 // ----------------------------------------------------------------------------
2444 // ----------------------------------------------------------------------------
2446 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2447 const wxString
& text
,
2453 // nothing special to do here
2454 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2458 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2459 const wxRect
& WXUNUSED(rect
))
2461 // we don't draw them
2464 // ----------------------------------------------------------------------------
2466 // ----------------------------------------------------------------------------
2468 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2469 const wxRect
& rectOrig
,
2471 const wxString
& label
,
2472 const wxBitmap
& bitmap
,
2476 wxRect rect
= rectOrig
;
2478 // the current tab is drawn indented (to the top for default case) and
2479 // bigger than the other ones
2480 const wxSize indent
= GetTabIndent();
2481 if ( flags
& wxCONTROL_SELECTED
)
2486 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2490 rect
.Inflate(indent
.x
, 0);
2492 rect
.height
+= indent
.y
;
2496 rect
.Inflate(indent
.x
, 0);
2497 rect
.height
+= indent
.y
;
2502 wxFAIL_MSG(_T("TODO"));
2507 // draw the text, image and the focus around them (if necessary)
2508 wxRect rectLabel
= rect
;
2509 rectLabel
.Deflate(1, 1);
2510 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2511 flags
, wxALIGN_CENTRE
, indexAccel
);
2513 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2514 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2517 x2
= rect
.GetRight(),
2518 y2
= rect
.GetBottom();
2520 // FIXME: all this code will break if the tab indent or the border width,
2521 // it is tied to the fact that both of them are equal to 2
2526 dc
.SetPen(m_penHighlight
);
2527 dc
.DrawLine(x
, y2
, x
, y
+ CUTOFF
);
2528 dc
.DrawLine(x
, y
+ CUTOFF
, x
+ CUTOFF
, y
);
2529 dc
.DrawLine(x
+ CUTOFF
, y
, x2
- CUTOFF
+ 1, y
);
2531 dc
.SetPen(m_penBlack
);
2532 dc
.DrawLine(x2
, y2
, x2
, y
+ CUTOFF
);
2533 dc
.DrawLine(x2
, y
+ CUTOFF
, x2
- CUTOFF
, y
);
2535 dc
.SetPen(m_penDarkGrey
);
2536 dc
.DrawLine(x2
- 1, y2
, x2
- 1, y
+ CUTOFF
- 1);
2538 if ( flags
& wxCONTROL_SELECTED
)
2540 dc
.SetPen(m_penLightGrey
);
2542 // overwrite the part of the border below this tab
2543 dc
.DrawLine(x
+ 1, y2
+ 1, x2
- 1, y2
+ 1);
2545 // and the shadow of the tab to the left of us
2546 dc
.DrawLine(x
+ 1, y
+ CUTOFF
+ 1, x
+ 1, y2
+ 1);
2551 dc
.SetPen(m_penHighlight
);
2552 // we need to continue one pixel further to overwrite the corner of
2553 // the border for the selected tab
2554 dc
.DrawLine(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0),
2556 dc
.DrawLine(x
, y2
- CUTOFF
, x
+ CUTOFF
, y2
);
2558 dc
.SetPen(m_penBlack
);
2559 dc
.DrawLine(x
+ CUTOFF
, y2
, x2
- CUTOFF
+ 1, y2
);
2560 dc
.DrawLine(x2
, y
, x2
, y2
- CUTOFF
);
2561 dc
.DrawLine(x2
, y2
- CUTOFF
, x2
- CUTOFF
, y2
);
2563 dc
.SetPen(m_penDarkGrey
);
2564 dc
.DrawLine(x
+ CUTOFF
, y2
- 1, x2
- CUTOFF
+ 1, y2
- 1);
2565 dc
.DrawLine(x2
- 1, y
, x2
- 1, y2
- CUTOFF
+ 1);
2567 if ( flags
& wxCONTROL_SELECTED
)
2569 dc
.SetPen(m_penLightGrey
);
2571 // overwrite the part of the (double!) border above this tab
2572 dc
.DrawLine(x
+ 1, y
- 1, x2
- 1, y
- 1);
2573 dc
.DrawLine(x
+ 1, y
- 2, x2
- 1, y
- 2);
2575 // and the shadow of the tab to the left of us
2576 dc
.DrawLine(x
+ 1, y2
- CUTOFF
, x
+ 1, y
- 1);
2582 wxFAIL_MSG(_T("TODO"));
2586 // ----------------------------------------------------------------------------
2588 // ----------------------------------------------------------------------------
2591 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2593 wxOrientation orient
) const
2596 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2597 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2599 if (orient
== wxHORIZONTAL
)
2613 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2615 wxOrientation orient
,
2618 bool transpose
= (orient
== wxVERTICAL
);
2619 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2620 (((style
& wxSL_TOP
) != 0) & !transpose
|
2621 ((style
& wxSL_LEFT
) != 0) & transpose
|
2622 ((style
& wxSL_BOTH
) != 0));
2623 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2624 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2625 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2626 ((style
& wxSL_BOTH
) != 0));
2628 wxRect rect
= rectOrig
;
2630 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2632 if (orient
== wxHORIZONTAL
) {
2633 rect
.x
+= SLIDER_MARGIN
;
2636 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2640 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2644 rect
.y
+= sizeThumb
.y
/2;
2646 rect
.width
-= 2*SLIDER_MARGIN
;
2647 rect
.height
= 2*BORDER_THICKNESS
;
2651 rect
.y
+= SLIDER_MARGIN
;
2654 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2658 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2662 rect
.x
+= sizeThumb
.x
/2;
2664 rect
.width
= 2*BORDER_THICKNESS
;
2665 rect
.height
-= 2*SLIDER_MARGIN
;
2671 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2672 const wxRect
& rectOrig
,
2674 wxOrientation orient
,
2679 /* show shaft geometry
2697 if (flags
& wxCONTROL_FOCUSED
) {
2698 DrawFocusRect(dc
, rectOrig
);
2701 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2703 if (rectShaft
) *rectShaft
= rect
;
2705 DrawSunkenBorder(dc
, &rect
);
2708 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2710 wxOrientation orient
,
2714 /* show thumb geometry
2723 H D B where H is hightlight colour
2737 The interior of this shape is filled with the hatched brush if the thumb
2741 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2743 bool transpose
= (orient
== wxVERTICAL
);
2744 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2745 (((style
& wxSL_TOP
) != 0) & !transpose
|
2746 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2747 ((style
& wxSL_BOTH
) == 0);
2748 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2749 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2750 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2751 ((style
& wxSL_BOTH
) == 0);
2753 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2754 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2756 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2757 x1
= (transpose
? rect
.y
: rect
.x
);
2758 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2759 x3
= (x1
-1+c
) + sizeArrow
;
2760 y1
= (transpose
? rect
.x
: rect
.y
);
2761 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2762 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2763 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2765 dc
.SetPen(m_penBlack
);
2767 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2769 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2772 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2776 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2779 dc
.SetPen(m_penDarkGrey
);
2780 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2782 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2786 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2789 dc
.SetPen(m_penHighlight
);
2792 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2793 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2797 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2799 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2802 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2805 if (flags
& wxCONTROL_PRESSED
) {
2806 // TODO: MSW fills the entire area inside, not just the rect
2807 wxRect rectInt
= rect
;
2810 rectInt
.SetLeft(y3
);
2811 rectInt
.SetRight(y4
);
2816 rectInt
.SetBottom(y4
);
2820 #if !defined(__WXMGL__)
2821 static const char *stipple_xpm
[] = {
2822 /* columns rows colors chars-per-pixel */
2831 // VS: MGL can only do 8x8 stipple brushes
2832 static const char *stipple_xpm
[] = {
2833 /* columns rows colors chars-per-pixel */
2848 dc
.SetBrush(wxBrush(stipple_xpm
));
2850 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2851 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2852 dc
.SetPen(*wxTRANSPARENT_PEN
);
2853 dc
.DrawRectangle(rectInt
);
2857 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2860 wxOrientation orient
,
2864 int WXUNUSED(flags
),
2867 /* show ticks geometry
2882 if (end
== start
) return;
2884 bool transpose
= (orient
== wxVERTICAL
);
2885 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2886 (((style
& wxSL_TOP
) != 0) & !transpose
|
2887 ((style
& wxSL_LEFT
) != 0) & transpose
|
2888 ((style
& wxSL_BOTH
) != 0));
2889 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2890 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2891 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2892 ((style
& wxSL_BOTH
) != 0));
2894 // default thumb size
2895 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2896 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
2898 // normal thumb size
2899 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2900 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
2902 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2904 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2905 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2906 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2907 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2908 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2909 y3
= (transpose
? rect
.x
: rect
.y
);
2910 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2913 dc
.SetPen(m_penBlack
);
2915 int range
= end
- start
;
2916 for ( int n
= 0; n
< range
; n
+= step
) {
2917 wxCoord x
= x1
+ (len
*n
) / range
;
2919 if (left
& (y1
> y3
)) {
2920 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2922 if (right
& (y4
> y2
)) {
2923 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2926 // always draw the line at the end position
2927 if (left
& (y1
> y3
)) {
2928 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2930 if (right
& (y4
> y2
)) {
2931 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2935 // ----------------------------------------------------------------------------
2937 // ----------------------------------------------------------------------------
2939 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2940 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2943 virtual wxSize
GetSize() const { return m_size
; }
2945 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2946 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2948 wxCoord
GetItemHeight() const { return m_heightItem
; }
2951 // the total size of the menu
2954 // the offset of the start of the menu item label
2957 // the offset of the start of the accel label
2960 // the height of a normal (not separator) item
2961 wxCoord m_heightItem
;
2963 friend wxMenuGeometryInfo
*
2964 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2967 // FIXME: all constants are hardcoded but shouldn't be
2968 static const wxCoord MENU_LEFT_MARGIN
= 9;
2969 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2970 static const wxCoord MENU_VERT_MARGIN
= 3;
2972 // the margin around bitmap/check marks (on each side)
2973 static const wxCoord MENU_BMP_MARGIN
= 2;
2975 // the margin between the labels and accel strings
2976 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2978 // the separator height in pixels: in fact, strangely enough, the real height
2979 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2981 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2983 // the size of the standard checkmark bitmap
2984 static const wxCoord MENU_CHECK_SIZE
= 9;
2986 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2987 const wxRect
& rectOrig
,
2988 const wxString
& label
,
2992 wxRect rect
= rectOrig
;
2995 wxDCTextColourChanger
colChanger(dc
);
2997 if ( flags
& wxCONTROL_SELECTED
)
2999 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3001 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3002 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3003 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3004 dc
.DrawRectangle(rect
);
3007 // don't draw the focus rect around menu bar items
3008 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3009 wxALIGN_CENTRE
, indexAccel
);
3012 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3014 const wxMenuGeometryInfo
& gi
,
3015 const wxString
& label
,
3016 const wxString
& accel
,
3017 const wxBitmap
& bitmap
,
3021 const wxWin32MenuGeometryInfo
& geometryInfo
=
3022 (const wxWin32MenuGeometryInfo
&)gi
;
3027 rect
.width
= geometryInfo
.GetSize().x
;
3028 rect
.height
= geometryInfo
.GetItemHeight();
3030 // draw the selected item specially
3031 wxDCTextColourChanger
colChanger(dc
);
3032 if ( flags
& wxCONTROL_SELECTED
)
3034 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3036 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3037 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3038 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3039 dc
.DrawRectangle(rect
);
3042 // draw the bitmap: use the bitmap provided or the standard checkmark for
3043 // the checkable items
3044 wxBitmap bmp
= bitmap
;
3045 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3047 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3052 rect
.SetRight(geometryInfo
.GetLabelOffset());
3053 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3057 rect
.x
= geometryInfo
.GetLabelOffset();
3058 rect
.SetRight(geometryInfo
.GetAccelOffset());
3060 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3062 // draw the accel string
3063 rect
.x
= geometryInfo
.GetAccelOffset();
3064 rect
.SetRight(geometryInfo
.GetSize().x
);
3066 // NB: no accel index here
3067 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3069 // draw the submenu indicator
3070 if ( flags
& wxCONTROL_ISSUBMENU
)
3072 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3073 rect
.width
= MENU_RIGHT_MARGIN
;
3075 wxArrowStyle arrowStyle
;
3076 if ( flags
& wxCONTROL_DISABLED
)
3077 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InversedDisabled
3079 else if ( flags
& wxCONTROL_SELECTED
)
3080 arrowStyle
= Arrow_Inversed
;
3082 arrowStyle
= Arrow_Normal
;
3084 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3088 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3090 const wxMenuGeometryInfo
& geomInfo
)
3092 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3095 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3097 wxSize size
= sizeText
;
3099 // FIXME: menubar height is configurable under Windows
3106 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3107 const wxMenu
& menu
) const
3109 // prepare the dc: for now we draw all the items with the system font
3111 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3113 // the height of a normal item
3114 wxCoord heightText
= dc
.GetCharHeight();
3119 // the max length of label and accel strings: the menu width is the sum of
3120 // them, even if they're for different items (as the accels should be
3123 // the max length of the bitmap is never 0 as Windows always leaves enough
3124 // space for a check mark indicator
3125 wxCoord widthLabelMax
= 0,
3127 widthBmpMax
= MENU_LEFT_MARGIN
;
3129 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3131 node
= node
->GetNext() )
3133 // height of this item
3136 wxMenuItem
*item
= node
->GetData();
3137 if ( item
->IsSeparator() )
3139 h
= MENU_SEPARATOR_HEIGHT
;
3141 else // not separator
3146 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3147 if ( widthLabel
> widthLabelMax
)
3149 widthLabelMax
= widthLabel
;
3153 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3154 if ( widthAccel
> widthAccelMax
)
3156 widthAccelMax
= widthAccel
;
3159 const wxBitmap
& bmp
= item
->GetBitmap();
3162 wxCoord widthBmp
= bmp
.GetWidth();
3163 if ( widthBmp
> widthBmpMax
)
3164 widthBmpMax
= widthBmp
;
3166 //else if ( item->IsCheckable() ): no need to check for this as
3167 // MENU_LEFT_MARGIN is big enough to show the check mark
3170 h
+= 2*MENU_VERT_MARGIN
;
3172 // remember the item position and height
3173 item
->SetGeometry(height
, h
);
3178 // bundle the metrics into a struct and return it
3179 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3181 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3182 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3183 if ( widthAccelMax
> 0 )
3185 // if we actually have any accesl, add a margin
3186 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3189 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3191 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3192 gi
->m_size
.y
= height
;
3197 // ----------------------------------------------------------------------------
3199 // ----------------------------------------------------------------------------
3201 static const wxCoord STATBAR_BORDER_X
= 2;
3202 static const wxCoord STATBAR_BORDER_Y
= 2;
3204 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3206 if ( borderBetweenFields
)
3207 *borderBetweenFields
= 2;
3209 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3212 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3214 const wxString
& label
,
3219 if ( flags
& wxCONTROL_ISDEFAULT
)
3221 // draw the size grip: it is a normal rect except that in the lower
3222 // right corner we have several bands which may be used for dragging
3223 // the status bar corner
3225 // each band consists of 4 stripes: m_penHighlight, double
3226 // m_penDarkGrey and transparent one
3227 wxCoord x2
= rect
.GetRight(),
3228 y2
= rect
.GetBottom();
3230 // draw the upper left part of the rect normally
3231 dc
.SetPen(m_penDarkGrey
);
3232 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3233 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3235 // draw the grey stripes of the grip
3237 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3238 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3240 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3241 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3244 // draw the white stripes
3245 dc
.SetPen(m_penHighlight
);
3246 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3247 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3249 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3252 // draw the remaining rect boundaries
3253 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3254 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3255 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3260 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3264 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3267 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3269 wxDCClipper
clipper(dc
, rectIn
);
3270 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3273 // ----------------------------------------------------------------------------
3275 // ----------------------------------------------------------------------------
3277 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3278 wxBitmap
* WXUNUSED(bmpFocus
),
3279 wxBitmap
*bmpPressed
,
3280 wxBitmap
*bmpDisabled
)
3282 static const wxCoord widthCombo
= 16;
3283 static const wxCoord heightCombo
= 17;
3289 bmpNormal
->Create(widthCombo
, heightCombo
);
3290 dcMem
.SelectObject(*bmpNormal
);
3291 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3292 Arrow_Down
, Arrow_Normal
);
3297 bmpPressed
->Create(widthCombo
, heightCombo
);
3298 dcMem
.SelectObject(*bmpPressed
);
3299 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3300 Arrow_Down
, Arrow_Pressed
);
3305 bmpDisabled
->Create(widthCombo
, heightCombo
);
3306 dcMem
.SelectObject(*bmpDisabled
);
3307 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3308 Arrow_Down
, Arrow_Disabled
);
3312 // ----------------------------------------------------------------------------
3314 // ----------------------------------------------------------------------------
3316 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3317 const wxColour
& col
,
3319 wxWindow
* WXUNUSED(window
))
3321 wxBrush
brush(col
, wxSOLID
);
3323 dc
.SetPen(*wxTRANSPARENT_PEN
);
3324 dc
.DrawRectangle(rect
);
3327 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3328 const wxColour
& col
,
3330 int WXUNUSED(flags
),
3333 // just fill it with the given or default bg colour
3334 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3335 DoDrawBackground(dc
, colBg
, rect
, window
);
3338 // ----------------------------------------------------------------------------
3340 // ----------------------------------------------------------------------------
3342 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3347 // get the bitmap for this arrow
3348 wxArrowDirection arrowDir
;
3351 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3352 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3353 case wxUP
: arrowDir
= Arrow_Up
; break;
3354 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3357 wxFAIL_MSG(_T("unknown arrow direction"));
3361 wxArrowStyle arrowStyle
;
3362 if ( flags
& wxCONTROL_PRESSED
)
3364 // can't be pressed and disabled
3365 arrowStyle
= Arrow_Pressed
;
3369 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3372 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3375 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3377 wxArrowDirection arrowDir
,
3378 wxArrowStyle arrowStyle
)
3380 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3382 // under Windows the arrows always have the same size so just centre it in
3383 // the provided rectangle
3384 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3385 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3387 // Windows does it like this...
3388 if ( arrowDir
== Arrow_Left
)
3392 dc
.DrawBitmap(bmp
, x
, y
, TRUE
/* use mask */);
3395 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3396 const wxRect
& rectAll
,
3397 wxArrowDirection arrowDir
,
3398 wxArrowStyle arrowStyle
)
3400 wxRect rect
= rectAll
;
3401 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3402 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3403 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3406 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3407 wxOrientation
WXUNUSED(orient
),
3409 int WXUNUSED(flags
))
3411 // we don't use the flags, the thumb never changes appearance
3412 wxRect rectThumb
= rect
;
3413 DrawArrowBorder(dc
, &rectThumb
);
3414 DrawBackground(dc
, wxNullColour
, rectThumb
);
3417 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3418 wxOrientation
WXUNUSED(orient
),
3419 const wxRect
& rectBar
,
3422 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3423 ? wxColourScheme::SCROLLBAR_PRESSED
3424 : wxColourScheme::SCROLLBAR
;
3425 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3428 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3430 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3433 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3434 wxScrollBar::Element elem
,
3437 return StandardGetScrollbarRect(scrollbar
, elem
,
3438 thumbPos
, m_sizeScrollbarArrow
);
3441 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3443 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3446 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3447 const wxPoint
& pt
) const
3449 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3452 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3455 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3458 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3461 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3464 // ----------------------------------------------------------------------------
3465 // top level windows
3466 // ----------------------------------------------------------------------------
3468 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3470 wxRect client
= GetFrameClientArea(rect
, flags
);
3472 if ( client
.Inside(pt
) )
3473 return wxHT_TOPLEVEL_CLIENT_AREA
;
3475 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3477 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3479 if ( flags
& wxTOPLEVEL_ICON
)
3481 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3482 return wxHT_TOPLEVEL_ICON
;
3485 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3486 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3487 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3489 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3491 if ( btnRect
.Inside(pt
) )
3492 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3493 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3495 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3497 if ( btnRect
.Inside(pt
) )
3498 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3499 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3501 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3503 if ( btnRect
.Inside(pt
) )
3504 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3505 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3507 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3509 if ( btnRect
.Inside(pt
) )
3510 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3511 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3513 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3515 if ( btnRect
.Inside(pt
) )
3516 return wxHT_TOPLEVEL_BUTTON_HELP
;
3517 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3520 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3521 return wxHT_TOPLEVEL_TITLEBAR
;
3524 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3526 // we are certainly at one of borders, lets decide which one:
3529 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3530 if ( pt
.x
< client
.x
)
3531 border
|= wxHT_TOPLEVEL_BORDER_W
;
3532 else if ( pt
.x
>= client
.width
+ client
.x
)
3533 border
|= wxHT_TOPLEVEL_BORDER_E
;
3534 if ( pt
.y
< client
.y
)
3535 border
|= wxHT_TOPLEVEL_BORDER_N
;
3536 else if ( pt
.y
>= client
.height
+ client
.y
)
3537 border
|= wxHT_TOPLEVEL_BORDER_S
;
3541 return wxHT_NOWHERE
;
3544 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3546 const wxString
& title
,
3550 int specialButtonFlags
)
3552 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3554 DrawFrameBorder(dc
, rect
, flags
);
3556 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3558 DrawFrameBackground(dc
, rect
, flags
);
3559 if ( flags
& wxTOPLEVEL_ICON
)
3560 DrawFrameIcon(dc
, rect
, icon
, flags
);
3561 DrawFrameTitle(dc
, rect
, title
, flags
);
3563 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3565 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3566 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3568 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3570 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3571 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3572 specialButtonFlags
: 0);
3573 x
-= FRAME_BUTTON_WIDTH
+ 2;
3575 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3577 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3578 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3579 specialButtonFlags
: 0);
3580 x
-= FRAME_BUTTON_WIDTH
;
3582 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3584 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3585 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3586 specialButtonFlags
: 0);
3587 x
-= FRAME_BUTTON_WIDTH
;
3589 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3591 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3592 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3593 specialButtonFlags
: 0);
3594 x
-= FRAME_BUTTON_WIDTH
;
3596 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3598 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3599 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3600 specialButtonFlags
: 0);
3605 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3609 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3613 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3614 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3615 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3616 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3617 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3620 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3624 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3626 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3627 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3628 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3630 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3631 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3633 DrawBackground(dc
, col
, r
);
3636 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3638 const wxString
& title
,
3641 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3642 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3643 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3645 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3646 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3647 if ( flags
& wxTOPLEVEL_ICON
)
3649 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3650 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3658 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3659 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3660 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3661 r
.width
-= FRAME_BUTTON_WIDTH
;
3662 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3663 r
.width
-= FRAME_BUTTON_WIDTH
;
3664 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3665 r
.width
-= FRAME_BUTTON_WIDTH
;
3666 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3667 r
.width
-= FRAME_BUTTON_WIDTH
;
3669 dc
.SetFont(m_titlebarFont
);
3670 dc
.SetTextForeground(col
);
3673 dc
.GetTextExtent(title
, &textW
, NULL
);
3674 if ( textW
> r
.width
)
3676 // text is too big, let's shorten it and add "..." after it:
3677 size_t len
= title
.length();
3678 wxCoord WSoFar
, letterW
;
3680 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3681 if ( WSoFar
> r
.width
)
3683 // not enough space to draw anything
3689 for (size_t i
= 0; i
< len
; i
++)
3691 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3692 if ( letterW
+ WSoFar
> r
.width
)
3698 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3699 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3702 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3703 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3706 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3713 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3714 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3718 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3719 wxCoord x
, wxCoord y
,
3723 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3728 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3729 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3730 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3731 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3732 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3734 wxFAIL_MSG(wxT("incorrect button specification"));
3737 if ( flags
& wxCONTROL_PRESSED
)
3739 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3740 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3741 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3742 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, TRUE
);
3746 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3747 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3748 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3749 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, TRUE
);
3754 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3759 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3761 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3762 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3763 FRAME_BORDER_THICKNESS
;
3766 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3768 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3769 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3775 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3778 wxSize
s(clientSize
);
3780 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3782 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3783 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3784 FRAME_BORDER_THICKNESS
;
3788 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3789 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3794 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3798 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3800 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3801 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3802 FRAME_BORDER_THICKNESS
;
3807 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3809 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3811 if ( flags
& wxTOPLEVEL_ICON
)
3812 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3813 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3814 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3815 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3816 s
.x
+= FRAME_BUTTON_WIDTH
;
3817 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3818 s
.x
+= FRAME_BUTTON_WIDTH
;
3819 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3820 s
.x
+= FRAME_BUTTON_WIDTH
;
3821 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3822 s
.x
+= FRAME_BUTTON_WIDTH
;
3828 wxSize
wxWin32Renderer::GetFrameIconSize() const
3830 return wxSize(16, 16);
3834 // ----------------------------------------------------------------------------
3836 // ----------------------------------------------------------------------------
3838 static char *error_xpm
[]={
3845 "...........########.............",
3846 "........###aaaaaaaa###..........",
3847 ".......#aaaaaaaaaaaaaa#.........",
3848 ".....##aaaaaaaaaaaaaaaa##.......",
3849 "....#aaaaaaaaaaaaaaaaaaaa#......",
3850 "...#aaaaaaaaaaaaaaaaaaaaaa#.....",
3851 "...#aaaaaaaaaaaaaaaaaaaaaa#b....",
3852 "..#aaaaaacaaaaaaaaaacaaaaaa#b...",
3853 ".#aaaaaacccaaaaaaaacccaaaaaa#...",
3854 ".#aaaaacccccaaaaaacccccaaaaa#b..",
3855 ".#aaaaaacccccaaaacccccaaaaaa#bb.",
3856 "#aaaaaaaacccccaacccccaaaaaaaa#b.",
3857 "#aaaaaaaaaccccccccccaaaaaaaaa#b.",
3858 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3859 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3860 "#aaaaaaaaaaaccccccaaaaaaaaaaa#bb",
3861 "#aaaaaaaaaaccccccccaaaaaaaaaa#bb",
3862 "#aaaaaaaaaccccccccccaaaaaaaaa#bb",
3863 "#aaaaaaaacccccaacccccaaaaaaaa#bb",
3864 ".#aaaaaacccccaaaacccccaaaaaa#bbb",
3865 ".#aaaaacccccaaaaaacccccaaaaa#bbb",
3866 ".#aaaaaacccaaaaaaaacccaaaaaa#bb.",
3867 "..#aaaaaacaaaaaaaaaacaaaaaa#bbb.",
3868 "...#aaaaaaaaaaaaaaaaaaaaaa#bbbb.",
3869 "...#aaaaaaaaaaaaaaaaaaaaaa#bbb..",
3870 "....#aaaaaaaaaaaaaaaaaaaa#bbb...",
3871 ".....##aaaaaaaaaaaaaaaa##bbbb...",
3872 "......b#aaaaaaaaaaaaaa#bbbbb....",
3873 ".......b###aaaaaaaa###bbbbb.....",
3874 ".........bb########bbbbbb.......",
3875 "..........bbbbbbbbbbbbbb........",
3876 ".............bbbbbbbb..........."};
3878 static char *info_xpm
[]={
3886 "...........########.............",
3887 "........###abbbbbba###..........",
3888 "......##abbbbbbbbbbbba##........",
3889 ".....#abbbbbbbbbbbbbbbba#.......",
3890 "....#bbbbbbbaccccabbbbbbbd......",
3891 "...#bbbbbbbbccccccbbbbbbbbd.....",
3892 "..#bbbbbbbbbccccccbbbbbbbbbd....",
3893 ".#abbbbbbbbbaccccabbbbbbbbbad...",
3894 ".#bbbbbbbbbbbbbbbbbbbbbbbbbbd#..",
3895 "#abbbbbbbbbbbbbbbbbbbbbbbbbbad#.",
3896 "#bbbbbbbbbbcccccccbbbbbbbbbbbd#.",
3897 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3898 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3899 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3900 "#bbbbbbbbbbbbcccccbbbbbbbbbbbd##",
3901 "#abbbbbbbbbbbcccccbbbbbbbbbbad##",
3902 ".#bbbbbbbbbbbcccccbbbbbbbbbbd###",
3903 ".#abbbbbbbbbbcccccbbbbbbbbbad###",
3904 "..#bbbbbbbbcccccccccbbbbbbbd###.",
3905 "...dbbbbbbbbbbbbbbbbbbbbbbd####.",
3906 "....dbbbbbbbbbbbbbbbbbbbbd####..",
3907 ".....dabbbbbbbbbbbbbbbbad####...",
3908 "......ddabbbbbbbbbbbbadd####....",
3909 ".......#dddabbbbbbaddd#####.....",
3910 "........###dddabbbd#######......",
3911 "..........####dbbbd#####........",
3912 ".............#dbbbd##...........",
3913 "...............dbbd##...........",
3914 "................dbd##...........",
3915 ".................dd##...........",
3916 "..................###...........",
3917 "...................##..........."};
3919 static char *question_xpm
[]={
3927 "...........########.............",
3928 "........###abbbbbba###..........",
3929 "......##abbbbbbbbbbbba##........",
3930 ".....#abbbbbbbbbbbbbbbba#.......",
3931 "....#bbbbbbbbbbbbbbbbbbbbc......",
3932 "...#bbbbbbbaddddddabbbbbbbc.....",
3933 "..#bbbbbbbadabbddddabbbbbbbc....",
3934 ".#abbbbbbbddbbbbddddbbbbbbbac...",
3935 ".#bbbbbbbbddddbbddddbbbbbbbbc#..",
3936 "#abbbbbbbbddddbaddddbbbbbbbbac#.",
3937 "#bbbbbbbbbaddabddddbbbbbbbbbbc#.",
3938 "#bbbbbbbbbbbbbadddbbbbbbbbbbbc##",
3939 "#bbbbbbbbbbbbbdddbbbbbbbbbbbbc##",
3940 "#bbbbbbbbbbbbbddabbbbbbbbbbbbc##",
3941 "#bbbbbbbbbbbbbddbbbbbbbbbbbbbc##",
3942 "#abbbbbbbbbbbbbbbbbbbbbbbbbbac##",
3943 ".#bbbbbbbbbbbaddabbbbbbbbbbbc###",
3944 ".#abbbbbbbbbbddddbbbbbbbbbbac###",
3945 "..#bbbbbbbbbbddddbbbbbbbbbbc###.",
3946 "...cbbbbbbbbbaddabbbbbbbbbc####.",
3947 "....cbbbbbbbbbbbbbbbbbbbbc####..",
3948 ".....cabbbbbbbbbbbbbbbbac####...",
3949 "......ccabbbbbbbbbbbbacc####....",
3950 ".......#cccabbbbbbaccc#####.....",
3951 "........###cccabbbc#######......",
3952 "..........####cbbbc#####........",
3953 ".............#cbbbc##...........",
3954 "...............cbbc##...........",
3955 "................cbc##...........",
3956 ".................cc##...........",
3957 "..................###...........",
3958 "...................##..........."};
3960 static char *warning_xpm
[]={
3968 ".............###................",
3969 "............#aabc...............",
3970 "...........#aaaabcd.............",
3971 "...........#aaaaacdd............",
3972 "..........#aaaaaabcdd...........",
3973 "..........#aaaaaaacdd...........",
3974 ".........#aaaaaaaabcdd..........",
3975 ".........#aaaaaaaaacdd..........",
3976 "........#aaaaaaaaaabcdd.........",
3977 "........#aaabcccbaaacdd.........",
3978 ".......#aaaacccccaaabcdd........",
3979 ".......#aaaacccccaaaacdd........",
3980 "......#aaaaacccccaaaabcdd.......",
3981 "......#aaaaacccccaaaaacdd.......",
3982 ".....#aaaaaacccccaaaaabcdd......",
3983 ".....#aaaaaa#ccc#aaaaaacdd......",
3984 "....#aaaaaaabcccbaaaaaabcdd.....",
3985 "....#aaaaaaaacccaaaaaaaacdd.....",
3986 "...#aaaaaaaaa#c#aaaaaaaabcdd....",
3987 "...#aaaaaaaaabcbaaaaaaaaacdd....",
3988 "..#aaaaaaaaaaacaaaaaaaaaabcdd...",
3989 "..#aaaaaaaaaaaaaaaaaaaaaaacdd...",
3990 ".#aaaaaaaaaaabccbaaaaaaaaabcdd..",
3991 ".#aaaaaaaaaaaccccaaaaaaaaaacdd..",
3992 "#aaaaaaaaaaaaccccaaaaaaaaaabcdd.",
3993 "#aaaaaaaaaaaabccbaaaaaaaaaaacdd.",
3994 "#aaaaaaaaaaaaaaaaaaaaaaaaaaacddd",
3995 "#aaaaaaaaaaaaaaaaaaaaaaaaaabcddd",
3996 ".#aaaaaaaaaaaaaaaaaaaaaaaabcdddd",
3997 "..#ccccccccccccccccccccccccddddd",
3998 "....ddddddddddddddddddddddddddd.",
3999 ".....ddddddddddddddddddddddddd.."};
4001 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4002 const wxArtClient
& WXUNUSED(client
),
4003 const wxSize
& WXUNUSED(size
))
4005 if ( id
== wxART_INFORMATION
)
4006 return wxBitmap(info_xpm
);
4007 if ( id
== wxART_ERROR
)
4008 return wxBitmap(error_xpm
);
4009 if ( id
== wxART_WARNING
)
4010 return wxBitmap(warning_xpm
);
4011 if ( id
== wxART_QUESTION
)
4012 return wxBitmap(question_xpm
);
4013 return wxNullBitmap
;
4017 // ----------------------------------------------------------------------------
4018 // text control geometry
4019 // ----------------------------------------------------------------------------
4021 static inline int GetTextBorderWidth()
4027 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4028 const wxRect
& rect
) const
4030 wxRect rectTotal
= rect
;
4032 wxCoord widthBorder
= GetTextBorderWidth();
4033 rectTotal
.Inflate(widthBorder
);
4035 // this is what Windows does
4042 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4044 wxCoord
*extraSpaceBeyond
) const
4046 wxRect rectText
= rect
;
4048 // undo GetTextTotalArea()
4049 if ( rectText
.height
> 0 )
4052 wxCoord widthBorder
= GetTextBorderWidth();
4053 rectText
.Inflate(-widthBorder
);
4055 if ( extraSpaceBeyond
)
4056 *extraSpaceBeyond
= 0;
4061 // ----------------------------------------------------------------------------
4063 // ----------------------------------------------------------------------------
4065 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4068 if ( wxDynamicCast(window
, wxScrollBar
) )
4070 // we only set the width of vert scrollbars and height of the
4072 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4073 size
->y
= m_sizeScrollbarArrow
.y
;
4075 size
->x
= m_sizeScrollbarArrow
.x
;
4077 // skip border width adjustments, they don't make sense for us
4080 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4083 if ( wxDynamicCast(window
, wxButton
) )
4085 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4087 // TODO: don't harcode all this
4088 size
->x
+= 3*window
->GetCharWidth();
4090 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4091 if ( size
->y
< heightBtn
- 8 )
4092 size
->y
= heightBtn
;
4097 // for compatibility with other ports, the buttons default size is never
4098 // less than the standard one, but not when display not PDAs.
4099 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4101 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4103 wxSize szDef
= wxButton::GetDefaultSize();
4104 if ( size
->x
< szDef
.x
)
4109 // no border width adjustments for buttons
4112 #endif // wxUSE_BUTTON
4114 // take into account the border width
4115 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4116 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4117 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4120 // ============================================================================
4122 // ============================================================================
4124 // ----------------------------------------------------------------------------
4125 // wxWin32InputHandler
4126 // ----------------------------------------------------------------------------
4128 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4130 m_renderer
= renderer
;
4133 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4134 const wxKeyEvent
& WXUNUSED(event
),
4135 bool WXUNUSED(pressed
))
4140 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4141 const wxMouseEvent
& event
)
4143 // clicking on the control gives it focus
4144 if ( event
.ButtonDown() )
4146 wxWindow
*win
= control
->GetInputWindow();
4148 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4149 ( win
->AcceptsFocus() ) )
4160 // ----------------------------------------------------------------------------
4161 // wxWin32ScrollBarInputHandler
4162 // ----------------------------------------------------------------------------
4164 wxWin32ScrollBarInputHandler::
4165 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4166 wxInputHandler
*handler
)
4167 : wxStdScrollBarInputHandler(renderer
, handler
)
4169 m_scrollPaused
= FALSE
;
4173 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4174 const wxControlAction
& action
)
4176 // stop if went beyond the position of the original click (this can only
4177 // happen when we scroll by pages)
4179 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4181 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4182 != wxHT_SCROLLBAR_BAR_2
;
4184 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4186 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4187 != wxHT_SCROLLBAR_BAR_1
;
4192 StopScrolling(scrollbar
);
4194 scrollbar
->Refresh();
4199 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4202 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4203 const wxMouseEvent
& event
)
4205 // remember the current state
4206 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4208 // do process the message
4209 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4211 // analyse the changes
4212 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4214 // we just started dragging the thumb, remember its initial position to
4215 // be able to restore it if the drag is cancelled later
4216 m_eventStartDrag
= event
;
4222 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4223 const wxMouseEvent
& event
)
4225 // we don't highlight scrollbar elements, so there is no need to process
4226 // mouse move events normally - only do it while mouse is captured (i.e.
4227 // when we're dragging the thumb or pressing on something)
4228 if ( !m_winCapture
)
4231 if ( event
.Entering() )
4233 // we're not interested in this at all
4237 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4239 if ( m_scrollPaused
)
4241 // check if the mouse returned to its original location
4243 if ( event
.Leaving() )
4249 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4250 if ( ht
== m_htLast
)
4252 // yes it did, resume scrolling
4253 m_scrollPaused
= FALSE
;
4254 if ( m_timerScroll
)
4256 // we were scrolling by line/page, restart timer
4257 m_timerScroll
->Start(m_interval
);
4259 Press(scrollbar
, TRUE
);
4261 else // we were dragging the thumb
4263 // restore its last location
4264 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4270 else // normal case, scrolling hasn't been paused
4272 // if we're scrolling the scrollbar because the arrow or the shaft was
4273 // pressed, check that the mouse stays on the same scrollbar element
4276 // Always let thumb jump back if we leave the scrollbar
4277 if ( event
.Moving() )
4279 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4281 else // event.Leaving()
4286 // Jump back only if we get far away from it
4287 wxPoint pos
= event
.GetPosition();
4288 if (scrollbar
->HasFlag( wxVERTICAL
))
4290 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4295 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4298 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4301 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4302 // is still ok - we only want to catch the case when the mouse leaves
4303 // the scrollbar here
4304 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4306 ht
= wxHT_SCROLLBAR_THUMB
;
4309 if ( ht
!= m_htLast
)
4311 // what were we doing? 2 possibilities: either an arrow/shaft was
4312 // pressed in which case we have a timer and so we just stop it or
4313 // we were dragging the thumb
4314 if ( m_timerScroll
)
4317 m_interval
= m_timerScroll
->GetInterval();
4318 m_timerScroll
->Stop();
4319 m_scrollPaused
= TRUE
;
4321 // unpress the arrow
4322 Press(scrollbar
, FALSE
);
4324 else // we were dragging the thumb
4326 // remember the current thumb position to be able to restore it
4327 // if the mouse returns to it later
4328 m_eventLastDrag
= event
;
4330 // and restore the original position (before dragging) of the
4332 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4339 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4342 // ----------------------------------------------------------------------------
4343 // wxWin32CheckboxInputHandler
4344 // ----------------------------------------------------------------------------
4346 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4347 const wxKeyEvent
& event
,
4352 wxControlAction action
;
4353 int keycode
= event
.GetKeyCode();
4357 action
= wxACTION_CHECKBOX_TOGGLE
;
4361 case WXK_NUMPAD_SUBTRACT
:
4362 action
= wxACTION_CHECKBOX_CHECK
;
4366 case WXK_NUMPAD_ADD
:
4367 case WXK_NUMPAD_EQUAL
:
4368 action
= wxACTION_CHECKBOX_CLEAR
;
4374 control
->PerformAction(action
);
4383 // ----------------------------------------------------------------------------
4384 // wxWin32TextCtrlInputHandler
4385 // ----------------------------------------------------------------------------
4387 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4388 const wxKeyEvent
& event
,
4391 // handle only MSW-specific text bindings here, the others are handled in
4395 int keycode
= event
.GetKeyCode();
4397 wxControlAction action
;
4398 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4400 action
= wxACTION_TEXT_CUT
;
4402 else if ( keycode
== WXK_INSERT
)
4404 if ( event
.ControlDown() )
4405 action
= wxACTION_TEXT_COPY
;
4406 else if ( event
.ShiftDown() )
4407 action
= wxACTION_TEXT_PASTE
;
4410 if ( action
!= wxACTION_NONE
)
4412 control
->PerformAction(action
);
4418 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4421 // ----------------------------------------------------------------------------
4422 // wxWin32StatusBarInputHandler
4423 // ----------------------------------------------------------------------------
4425 wxWin32StatusBarInputHandler::
4426 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4427 : wxStdInputHandler(handler
)
4432 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4433 const wxPoint
& pt
) const
4435 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4436 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4439 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4441 wxCHECK_MSG( parentTLW
, FALSE
,
4442 _T("the status bar should be a child of a TLW") );
4444 // a maximized window can't be resized anyhow
4445 if ( !parentTLW
->IsMaximized() )
4447 // VZ: I think that the standard Windows behaviour is to only
4448 // show the resizing cursor when the mouse is on top of the
4449 // grip itself but apparently different Windows versions behave
4450 // differently (?) and it seems a better UI to allow resizing
4451 // the status bar even when the mouse is above the grip
4452 wxSize sizeSbar
= statbar
->GetSize();
4454 int diff
= sizeSbar
.x
- pt
.x
;
4455 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4462 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4463 const wxMouseEvent
& event
)
4465 if ( event
.Button(1) )
4467 if ( event
.ButtonDown(1) )
4469 wxWindow
*statbar
= consumer
->GetInputWindow();
4471 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4473 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4477 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4478 wxHT_TOPLEVEL_BORDER_SE
);
4480 statbar
->SetCursor(m_cursorOld
);
4488 return wxStdInputHandler::HandleMouse(consumer
, event
);
4491 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4492 const wxMouseEvent
& event
)
4494 wxWindow
*statbar
= consumer
->GetInputWindow();
4496 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4497 if ( isOnGrip
!= m_isOnGrip
)
4499 m_isOnGrip
= isOnGrip
;
4502 m_cursorOld
= statbar
->GetCursor();
4503 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4507 statbar
->SetCursor(m_cursorOld
);
4511 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4514 // ----------------------------------------------------------------------------
4515 // wxWin32FrameInputHandler
4516 // ----------------------------------------------------------------------------
4518 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4521 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4523 void Attach(wxInputConsumer
*consumer
);
4527 DECLARE_EVENT_TABLE()
4528 void OnSystemMenu(wxCommandEvent
&event
);
4529 void OnCloseFrame(wxCommandEvent
&event
);
4530 void OnClose(wxCloseEvent
&event
);
4532 wxWin32FrameInputHandler
*m_inputHnd
;
4533 wxTopLevelWindow
*m_wnd
;
4534 wxAcceleratorTable m_oldAccelTable
;
4537 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4538 wxWin32FrameInputHandler
*handler
)
4540 m_inputHnd
= handler
;
4544 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4546 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4548 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4549 m_wnd
->PushEventHandler(this);
4551 // VS: This code relies on using generic implementation of
4552 // wxAcceleratorTable in wxUniv!
4553 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4554 m_oldAccelTable
= table
;
4555 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4556 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4557 m_wnd
->SetAcceleratorTable(table
);
4560 void wxWin32SystemMenuEvtHandler::Detach()
4564 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4565 m_wnd
->RemoveEventHandler(this);
4570 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4571 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4572 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4573 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4576 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4578 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4579 !m_wnd
->IsMaximized()) ?
4580 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4581 FRAME_BORDER_THICKNESS
;
4582 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4583 pt
.x
= -pt
.x
+ border
;
4584 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4586 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4587 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4588 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4589 m_wnd
->SetAcceleratorTable(table
);
4592 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4594 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4595 wxTOPLEVEL_BUTTON_CLOSE
);
4598 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4605 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4606 : wxStdFrameInputHandler(handler
)
4608 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4611 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4613 if ( m_menuHandler
)
4615 m_menuHandler
->Detach();
4616 delete m_menuHandler
;
4620 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4621 const wxMouseEvent
& event
)
4623 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4625 wxTopLevelWindow
*tlw
=
4626 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4628 long hit
= tlw
->HitTest(event
.GetPosition());
4630 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4632 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4633 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4634 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4637 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4639 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4640 (event
.RightDown() &&
4641 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4642 hit
== wxHT_TOPLEVEL_ICON
)) )
4644 PopupSystemMenu(tlw
, event
.GetPosition());
4650 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4653 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4654 const wxPoint
& pos
) const
4656 wxMenu
*menu
= new wxMenu
;
4658 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4659 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4660 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4661 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4662 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4663 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4664 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4665 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4666 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4667 menu
->AppendSeparator();
4668 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4670 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4672 if ( window
->IsMaximized() )
4674 menu
->Enable(wxID_MAXIMIZE_FRAME
, FALSE
);
4675 menu
->Enable(wxID_MOVE_FRAME
, FALSE
);
4676 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4677 menu
->Enable(wxID_RESIZE_FRAME
, FALSE
);
4680 menu
->Enable(wxID_RESTORE_FRAME
, FALSE
);
4683 window
->PopupMenu(menu
, pos
);
4687 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4690 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4692 // always detach if active frame changed:
4693 m_menuHandler
->Detach();
4697 m_menuHandler
->Attach(consumer
);
4701 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);