1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/themes/win32.cpp
3 // Purpose: wxUniversal theme implementing Win32-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
31 #include "wx/window.h"
33 #include "wx/dcmemory.h"
35 #include "wx/button.h"
36 #include "wx/bmpbuttn.h"
37 #include "wx/listbox.h"
38 #include "wx/checklst.h"
39 #include "wx/combobox.h"
40 #include "wx/scrolbar.h"
41 #include "wx/slider.h"
42 #include "wx/textctrl.h"
43 #include "wx/listbox.h"
44 #include "wx/toolbar.h"
45 #include "wx/statusbr.h"
48 // for COLOR_* constants
49 #include "wx/msw/private.h"
52 #include "wx/settings.h"
55 #include "wx/notebook.h"
56 #include "wx/spinbutt.h"
57 #include "wx/artprov.h"
58 #include "wx/toplevel.h"
60 #ifdef wxUSE_TOGGLEBTN
61 #include "wx/tglbtn.h"
62 #endif // wxUSE_TOGGLEBTN
64 #include "wx/univ/scrtimer.h"
65 #include "wx/univ/renderer.h"
66 #include "wx/univ/inphand.h"
67 #include "wx/univ/colschem.h"
68 #include "wx/univ/theme.h"
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 static const int BORDER_THICKNESS
= 2;
76 // the offset between the label and focus rect around it
77 static const int FOCUS_RECT_OFFSET_X
= 1;
78 static const int FOCUS_RECT_OFFSET_Y
= 1;
80 static const int FRAME_BORDER_THICKNESS
= 3;
81 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
82 static const int FRAME_TITLEBAR_HEIGHT
= 18;
83 static const int FRAME_BUTTON_WIDTH
= 16;
84 static const int FRAME_BUTTON_HEIGHT
= 14;
86 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
87 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
88 static const size_t STATUSBAR_GRIP_SIZE
=
89 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
91 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
92 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
93 static const wxCoord SLIDER_TICK_LENGTH
= 6;
105 IndicatorState_Normal
,
106 IndicatorState_Pressed
, // this one is for check/radioboxes
107 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
108 IndicatorState_Disabled
,
109 IndicatorState_SelectedDisabled
, // only for the menus
115 IndicatorStatus_Checked
,
116 IndicatorStatus_Unchecked
,
117 IndicatorStatus_Undeterminated
,
121 // wxWin32Renderer: draw the GUI elements in Win32 style
122 // ----------------------------------------------------------------------------
124 class wxWin32Renderer
: public wxRenderer
128 enum wxArrowDirection
143 Arrow_InvertedDisabled
,
147 enum wxFrameButtonType
150 FrameButton_Minimize
,
151 FrameButton_Maximize
,
158 wxWin32Renderer(const wxColourScheme
*scheme
);
160 // implement the base class pure virtuals
161 virtual void DrawBackground(wxDC
& dc
,
165 wxWindow
*window
= NULL
);
166 virtual void DrawLabel(wxDC
& dc
,
167 const wxString
& label
,
170 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
172 wxRect
*rectBounds
= NULL
);
173 virtual void DrawButtonLabel(wxDC
& dc
,
174 const wxString
& label
,
175 const wxBitmap
& image
,
178 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
180 wxRect
*rectBounds
= NULL
);
181 virtual void DrawBorder(wxDC
& dc
,
185 wxRect
*rectIn
= (wxRect
*)NULL
);
186 virtual void DrawHorizontalLine(wxDC
& dc
,
187 wxCoord y
, wxCoord x1
, wxCoord x2
);
188 virtual void DrawVerticalLine(wxDC
& dc
,
189 wxCoord x
, wxCoord y1
, wxCoord y2
);
190 virtual void DrawFrame(wxDC
& dc
,
191 const wxString
& label
,
194 int alignment
= wxALIGN_LEFT
,
195 int indexAccel
= -1);
196 virtual void DrawTextBorder(wxDC
& dc
,
200 wxRect
*rectIn
= (wxRect
*)NULL
);
201 virtual void DrawButtonBorder(wxDC
& dc
,
204 wxRect
*rectIn
= (wxRect
*)NULL
);
205 virtual void DrawArrow(wxDC
& dc
,
209 virtual void DrawScrollbarArrow(wxDC
& dc
,
213 { DrawArrow(dc
, dir
, rect
, flags
); }
214 virtual void DrawScrollbarThumb(wxDC
& dc
,
215 wxOrientation orient
,
218 virtual void DrawScrollbarShaft(wxDC
& dc
,
219 wxOrientation orient
,
222 virtual void DrawScrollCorner(wxDC
& dc
,
224 virtual void DrawItem(wxDC
& dc
,
225 const wxString
& label
,
228 virtual void DrawCheckItem(wxDC
& dc
,
229 const wxString
& label
,
230 const wxBitmap
& bitmap
,
233 virtual void DrawCheckButton(wxDC
& dc
,
234 const wxString
& label
,
235 const wxBitmap
& bitmap
,
238 wxAlignment align
= wxALIGN_LEFT
,
239 int indexAccel
= -1);
240 virtual void DrawRadioButton(wxDC
& dc
,
241 const wxString
& label
,
242 const wxBitmap
& bitmap
,
245 wxAlignment align
= wxALIGN_LEFT
,
246 int indexAccel
= -1);
247 virtual void DrawToolBarButton(wxDC
& dc
,
248 const wxString
& label
,
249 const wxBitmap
& bitmap
,
254 virtual void DrawTextLine(wxDC
& dc
,
255 const wxString
& text
,
260 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
261 virtual void DrawTab(wxDC
& dc
,
264 const wxString
& label
,
265 const wxBitmap
& bitmap
= wxNullBitmap
,
267 int indexAccel
= -1);
269 virtual void DrawSliderShaft(wxDC
& dc
,
272 wxOrientation orient
,
275 wxRect
*rectShaft
= NULL
);
276 virtual void DrawSliderThumb(wxDC
& dc
,
278 wxOrientation orient
,
281 virtual void DrawSliderTicks(wxDC
& dc
,
284 wxOrientation orient
,
291 virtual void DrawMenuBarItem(wxDC
& dc
,
293 const wxString
& label
,
295 int indexAccel
= -1);
296 virtual void DrawMenuItem(wxDC
& dc
,
298 const wxMenuGeometryInfo
& geometryInfo
,
299 const wxString
& label
,
300 const wxString
& accel
,
301 const wxBitmap
& bitmap
= wxNullBitmap
,
303 int indexAccel
= -1);
304 virtual void DrawMenuSeparator(wxDC
& dc
,
306 const wxMenuGeometryInfo
& geomInfo
);
308 virtual void DrawStatusField(wxDC
& dc
,
310 const wxString
& label
,
311 int flags
= 0, int style
= 0);
314 virtual void DrawFrameTitleBar(wxDC
& dc
,
316 const wxString
& title
,
319 int specialButton
= 0,
320 int specialButtonFlags
= 0);
321 virtual void DrawFrameBorder(wxDC
& dc
,
324 virtual void DrawFrameBackground(wxDC
& dc
,
327 virtual void DrawFrameTitle(wxDC
& dc
,
329 const wxString
& title
,
331 virtual void DrawFrameIcon(wxDC
& dc
,
335 virtual void DrawFrameButton(wxDC
& dc
,
336 wxCoord x
, wxCoord y
,
339 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
340 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
341 virtual wxSize
GetFrameMinSize(int flags
) const;
342 virtual wxSize
GetFrameIconSize() const;
343 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
345 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
347 wxBitmap
*bmpPressed
,
348 wxBitmap
*bmpDisabled
);
350 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
351 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
352 virtual bool AreScrollbarsInsideBorder() const;
354 virtual wxSize
GetScrollbarArrowSize() const
355 { return m_sizeScrollbarArrow
; }
356 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
357 wxScrollBar::Element elem
,
358 int thumbPos
= -1) const;
359 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
360 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
361 const wxPoint
& pt
) const;
362 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
364 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
365 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
366 { return fontHeight
+ 2; }
367 virtual wxSize
GetCheckBitmapSize() const
368 { return wxSize(13, 13); }
369 virtual wxSize
GetRadioBitmapSize() const
370 { return wxSize(12, 12); }
371 virtual wxCoord
GetCheckItemMargin() const
374 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
375 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
376 virtual wxSize
GetToolBarMargin() const
377 { return wxSize(4, 4); }
379 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
380 const wxRect
& rect
) const;
381 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
383 wxCoord
*extraSpaceBeyond
) const;
385 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
386 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
388 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
389 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
390 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
392 wxOrientation orient
,
393 long style
= 0) const;
394 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
396 wxOrientation orient
) const;
397 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
399 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
400 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
401 const wxMenu
& menu
) const;
403 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
406 // helper of DrawLabel() and DrawCheckOrRadioButton()
407 void DoDrawLabel(wxDC
& dc
,
408 const wxString
& label
,
411 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
413 wxRect
*rectBounds
= NULL
,
414 const wxPoint
& focusOffset
415 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
417 // common part of DrawLabel() and DrawItem()
418 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
420 // DrawLabel() and DrawButtonLabel() helper
421 void DrawLabelShadow(wxDC
& dc
,
422 const wxString
& label
,
427 // DrawButtonBorder() helper
428 void DoDrawBackground(wxDC
& dc
,
431 wxWindow
*window
= NULL
);
433 // DrawBorder() helpers: all of them shift and clip the DC after drawing
436 // just draw a rectangle with the given pen
437 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
439 // draw the lower left part of rectangle
440 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
442 // draw the rectange using the first brush for the left and top sides and
443 // the second one for the bottom and right ones
444 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
445 const wxPen
& pen1
, const wxPen
& pen2
);
447 // draw the normal 3D border
448 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
450 // draw the sunken 3D border
451 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
453 // draw the border used for scrollbar arrows
454 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
456 // public DrawArrow()s helper
457 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
458 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
460 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
461 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
462 wxArrowDirection arrowDir
,
463 wxArrowStyle arrowStyle
);
465 // DrawCheckButton/DrawRadioButton helper
466 void DrawCheckOrRadioButton(wxDC
& dc
,
467 const wxString
& label
,
468 const wxBitmap
& bitmap
,
473 wxCoord focusOffsetY
);
475 // draw a normal or transposed line (useful for using the same code fo both
476 // horizontal and vertical widgets)
477 void DrawLine(wxDC
& dc
,
478 wxCoord x1
, wxCoord y1
,
479 wxCoord x2
, wxCoord y2
,
480 bool transpose
= false)
483 dc
.DrawLine(y1
, x1
, y2
, x2
);
485 dc
.DrawLine(x1
, y1
, x2
, y2
);
488 // get the standard check/radio button bitmap
489 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
490 wxBitmap
GetCheckBitmap(int flags
)
491 { return GetIndicator(IndicatorType_Check
, flags
); }
492 wxBitmap
GetRadioBitmap(int flags
)
493 { return GetIndicator(IndicatorType_Radio
, flags
); }
496 const wxColourScheme
*m_scheme
;
498 // the sizing parameters (TODO make them changeable)
499 wxSize m_sizeScrollbarArrow
;
501 // GDI objects we use for drawing
502 wxColour m_colDarkGrey
,
510 wxFont m_titlebarFont
;
512 // the checked and unchecked bitmaps for DrawCheckItem()
513 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
515 // the bitmaps returned by GetIndicator()
516 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
518 [IndicatorStatus_Max
];
521 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
523 // first row is for the normal state, second - for the disabled
524 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
527 // ----------------------------------------------------------------------------
528 // wxWin32InputHandler and derived classes: process the keyboard and mouse
529 // messages according to Windows standards
530 // ----------------------------------------------------------------------------
532 class wxWin32InputHandler
: public wxInputHandler
535 wxWin32InputHandler(wxWin32Renderer
*renderer
);
537 virtual bool HandleKey(wxInputConsumer
*control
,
538 const wxKeyEvent
& event
,
540 virtual bool HandleMouse(wxInputConsumer
*control
,
541 const wxMouseEvent
& event
);
544 wxWin32Renderer
*m_renderer
;
547 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
550 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
551 wxInputHandler
*handler
);
553 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
554 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
556 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
557 const wxControlAction
& action
);
560 virtual bool IsAllowedButton(int button
) { return button
== 1; }
562 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
565 // we don't highlight anything
568 // the first and last event which caused the thumb to move
569 wxMouseEvent m_eventStartDrag
,
572 // have we paused the scrolling because the mouse moved?
575 // we remember the interval of the timer to be able to restart it
579 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
582 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
583 : wxStdCheckboxInputHandler(handler
) { }
585 virtual bool HandleKey(wxInputConsumer
*control
,
586 const wxKeyEvent
& event
,
590 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
593 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
594 : wxStdTextCtrlInputHandler(handler
) { }
596 virtual bool HandleKey(wxInputConsumer
*control
,
597 const wxKeyEvent
& event
,
601 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
604 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
606 virtual bool HandleMouse(wxInputConsumer
*consumer
,
607 const wxMouseEvent
& event
);
609 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
610 const wxMouseEvent
& event
);
613 // is the given point over the statusbar grip?
614 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
617 // the cursor we had replaced with the resize one
618 wxCursor m_cursorOld
;
620 // was the mouse over the grip last time we checked?
624 class wxWin32SystemMenuEvtHandler
;
626 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
629 wxWin32FrameInputHandler(wxInputHandler
*handler
);
630 ~wxWin32FrameInputHandler();
632 virtual bool HandleMouse(wxInputConsumer
*control
,
633 const wxMouseEvent
& event
);
635 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
637 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
640 // was the mouse over the grip last time we checked?
641 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
644 // ----------------------------------------------------------------------------
645 // wxWin32ColourScheme: uses (default) Win32 colours
646 // ----------------------------------------------------------------------------
648 class wxWin32ColourScheme
: public wxColourScheme
651 virtual wxColour
Get(StdColour col
) const;
652 virtual wxColour
GetBackground(wxWindow
*win
) const;
655 // ----------------------------------------------------------------------------
656 // wxWin32ArtProvider
657 // ----------------------------------------------------------------------------
659 class wxWin32ArtProvider
: public wxArtProvider
662 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
663 const wxArtClient
& client
,
667 // ----------------------------------------------------------------------------
669 // ----------------------------------------------------------------------------
671 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
673 class wxWin32Theme
: public wxTheme
677 virtual ~wxWin32Theme();
679 virtual wxRenderer
*GetRenderer();
680 virtual wxArtProvider
*GetArtProvider();
681 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
682 virtual wxColourScheme
*GetColourScheme();
685 // get the default input handler
686 wxInputHandler
*GetDefaultInputHandler();
688 wxWin32Renderer
*m_renderer
;
690 wxWin32ArtProvider
*m_artProvider
;
692 // the names of the already created handlers and the handlers themselves
693 // (these arrays are synchronized)
694 wxSortedArrayString m_handlerNames
;
695 wxArrayHandlers m_handlers
;
697 wxWin32InputHandler
*m_handlerDefault
;
699 wxWin32ColourScheme
*m_scheme
;
701 WX_DECLARE_THEME(win32
)
704 // ----------------------------------------------------------------------------
706 // ----------------------------------------------------------------------------
708 // frame buttons bitmaps
710 static const char *frame_button_close_xpm
[] = {
725 static const char *frame_button_help_xpm
[] = {
740 static const char *frame_button_maximize_xpm
[] = {
755 static const char *frame_button_minimize_xpm
[] = {
770 static const char *frame_button_restore_xpm
[] = {
787 static const char *checked_menu_xpm
[] = {
788 /* columns rows colors chars-per-pixel */
804 static const char *selected_checked_menu_xpm
[] = {
805 /* columns rows colors chars-per-pixel */
821 static const char *disabled_checked_menu_xpm
[] = {
822 /* columns rows colors chars-per-pixel */
839 static const char *selected_disabled_checked_menu_xpm
[] = {
840 /* columns rows colors chars-per-pixel */
856 // checkbox and radiobox bitmaps below
858 static const char *checked_xpm
[] = {
859 /* columns rows colors chars-per-pixel */
882 static const char *pressed_checked_xpm
[] = {
883 /* columns rows colors chars-per-pixel */
905 static const char *pressed_disabled_checked_xpm
[] = {
906 /* columns rows colors chars-per-pixel */
928 static const char *checked_item_xpm
[] = {
929 /* columns rows colors chars-per-pixel */
950 static const char *unchecked_xpm
[] = {
951 /* columns rows colors chars-per-pixel */
974 static const char *pressed_unchecked_xpm
[] = {
975 /* columns rows colors chars-per-pixel */
997 static const char *unchecked_item_xpm
[] = {
998 /* columns rows colors chars-per-pixel */
1018 static const char *undetermined_xpm
[] = {
1019 /* columns rows colors chars-per-pixel */
1042 static const char *pressed_undetermined_xpm
[] = {
1043 /* columns rows colors chars-per-pixel */
1066 static const char *checked_radio_xpm
[] = {
1067 /* columns rows colors chars-per-pixel */
1090 static const char *pressed_checked_radio_xpm
[] = {
1091 /* columns rows colors chars-per-pixel */
1114 static const char *pressed_disabled_checked_radio_xpm
[] = {
1115 /* columns rows colors chars-per-pixel */
1138 static const char *unchecked_radio_xpm
[] = {
1139 /* columns rows colors chars-per-pixel */
1162 static const char *pressed_unchecked_radio_xpm
[] = {
1163 /* columns rows colors chars-per-pixel */
1186 static const char **
1187 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1192 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1195 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1198 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1204 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1207 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1210 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1216 { checked_menu_xpm
, NULL
, NULL
},
1219 { selected_checked_menu_xpm
, NULL
, NULL
},
1222 { disabled_checked_menu_xpm
, NULL
, NULL
},
1224 // disabled selected state
1225 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1229 static const char **xpmChecked
[IndicatorStatus_Max
] =
1235 // ============================================================================
1237 // ============================================================================
1239 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1241 // ----------------------------------------------------------------------------
1243 // ----------------------------------------------------------------------------
1245 wxWin32Theme::wxWin32Theme()
1249 m_handlerDefault
= NULL
;
1250 m_artProvider
= NULL
;
1253 wxWin32Theme::~wxWin32Theme()
1255 size_t count
= m_handlers
.GetCount();
1256 for ( size_t n
= 0; n
< count
; n
++ )
1258 if ( m_handlers
[n
] != m_handlerDefault
)
1259 delete m_handlers
[n
];
1262 delete m_handlerDefault
;
1266 wxArtProvider::RemoveProvider(m_artProvider
);
1269 wxRenderer
*wxWin32Theme::GetRenderer()
1273 m_renderer
= new wxWin32Renderer(GetColourScheme());
1279 wxArtProvider
*wxWin32Theme::GetArtProvider()
1281 if ( !m_artProvider
)
1283 m_artProvider
= new wxWin32ArtProvider
;
1286 return m_artProvider
;
1289 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1291 if ( !m_handlerDefault
)
1293 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1296 return m_handlerDefault
;
1299 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1301 wxInputHandler
*handler
;
1302 int n
= m_handlerNames
.Index(control
);
1303 if ( n
== wxNOT_FOUND
)
1305 // create a new handler
1306 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1307 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1308 GetDefaultInputHandler());
1310 else if ( control
== wxINP_HANDLER_BUTTON
)
1311 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1312 #endif // wxUSE_BUTTON
1314 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1315 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1316 #endif // wxUSE_CHECKBOX
1318 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1319 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1320 #endif // wxUSE_COMBOBOX
1322 else if ( control
== wxINP_HANDLER_LISTBOX
)
1323 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1324 #endif // wxUSE_LISTBOX
1325 #if wxUSE_CHECKLISTBOX
1326 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1327 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1328 #endif // wxUSE_CHECKLISTBOX
1330 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1331 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1332 #endif // wxUSE_TEXTCTRL
1334 else if ( control
== wxINP_HANDLER_SLIDER
)
1335 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1336 #endif // wxUSE_SLIDER
1338 else if ( control
== wxINP_HANDLER_SPINBTN
)
1339 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1340 #endif // wxUSE_SPINBTN
1342 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1343 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1344 #endif // wxUSE_NOTEBOOK
1346 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1347 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1348 #endif // wxUSE_STATUSBAR
1350 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1351 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1352 #endif // wxUSE_TOOLBAR
1353 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1354 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1356 handler
= GetDefaultInputHandler();
1358 n
= m_handlerNames
.Add(control
);
1359 m_handlers
.Insert(handler
, n
);
1361 else // we already have it
1363 handler
= m_handlers
[n
];
1369 wxColourScheme
*wxWin32Theme::GetColourScheme()
1373 m_scheme
= new wxWin32ColourScheme
;
1378 // ============================================================================
1379 // wxWin32ColourScheme
1380 // ============================================================================
1382 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1385 if ( win
->UseBgCol() )
1387 // use the user specified colour
1388 col
= win
->GetBackgroundColour();
1391 if ( !win
->ShouldInheritColours() )
1393 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1395 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1403 if ( !win
->IsEnabled() ) // not IsEditable()
1409 // doesn't depend on the state
1416 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1420 int flags
= win
->GetStateFlags();
1422 // the colour set by the user should be used for the normal state
1423 // and for the states for which we don't have any specific colours
1424 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1426 if ( wxDynamicCast(win
, wxScrollBar
) )
1427 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1437 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1441 // use the system colours under Windows
1442 #if defined(__WXMSW__)
1443 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1445 case CONTROL_PRESSED
:
1446 case CONTROL_CURRENT
:
1447 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1449 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1451 #if defined(COLOR_3DLIGHT)
1452 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1454 case SCROLLBAR
: return wxColour(0xe0e0e0);
1456 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1458 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1459 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1461 #if defined(COLOR_3DDKSHADOW)
1462 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1464 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1467 case CONTROL_TEXT_DISABLED
:
1468 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1470 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1472 case CONTROL_TEXT_DISABLED_SHADOW
:
1473 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1475 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1476 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1477 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1478 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1480 case DESKTOP
: return wxColour(0x808000);
1482 // use the standard Windows colours elsewhere
1483 case WINDOW
: return *wxWHITE
;
1485 case CONTROL_PRESSED
:
1486 case CONTROL_CURRENT
:
1487 case CONTROL
: return wxColour(0xc0c0c0);
1489 case CONTROL_TEXT
: return *wxBLACK
;
1491 case SCROLLBAR
: return wxColour(0xe0e0e0);
1492 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1494 case HIGHLIGHT
: return wxColour(0x800000);
1495 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1497 case SHADOW_DARK
: return *wxBLACK
;
1499 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1500 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1502 case SHADOW_IN
: return wxColour(0xc0c0c0);
1504 case CONTROL_TEXT_DISABLED_SHADOW
:
1505 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1507 case TITLEBAR
: return wxColour(0xaeaaae);
1508 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1509 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1510 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1512 case DESKTOP
: return wxColour(0x808000);
1515 case GAUGE
: return Get(HIGHLIGHT
);
1519 wxFAIL_MSG(_T("invalid standard colour"));
1524 // ============================================================================
1526 // ============================================================================
1528 // ----------------------------------------------------------------------------
1530 // ----------------------------------------------------------------------------
1532 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1536 m_sizeScrollbarArrow
= wxSize(16, 16);
1538 // init colours and pens
1539 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1541 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1542 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1544 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1546 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1547 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1549 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1550 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1552 // init the arrow bitmaps
1553 static const size_t ARROW_WIDTH
= 7;
1554 static const size_t ARROW_LENGTH
= 4;
1557 wxMemoryDC dcNormal
,
1560 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1562 bool isVertical
= n
> Arrow_Right
;
1575 // disabled arrow is larger because of the shadow
1576 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1577 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1579 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1580 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1582 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1583 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1587 dcNormal
.SetPen(m_penBlack
);
1588 dcDisabled
.SetPen(m_penDarkGrey
);
1590 // calculate the position of the point of the arrow
1594 x1
= (ARROW_WIDTH
- 1)/2;
1595 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1599 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1600 y1
= (ARROW_WIDTH
- 1)/2;
1611 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1613 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1614 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1621 if ( n
== Arrow_Up
)
1632 else // left or right arrow
1637 if ( n
== Arrow_Left
)
1650 // draw the shadow for the disabled one
1651 dcDisabled
.SetPen(m_penHighlight
);
1656 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1660 x1
= ARROW_LENGTH
- 1;
1661 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1664 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1665 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1670 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1674 x1
= ARROW_WIDTH
- 1;
1676 x2
= (ARROW_WIDTH
- 1)/2;
1678 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1679 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1684 // create the inverted bitmap but only for the right arrow as we only
1685 // use it for the menus
1686 if ( n
== Arrow_Right
)
1688 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1689 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1691 dcInverse
.Blit(0, 0, w
, h
,
1694 dcInverse
.SelectObject(wxNullBitmap
);
1696 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1697 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1699 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1700 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1702 dcInverse
.Blit(0, 0, w
, h
,
1705 dcInverse
.SelectObject(wxNullBitmap
);
1707 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1708 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1711 dcNormal
.SelectObject(wxNullBitmap
);
1712 dcDisabled
.SelectObject(wxNullBitmap
);
1714 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1715 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1716 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1717 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1719 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1722 // init the frame buttons bitmaps
1723 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1724 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1725 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1726 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1727 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1730 // ----------------------------------------------------------------------------
1732 // ----------------------------------------------------------------------------
1735 The raised border in Win32 looks like this:
1737 IIIIIIIIIIIIIIIIIIIIIIB
1739 I GB I = white (HILIGHT)
1740 I GB H = light grey (LIGHT)
1741 I GB G = dark grey (SHADOI)
1742 I GB B = black (DKSHADOI)
1743 I GB I = hIghlight (COLOR_3DHILIGHT)
1745 IGGGGGGGGGGGGGGGGGGGGGB
1746 BBBBBBBBBBBBBBBBBBBBBBB
1748 The sunken border looks like this:
1750 GGGGGGGGGGGGGGGGGGGGGGI
1751 GBBBBBBBBBBBBBBBBBBBBHI
1758 GHHHHHHHHHHHHHHHHHHHHHI
1759 IIIIIIIIIIIIIIIIIIIIIII
1761 The static border (used for the controls which don't get focus) is like
1764 GGGGGGGGGGGGGGGGGGGGGGW
1772 WWWWWWWWWWWWWWWWWWWWWWW
1774 The most complicated is the double border:
1776 HHHHHHHHHHHHHHHHHHHHHHB
1777 HWWWWWWWWWWWWWWWWWWWWGB
1778 HWHHHHHHHHHHHHHHHHHHHGB
1783 HWHHHHHHHHHHHHHHHHHHHGB
1784 HGGGGGGGGGGGGGGGGGGGGGB
1785 BBBBBBBBBBBBBBBBBBBBBBB
1787 And the simple border is, well, simple:
1789 BBBBBBBBBBBBBBBBBBBBBBB
1798 BBBBBBBBBBBBBBBBBBBBBBB
1801 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1805 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1806 dc
.DrawRectangle(*rect
);
1812 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1814 // draw the bottom and right sides
1816 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1817 rect
->GetRight() + 1, rect
->GetBottom());
1818 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1819 rect
->GetRight(), rect
->GetBottom());
1825 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1826 const wxPen
& pen1
, const wxPen
& pen2
)
1828 // draw the rectangle
1830 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1831 rect
->GetLeft(), rect
->GetBottom());
1832 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1833 rect
->GetRight(), rect
->GetTop());
1835 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1836 rect
->GetRight(), rect
->GetBottom());
1837 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1838 rect
->GetRight() + 1, rect
->GetBottom());
1844 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1846 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1847 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1850 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1852 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1853 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1856 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1860 DrawRect(dc
, rect
, m_penDarkGrey
);
1862 // the arrow is usually drawn inside border of width 2 and is offset by
1863 // another pixel in both directions when it's pressed - as the border
1864 // in this case is more narrow as well, we have to adjust rect like
1872 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1873 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1877 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1879 const wxRect
& rectTotal
,
1880 int WXUNUSED(flags
),
1885 wxRect rect
= rectTotal
;
1889 case wxBORDER_SUNKEN
:
1890 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1892 DrawSunkenBorder(dc
, &rect
);
1896 case wxBORDER_STATIC
:
1897 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1900 case wxBORDER_RAISED
:
1901 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1903 DrawRaisedBorder(dc
, &rect
);
1907 case wxBORDER_DOUBLE
:
1908 DrawArrowBorder(dc
, &rect
);
1909 DrawRect(dc
, &rect
, m_penLightGrey
);
1912 case wxBORDER_SIMPLE
:
1913 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1915 DrawRect(dc
, &rect
, m_penBlack
);
1920 wxFAIL_MSG(_T("unknown border type"));
1923 case wxBORDER_DEFAULT
:
1932 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1937 case wxBORDER_RAISED
:
1938 case wxBORDER_SUNKEN
:
1939 width
= BORDER_THICKNESS
;
1942 case wxBORDER_SIMPLE
:
1943 case wxBORDER_STATIC
:
1947 case wxBORDER_DOUBLE
:
1953 // char *crash = NULL;
1955 wxFAIL_MSG(_T("unknown border type"));
1959 case wxBORDER_DEFAULT
:
1969 rect
.height
= width
;
1974 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1979 // ----------------------------------------------------------------------------
1981 // ----------------------------------------------------------------------------
1983 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1989 // text controls are not special under windows
1990 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1993 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1994 const wxRect
& rectTotal
,
1998 wxRect rect
= rectTotal
;
2000 if ( flags
& wxCONTROL_PRESSED
)
2002 // button pressed: draw a double border around it
2003 DrawRect(dc
, &rect
, m_penBlack
);
2004 DrawRect(dc
, &rect
, m_penDarkGrey
);
2008 // button not pressed
2010 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
2012 // button either default or focused (or both): add an extra border around it
2013 DrawRect(dc
, &rect
, m_penBlack
);
2016 // now draw a normal button
2017 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
2018 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
2027 // ----------------------------------------------------------------------------
2029 // ----------------------------------------------------------------------------
2031 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
2032 wxCoord y
, wxCoord x1
, wxCoord x2
)
2034 dc
.SetPen(m_penDarkGrey
);
2035 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2036 dc
.SetPen(m_penHighlight
);
2038 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2041 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
2042 wxCoord x
, wxCoord y1
, wxCoord y2
)
2044 dc
.SetPen(m_penDarkGrey
);
2045 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2046 dc
.SetPen(m_penHighlight
);
2048 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2051 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
2052 const wxString
& label
,
2058 wxCoord height
= 0; // of the label
2059 wxRect rectFrame
= rect
;
2060 if ( !label
.empty() )
2062 // the text should touch the top border of the rect, so the frame
2063 // itself should be lower
2064 dc
.GetTextExtent(label
, NULL
, &height
);
2065 rectFrame
.y
+= height
/ 2;
2066 rectFrame
.height
-= height
/ 2;
2068 // we have to draw each part of the frame individually as we can't
2069 // erase the background beyond the label as it might contain some
2070 // pixmap already, so drawing everything and then overwriting part of
2071 // the frame with label doesn't work
2073 // TODO: the +5 and space insertion should be customizable
2076 rectText
.x
= rectFrame
.x
+ 5;
2077 rectText
.y
= rect
.y
;
2078 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2079 rectText
.height
= height
;
2082 label2
<< _T(' ') << label
<< _T(' ');
2083 if ( indexAccel
!= -1 )
2085 // adjust it as we prepended a space
2090 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2092 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2096 // just draw the complete frame
2097 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2098 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2102 // ----------------------------------------------------------------------------
2104 // ----------------------------------------------------------------------------
2106 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2108 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2109 // pixels each while we really need dots here... PS_ALTERNATE might
2110 // work, but it is for NT 5 only
2112 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2114 // draw the pixels manually: note that to behave in the same manner as
2115 // DrawRect(), we must exclude the bottom and right borders from the
2117 wxCoord x1
= rect
.GetLeft(),
2119 x2
= rect
.GetRight(),
2120 y2
= rect
.GetBottom();
2122 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2124 // this seems to be closer than what Windows does than wxINVERT although
2125 // I'm still not sure if it's correct
2126 dc
.SetLogicalFunction(wxAND_REVERSE
);
2129 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2130 dc
.DrawPoint(z
, rect
.GetTop());
2132 wxCoord shift
= z
== x2
? 0 : 1;
2133 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2134 dc
.DrawPoint(x2
, z
);
2136 shift
= z
== y2
? 0 : 1;
2137 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2138 dc
.DrawPoint(z
, y2
);
2140 shift
= z
== x1
? 0 : 1;
2141 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2142 dc
.DrawPoint(x1
, z
);
2144 dc
.SetLogicalFunction(wxCOPY
);
2148 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2149 const wxString
& label
,
2154 // draw shadow of the text
2155 dc
.SetTextForeground(m_colHighlight
);
2156 wxRect rectShadow
= rect
;
2159 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2161 // make the text grey
2162 dc
.SetTextForeground(m_colDarkGrey
);
2165 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2166 const wxString
& label
,
2173 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2176 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2177 const wxString
& label
,
2183 const wxPoint
& focusOffset
)
2185 // the underscores are not drawn for focused controls in wxMSW
2186 if ( flags
& wxCONTROL_FOCUSED
)
2191 if ( flags
& wxCONTROL_DISABLED
)
2193 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2194 // currently only can happen for a menu item and it seems that Windows
2195 // doesn't draw the shadow in this case, so we don't do it neither
2196 if ( flags
& wxCONTROL_SELECTED
)
2198 // just make the label text greyed out
2199 dc
.SetTextForeground(m_colDarkGrey
);
2201 else // draw normal disabled label
2203 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2208 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2210 if ( flags
& wxCONTROL_DISABLED
)
2212 // restore the fg colour
2213 dc
.SetTextForeground(*wxBLACK
);
2216 if ( flags
& wxCONTROL_FOCUSED
)
2218 if ( focusOffset
.x
|| focusOffset
.y
)
2220 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2223 DrawFocusRect(dc
, rectLabel
);
2227 *rectBounds
= rectLabel
;
2230 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2231 const wxString
& label
,
2232 const wxBitmap
& image
,
2239 // the underscores are not drawn for focused controls in wxMSW
2240 if ( flags
& wxCONTROL_PRESSED
)
2245 wxRect rectLabel
= rect
;
2246 if ( !label
.empty() )
2248 // shift the label if a button is pressed
2249 if ( flags
& wxCONTROL_PRESSED
)
2255 if ( flags
& wxCONTROL_DISABLED
)
2257 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2260 // leave enough space for the focus rectangle
2261 if ( flags
& wxCONTROL_FOCUSED
)
2263 rectLabel
.Inflate(-2);
2267 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2269 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2271 if ( flags
& wxCONTROL_PRESSED
)
2273 // the focus rectangle is never pressed, so undo the shift done
2281 DrawFocusRect(dc
, rectLabel
);
2285 // ----------------------------------------------------------------------------
2286 // (check)listbox items
2287 // ----------------------------------------------------------------------------
2289 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2290 const wxString
& label
,
2294 wxDCTextColourChanger
colChanger(dc
);
2296 if ( flags
& wxCONTROL_SELECTED
)
2298 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2300 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2301 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2302 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2303 dc
.DrawRectangle(rect
);
2306 wxRect rectText
= rect
;
2308 rectText
.width
-= 2;
2309 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2311 if ( flags
& wxCONTROL_FOCUSED
)
2313 DrawFocusRect(dc
, rect
);
2317 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2318 const wxString
& label
,
2319 const wxBitmap
& bitmap
,
2328 else // use default bitmap
2330 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2331 ? IndicatorStatus_Checked
2332 : IndicatorStatus_Unchecked
;
2334 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2336 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2339 bmp
= m_bmpCheckBitmaps
[i
];
2342 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2343 true /* use mask */);
2345 wxRect rectLabel
= rect
;
2346 int bmpWidth
= bmp
.GetWidth();
2347 rectLabel
.x
+= bmpWidth
;
2348 rectLabel
.width
-= bmpWidth
;
2350 DrawItem(dc
, label
, rectLabel
, flags
);
2353 // ----------------------------------------------------------------------------
2354 // check/radio buttons
2355 // ----------------------------------------------------------------------------
2357 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2359 IndicatorState indState
;
2360 if ( flags
& wxCONTROL_SELECTED
)
2361 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2362 : IndicatorState_Selected
;
2363 else if ( flags
& wxCONTROL_DISABLED
)
2364 indState
= IndicatorState_Disabled
;
2365 else if ( flags
& wxCONTROL_PRESSED
)
2366 indState
= IndicatorState_Pressed
;
2368 indState
= IndicatorState_Normal
;
2370 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2371 ? IndicatorStatus_Checked
2372 : ( flags
& wxCONTROL_UNDETERMINED
2373 ? IndicatorStatus_Undeterminated
2374 : IndicatorStatus_Unchecked
);
2376 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2379 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2382 // create and cache it
2383 bmp
= wxBitmap(xpm
);
2384 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2391 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2392 const wxString
& label
,
2393 const wxBitmap
& bitmap
,
2398 wxCoord focusOffsetY
)
2400 // calculate the position of the bitmap and of the label
2401 wxCoord heightBmp
= bitmap
.GetHeight();
2403 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2406 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2407 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2409 // align label vertically with the bitmap - looks nicer like this
2410 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2412 // calc horz position
2413 if ( align
== wxALIGN_RIGHT
)
2415 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2416 rectLabel
.x
= rect
.x
+ 3;
2417 rectLabel
.SetRight(xBmp
);
2419 else // normal (checkbox to the left of the text) case
2422 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2423 rectLabel
.SetRight(rect
.GetRight());
2426 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2429 dc
, label
, rectLabel
,
2431 wxALIGN_LEFT
| wxALIGN_TOP
,
2433 NULL
, // we don't need bounding rect
2434 // use custom vert focus rect offset
2435 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2439 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2440 const wxString
& label
,
2441 const wxBitmap
& bitmap
,
2451 bmp
= GetRadioBitmap(flags
);
2453 DrawCheckOrRadioButton(dc
, label
,
2455 rect
, flags
, align
, indexAccel
,
2456 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2459 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2460 const wxString
& label
,
2461 const wxBitmap
& bitmap
,
2471 bmp
= GetCheckBitmap(flags
);
2473 DrawCheckOrRadioButton(dc
, label
,
2475 rect
, flags
, align
, indexAccel
,
2476 0); // no focus rect offset for checkboxes
2479 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2480 const wxString
& label
,
2481 const wxBitmap
& bitmap
,
2482 const wxRect
& rectOrig
,
2487 if (style
== wxTOOL_STYLE_BUTTON
)
2489 wxRect rect
= rectOrig
;
2490 rect
.Deflate(BORDER_THICKNESS
);
2492 if ( flags
& wxCONTROL_PRESSED
)
2494 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2496 else if ( flags
& wxCONTROL_CURRENT
)
2498 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2501 if(tbarStyle
& wxTB_TEXT
)
2503 if(tbarStyle
& wxTB_HORIZONTAL
)
2505 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2509 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
2514 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
2515 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
2516 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
2519 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2521 // leave a small gap aroudn the line, also account for the toolbar
2523 if(rectOrig
.height
> rectOrig
.width
)
2526 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2527 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2528 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2533 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
2534 rectOrig
.x
+ 2*BORDER_THICKNESS
,
2535 rectOrig
.GetRight() - BORDER_THICKNESS
);
2538 // don't draw wxTOOL_STYLE_CONTROL
2541 // ----------------------------------------------------------------------------
2543 // ----------------------------------------------------------------------------
2545 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2546 const wxString
& text
,
2552 // nothing special to do here
2553 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2557 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2558 const wxRect
& WXUNUSED(rect
))
2560 // we don't draw them
2563 // ----------------------------------------------------------------------------
2565 // ----------------------------------------------------------------------------
2567 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2568 const wxRect
& rectOrig
,
2570 const wxString
& label
,
2571 const wxBitmap
& bitmap
,
2575 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2576 #define REVERSE_FOR_VERTICAL(X,Y) \
2577 SELECT_FOR_VERTICAL(X,Y) \
2579 SELECT_FOR_VERTICAL(Y,X)
2581 wxRect rect
= rectOrig
;
2583 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2585 // the current tab is drawn indented (to the top for default case) and
2586 // bigger than the other ones
2587 const wxSize indent
= GetTabIndent();
2588 if ( flags
& wxCONTROL_SELECTED
)
2590 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
2591 SELECT_FOR_VERTICAL( 0, indent
.y
));
2595 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2602 rect
.height
+= indent
.y
;
2609 rect
.width
+= indent
.x
;
2614 // draw the text, image and the focus around them (if necessary)
2615 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2616 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2618 rectLabel
.Deflate(1, 1);
2621 // draw it horizontally into memory and rotate for screen
2623 wxBitmap bitmapRotated
,
2624 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2625 rectLabel
.y
+ rectLabel
.height
);
2626 dcMem
.SelectObject(bitmapMem
);
2627 dcMem
.SetBackground(dc
.GetBackground());
2628 dcMem
.SetFont(dc
.GetFont());
2629 dcMem
.SetTextForeground(dc
.GetTextForeground());
2631 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
2632 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2633 flags
, wxALIGN_CENTRE
, indexAccel
);
2634 dcMem
.SelectObject(wxNullBitmap
);
2635 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2636 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2637 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2641 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2642 flags
, wxALIGN_CENTRE
, indexAccel
);
2645 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2646 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2647 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2648 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2649 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2650 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2652 // FIXME: all this code will break if the tab indent or the border width,
2653 // it is tied to the fact that both of them are equal to 2
2659 // left orientation looks like top but IsVertical makes x and y reversed
2661 // top is not vertical so use coordinates in written order
2662 dc
.SetPen(m_penHighlight
);
2663 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2664 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2665 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2666 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2667 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2668 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2670 dc
.SetPen(m_penBlack
);
2671 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2672 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2673 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2674 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2676 dc
.SetPen(m_penDarkGrey
);
2677 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2678 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2680 if ( flags
& wxCONTROL_SELECTED
)
2682 dc
.SetPen(m_penLightGrey
);
2684 // overwrite the part of the border below this tab
2685 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2686 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2688 // and the shadow of the tab to the left of us
2689 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2690 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2695 // right orientation looks like bottom but IsVertical makes x and y reversed
2697 // bottom is not vertical so use coordinates in written order
2698 dc
.SetPen(m_penHighlight
);
2699 // we need to continue one pixel further to overwrite the corner of
2700 // the border for the selected tab
2701 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
2702 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2703 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2704 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2706 dc
.SetPen(m_penBlack
);
2707 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2708 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2709 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2710 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2711 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2712 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2714 dc
.SetPen(m_penDarkGrey
);
2715 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2716 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2717 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2718 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2720 if ( flags
& wxCONTROL_SELECTED
)
2722 dc
.SetPen(m_penLightGrey
);
2724 // overwrite the part of the (double!) border above this tab
2725 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2726 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2727 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2728 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2730 // and the shadow of the tab to the left of us
2731 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2732 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2737 #undef SELECT_FOR_VERTICAL
2738 #undef REVERSE_FOR_VERTICAL
2741 // ----------------------------------------------------------------------------
2743 // ----------------------------------------------------------------------------
2746 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2748 wxOrientation orient
) const
2751 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2752 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2754 if (orient
== wxHORIZONTAL
)
2768 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2770 wxOrientation orient
,
2773 bool transpose
= (orient
== wxVERTICAL
);
2774 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2775 (((style
& wxSL_TOP
) != 0) & !transpose
|
2776 ((style
& wxSL_LEFT
) != 0) & transpose
|
2777 ((style
& wxSL_BOTH
) != 0));
2778 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2779 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2780 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2781 ((style
& wxSL_BOTH
) != 0));
2783 wxRect rect
= rectOrig
;
2785 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2787 if (orient
== wxHORIZONTAL
) {
2788 rect
.x
+= SLIDER_MARGIN
;
2791 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2795 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2799 rect
.y
+= sizeThumb
.y
/2;
2801 rect
.width
-= 2*SLIDER_MARGIN
;
2802 rect
.height
= 2*BORDER_THICKNESS
;
2806 rect
.y
+= SLIDER_MARGIN
;
2809 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2813 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2817 rect
.x
+= sizeThumb
.x
/2;
2819 rect
.width
= 2*BORDER_THICKNESS
;
2820 rect
.height
-= 2*SLIDER_MARGIN
;
2826 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2827 const wxRect
& rectOrig
,
2829 wxOrientation orient
,
2834 /* show shaft geometry
2852 if (flags
& wxCONTROL_FOCUSED
) {
2853 DrawFocusRect(dc
, rectOrig
);
2856 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2858 if (rectShaft
) *rectShaft
= rect
;
2860 DrawSunkenBorder(dc
, &rect
);
2863 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2865 wxOrientation orient
,
2869 /* show thumb geometry
2878 H D B where H is highlight colour
2892 The interior of this shape is filled with the hatched brush if the thumb
2896 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2898 bool transpose
= (orient
== wxVERTICAL
);
2899 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2900 (((style
& wxSL_TOP
) != 0) & !transpose
|
2901 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2902 ((style
& wxSL_BOTH
) == 0);
2903 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2904 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2905 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2906 ((style
& wxSL_BOTH
) == 0);
2908 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2909 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2911 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2912 x1
= (transpose
? rect
.y
: rect
.x
);
2913 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2914 x3
= (x1
-1+c
) + sizeArrow
;
2915 y1
= (transpose
? rect
.x
: rect
.y
);
2916 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2917 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2918 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2920 dc
.SetPen(m_penBlack
);
2922 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2924 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2927 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2931 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2934 dc
.SetPen(m_penDarkGrey
);
2935 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2937 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2941 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2944 dc
.SetPen(m_penHighlight
);
2947 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2948 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2952 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2954 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2957 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2960 if (flags
& wxCONTROL_PRESSED
) {
2961 // TODO: MSW fills the entire area inside, not just the rect
2962 wxRect rectInt
= rect
;
2965 rectInt
.SetLeft(y3
);
2966 rectInt
.SetRight(y4
);
2971 rectInt
.SetBottom(y4
);
2975 #if !defined(__WXMGL__)
2976 static const char *stipple_xpm
[] = {
2977 /* columns rows colors chars-per-pixel */
2986 // VS: MGL can only do 8x8 stipple brushes
2987 static const char *stipple_xpm
[] = {
2988 /* columns rows colors chars-per-pixel */
3003 dc
.SetBrush(wxBrush(stipple_xpm
));
3005 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
3006 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
3007 dc
.SetPen(*wxTRANSPARENT_PEN
);
3008 dc
.DrawRectangle(rectInt
);
3012 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
3015 wxOrientation orient
,
3019 int WXUNUSED(flags
),
3022 /* show ticks geometry
3037 if (end
== start
) return;
3039 bool transpose
= (orient
== wxVERTICAL
);
3040 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
3041 (((style
& wxSL_TOP
) != 0) & !transpose
|
3042 ((style
& wxSL_LEFT
) != 0) & transpose
|
3043 ((style
& wxSL_BOTH
) != 0));
3044 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
3045 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
3046 ((style
& wxSL_RIGHT
) != 0) & transpose
|
3047 ((style
& wxSL_BOTH
) != 0));
3049 // default thumb size
3050 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
3051 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
3053 // normal thumb size
3054 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
3055 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
3057 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
3059 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
3060 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
3061 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
3062 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
3063 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
3064 y3
= (transpose
? rect
.x
: rect
.y
);
3065 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
3068 dc
.SetPen(m_penBlack
);
3070 int range
= end
- start
;
3071 for ( int n
= 0; n
< range
; n
+= step
) {
3072 wxCoord x
= x1
+ (len
*n
) / range
;
3074 if (left
& (y1
> y3
)) {
3075 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
3077 if (right
& (y4
> y2
)) {
3078 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
3081 // always draw the line at the end position
3082 if (left
& (y1
> y3
)) {
3083 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3085 if (right
& (y4
> y2
)) {
3086 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3090 // ----------------------------------------------------------------------------
3092 // ----------------------------------------------------------------------------
3094 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3095 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3098 virtual wxSize
GetSize() const { return m_size
; }
3100 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3101 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3103 wxCoord
GetItemHeight() const { return m_heightItem
; }
3106 // the total size of the menu
3109 // the offset of the start of the menu item label
3112 // the offset of the start of the accel label
3115 // the height of a normal (not separator) item
3116 wxCoord m_heightItem
;
3118 friend wxMenuGeometryInfo
*
3119 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3122 // FIXME: all constants are hardcoded but shouldn't be
3123 static const wxCoord MENU_LEFT_MARGIN
= 9;
3124 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3125 static const wxCoord MENU_VERT_MARGIN
= 3;
3127 // the margin around bitmap/check marks (on each side)
3128 static const wxCoord MENU_BMP_MARGIN
= 2;
3130 // the margin between the labels and accel strings
3131 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3133 // the separator height in pixels: in fact, strangely enough, the real height
3134 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3136 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3138 // the size of the standard checkmark bitmap
3139 static const wxCoord MENU_CHECK_SIZE
= 9;
3141 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3142 const wxRect
& rectOrig
,
3143 const wxString
& label
,
3147 wxRect rect
= rectOrig
;
3150 wxDCTextColourChanger
colChanger(dc
);
3152 if ( flags
& wxCONTROL_SELECTED
)
3154 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3156 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3157 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3158 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3159 dc
.DrawRectangle(rect
);
3162 // don't draw the focus rect around menu bar items
3163 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3164 wxALIGN_CENTRE
, indexAccel
);
3167 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3169 const wxMenuGeometryInfo
& gi
,
3170 const wxString
& label
,
3171 const wxString
& accel
,
3172 const wxBitmap
& bitmap
,
3176 const wxWin32MenuGeometryInfo
& geometryInfo
=
3177 (const wxWin32MenuGeometryInfo
&)gi
;
3182 rect
.width
= geometryInfo
.GetSize().x
;
3183 rect
.height
= geometryInfo
.GetItemHeight();
3185 // draw the selected item specially
3186 wxDCTextColourChanger
colChanger(dc
);
3187 if ( flags
& wxCONTROL_SELECTED
)
3189 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3191 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3192 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3193 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3194 dc
.DrawRectangle(rect
);
3197 // draw the bitmap: use the bitmap provided or the standard checkmark for
3198 // the checkable items
3199 wxBitmap bmp
= bitmap
;
3200 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3202 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3207 rect
.SetRight(geometryInfo
.GetLabelOffset());
3208 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3212 rect
.x
= geometryInfo
.GetLabelOffset();
3213 rect
.SetRight(geometryInfo
.GetAccelOffset());
3215 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3217 // draw the accel string
3218 rect
.x
= geometryInfo
.GetAccelOffset();
3219 rect
.SetRight(geometryInfo
.GetSize().x
);
3221 // NB: no accel index here
3222 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3224 // draw the submenu indicator
3225 if ( flags
& wxCONTROL_ISSUBMENU
)
3227 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3228 rect
.width
= MENU_RIGHT_MARGIN
;
3230 wxArrowStyle arrowStyle
;
3231 if ( flags
& wxCONTROL_DISABLED
)
3232 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
3234 else if ( flags
& wxCONTROL_SELECTED
)
3235 arrowStyle
= Arrow_Inverted
;
3237 arrowStyle
= Arrow_Normal
;
3239 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3243 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3245 const wxMenuGeometryInfo
& geomInfo
)
3247 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3250 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3252 wxSize size
= sizeText
;
3254 // FIXME: menubar height is configurable under Windows
3261 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3262 const wxMenu
& menu
) const
3264 // prepare the dc: for now we draw all the items with the system font
3266 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3268 // the height of a normal item
3269 wxCoord heightText
= dc
.GetCharHeight();
3274 // the max length of label and accel strings: the menu width is the sum of
3275 // them, even if they're for different items (as the accels should be
3278 // the max length of the bitmap is never 0 as Windows always leaves enough
3279 // space for a check mark indicator
3280 wxCoord widthLabelMax
= 0,
3282 widthBmpMax
= MENU_LEFT_MARGIN
;
3284 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3286 node
= node
->GetNext() )
3288 // height of this item
3291 wxMenuItem
*item
= node
->GetData();
3292 if ( item
->IsSeparator() )
3294 h
= MENU_SEPARATOR_HEIGHT
;
3296 else // not separator
3301 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3302 if ( widthLabel
> widthLabelMax
)
3304 widthLabelMax
= widthLabel
;
3308 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3309 if ( widthAccel
> widthAccelMax
)
3311 widthAccelMax
= widthAccel
;
3314 const wxBitmap
& bmp
= item
->GetBitmap();
3317 wxCoord widthBmp
= bmp
.GetWidth();
3318 if ( widthBmp
> widthBmpMax
)
3319 widthBmpMax
= widthBmp
;
3321 //else if ( item->IsCheckable() ): no need to check for this as
3322 // MENU_LEFT_MARGIN is big enough to show the check mark
3325 h
+= 2*MENU_VERT_MARGIN
;
3327 // remember the item position and height
3328 item
->SetGeometry(height
, h
);
3333 // bundle the metrics into a struct and return it
3334 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3336 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3337 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3338 if ( widthAccelMax
> 0 )
3340 // if we actually have any accesl, add a margin
3341 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3344 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3346 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3347 gi
->m_size
.y
= height
;
3352 // ----------------------------------------------------------------------------
3354 // ----------------------------------------------------------------------------
3356 static const wxCoord STATBAR_BORDER_X
= 2;
3357 static const wxCoord STATBAR_BORDER_Y
= 2;
3359 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3361 if ( borderBetweenFields
)
3362 *borderBetweenFields
= 2;
3364 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3367 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3369 const wxString
& label
,
3370 int flags
, int style
/*=0*/)
3374 if ( flags
& wxCONTROL_ISDEFAULT
)
3376 // draw the size grip: it is a normal rect except that in the lower
3377 // right corner we have several bands which may be used for dragging
3378 // the status bar corner
3380 // each band consists of 4 stripes: m_penHighlight, double
3381 // m_penDarkGrey and transparent one
3382 wxCoord x2
= rect
.GetRight(),
3383 y2
= rect
.GetBottom();
3385 // draw the upper left part of the rect normally
3386 if (style
!= wxSB_FLAT
)
3388 if (style
== wxSB_RAISED
)
3389 dc
.SetPen(m_penHighlight
);
3391 dc
.SetPen(m_penDarkGrey
);
3392 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3393 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3396 // draw the grey stripes of the grip
3398 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3399 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3401 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3402 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3405 // draw the white stripes
3406 dc
.SetPen(m_penHighlight
);
3407 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3408 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3410 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3413 // draw the remaining rect boundaries
3414 if (style
!= wxSB_FLAT
)
3416 if (style
== wxSB_RAISED
)
3417 dc
.SetPen(m_penDarkGrey
);
3419 dc
.SetPen(m_penHighlight
);
3420 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3421 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3422 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3428 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3432 if (style
== wxSB_RAISED
)
3433 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3434 else if (style
!= wxSB_FLAT
)
3435 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3438 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3440 wxDCClipper
clipper(dc
, rectIn
);
3441 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3444 // ----------------------------------------------------------------------------
3446 // ----------------------------------------------------------------------------
3448 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3449 wxBitmap
* WXUNUSED(bmpFocus
),
3450 wxBitmap
*bmpPressed
,
3451 wxBitmap
*bmpDisabled
)
3453 static const wxCoord widthCombo
= 16;
3454 static const wxCoord heightCombo
= 17;
3460 bmpNormal
->Create(widthCombo
, heightCombo
);
3461 dcMem
.SelectObject(*bmpNormal
);
3462 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3463 Arrow_Down
, Arrow_Normal
);
3468 bmpPressed
->Create(widthCombo
, heightCombo
);
3469 dcMem
.SelectObject(*bmpPressed
);
3470 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3471 Arrow_Down
, Arrow_Pressed
);
3476 bmpDisabled
->Create(widthCombo
, heightCombo
);
3477 dcMem
.SelectObject(*bmpDisabled
);
3478 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3479 Arrow_Down
, Arrow_Disabled
);
3483 // ----------------------------------------------------------------------------
3485 // ----------------------------------------------------------------------------
3487 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3488 const wxColour
& col
,
3490 wxWindow
* WXUNUSED(window
))
3492 wxBrush
brush(col
, wxSOLID
);
3494 dc
.SetPen(*wxTRANSPARENT_PEN
);
3495 dc
.DrawRectangle(rect
);
3498 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3499 const wxColour
& col
,
3501 int WXUNUSED(flags
),
3504 // just fill it with the given or default bg colour
3505 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3506 DoDrawBackground(dc
, colBg
, rect
, window
);
3509 // ----------------------------------------------------------------------------
3511 // ----------------------------------------------------------------------------
3513 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3518 // get the bitmap for this arrow
3519 wxArrowDirection arrowDir
;
3522 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3523 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3524 case wxUP
: arrowDir
= Arrow_Up
; break;
3525 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3528 wxFAIL_MSG(_T("unknown arrow direction"));
3532 wxArrowStyle arrowStyle
;
3533 if ( flags
& wxCONTROL_PRESSED
)
3535 // can't be pressed and disabled
3536 arrowStyle
= Arrow_Pressed
;
3540 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3543 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3546 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3548 wxArrowDirection arrowDir
,
3549 wxArrowStyle arrowStyle
)
3551 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3553 // under Windows the arrows always have the same size so just centre it in
3554 // the provided rectangle
3555 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3556 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3558 // Windows does it like this...
3559 if ( arrowDir
== Arrow_Left
)
3563 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3566 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3567 const wxRect
& rectAll
,
3568 wxArrowDirection arrowDir
,
3569 wxArrowStyle arrowStyle
)
3571 wxRect rect
= rectAll
;
3572 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3573 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3574 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3577 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3578 wxOrientation
WXUNUSED(orient
),
3580 int WXUNUSED(flags
))
3582 // we don't use the flags, the thumb never changes appearance
3583 wxRect rectThumb
= rect
;
3584 DrawArrowBorder(dc
, &rectThumb
);
3585 DrawBackground(dc
, wxNullColour
, rectThumb
);
3588 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3589 wxOrientation
WXUNUSED(orient
),
3590 const wxRect
& rectBar
,
3593 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3594 ? wxColourScheme::SCROLLBAR_PRESSED
3595 : wxColourScheme::SCROLLBAR
;
3596 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3599 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3601 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3604 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3605 wxScrollBar::Element elem
,
3608 return StandardGetScrollbarRect(scrollbar
, elem
,
3609 thumbPos
, m_sizeScrollbarArrow
);
3612 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3614 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3617 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3618 const wxPoint
& pt
) const
3620 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3623 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3626 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3629 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3632 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3635 // ----------------------------------------------------------------------------
3636 // top level windows
3637 // ----------------------------------------------------------------------------
3639 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3641 wxRect client
= GetFrameClientArea(rect
, flags
);
3643 if ( client
.Inside(pt
) )
3644 return wxHT_TOPLEVEL_CLIENT_AREA
;
3646 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3648 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3650 if ( flags
& wxTOPLEVEL_ICON
)
3652 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3653 return wxHT_TOPLEVEL_ICON
;
3656 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3657 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3658 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3660 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3662 if ( btnRect
.Inside(pt
) )
3663 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3664 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3666 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3668 if ( btnRect
.Inside(pt
) )
3669 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3670 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3672 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3674 if ( btnRect
.Inside(pt
) )
3675 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3676 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3678 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3680 if ( btnRect
.Inside(pt
) )
3681 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3682 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3684 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3686 if ( btnRect
.Inside(pt
) )
3687 return wxHT_TOPLEVEL_BUTTON_HELP
;
3688 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3691 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3692 return wxHT_TOPLEVEL_TITLEBAR
;
3695 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3697 // we are certainly at one of borders, lets decide which one:
3700 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3701 if ( pt
.x
< client
.x
)
3702 border
|= wxHT_TOPLEVEL_BORDER_W
;
3703 else if ( pt
.x
>= client
.width
+ client
.x
)
3704 border
|= wxHT_TOPLEVEL_BORDER_E
;
3705 if ( pt
.y
< client
.y
)
3706 border
|= wxHT_TOPLEVEL_BORDER_N
;
3707 else if ( pt
.y
>= client
.height
+ client
.y
)
3708 border
|= wxHT_TOPLEVEL_BORDER_S
;
3712 return wxHT_NOWHERE
;
3715 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3717 const wxString
& title
,
3721 int specialButtonFlags
)
3723 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3725 DrawFrameBorder(dc
, rect
, flags
);
3727 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3729 DrawFrameBackground(dc
, rect
, flags
);
3730 if ( flags
& wxTOPLEVEL_ICON
)
3731 DrawFrameIcon(dc
, rect
, icon
, flags
);
3732 DrawFrameTitle(dc
, rect
, title
, flags
);
3734 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3736 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3737 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3739 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3741 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3742 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3743 specialButtonFlags
: 0);
3744 x
-= FRAME_BUTTON_WIDTH
+ 2;
3746 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3748 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3749 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3750 specialButtonFlags
: 0);
3751 x
-= FRAME_BUTTON_WIDTH
;
3753 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3755 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3756 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3757 specialButtonFlags
: 0);
3758 x
-= FRAME_BUTTON_WIDTH
;
3760 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3762 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3763 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3764 specialButtonFlags
: 0);
3765 x
-= FRAME_BUTTON_WIDTH
;
3767 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3769 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3770 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3771 specialButtonFlags
: 0);
3776 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3780 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3784 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3785 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3786 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3787 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3788 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3791 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3795 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3797 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3798 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3799 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3801 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3802 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3804 DrawBackground(dc
, col
, r
);
3807 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3809 const wxString
& title
,
3812 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3813 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3814 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3816 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3817 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3818 if ( flags
& wxTOPLEVEL_ICON
)
3820 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3821 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3829 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3830 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3831 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3832 r
.width
-= FRAME_BUTTON_WIDTH
;
3833 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3834 r
.width
-= FRAME_BUTTON_WIDTH
;
3835 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3836 r
.width
-= FRAME_BUTTON_WIDTH
;
3837 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3838 r
.width
-= FRAME_BUTTON_WIDTH
;
3840 dc
.SetFont(m_titlebarFont
);
3841 dc
.SetTextForeground(col
);
3844 dc
.GetTextExtent(title
, &textW
, NULL
);
3845 if ( textW
> r
.width
)
3847 // text is too big, let's shorten it and add "..." after it:
3848 size_t len
= title
.length();
3849 wxCoord WSoFar
, letterW
;
3851 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3852 if ( WSoFar
> r
.width
)
3854 // not enough space to draw anything
3860 for (size_t i
= 0; i
< len
; i
++)
3862 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3863 if ( letterW
+ WSoFar
> r
.width
)
3869 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3870 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3873 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3874 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3877 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3884 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3885 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3889 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3890 wxCoord x
, wxCoord y
,
3894 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3899 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3900 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3901 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3902 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3903 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3905 wxFAIL_MSG(wxT("incorrect button specification"));
3908 if ( flags
& wxCONTROL_PRESSED
)
3910 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3911 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3912 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3913 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3917 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3918 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3919 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3920 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3925 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3930 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3932 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3933 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3934 FRAME_BORDER_THICKNESS
;
3937 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3939 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3940 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3946 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3949 wxSize
s(clientSize
);
3951 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3953 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3954 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3955 FRAME_BORDER_THICKNESS
;
3959 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3960 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3965 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3969 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3971 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3972 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3973 FRAME_BORDER_THICKNESS
;
3978 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3980 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3982 if ( flags
& wxTOPLEVEL_ICON
)
3983 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3984 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3985 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3986 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3987 s
.x
+= FRAME_BUTTON_WIDTH
;
3988 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3989 s
.x
+= FRAME_BUTTON_WIDTH
;
3990 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3991 s
.x
+= FRAME_BUTTON_WIDTH
;
3992 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3993 s
.x
+= FRAME_BUTTON_WIDTH
;
3999 wxSize
wxWin32Renderer::GetFrameIconSize() const
4001 return wxSize(16, 16);
4005 // ----------------------------------------------------------------------------
4007 // ----------------------------------------------------------------------------
4009 /* Copyright (c) Julian Smart */
4010 static char *error_xpm
[]={
4011 /* columns rows colors chars-per-pixel */
4088 " $oooooooooooo%& ",
4089 " *=-ooooooooooooo;: ",
4090 " *oooooooooooooooooo> ",
4091 " =ooooooooooooooooooo, ",
4092 " $-ooooooooooooooooooo<1 ",
4093 " .oooooo2334ooo533oooooo6 ",
4094 " +ooooooo789oo2883oooooo0q ",
4095 " oooooooo2w83o78eoooooooor ",
4096 " toooooooooy88u884oooooooori ",
4097 " Xooooooooooe888poooooooooas ",
4098 " ooooooooooo4889doooooooooof ",
4099 " ooooooooooo588w2oooooooooofi ",
4100 " oooooooooodw8887oooooooooofi ",
4101 " goooooooooh8w588jooooooookli ",
4102 " tooooooooz885op8wdooooooorix ",
4103 " oooooood98cood98cooooooori ",
4104 " @oooooop8w2ooo5885ooooovbi ",
4105 " n%ooooooooooooooooooooomiM ",
4106 " &;oooooooooooooooooooNBiV ",
4107 " :ooooooooooooooooooCZiA ",
4108 " nSooooooooooooooooCDiF ",
4109 " nG<oooooooooooooNZiiH ",
4110 " 160ooooooooovmBiFH ",
4111 " nqrraoookrrbiiA ",
4118 /* Copyright (c) Julian Smart */
4119 static char *info_xpm
[]={
4120 /* columns rows colors chars-per-pixel */
4142 " ..XXXXXXXXXXXXX.. ",
4143 " .XXXXXXXXXXXXXXXXX. ",
4144 " .XXXXXXXXoO+XXXXXXXX. ",
4145 " .XXXXXXXXX@#OXXXXXXXXX. ",
4146 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
4147 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
4148 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
4149 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
4150 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
4151 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
4152 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4153 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4154 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
4155 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
4156 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
4157 " .XXXXXXXXXXXXXXXXX.%%%% ",
4158 " ..XXXXXXXXXXXXX..%%%% ",
4159 " %...XXXXXXXX..%%%%% ",
4160 " %%%..XXXXXX.%%%%% ",
4174 /* Copyright (c) Julian Smart */
4175 static char *question_xpm
[]={
4176 /* columns rows colors chars-per-pixel */
4197 " ..XXXXXXXXXXXXX.. ",
4198 " .XXXXXXoO++@XXXXXX. ",
4199 " .XXXXXXO#$$$$#%XXXXX. ",
4200 " .XXXXXX@$$#&&#$#oXXXXX. ",
4201 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
4202 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
4203 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
4204 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
4205 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
4206 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
4207 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
4208 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
4209 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
4210 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
4211 " .XXXXXXXX-$$XXXXXXXX.:::: ",
4212 " .XXXXXXXO++XXXXXXX.:::: ",
4213 " ..XXXXXXXXXXXXX..:::: ",
4214 " :...XXXXXXXX..::::: ",
4215 " :::..XXXXXX.::::: ",
4229 /* Copyright (c) Julian Smart */
4230 static char *warning_xpm
[]={
4231 /* columns rows colors chars-per-pixel */
4257 " ..XXXXO@#XXX... ",
4258 " ...XXXXO@#XXXX.. ",
4259 " ..XXXXXO@#XXXX... ",
4260 " ...XXXXXo@OXXXXX.. ",
4261 " ...XXXXXXo@OXXXXXX.. ",
4262 " ..XXXXXXX$@OXXXXXX... ",
4263 " ...XXXXXXXX@XXXXXXXX.. ",
4264 " ...XXXXXXXXXXXXXXXXXX... ",
4265 " ..XXXXXXXXXXOXXXXXXXXX.. ",
4266 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
4267 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
4268 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
4269 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
4270 " .............................. ",
4271 " .............................. ",
4278 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4279 const wxArtClient
& WXUNUSED(client
),
4280 const wxSize
& WXUNUSED(size
))
4282 if ( id
== wxART_INFORMATION
)
4283 return wxBitmap(info_xpm
);
4284 if ( id
== wxART_ERROR
)
4285 return wxBitmap(error_xpm
);
4286 if ( id
== wxART_WARNING
)
4287 return wxBitmap(warning_xpm
);
4288 if ( id
== wxART_QUESTION
)
4289 return wxBitmap(question_xpm
);
4290 return wxNullBitmap
;
4294 // ----------------------------------------------------------------------------
4295 // text control geometry
4296 // ----------------------------------------------------------------------------
4298 static inline int GetTextBorderWidth()
4304 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4305 const wxRect
& rect
) const
4307 wxRect rectTotal
= rect
;
4309 wxCoord widthBorder
= GetTextBorderWidth();
4310 rectTotal
.Inflate(widthBorder
);
4312 // this is what Windows does
4319 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4321 wxCoord
*extraSpaceBeyond
) const
4323 wxRect rectText
= rect
;
4325 // undo GetTextTotalArea()
4326 if ( rectText
.height
> 0 )
4329 wxCoord widthBorder
= GetTextBorderWidth();
4330 rectText
.Inflate(-widthBorder
);
4332 if ( extraSpaceBeyond
)
4333 *extraSpaceBeyond
= 0;
4338 // ----------------------------------------------------------------------------
4340 // ----------------------------------------------------------------------------
4342 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4345 if ( wxDynamicCast(window
, wxScrollBar
) )
4347 // we only set the width of vert scrollbars and height of the
4349 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4350 size
->y
= m_sizeScrollbarArrow
.y
;
4352 size
->x
= m_sizeScrollbarArrow
.x
;
4354 // skip border width adjustments, they don't make sense for us
4357 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4360 if ( wxDynamicCast(window
, wxBitmapButton
) )
4364 #endif // wxUSE_BMPBUTTON
4365 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
4368 || wxDynamicCast(window
, wxButton
)
4369 # endif // wxUSE_BUTTON
4370 # if wxUSE_TOGGLEBTN
4371 || wxDynamicCast(window
, wxToggleButton
)
4372 # endif // wxUSE_TOGGLEBTN
4375 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4377 // TODO: don't harcode all this
4378 size
->x
+= 3*window
->GetCharWidth();
4380 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4381 if ( size
->y
< heightBtn
- 8 )
4382 size
->y
= heightBtn
;
4387 // for compatibility with other ports, the buttons default size is never
4388 // less than the standard one, but not when display not PDAs.
4389 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4391 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4393 wxSize szDef
= wxButton::GetDefaultSize();
4394 if ( size
->x
< szDef
.x
)
4399 // no border width adjustments for buttons
4402 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
4404 // take into account the border width
4405 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4406 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4407 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4410 // ============================================================================
4412 // ============================================================================
4414 // ----------------------------------------------------------------------------
4415 // wxWin32InputHandler
4416 // ----------------------------------------------------------------------------
4418 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4420 m_renderer
= renderer
;
4423 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4424 const wxKeyEvent
& WXUNUSED(event
),
4425 bool WXUNUSED(pressed
))
4430 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4431 const wxMouseEvent
& event
)
4433 // clicking on the control gives it focus
4434 if ( event
.ButtonDown() )
4436 wxWindow
*win
= control
->GetInputWindow();
4438 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4439 ( win
->AcceptsFocus() ) )
4450 // ----------------------------------------------------------------------------
4451 // wxWin32ScrollBarInputHandler
4452 // ----------------------------------------------------------------------------
4454 wxWin32ScrollBarInputHandler::
4455 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4456 wxInputHandler
*handler
)
4457 : wxStdScrollBarInputHandler(renderer
, handler
)
4459 m_scrollPaused
= false;
4463 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4464 const wxControlAction
& action
)
4466 // stop if went beyond the position of the original click (this can only
4467 // happen when we scroll by pages)
4469 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4471 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4472 != wxHT_SCROLLBAR_BAR_2
;
4474 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4476 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4477 != wxHT_SCROLLBAR_BAR_1
;
4482 StopScrolling(scrollbar
);
4484 scrollbar
->Refresh();
4489 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4492 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4493 const wxMouseEvent
& event
)
4495 // remember the current state
4496 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4498 // do process the message
4499 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4501 // analyse the changes
4502 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4504 // we just started dragging the thumb, remember its initial position to
4505 // be able to restore it if the drag is cancelled later
4506 m_eventStartDrag
= event
;
4512 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4513 const wxMouseEvent
& event
)
4515 // we don't highlight scrollbar elements, so there is no need to process
4516 // mouse move events normally - only do it while mouse is captured (i.e.
4517 // when we're dragging the thumb or pressing on something)
4518 if ( !m_winCapture
)
4521 if ( event
.Entering() )
4523 // we're not interested in this at all
4527 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4529 if ( m_scrollPaused
)
4531 // check if the mouse returned to its original location
4533 if ( event
.Leaving() )
4539 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4540 if ( ht
== m_htLast
)
4542 // yes it did, resume scrolling
4543 m_scrollPaused
= false;
4544 if ( m_timerScroll
)
4546 // we were scrolling by line/page, restart timer
4547 m_timerScroll
->Start(m_interval
);
4549 Press(scrollbar
, true);
4551 else // we were dragging the thumb
4553 // restore its last location
4554 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4560 else // normal case, scrolling hasn't been paused
4562 // if we're scrolling the scrollbar because the arrow or the shaft was
4563 // pressed, check that the mouse stays on the same scrollbar element
4566 // Always let thumb jump back if we leave the scrollbar
4567 if ( event
.Moving() )
4569 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4571 else // event.Leaving()
4576 // Jump back only if we get far away from it
4577 wxPoint pos
= event
.GetPosition();
4578 if (scrollbar
->HasFlag( wxVERTICAL
))
4580 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4585 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4588 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4591 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4592 // is still ok - we only want to catch the case when the mouse leaves
4593 // the scrollbar here
4594 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4596 ht
= wxHT_SCROLLBAR_THUMB
;
4599 if ( ht
!= m_htLast
)
4601 // what were we doing? 2 possibilities: either an arrow/shaft was
4602 // pressed in which case we have a timer and so we just stop it or
4603 // we were dragging the thumb
4604 if ( m_timerScroll
)
4607 m_interval
= m_timerScroll
->GetInterval();
4608 m_timerScroll
->Stop();
4609 m_scrollPaused
= true;
4611 // unpress the arrow
4612 Press(scrollbar
, false);
4614 else // we were dragging the thumb
4616 // remember the current thumb position to be able to restore it
4617 // if the mouse returns to it later
4618 m_eventLastDrag
= event
;
4620 // and restore the original position (before dragging) of the
4622 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4629 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4632 // ----------------------------------------------------------------------------
4633 // wxWin32CheckboxInputHandler
4634 // ----------------------------------------------------------------------------
4636 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4637 const wxKeyEvent
& event
,
4642 wxControlAction action
;
4643 int keycode
= event
.GetKeyCode();
4647 action
= wxACTION_CHECKBOX_TOGGLE
;
4651 case WXK_NUMPAD_SUBTRACT
:
4652 action
= wxACTION_CHECKBOX_CHECK
;
4656 case WXK_NUMPAD_ADD
:
4657 case WXK_NUMPAD_EQUAL
:
4658 action
= wxACTION_CHECKBOX_CLEAR
;
4662 if ( !action
.IsEmpty() )
4664 control
->PerformAction(action
);
4673 // ----------------------------------------------------------------------------
4674 // wxWin32TextCtrlInputHandler
4675 // ----------------------------------------------------------------------------
4677 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4678 const wxKeyEvent
& event
,
4681 // handle only MSW-specific text bindings here, the others are handled in
4685 int keycode
= event
.GetKeyCode();
4687 wxControlAction action
;
4688 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4690 action
= wxACTION_TEXT_CUT
;
4692 else if ( keycode
== WXK_INSERT
)
4694 if ( event
.ControlDown() )
4695 action
= wxACTION_TEXT_COPY
;
4696 else if ( event
.ShiftDown() )
4697 action
= wxACTION_TEXT_PASTE
;
4700 if ( action
!= wxACTION_NONE
)
4702 control
->PerformAction(action
);
4708 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4711 // ----------------------------------------------------------------------------
4712 // wxWin32StatusBarInputHandler
4713 // ----------------------------------------------------------------------------
4715 wxWin32StatusBarInputHandler::
4716 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4717 : wxStdInputHandler(handler
)
4722 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4723 const wxPoint
& pt
) const
4725 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4726 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4729 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4731 wxCHECK_MSG( parentTLW
, false,
4732 _T("the status bar should be a child of a TLW") );
4734 // a maximized window can't be resized anyhow
4735 if ( !parentTLW
->IsMaximized() )
4737 // VZ: I think that the standard Windows behaviour is to only
4738 // show the resizing cursor when the mouse is on top of the
4739 // grip itself but apparently different Windows versions behave
4740 // differently (?) and it seems a better UI to allow resizing
4741 // the status bar even when the mouse is above the grip
4742 wxSize sizeSbar
= statbar
->GetSize();
4744 int diff
= sizeSbar
.x
- pt
.x
;
4745 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4752 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4753 const wxMouseEvent
& event
)
4755 if ( event
.Button(1) )
4757 if ( event
.ButtonDown(1) )
4759 wxWindow
*statbar
= consumer
->GetInputWindow();
4761 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4763 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4767 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4768 wxHT_TOPLEVEL_BORDER_SE
);
4770 statbar
->SetCursor(m_cursorOld
);
4778 return wxStdInputHandler::HandleMouse(consumer
, event
);
4781 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4782 const wxMouseEvent
& event
)
4784 wxWindow
*statbar
= consumer
->GetInputWindow();
4786 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4787 if ( isOnGrip
!= m_isOnGrip
)
4789 m_isOnGrip
= isOnGrip
;
4792 m_cursorOld
= statbar
->GetCursor();
4793 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4797 statbar
->SetCursor(m_cursorOld
);
4801 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4804 // ----------------------------------------------------------------------------
4805 // wxWin32FrameInputHandler
4806 // ----------------------------------------------------------------------------
4808 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4811 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4813 void Attach(wxInputConsumer
*consumer
);
4817 DECLARE_EVENT_TABLE()
4818 void OnSystemMenu(wxCommandEvent
&event
);
4819 void OnCloseFrame(wxCommandEvent
&event
);
4820 void OnClose(wxCloseEvent
&event
);
4822 wxWin32FrameInputHandler
*m_inputHnd
;
4823 wxTopLevelWindow
*m_wnd
;
4825 wxAcceleratorTable m_oldAccelTable
;
4829 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4830 wxWin32FrameInputHandler
*handler
)
4832 m_inputHnd
= handler
;
4836 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4838 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4840 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4841 m_wnd
->PushEventHandler(this);
4844 // VS: This code relies on using generic implementation of
4845 // wxAcceleratorTable in wxUniv!
4846 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4847 m_oldAccelTable
= table
;
4848 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4849 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4850 m_wnd
->SetAcceleratorTable(table
);
4854 void wxWin32SystemMenuEvtHandler::Detach()
4859 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4861 m_wnd
->RemoveEventHandler(this);
4866 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4867 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4868 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4869 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4872 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4874 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4875 !m_wnd
->IsMaximized()) ?
4876 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4877 FRAME_BORDER_THICKNESS
;
4878 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4879 pt
.x
= -pt
.x
+ border
;
4880 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4883 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4884 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4887 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4890 m_wnd
->SetAcceleratorTable(table
);
4894 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4896 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4897 wxTOPLEVEL_BUTTON_CLOSE
);
4900 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4907 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4908 : wxStdFrameInputHandler(handler
)
4910 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4913 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4915 if ( m_menuHandler
)
4917 m_menuHandler
->Detach();
4918 delete m_menuHandler
;
4922 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4923 const wxMouseEvent
& event
)
4925 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4927 wxTopLevelWindow
*tlw
=
4928 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4930 long hit
= tlw
->HitTest(event
.GetPosition());
4932 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4934 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4935 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4936 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4939 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4941 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4942 (event
.RightDown() &&
4943 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4944 hit
== wxHT_TOPLEVEL_ICON
)) )
4946 PopupSystemMenu(tlw
, event
.GetPosition());
4952 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4955 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4956 const wxPoint
& pos
) const
4958 wxMenu
*menu
= new wxMenu
;
4960 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4961 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4962 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4963 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4964 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4965 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4966 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4967 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4968 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4969 menu
->AppendSeparator();
4970 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4972 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4974 if ( window
->IsMaximized() )
4976 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4977 menu
->Enable(wxID_MOVE_FRAME
, false);
4978 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4979 menu
->Enable(wxID_RESIZE_FRAME
, false);
4982 menu
->Enable(wxID_RESTORE_FRAME
, false);
4985 window
->PopupMenu(menu
, pos
);
4989 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4992 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4994 // always detach if active frame changed:
4995 m_menuHandler
->Detach();
4999 m_menuHandler
->Attach(consumer
);
5003 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);