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
,
253 virtual void DrawTextLine(wxDC
& dc
,
254 const wxString
& text
,
259 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
260 virtual void DrawTab(wxDC
& dc
,
263 const wxString
& label
,
264 const wxBitmap
& bitmap
= wxNullBitmap
,
266 int indexAccel
= -1);
268 virtual void DrawSliderShaft(wxDC
& dc
,
271 wxOrientation orient
,
274 wxRect
*rectShaft
= NULL
);
275 virtual void DrawSliderThumb(wxDC
& dc
,
277 wxOrientation orient
,
280 virtual void DrawSliderTicks(wxDC
& dc
,
283 wxOrientation orient
,
290 virtual void DrawMenuBarItem(wxDC
& dc
,
292 const wxString
& label
,
294 int indexAccel
= -1);
295 virtual void DrawMenuItem(wxDC
& dc
,
297 const wxMenuGeometryInfo
& geometryInfo
,
298 const wxString
& label
,
299 const wxString
& accel
,
300 const wxBitmap
& bitmap
= wxNullBitmap
,
302 int indexAccel
= -1);
303 virtual void DrawMenuSeparator(wxDC
& dc
,
305 const wxMenuGeometryInfo
& geomInfo
);
307 virtual void DrawStatusField(wxDC
& dc
,
309 const wxString
& label
,
310 int flags
= 0, int style
= 0);
313 virtual void DrawFrameTitleBar(wxDC
& dc
,
315 const wxString
& title
,
318 int specialButton
= 0,
319 int specialButtonFlags
= 0);
320 virtual void DrawFrameBorder(wxDC
& dc
,
323 virtual void DrawFrameBackground(wxDC
& dc
,
326 virtual void DrawFrameTitle(wxDC
& dc
,
328 const wxString
& title
,
330 virtual void DrawFrameIcon(wxDC
& dc
,
334 virtual void DrawFrameButton(wxDC
& dc
,
335 wxCoord x
, wxCoord y
,
338 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
339 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
340 virtual wxSize
GetFrameMinSize(int flags
) const;
341 virtual wxSize
GetFrameIconSize() const;
342 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
344 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
346 wxBitmap
*bmpPressed
,
347 wxBitmap
*bmpDisabled
);
349 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
350 virtual wxRect
GetBorderDimensions(wxBorder border
) const;
351 virtual bool AreScrollbarsInsideBorder() const;
353 virtual wxSize
GetScrollbarArrowSize() const
354 { return m_sizeScrollbarArrow
; }
355 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
356 wxScrollBar::Element elem
,
357 int thumbPos
= -1) const;
358 virtual wxCoord
GetScrollbarSize(const wxScrollBar
*scrollbar
);
359 virtual wxHitTest
HitTestScrollbar(const wxScrollBar
*scrollbar
,
360 const wxPoint
& pt
) const;
361 virtual wxCoord
ScrollbarToPixel(const wxScrollBar
*scrollbar
,
363 virtual int PixelToScrollbar(const wxScrollBar
*scrollbar
, wxCoord coord
);
364 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
365 { return fontHeight
+ 2; }
366 virtual wxSize
GetCheckBitmapSize() const
367 { return wxSize(13, 13); }
368 virtual wxSize
GetRadioBitmapSize() const
369 { return wxSize(12, 12); }
370 virtual wxCoord
GetCheckItemMargin() const
373 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
374 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
375 virtual wxSize
GetToolBarMargin() const
376 { return wxSize(4, 4); }
378 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
379 const wxRect
& rect
) const;
380 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
382 wxCoord
*extraSpaceBeyond
) const;
384 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
385 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
387 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
388 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
389 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
391 wxOrientation orient
,
392 long style
= 0) const;
393 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
395 wxOrientation orient
) const;
396 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
398 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
399 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
400 const wxMenu
& menu
) const;
402 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
405 // helper of DrawLabel() and DrawCheckOrRadioButton()
406 void DoDrawLabel(wxDC
& dc
,
407 const wxString
& label
,
410 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
412 wxRect
*rectBounds
= NULL
,
413 const wxPoint
& focusOffset
414 = wxPoint(FOCUS_RECT_OFFSET_X
, FOCUS_RECT_OFFSET_Y
));
416 // common part of DrawLabel() and DrawItem()
417 void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
419 // DrawLabel() and DrawButtonLabel() helper
420 void DrawLabelShadow(wxDC
& dc
,
421 const wxString
& label
,
426 // DrawButtonBorder() helper
427 void DoDrawBackground(wxDC
& dc
,
430 wxWindow
*window
= NULL
);
432 // DrawBorder() helpers: all of them shift and clip the DC after drawing
435 // just draw a rectangle with the given pen
436 void DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
438 // draw the lower left part of rectangle
439 void DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
);
441 // draw the rectange using the first brush for the left and top sides and
442 // the second one for the bottom and right ones
443 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
444 const wxPen
& pen1
, const wxPen
& pen2
);
446 // draw the normal 3D border
447 void DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
);
449 // draw the sunken 3D border
450 void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
452 // draw the border used for scrollbar arrows
453 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
455 // public DrawArrow()s helper
456 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
457 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
459 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
460 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
461 wxArrowDirection arrowDir
,
462 wxArrowStyle arrowStyle
);
464 // DrawCheckButton/DrawRadioButton helper
465 void DrawCheckOrRadioButton(wxDC
& dc
,
466 const wxString
& label
,
467 const wxBitmap
& bitmap
,
472 wxCoord focusOffsetY
);
474 // draw a normal or transposed line (useful for using the same code fo both
475 // horizontal and vertical widgets)
476 void DrawLine(wxDC
& dc
,
477 wxCoord x1
, wxCoord y1
,
478 wxCoord x2
, wxCoord y2
,
479 bool transpose
= false)
482 dc
.DrawLine(y1
, x1
, y2
, x2
);
484 dc
.DrawLine(x1
, y1
, x2
, y2
);
487 // get the standard check/radio button bitmap
488 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
489 wxBitmap
GetCheckBitmap(int flags
)
490 { return GetIndicator(IndicatorType_Check
, flags
); }
491 wxBitmap
GetRadioBitmap(int flags
)
492 { return GetIndicator(IndicatorType_Radio
, flags
); }
495 const wxColourScheme
*m_scheme
;
497 // the sizing parameters (TODO make them changeable)
498 wxSize m_sizeScrollbarArrow
;
500 // GDI objects we use for drawing
501 wxColour m_colDarkGrey
,
509 wxFont m_titlebarFont
;
511 // the checked and unchecked bitmaps for DrawCheckItem()
512 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
514 // the bitmaps returned by GetIndicator()
515 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
517 [IndicatorStatus_Max
];
520 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
522 // first row is for the normal state, second - for the disabled
523 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
526 // ----------------------------------------------------------------------------
527 // wxWin32InputHandler and derived classes: process the keyboard and mouse
528 // messages according to Windows standards
529 // ----------------------------------------------------------------------------
531 class wxWin32InputHandler
: public wxInputHandler
534 wxWin32InputHandler(wxWin32Renderer
*renderer
);
536 virtual bool HandleKey(wxInputConsumer
*control
,
537 const wxKeyEvent
& event
,
539 virtual bool HandleMouse(wxInputConsumer
*control
,
540 const wxMouseEvent
& event
);
543 wxWin32Renderer
*m_renderer
;
546 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
549 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
550 wxInputHandler
*handler
);
552 virtual bool HandleMouse(wxInputConsumer
*control
, const wxMouseEvent
& event
);
553 virtual bool HandleMouseMove(wxInputConsumer
*control
, const wxMouseEvent
& event
);
555 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
556 const wxControlAction
& action
);
559 virtual bool IsAllowedButton(int button
) { return button
== 1; }
561 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
564 // we don't highlight anything
567 // the first and last event which caused the thumb to move
568 wxMouseEvent m_eventStartDrag
,
571 // have we paused the scrolling because the mouse moved?
574 // we remember the interval of the timer to be able to restart it
578 class wxWin32CheckboxInputHandler
: public wxStdCheckboxInputHandler
581 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
582 : wxStdCheckboxInputHandler(handler
) { }
584 virtual bool HandleKey(wxInputConsumer
*control
,
585 const wxKeyEvent
& event
,
589 class wxWin32TextCtrlInputHandler
: public wxStdTextCtrlInputHandler
592 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
593 : wxStdTextCtrlInputHandler(handler
) { }
595 virtual bool HandleKey(wxInputConsumer
*control
,
596 const wxKeyEvent
& event
,
600 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
603 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
605 virtual bool HandleMouse(wxInputConsumer
*consumer
,
606 const wxMouseEvent
& event
);
608 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
609 const wxMouseEvent
& event
);
612 // is the given point over the statusbar grip?
613 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
616 // the cursor we had replaced with the resize one
617 wxCursor m_cursorOld
;
619 // was the mouse over the grip last time we checked?
623 class wxWin32SystemMenuEvtHandler
;
625 class wxWin32FrameInputHandler
: public wxStdFrameInputHandler
628 wxWin32FrameInputHandler(wxInputHandler
*handler
);
629 ~wxWin32FrameInputHandler();
631 virtual bool HandleMouse(wxInputConsumer
*control
,
632 const wxMouseEvent
& event
);
634 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
636 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
639 // was the mouse over the grip last time we checked?
640 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
643 // ----------------------------------------------------------------------------
644 // wxWin32ColourScheme: uses (default) Win32 colours
645 // ----------------------------------------------------------------------------
647 class wxWin32ColourScheme
: public wxColourScheme
650 virtual wxColour
Get(StdColour col
) const;
651 virtual wxColour
GetBackground(wxWindow
*win
) const;
654 // ----------------------------------------------------------------------------
655 // wxWin32ArtProvider
656 // ----------------------------------------------------------------------------
658 class wxWin32ArtProvider
: public wxArtProvider
661 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
662 const wxArtClient
& client
,
666 // ----------------------------------------------------------------------------
668 // ----------------------------------------------------------------------------
670 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
672 class wxWin32Theme
: public wxTheme
676 virtual ~wxWin32Theme();
678 virtual wxRenderer
*GetRenderer();
679 virtual wxArtProvider
*GetArtProvider();
680 virtual wxInputHandler
*GetInputHandler(const wxString
& control
);
681 virtual wxColourScheme
*GetColourScheme();
684 // get the default input handler
685 wxInputHandler
*GetDefaultInputHandler();
687 wxWin32Renderer
*m_renderer
;
689 wxWin32ArtProvider
*m_artProvider
;
691 // the names of the already created handlers and the handlers themselves
692 // (these arrays are synchronized)
693 wxSortedArrayString m_handlerNames
;
694 wxArrayHandlers m_handlers
;
696 wxWin32InputHandler
*m_handlerDefault
;
698 wxWin32ColourScheme
*m_scheme
;
700 WX_DECLARE_THEME(win32
)
703 // ----------------------------------------------------------------------------
705 // ----------------------------------------------------------------------------
707 // frame buttons bitmaps
709 static const char *frame_button_close_xpm
[] = {
724 static const char *frame_button_help_xpm
[] = {
739 static const char *frame_button_maximize_xpm
[] = {
754 static const char *frame_button_minimize_xpm
[] = {
769 static const char *frame_button_restore_xpm
[] = {
786 static const char *checked_menu_xpm
[] = {
787 /* columns rows colors chars-per-pixel */
803 static const char *selected_checked_menu_xpm
[] = {
804 /* columns rows colors chars-per-pixel */
820 static const char *disabled_checked_menu_xpm
[] = {
821 /* columns rows colors chars-per-pixel */
838 static const char *selected_disabled_checked_menu_xpm
[] = {
839 /* columns rows colors chars-per-pixel */
855 // checkbox and radiobox bitmaps below
857 static const char *checked_xpm
[] = {
858 /* columns rows colors chars-per-pixel */
881 static const char *pressed_checked_xpm
[] = {
882 /* columns rows colors chars-per-pixel */
904 static const char *pressed_disabled_checked_xpm
[] = {
905 /* columns rows colors chars-per-pixel */
927 static const char *checked_item_xpm
[] = {
928 /* columns rows colors chars-per-pixel */
949 static const char *unchecked_xpm
[] = {
950 /* columns rows colors chars-per-pixel */
973 static const char *pressed_unchecked_xpm
[] = {
974 /* columns rows colors chars-per-pixel */
996 static const char *unchecked_item_xpm
[] = {
997 /* columns rows colors chars-per-pixel */
1017 static const char *undetermined_xpm
[] = {
1018 /* columns rows colors chars-per-pixel */
1041 static const char *pressed_undetermined_xpm
[] = {
1042 /* columns rows colors chars-per-pixel */
1065 static const char *checked_radio_xpm
[] = {
1066 /* columns rows colors chars-per-pixel */
1089 static const char *pressed_checked_radio_xpm
[] = {
1090 /* columns rows colors chars-per-pixel */
1113 static const char *pressed_disabled_checked_radio_xpm
[] = {
1114 /* columns rows colors chars-per-pixel */
1137 static const char *unchecked_radio_xpm
[] = {
1138 /* columns rows colors chars-per-pixel */
1161 static const char *pressed_unchecked_radio_xpm
[] = {
1162 /* columns rows colors chars-per-pixel */
1185 static const char **
1186 xpmIndicators
[IndicatorType_Max
][IndicatorState_Max
][IndicatorStatus_Max
] =
1191 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1194 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1197 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1203 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1206 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1209 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1215 { checked_menu_xpm
, NULL
, NULL
},
1218 { selected_checked_menu_xpm
, NULL
, NULL
},
1221 { disabled_checked_menu_xpm
, NULL
, NULL
},
1223 // disabled selected state
1224 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1228 static const char **xpmChecked
[IndicatorStatus_Max
] =
1234 // ============================================================================
1236 // ============================================================================
1238 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1240 // ----------------------------------------------------------------------------
1242 // ----------------------------------------------------------------------------
1244 wxWin32Theme::wxWin32Theme()
1248 m_handlerDefault
= NULL
;
1249 m_artProvider
= NULL
;
1252 wxWin32Theme::~wxWin32Theme()
1254 size_t count
= m_handlers
.GetCount();
1255 for ( size_t n
= 0; n
< count
; n
++ )
1257 if ( m_handlers
[n
] != m_handlerDefault
)
1258 delete m_handlers
[n
];
1261 delete m_handlerDefault
;
1265 wxArtProvider::RemoveProvider(m_artProvider
);
1268 wxRenderer
*wxWin32Theme::GetRenderer()
1272 m_renderer
= new wxWin32Renderer(GetColourScheme());
1278 wxArtProvider
*wxWin32Theme::GetArtProvider()
1280 if ( !m_artProvider
)
1282 m_artProvider
= new wxWin32ArtProvider
;
1285 return m_artProvider
;
1288 wxInputHandler
*wxWin32Theme::GetDefaultInputHandler()
1290 if ( !m_handlerDefault
)
1292 m_handlerDefault
= new wxWin32InputHandler(m_renderer
);
1295 return m_handlerDefault
;
1298 wxInputHandler
*wxWin32Theme::GetInputHandler(const wxString
& control
)
1300 wxInputHandler
*handler
;
1301 int n
= m_handlerNames
.Index(control
);
1302 if ( n
== wxNOT_FOUND
)
1304 // create a new handler
1305 if ( control
== wxINP_HANDLER_SCROLLBAR
)
1306 handler
= new wxWin32ScrollBarInputHandler(m_renderer
,
1307 GetDefaultInputHandler());
1309 else if ( control
== wxINP_HANDLER_BUTTON
)
1310 handler
= new wxStdButtonInputHandler(GetDefaultInputHandler());
1311 #endif // wxUSE_BUTTON
1313 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1314 handler
= new wxWin32CheckboxInputHandler(GetDefaultInputHandler());
1315 #endif // wxUSE_CHECKBOX
1317 else if ( control
== wxINP_HANDLER_COMBOBOX
)
1318 handler
= new wxStdComboBoxInputHandler(GetDefaultInputHandler());
1319 #endif // wxUSE_COMBOBOX
1321 else if ( control
== wxINP_HANDLER_LISTBOX
)
1322 handler
= new wxStdListboxInputHandler(GetDefaultInputHandler());
1323 #endif // wxUSE_LISTBOX
1324 #if wxUSE_CHECKLISTBOX
1325 else if ( control
== wxINP_HANDLER_CHECKLISTBOX
)
1326 handler
= new wxStdCheckListboxInputHandler(GetDefaultInputHandler());
1327 #endif // wxUSE_CHECKLISTBOX
1329 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1330 handler
= new wxWin32TextCtrlInputHandler(GetDefaultInputHandler());
1331 #endif // wxUSE_TEXTCTRL
1333 else if ( control
== wxINP_HANDLER_SLIDER
)
1334 handler
= new wxStdSliderButtonInputHandler(GetDefaultInputHandler());
1335 #endif // wxUSE_SLIDER
1337 else if ( control
== wxINP_HANDLER_SPINBTN
)
1338 handler
= new wxStdSpinButtonInputHandler(GetDefaultInputHandler());
1339 #endif // wxUSE_SPINBTN
1341 else if ( control
== wxINP_HANDLER_NOTEBOOK
)
1342 handler
= new wxStdNotebookInputHandler(GetDefaultInputHandler());
1343 #endif // wxUSE_NOTEBOOK
1345 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1346 handler
= new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
1347 #endif // wxUSE_STATUSBAR
1349 else if ( control
== wxINP_HANDLER_TOOLBAR
)
1350 handler
= new wxStdToolbarInputHandler(GetDefaultInputHandler());
1351 #endif // wxUSE_TOOLBAR
1352 else if ( control
== wxINP_HANDLER_TOPLEVEL
)
1353 handler
= new wxWin32FrameInputHandler(GetDefaultInputHandler());
1355 handler
= GetDefaultInputHandler();
1357 n
= m_handlerNames
.Add(control
);
1358 m_handlers
.Insert(handler
, n
);
1360 else // we already have it
1362 handler
= m_handlers
[n
];
1368 wxColourScheme
*wxWin32Theme::GetColourScheme()
1372 m_scheme
= new wxWin32ColourScheme
;
1377 // ============================================================================
1378 // wxWin32ColourScheme
1379 // ============================================================================
1381 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1384 if ( win
->UseBgCol() )
1386 // use the user specified colour
1387 col
= win
->GetBackgroundColour();
1390 if ( !win
->ShouldInheritColours() )
1392 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1394 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1402 if ( !win
->IsEnabled() ) // not IsEditable()
1408 // doesn't depend on the state
1415 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1419 int flags
= win
->GetStateFlags();
1421 // the colour set by the user should be used for the normal state
1422 // and for the states for which we don't have any specific colours
1423 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1425 if ( wxDynamicCast(win
, wxScrollBar
) )
1426 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1436 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1440 // use the system colours under Windows
1441 #if defined(__WXMSW__)
1442 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1444 case CONTROL_PRESSED
:
1445 case CONTROL_CURRENT
:
1446 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1448 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1450 #if defined(COLOR_3DLIGHT)
1451 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1453 case SCROLLBAR
: return wxColour(0xe0e0e0);
1455 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1457 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1458 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1460 #if defined(COLOR_3DDKSHADOW)
1461 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1463 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1466 case CONTROL_TEXT_DISABLED
:
1467 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1469 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1471 case CONTROL_TEXT_DISABLED_SHADOW
:
1472 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1474 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1475 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1476 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1477 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1479 case DESKTOP
: return wxColour(0x808000);
1481 // use the standard Windows colours elsewhere
1482 case WINDOW
: return *wxWHITE
;
1484 case CONTROL_PRESSED
:
1485 case CONTROL_CURRENT
:
1486 case CONTROL
: return wxColour(0xc0c0c0);
1488 case CONTROL_TEXT
: return *wxBLACK
;
1490 case SCROLLBAR
: return wxColour(0xe0e0e0);
1491 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1493 case HIGHLIGHT
: return wxColour(0x800000);
1494 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1496 case SHADOW_DARK
: return *wxBLACK
;
1498 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1499 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1501 case SHADOW_IN
: return wxColour(0xc0c0c0);
1503 case CONTROL_TEXT_DISABLED_SHADOW
:
1504 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1506 case TITLEBAR
: return wxColour(0xaeaaae);
1507 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1508 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1509 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1511 case DESKTOP
: return wxColour(0x808000);
1514 case GAUGE
: return Get(HIGHLIGHT
);
1518 wxFAIL_MSG(_T("invalid standard colour"));
1523 // ============================================================================
1525 // ============================================================================
1527 // ----------------------------------------------------------------------------
1529 // ----------------------------------------------------------------------------
1531 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1535 m_sizeScrollbarArrow
= wxSize(16, 16);
1537 // init colours and pens
1538 m_penBlack
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_DARK
), 0, wxSOLID
);
1540 m_colDarkGrey
= wxSCHEME_COLOUR(scheme
, SHADOW_OUT
);
1541 m_penDarkGrey
= wxPen(m_colDarkGrey
, 0, wxSOLID
);
1543 m_penLightGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SHADOW_IN
), 0, wxSOLID
);
1545 m_colHighlight
= wxSCHEME_COLOUR(scheme
, SHADOW_HIGHLIGHT
);
1546 m_penHighlight
= wxPen(m_colHighlight
, 0, wxSOLID
);
1548 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1549 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1551 // init the arrow bitmaps
1552 static const size_t ARROW_WIDTH
= 7;
1553 static const size_t ARROW_LENGTH
= 4;
1556 wxMemoryDC dcNormal
,
1559 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1561 bool isVertical
= n
> Arrow_Right
;
1574 // disabled arrow is larger because of the shadow
1575 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1576 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1578 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1579 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1581 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1582 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1586 dcNormal
.SetPen(m_penBlack
);
1587 dcDisabled
.SetPen(m_penDarkGrey
);
1589 // calculate the position of the point of the arrow
1593 x1
= (ARROW_WIDTH
- 1)/2;
1594 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1598 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1599 y1
= (ARROW_WIDTH
- 1)/2;
1610 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1612 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1613 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1620 if ( n
== Arrow_Up
)
1631 else // left or right arrow
1636 if ( n
== Arrow_Left
)
1649 // draw the shadow for the disabled one
1650 dcDisabled
.SetPen(m_penHighlight
);
1655 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1659 x1
= ARROW_LENGTH
- 1;
1660 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1663 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1664 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1669 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1673 x1
= ARROW_WIDTH
- 1;
1675 x2
= (ARROW_WIDTH
- 1)/2;
1677 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1678 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1683 // create the inverted bitmap but only for the right arrow as we only
1684 // use it for the menus
1685 if ( n
== Arrow_Right
)
1687 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1688 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1690 dcInverse
.Blit(0, 0, w
, h
,
1693 dcInverse
.SelectObject(wxNullBitmap
);
1695 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1696 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1698 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1699 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1701 dcInverse
.Blit(0, 0, w
, h
,
1704 dcInverse
.SelectObject(wxNullBitmap
);
1706 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1707 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1710 dcNormal
.SelectObject(wxNullBitmap
);
1711 dcDisabled
.SelectObject(wxNullBitmap
);
1713 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1714 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1715 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1716 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1718 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1721 // init the frame buttons bitmaps
1722 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1723 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1724 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1725 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1726 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1729 // ----------------------------------------------------------------------------
1731 // ----------------------------------------------------------------------------
1734 The raised border in Win32 looks like this:
1736 IIIIIIIIIIIIIIIIIIIIIIB
1738 I GB I = white (HILIGHT)
1739 I GB H = light grey (LIGHT)
1740 I GB G = dark grey (SHADOI)
1741 I GB B = black (DKSHADOI)
1742 I GB I = hIghlight (COLOR_3DHILIGHT)
1744 IGGGGGGGGGGGGGGGGGGGGGB
1745 BBBBBBBBBBBBBBBBBBBBBBB
1747 The sunken border looks like this:
1749 GGGGGGGGGGGGGGGGGGGGGGI
1750 GBBBBBBBBBBBBBBBBBBBBHI
1757 GHHHHHHHHHHHHHHHHHHHHHI
1758 IIIIIIIIIIIIIIIIIIIIIII
1760 The static border (used for the controls which don't get focus) is like
1763 GGGGGGGGGGGGGGGGGGGGGGW
1771 WWWWWWWWWWWWWWWWWWWWWWW
1773 The most complicated is the double border:
1775 HHHHHHHHHHHHHHHHHHHHHHB
1776 HWWWWWWWWWWWWWWWWWWWWGB
1777 HWHHHHHHHHHHHHHHHHHHHGB
1782 HWHHHHHHHHHHHHHHHHHHHGB
1783 HGGGGGGGGGGGGGGGGGGGGGB
1784 BBBBBBBBBBBBBBBBBBBBBBB
1786 And the simple border is, well, simple:
1788 BBBBBBBBBBBBBBBBBBBBBBB
1797 BBBBBBBBBBBBBBBBBBBBBBB
1800 void wxWin32Renderer::DrawRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1804 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1805 dc
.DrawRectangle(*rect
);
1811 void wxWin32Renderer::DrawHalfRect(wxDC
& dc
, wxRect
*rect
, const wxPen
& pen
)
1813 // draw the bottom and right sides
1815 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1816 rect
->GetRight() + 1, rect
->GetBottom());
1817 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1818 rect
->GetRight(), rect
->GetBottom());
1824 void wxWin32Renderer::DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
1825 const wxPen
& pen1
, const wxPen
& pen2
)
1827 // draw the rectangle
1829 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
1830 rect
->GetLeft(), rect
->GetBottom());
1831 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
1832 rect
->GetRight(), rect
->GetTop());
1834 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
1835 rect
->GetRight(), rect
->GetBottom());
1836 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
1837 rect
->GetRight() + 1, rect
->GetBottom());
1843 void wxWin32Renderer::DrawRaisedBorder(wxDC
& dc
, wxRect
*rect
)
1845 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
1846 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
1849 void wxWin32Renderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
1851 DrawShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
1852 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
1855 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
1859 DrawRect(dc
, rect
, m_penDarkGrey
);
1861 // the arrow is usually drawn inside border of width 2 and is offset by
1862 // another pixel in both directions when it's pressed - as the border
1863 // in this case is more narrow as well, we have to adjust rect like
1871 DrawShadedRect(dc
, rect
, m_penLightGrey
, m_penBlack
);
1872 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penDarkGrey
);
1876 void wxWin32Renderer::DrawBorder(wxDC
& dc
,
1878 const wxRect
& rectTotal
,
1879 int WXUNUSED(flags
),
1884 wxRect rect
= rectTotal
;
1888 case wxBORDER_SUNKEN
:
1889 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1891 DrawSunkenBorder(dc
, &rect
);
1895 case wxBORDER_STATIC
:
1896 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1899 case wxBORDER_RAISED
:
1900 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1902 DrawRaisedBorder(dc
, &rect
);
1906 case wxBORDER_DOUBLE
:
1907 DrawArrowBorder(dc
, &rect
);
1908 DrawRect(dc
, &rect
, m_penLightGrey
);
1911 case wxBORDER_SIMPLE
:
1912 for ( i
= 0; i
< BORDER_THICKNESS
/ 2; i
++ )
1914 DrawRect(dc
, &rect
, m_penBlack
);
1919 wxFAIL_MSG(_T("unknown border type"));
1922 case wxBORDER_DEFAULT
:
1931 wxRect
wxWin32Renderer::GetBorderDimensions(wxBorder border
) const
1936 case wxBORDER_RAISED
:
1937 case wxBORDER_SUNKEN
:
1938 width
= BORDER_THICKNESS
;
1941 case wxBORDER_SIMPLE
:
1942 case wxBORDER_STATIC
:
1946 case wxBORDER_DOUBLE
:
1952 // char *crash = NULL;
1954 wxFAIL_MSG(_T("unknown border type"));
1958 case wxBORDER_DEFAULT
:
1968 rect
.height
= width
;
1973 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1978 // ----------------------------------------------------------------------------
1980 // ----------------------------------------------------------------------------
1982 void wxWin32Renderer::DrawTextBorder(wxDC
& dc
,
1988 // text controls are not special under windows
1989 DrawBorder(dc
, border
, rect
, flags
, rectIn
);
1992 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1993 const wxRect
& rectTotal
,
1997 wxRect rect
= rectTotal
;
1999 if ( flags
& wxCONTROL_PRESSED
)
2001 // button pressed: draw a double border around it
2002 DrawRect(dc
, &rect
, m_penBlack
);
2003 DrawRect(dc
, &rect
, m_penDarkGrey
);
2007 // button not pressed
2009 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
2011 // button either default or focused (or both): add an extra border around it
2012 DrawRect(dc
, &rect
, m_penBlack
);
2015 // now draw a normal button
2016 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
2017 DrawHalfRect(dc
, &rect
, m_penDarkGrey
);
2026 // ----------------------------------------------------------------------------
2028 // ----------------------------------------------------------------------------
2030 void wxWin32Renderer::DrawHorizontalLine(wxDC
& dc
,
2031 wxCoord y
, wxCoord x1
, wxCoord x2
)
2033 dc
.SetPen(m_penDarkGrey
);
2034 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2035 dc
.SetPen(m_penHighlight
);
2037 dc
.DrawLine(x1
, y
, x2
+ 1, y
);
2040 void wxWin32Renderer::DrawVerticalLine(wxDC
& dc
,
2041 wxCoord x
, wxCoord y1
, wxCoord y2
)
2043 dc
.SetPen(m_penDarkGrey
);
2044 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2045 dc
.SetPen(m_penHighlight
);
2047 dc
.DrawLine(x
, y1
, x
, y2
+ 1);
2050 void wxWin32Renderer::DrawFrame(wxDC
& dc
,
2051 const wxString
& label
,
2057 wxCoord height
= 0; // of the label
2058 wxRect rectFrame
= rect
;
2059 if ( !label
.empty() )
2061 // the text should touch the top border of the rect, so the frame
2062 // itself should be lower
2063 dc
.GetTextExtent(label
, NULL
, &height
);
2064 rectFrame
.y
+= height
/ 2;
2065 rectFrame
.height
-= height
/ 2;
2067 // we have to draw each part of the frame individually as we can't
2068 // erase the background beyond the label as it might contain some
2069 // pixmap already, so drawing everything and then overwriting part of
2070 // the frame with label doesn't work
2072 // TODO: the +5 and space insertion should be customizable
2075 rectText
.x
= rectFrame
.x
+ 5;
2076 rectText
.y
= rect
.y
;
2077 rectText
.width
= rectFrame
.width
- 7; // +2 border width
2078 rectText
.height
= height
;
2081 label2
<< _T(' ') << label
<< _T(' ');
2082 if ( indexAccel
!= -1 )
2084 // adjust it as we prepended a space
2089 DrawLabel(dc
, label2
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
2091 StandardDrawFrame(dc
, rectFrame
, rectLabel
);
2095 // just draw the complete frame
2096 DrawShadedRect(dc
, &rectFrame
, m_penDarkGrey
, m_penHighlight
);
2097 DrawShadedRect(dc
, &rectFrame
, m_penHighlight
, m_penDarkGrey
);
2101 // ----------------------------------------------------------------------------
2103 // ----------------------------------------------------------------------------
2105 void wxWin32Renderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
2107 // VZ: this doesn't work under Windows, the dotted pen has dots of 3
2108 // pixels each while we really need dots here... PS_ALTERNATE might
2109 // work, but it is for NT 5 only
2111 DrawRect(dc
, &rect
, wxPen(*wxBLACK
, 0, wxDOT
));
2113 // draw the pixels manually: note that to behave in the same manner as
2114 // DrawRect(), we must exclude the bottom and right borders from the
2116 wxCoord x1
= rect
.GetLeft(),
2118 x2
= rect
.GetRight(),
2119 y2
= rect
.GetBottom();
2121 dc
.SetPen(wxPen(*wxBLACK
, 0, wxSOLID
));
2123 // this seems to be closer than what Windows does than wxINVERT although
2124 // I'm still not sure if it's correct
2125 dc
.SetLogicalFunction(wxAND_REVERSE
);
2128 for ( z
= x1
+ 1; z
< x2
; z
+= 2 )
2129 dc
.DrawPoint(z
, rect
.GetTop());
2131 wxCoord shift
= z
== x2
? 0 : 1;
2132 for ( z
= y1
+ shift
; z
< y2
; z
+= 2 )
2133 dc
.DrawPoint(x2
, z
);
2135 shift
= z
== y2
? 0 : 1;
2136 for ( z
= x2
- shift
; z
> x1
; z
-= 2 )
2137 dc
.DrawPoint(z
, y2
);
2139 shift
= z
== x1
? 0 : 1;
2140 for ( z
= y2
- shift
; z
> y1
; z
-= 2 )
2141 dc
.DrawPoint(x1
, z
);
2143 dc
.SetLogicalFunction(wxCOPY
);
2147 void wxWin32Renderer::DrawLabelShadow(wxDC
& dc
,
2148 const wxString
& label
,
2153 // draw shadow of the text
2154 dc
.SetTextForeground(m_colHighlight
);
2155 wxRect rectShadow
= rect
;
2158 dc
.DrawLabel(label
, rectShadow
, alignment
, indexAccel
);
2160 // make the text grey
2161 dc
.SetTextForeground(m_colDarkGrey
);
2164 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
2165 const wxString
& label
,
2172 DoDrawLabel(dc
, label
, rect
, flags
, alignment
, indexAccel
, rectBounds
);
2175 void wxWin32Renderer::DoDrawLabel(wxDC
& dc
,
2176 const wxString
& label
,
2182 const wxPoint
& focusOffset
)
2184 // the underscores are not drawn for focused controls in wxMSW
2185 if ( flags
& wxCONTROL_FOCUSED
)
2190 if ( flags
& wxCONTROL_DISABLED
)
2192 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
2193 // currently only can happen for a menu item and it seems that Windows
2194 // doesn't draw the shadow in this case, so we don't do it neither
2195 if ( flags
& wxCONTROL_SELECTED
)
2197 // just make the label text greyed out
2198 dc
.SetTextForeground(m_colDarkGrey
);
2200 else // draw normal disabled label
2202 DrawLabelShadow(dc
, label
, rect
, alignment
, indexAccel
);
2207 dc
.DrawLabel(label
, wxNullBitmap
, rect
, alignment
, indexAccel
, &rectLabel
);
2209 if ( flags
& wxCONTROL_DISABLED
)
2211 // restore the fg colour
2212 dc
.SetTextForeground(*wxBLACK
);
2215 if ( flags
& wxCONTROL_FOCUSED
)
2217 if ( focusOffset
.x
|| focusOffset
.y
)
2219 rectLabel
.Inflate(focusOffset
.x
, focusOffset
.y
);
2222 DrawFocusRect(dc
, rectLabel
);
2226 *rectBounds
= rectLabel
;
2229 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
2230 const wxString
& label
,
2231 const wxBitmap
& image
,
2238 // the underscores are not drawn for focused controls in wxMSW
2239 if ( flags
& wxCONTROL_PRESSED
)
2244 wxRect rectLabel
= rect
;
2245 if ( !label
.empty() )
2247 // shift the label if a button is pressed
2248 if ( flags
& wxCONTROL_PRESSED
)
2254 if ( flags
& wxCONTROL_DISABLED
)
2256 DrawLabelShadow(dc
, label
, rectLabel
, alignment
, indexAccel
);
2259 // leave enough space for the focus rectangle
2260 if ( flags
& wxCONTROL_FOCUSED
)
2262 rectLabel
.Inflate(-2);
2266 dc
.DrawLabel(label
, image
, rectLabel
, alignment
, indexAccel
, rectBounds
);
2268 if ( !label
.empty() && (flags
& wxCONTROL_FOCUSED
) )
2270 if ( flags
& wxCONTROL_PRESSED
)
2272 // the focus rectangle is never pressed, so undo the shift done
2280 DrawFocusRect(dc
, rectLabel
);
2284 // ----------------------------------------------------------------------------
2285 // (check)listbox items
2286 // ----------------------------------------------------------------------------
2288 void wxWin32Renderer::DrawItem(wxDC
& dc
,
2289 const wxString
& label
,
2293 wxDCTextColourChanger
colChanger(dc
);
2295 if ( flags
& wxCONTROL_SELECTED
)
2297 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2299 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2300 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
2301 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
2302 dc
.DrawRectangle(rect
);
2305 wxRect rectText
= rect
;
2307 rectText
.width
-= 2;
2308 dc
.DrawLabel(label
, wxNullBitmap
, rectText
);
2310 if ( flags
& wxCONTROL_FOCUSED
)
2312 DrawFocusRect(dc
, rect
);
2316 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
2317 const wxString
& label
,
2318 const wxBitmap
& bitmap
,
2327 else // use default bitmap
2329 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
2330 ? IndicatorStatus_Checked
2331 : IndicatorStatus_Unchecked
;
2333 if ( !m_bmpCheckBitmaps
[i
].Ok() )
2335 m_bmpCheckBitmaps
[i
] = wxBitmap(xpmChecked
[i
]);
2338 bmp
= m_bmpCheckBitmaps
[i
];
2341 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
2342 true /* use mask */);
2344 wxRect rectLabel
= rect
;
2345 int bmpWidth
= bmp
.GetWidth();
2346 rectLabel
.x
+= bmpWidth
;
2347 rectLabel
.width
-= bmpWidth
;
2349 DrawItem(dc
, label
, rectLabel
, flags
);
2352 // ----------------------------------------------------------------------------
2353 // check/radio buttons
2354 // ----------------------------------------------------------------------------
2356 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
2358 IndicatorState indState
;
2359 if ( flags
& wxCONTROL_SELECTED
)
2360 indState
= flags
& wxCONTROL_DISABLED
? IndicatorState_SelectedDisabled
2361 : IndicatorState_Selected
;
2362 else if ( flags
& wxCONTROL_DISABLED
)
2363 indState
= IndicatorState_Disabled
;
2364 else if ( flags
& wxCONTROL_PRESSED
)
2365 indState
= IndicatorState_Pressed
;
2367 indState
= IndicatorState_Normal
;
2369 IndicatorStatus indStatus
= flags
& wxCONTROL_CHECKED
2370 ? IndicatorStatus_Checked
2371 : ( flags
& wxCONTROL_UNDETERMINED
2372 ? IndicatorStatus_Undeterminated
2373 : IndicatorStatus_Unchecked
);
2375 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
2378 const char **xpm
= xpmIndicators
[indType
][indState
][indStatus
];
2381 // create and cache it
2382 bmp
= wxBitmap(xpm
);
2383 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
2390 void wxWin32Renderer::DrawCheckOrRadioButton(wxDC
& dc
,
2391 const wxString
& label
,
2392 const wxBitmap
& bitmap
,
2397 wxCoord focusOffsetY
)
2399 // calculate the position of the bitmap and of the label
2400 wxCoord heightBmp
= bitmap
.GetHeight();
2402 yBmp
= rect
.y
+ (rect
.height
- heightBmp
) / 2;
2405 dc
.GetMultiLineTextExtent(label
, NULL
, &rectLabel
.height
);
2406 rectLabel
.y
= rect
.y
+ (rect
.height
- rectLabel
.height
) / 2;
2408 // align label vertically with the bitmap - looks nicer like this
2409 rectLabel
.y
-= (rectLabel
.height
- heightBmp
) % 2;
2411 // calc horz position
2412 if ( align
== wxALIGN_RIGHT
)
2414 xBmp
= rect
.GetRight() - bitmap
.GetWidth();
2415 rectLabel
.x
= rect
.x
+ 3;
2416 rectLabel
.SetRight(xBmp
);
2418 else // normal (checkbox to the left of the text) case
2421 rectLabel
.x
= xBmp
+ bitmap
.GetWidth() + 5;
2422 rectLabel
.SetRight(rect
.GetRight());
2425 dc
.DrawBitmap(bitmap
, xBmp
, yBmp
, true /* use mask */);
2428 dc
, label
, rectLabel
,
2430 wxALIGN_LEFT
| wxALIGN_TOP
,
2432 NULL
, // we don't need bounding rect
2433 // use custom vert focus rect offset
2434 wxPoint(FOCUS_RECT_OFFSET_X
, focusOffsetY
)
2438 void wxWin32Renderer::DrawRadioButton(wxDC
& dc
,
2439 const wxString
& label
,
2440 const wxBitmap
& bitmap
,
2450 bmp
= GetRadioBitmap(flags
);
2452 DrawCheckOrRadioButton(dc
, label
,
2454 rect
, flags
, align
, indexAccel
,
2455 FOCUS_RECT_OFFSET_Y
); // default focus rect offset
2458 void wxWin32Renderer::DrawCheckButton(wxDC
& dc
,
2459 const wxString
& label
,
2460 const wxBitmap
& bitmap
,
2470 bmp
= GetCheckBitmap(flags
);
2472 DrawCheckOrRadioButton(dc
, label
,
2474 rect
, flags
, align
, indexAccel
,
2475 0); // no focus rect offset for checkboxes
2478 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
2479 const wxString
& label
,
2480 const wxBitmap
& bitmap
,
2481 const wxRect
& rectOrig
,
2485 if (style
== wxTOOL_STYLE_BUTTON
)
2487 wxRect rect
= rectOrig
;
2488 rect
.Deflate(BORDER_THICKNESS
);
2490 if ( flags
& wxCONTROL_PRESSED
)
2492 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2494 else if ( flags
& wxCONTROL_CURRENT
)
2496 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2499 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2501 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2503 // leave a small gap aroudn the line, also account for the toolbar
2505 if(rectOrig
.height
> rectOrig
.width
)
2508 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2509 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2510 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2515 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
2516 rectOrig
.x
+ 2*BORDER_THICKNESS
,
2517 rectOrig
.GetRight() - BORDER_THICKNESS
);
2520 // don't draw wxTOOL_STYLE_CONTROL
2523 // ----------------------------------------------------------------------------
2525 // ----------------------------------------------------------------------------
2527 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2528 const wxString
& text
,
2534 // nothing special to do here
2535 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2539 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2540 const wxRect
& WXUNUSED(rect
))
2542 // we don't draw them
2545 // ----------------------------------------------------------------------------
2547 // ----------------------------------------------------------------------------
2549 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2550 const wxRect
& rectOrig
,
2552 const wxString
& label
,
2553 const wxBitmap
& bitmap
,
2557 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2558 #define REVERSE_FOR_VERTICAL(X,Y) \
2559 SELECT_FOR_VERTICAL(X,Y) \
2561 SELECT_FOR_VERTICAL(Y,X)
2563 wxRect rect
= rectOrig
;
2565 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2567 // the current tab is drawn indented (to the top for default case) and
2568 // bigger than the other ones
2569 const wxSize indent
= GetTabIndent();
2570 if ( flags
& wxCONTROL_SELECTED
)
2572 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
2573 SELECT_FOR_VERTICAL( 0, indent
.y
));
2577 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2584 rect
.height
+= indent
.y
;
2591 rect
.width
+= indent
.x
;
2596 // draw the text, image and the focus around them (if necessary)
2597 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2598 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2600 rectLabel
.Deflate(1, 1);
2603 // draw it horizontally into memory and rotate for screen
2605 wxBitmap bitmapRotated
,
2606 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2607 rectLabel
.y
+ rectLabel
.height
);
2608 dcMem
.SelectObject(bitmapMem
);
2609 dcMem
.SetBackground(dc
.GetBackground());
2610 dcMem
.SetFont(dc
.GetFont());
2611 dcMem
.SetTextForeground(dc
.GetTextForeground());
2613 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
2614 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2615 flags
, wxALIGN_CENTRE
, indexAccel
);
2616 dcMem
.SelectObject(wxNullBitmap
);
2617 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2618 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2619 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2623 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2624 flags
, wxALIGN_CENTRE
, indexAccel
);
2627 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2628 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2629 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2630 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2631 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2632 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2634 // FIXME: all this code will break if the tab indent or the border width,
2635 // it is tied to the fact that both of them are equal to 2
2641 // left orientation looks like top but IsVertical makes x and y reversed
2643 // top is not vertical so use coordinates in written order
2644 dc
.SetPen(m_penHighlight
);
2645 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2646 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2647 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2648 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2649 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2650 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2652 dc
.SetPen(m_penBlack
);
2653 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2654 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2655 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2656 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2658 dc
.SetPen(m_penDarkGrey
);
2659 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2660 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2662 if ( flags
& wxCONTROL_SELECTED
)
2664 dc
.SetPen(m_penLightGrey
);
2666 // overwrite the part of the border below this tab
2667 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2668 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2670 // and the shadow of the tab to the left of us
2671 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2672 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2677 // right orientation looks like bottom but IsVertical makes x and y reversed
2679 // bottom is not vertical so use coordinates in written order
2680 dc
.SetPen(m_penHighlight
);
2681 // we need to continue one pixel further to overwrite the corner of
2682 // the border for the selected tab
2683 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
2684 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2685 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2686 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2688 dc
.SetPen(m_penBlack
);
2689 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2690 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2691 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2692 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2693 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2694 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2696 dc
.SetPen(m_penDarkGrey
);
2697 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2698 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2699 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2700 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2702 if ( flags
& wxCONTROL_SELECTED
)
2704 dc
.SetPen(m_penLightGrey
);
2706 // overwrite the part of the (double!) border above this tab
2707 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2708 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2709 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2710 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2712 // and the shadow of the tab to the left of us
2713 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2714 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2719 #undef SELECT_FOR_VERTICAL
2720 #undef REVERSE_FOR_VERTICAL
2723 // ----------------------------------------------------------------------------
2725 // ----------------------------------------------------------------------------
2728 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2730 wxOrientation orient
) const
2733 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2734 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2736 if (orient
== wxHORIZONTAL
)
2750 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2752 wxOrientation orient
,
2755 bool transpose
= (orient
== wxVERTICAL
);
2756 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2757 (((style
& wxSL_TOP
) != 0) & !transpose
|
2758 ((style
& wxSL_LEFT
) != 0) & transpose
|
2759 ((style
& wxSL_BOTH
) != 0));
2760 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2761 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2762 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2763 ((style
& wxSL_BOTH
) != 0));
2765 wxRect rect
= rectOrig
;
2767 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2769 if (orient
== wxHORIZONTAL
) {
2770 rect
.x
+= SLIDER_MARGIN
;
2773 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2777 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2781 rect
.y
+= sizeThumb
.y
/2;
2783 rect
.width
-= 2*SLIDER_MARGIN
;
2784 rect
.height
= 2*BORDER_THICKNESS
;
2788 rect
.y
+= SLIDER_MARGIN
;
2791 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2795 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2799 rect
.x
+= sizeThumb
.x
/2;
2801 rect
.width
= 2*BORDER_THICKNESS
;
2802 rect
.height
-= 2*SLIDER_MARGIN
;
2808 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2809 const wxRect
& rectOrig
,
2811 wxOrientation orient
,
2816 /* show shaft geometry
2834 if (flags
& wxCONTROL_FOCUSED
) {
2835 DrawFocusRect(dc
, rectOrig
);
2838 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2840 if (rectShaft
) *rectShaft
= rect
;
2842 DrawSunkenBorder(dc
, &rect
);
2845 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2847 wxOrientation orient
,
2851 /* show thumb geometry
2860 H D B where H is highlight colour
2874 The interior of this shape is filled with the hatched brush if the thumb
2878 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2880 bool transpose
= (orient
== wxVERTICAL
);
2881 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2882 (((style
& wxSL_TOP
) != 0) & !transpose
|
2883 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2884 ((style
& wxSL_BOTH
) == 0);
2885 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2886 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2887 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2888 ((style
& wxSL_BOTH
) == 0);
2890 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2891 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2893 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2894 x1
= (transpose
? rect
.y
: rect
.x
);
2895 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2896 x3
= (x1
-1+c
) + sizeArrow
;
2897 y1
= (transpose
? rect
.x
: rect
.y
);
2898 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2899 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2900 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2902 dc
.SetPen(m_penBlack
);
2904 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2906 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2909 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2913 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2916 dc
.SetPen(m_penDarkGrey
);
2917 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2919 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2923 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2926 dc
.SetPen(m_penHighlight
);
2929 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2930 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2934 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2936 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2939 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2942 if (flags
& wxCONTROL_PRESSED
) {
2943 // TODO: MSW fills the entire area inside, not just the rect
2944 wxRect rectInt
= rect
;
2947 rectInt
.SetLeft(y3
);
2948 rectInt
.SetRight(y4
);
2953 rectInt
.SetBottom(y4
);
2957 #if !defined(__WXMGL__)
2958 static const char *stipple_xpm
[] = {
2959 /* columns rows colors chars-per-pixel */
2968 // VS: MGL can only do 8x8 stipple brushes
2969 static const char *stipple_xpm
[] = {
2970 /* columns rows colors chars-per-pixel */
2985 dc
.SetBrush(wxBrush(stipple_xpm
));
2987 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2988 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2989 dc
.SetPen(*wxTRANSPARENT_PEN
);
2990 dc
.DrawRectangle(rectInt
);
2994 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2997 wxOrientation orient
,
3001 int WXUNUSED(flags
),
3004 /* show ticks geometry
3019 if (end
== start
) return;
3021 bool transpose
= (orient
== wxVERTICAL
);
3022 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
3023 (((style
& wxSL_TOP
) != 0) & !transpose
|
3024 ((style
& wxSL_LEFT
) != 0) & transpose
|
3025 ((style
& wxSL_BOTH
) != 0));
3026 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
3027 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
3028 ((style
& wxSL_RIGHT
) != 0) & transpose
|
3029 ((style
& wxSL_BOTH
) != 0));
3031 // default thumb size
3032 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
3033 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
3035 // normal thumb size
3036 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
3037 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
3039 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
3041 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
3042 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
3043 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
3044 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
3045 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
3046 y3
= (transpose
? rect
.x
: rect
.y
);
3047 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
3050 dc
.SetPen(m_penBlack
);
3052 int range
= end
- start
;
3053 for ( int n
= 0; n
< range
; n
+= step
) {
3054 wxCoord x
= x1
+ (len
*n
) / range
;
3056 if (left
& (y1
> y3
)) {
3057 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
3059 if (right
& (y4
> y2
)) {
3060 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
3063 // always draw the line at the end position
3064 if (left
& (y1
> y3
)) {
3065 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3067 if (right
& (y4
> y2
)) {
3068 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3072 // ----------------------------------------------------------------------------
3074 // ----------------------------------------------------------------------------
3076 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3077 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3080 virtual wxSize
GetSize() const { return m_size
; }
3082 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3083 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3085 wxCoord
GetItemHeight() const { return m_heightItem
; }
3088 // the total size of the menu
3091 // the offset of the start of the menu item label
3094 // the offset of the start of the accel label
3097 // the height of a normal (not separator) item
3098 wxCoord m_heightItem
;
3100 friend wxMenuGeometryInfo
*
3101 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3104 // FIXME: all constants are hardcoded but shouldn't be
3105 static const wxCoord MENU_LEFT_MARGIN
= 9;
3106 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3107 static const wxCoord MENU_VERT_MARGIN
= 3;
3109 // the margin around bitmap/check marks (on each side)
3110 static const wxCoord MENU_BMP_MARGIN
= 2;
3112 // the margin between the labels and accel strings
3113 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3115 // the separator height in pixels: in fact, strangely enough, the real height
3116 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3118 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3120 // the size of the standard checkmark bitmap
3121 static const wxCoord MENU_CHECK_SIZE
= 9;
3123 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3124 const wxRect
& rectOrig
,
3125 const wxString
& label
,
3129 wxRect rect
= rectOrig
;
3132 wxDCTextColourChanger
colChanger(dc
);
3134 if ( flags
& wxCONTROL_SELECTED
)
3136 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3138 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3139 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3140 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3141 dc
.DrawRectangle(rect
);
3144 // don't draw the focus rect around menu bar items
3145 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3146 wxALIGN_CENTRE
, indexAccel
);
3149 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3151 const wxMenuGeometryInfo
& gi
,
3152 const wxString
& label
,
3153 const wxString
& accel
,
3154 const wxBitmap
& bitmap
,
3158 const wxWin32MenuGeometryInfo
& geometryInfo
=
3159 (const wxWin32MenuGeometryInfo
&)gi
;
3164 rect
.width
= geometryInfo
.GetSize().x
;
3165 rect
.height
= geometryInfo
.GetItemHeight();
3167 // draw the selected item specially
3168 wxDCTextColourChanger
colChanger(dc
);
3169 if ( flags
& wxCONTROL_SELECTED
)
3171 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3173 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3174 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3175 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3176 dc
.DrawRectangle(rect
);
3179 // draw the bitmap: use the bitmap provided or the standard checkmark for
3180 // the checkable items
3181 wxBitmap bmp
= bitmap
;
3182 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3184 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3189 rect
.SetRight(geometryInfo
.GetLabelOffset());
3190 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3194 rect
.x
= geometryInfo
.GetLabelOffset();
3195 rect
.SetRight(geometryInfo
.GetAccelOffset());
3197 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3199 // draw the accel string
3200 rect
.x
= geometryInfo
.GetAccelOffset();
3201 rect
.SetRight(geometryInfo
.GetSize().x
);
3203 // NB: no accel index here
3204 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3206 // draw the submenu indicator
3207 if ( flags
& wxCONTROL_ISSUBMENU
)
3209 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3210 rect
.width
= MENU_RIGHT_MARGIN
;
3212 wxArrowStyle arrowStyle
;
3213 if ( flags
& wxCONTROL_DISABLED
)
3214 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
3216 else if ( flags
& wxCONTROL_SELECTED
)
3217 arrowStyle
= Arrow_Inverted
;
3219 arrowStyle
= Arrow_Normal
;
3221 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3225 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3227 const wxMenuGeometryInfo
& geomInfo
)
3229 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3232 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3234 wxSize size
= sizeText
;
3236 // FIXME: menubar height is configurable under Windows
3243 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3244 const wxMenu
& menu
) const
3246 // prepare the dc: for now we draw all the items with the system font
3248 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3250 // the height of a normal item
3251 wxCoord heightText
= dc
.GetCharHeight();
3256 // the max length of label and accel strings: the menu width is the sum of
3257 // them, even if they're for different items (as the accels should be
3260 // the max length of the bitmap is never 0 as Windows always leaves enough
3261 // space for a check mark indicator
3262 wxCoord widthLabelMax
= 0,
3264 widthBmpMax
= MENU_LEFT_MARGIN
;
3266 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3268 node
= node
->GetNext() )
3270 // height of this item
3273 wxMenuItem
*item
= node
->GetData();
3274 if ( item
->IsSeparator() )
3276 h
= MENU_SEPARATOR_HEIGHT
;
3278 else // not separator
3283 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3284 if ( widthLabel
> widthLabelMax
)
3286 widthLabelMax
= widthLabel
;
3290 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3291 if ( widthAccel
> widthAccelMax
)
3293 widthAccelMax
= widthAccel
;
3296 const wxBitmap
& bmp
= item
->GetBitmap();
3299 wxCoord widthBmp
= bmp
.GetWidth();
3300 if ( widthBmp
> widthBmpMax
)
3301 widthBmpMax
= widthBmp
;
3303 //else if ( item->IsCheckable() ): no need to check for this as
3304 // MENU_LEFT_MARGIN is big enough to show the check mark
3307 h
+= 2*MENU_VERT_MARGIN
;
3309 // remember the item position and height
3310 item
->SetGeometry(height
, h
);
3315 // bundle the metrics into a struct and return it
3316 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3318 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3319 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3320 if ( widthAccelMax
> 0 )
3322 // if we actually have any accesl, add a margin
3323 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3326 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3328 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3329 gi
->m_size
.y
= height
;
3334 // ----------------------------------------------------------------------------
3336 // ----------------------------------------------------------------------------
3338 static const wxCoord STATBAR_BORDER_X
= 2;
3339 static const wxCoord STATBAR_BORDER_Y
= 2;
3341 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3343 if ( borderBetweenFields
)
3344 *borderBetweenFields
= 2;
3346 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3349 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3351 const wxString
& label
,
3352 int flags
, int style
/*=0*/)
3356 if ( flags
& wxCONTROL_ISDEFAULT
)
3358 // draw the size grip: it is a normal rect except that in the lower
3359 // right corner we have several bands which may be used for dragging
3360 // the status bar corner
3362 // each band consists of 4 stripes: m_penHighlight, double
3363 // m_penDarkGrey and transparent one
3364 wxCoord x2
= rect
.GetRight(),
3365 y2
= rect
.GetBottom();
3367 // draw the upper left part of the rect normally
3368 if (style
!= wxSB_FLAT
)
3370 if (style
== wxSB_RAISED
)
3371 dc
.SetPen(m_penHighlight
);
3373 dc
.SetPen(m_penDarkGrey
);
3374 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3375 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3378 // draw the grey stripes of the grip
3380 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3381 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3383 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3384 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3387 // draw the white stripes
3388 dc
.SetPen(m_penHighlight
);
3389 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3390 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3392 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3395 // draw the remaining rect boundaries
3396 if (style
!= wxSB_FLAT
)
3398 if (style
== wxSB_RAISED
)
3399 dc
.SetPen(m_penDarkGrey
);
3401 dc
.SetPen(m_penHighlight
);
3402 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3403 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3404 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3410 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3414 if (style
== wxSB_RAISED
)
3415 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3416 else if (style
!= wxSB_FLAT
)
3417 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3420 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3422 wxDCClipper
clipper(dc
, rectIn
);
3423 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3426 // ----------------------------------------------------------------------------
3428 // ----------------------------------------------------------------------------
3430 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3431 wxBitmap
* WXUNUSED(bmpFocus
),
3432 wxBitmap
*bmpPressed
,
3433 wxBitmap
*bmpDisabled
)
3435 static const wxCoord widthCombo
= 16;
3436 static const wxCoord heightCombo
= 17;
3442 bmpNormal
->Create(widthCombo
, heightCombo
);
3443 dcMem
.SelectObject(*bmpNormal
);
3444 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3445 Arrow_Down
, Arrow_Normal
);
3450 bmpPressed
->Create(widthCombo
, heightCombo
);
3451 dcMem
.SelectObject(*bmpPressed
);
3452 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3453 Arrow_Down
, Arrow_Pressed
);
3458 bmpDisabled
->Create(widthCombo
, heightCombo
);
3459 dcMem
.SelectObject(*bmpDisabled
);
3460 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3461 Arrow_Down
, Arrow_Disabled
);
3465 // ----------------------------------------------------------------------------
3467 // ----------------------------------------------------------------------------
3469 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3470 const wxColour
& col
,
3472 wxWindow
* WXUNUSED(window
))
3474 wxBrush
brush(col
, wxSOLID
);
3476 dc
.SetPen(*wxTRANSPARENT_PEN
);
3477 dc
.DrawRectangle(rect
);
3480 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3481 const wxColour
& col
,
3483 int WXUNUSED(flags
),
3486 // just fill it with the given or default bg colour
3487 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3488 DoDrawBackground(dc
, colBg
, rect
, window
);
3491 // ----------------------------------------------------------------------------
3493 // ----------------------------------------------------------------------------
3495 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3500 // get the bitmap for this arrow
3501 wxArrowDirection arrowDir
;
3504 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3505 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3506 case wxUP
: arrowDir
= Arrow_Up
; break;
3507 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3510 wxFAIL_MSG(_T("unknown arrow direction"));
3514 wxArrowStyle arrowStyle
;
3515 if ( flags
& wxCONTROL_PRESSED
)
3517 // can't be pressed and disabled
3518 arrowStyle
= Arrow_Pressed
;
3522 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3525 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3528 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3530 wxArrowDirection arrowDir
,
3531 wxArrowStyle arrowStyle
)
3533 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3535 // under Windows the arrows always have the same size so just centre it in
3536 // the provided rectangle
3537 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3538 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3540 // Windows does it like this...
3541 if ( arrowDir
== Arrow_Left
)
3545 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3548 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3549 const wxRect
& rectAll
,
3550 wxArrowDirection arrowDir
,
3551 wxArrowStyle arrowStyle
)
3553 wxRect rect
= rectAll
;
3554 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3555 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3556 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3559 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3560 wxOrientation
WXUNUSED(orient
),
3562 int WXUNUSED(flags
))
3564 // we don't use the flags, the thumb never changes appearance
3565 wxRect rectThumb
= rect
;
3566 DrawArrowBorder(dc
, &rectThumb
);
3567 DrawBackground(dc
, wxNullColour
, rectThumb
);
3570 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3571 wxOrientation
WXUNUSED(orient
),
3572 const wxRect
& rectBar
,
3575 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3576 ? wxColourScheme::SCROLLBAR_PRESSED
3577 : wxColourScheme::SCROLLBAR
;
3578 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3581 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3583 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3586 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3587 wxScrollBar::Element elem
,
3590 return StandardGetScrollbarRect(scrollbar
, elem
,
3591 thumbPos
, m_sizeScrollbarArrow
);
3594 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3596 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3599 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3600 const wxPoint
& pt
) const
3602 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3605 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3608 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3611 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3614 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3617 // ----------------------------------------------------------------------------
3618 // top level windows
3619 // ----------------------------------------------------------------------------
3621 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3623 wxRect client
= GetFrameClientArea(rect
, flags
);
3625 if ( client
.Inside(pt
) )
3626 return wxHT_TOPLEVEL_CLIENT_AREA
;
3628 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3630 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3632 if ( flags
& wxTOPLEVEL_ICON
)
3634 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3635 return wxHT_TOPLEVEL_ICON
;
3638 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3639 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3640 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3642 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3644 if ( btnRect
.Inside(pt
) )
3645 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3646 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3648 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3650 if ( btnRect
.Inside(pt
) )
3651 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3652 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3654 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3656 if ( btnRect
.Inside(pt
) )
3657 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3658 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3660 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3662 if ( btnRect
.Inside(pt
) )
3663 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3664 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3666 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3668 if ( btnRect
.Inside(pt
) )
3669 return wxHT_TOPLEVEL_BUTTON_HELP
;
3670 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3673 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3674 return wxHT_TOPLEVEL_TITLEBAR
;
3677 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3679 // we are certainly at one of borders, lets decide which one:
3682 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3683 if ( pt
.x
< client
.x
)
3684 border
|= wxHT_TOPLEVEL_BORDER_W
;
3685 else if ( pt
.x
>= client
.width
+ client
.x
)
3686 border
|= wxHT_TOPLEVEL_BORDER_E
;
3687 if ( pt
.y
< client
.y
)
3688 border
|= wxHT_TOPLEVEL_BORDER_N
;
3689 else if ( pt
.y
>= client
.height
+ client
.y
)
3690 border
|= wxHT_TOPLEVEL_BORDER_S
;
3694 return wxHT_NOWHERE
;
3697 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3699 const wxString
& title
,
3703 int specialButtonFlags
)
3705 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3707 DrawFrameBorder(dc
, rect
, flags
);
3709 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3711 DrawFrameBackground(dc
, rect
, flags
);
3712 if ( flags
& wxTOPLEVEL_ICON
)
3713 DrawFrameIcon(dc
, rect
, icon
, flags
);
3714 DrawFrameTitle(dc
, rect
, title
, flags
);
3716 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3718 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3719 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3721 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3723 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3724 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3725 specialButtonFlags
: 0);
3726 x
-= FRAME_BUTTON_WIDTH
+ 2;
3728 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3730 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3731 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3732 specialButtonFlags
: 0);
3733 x
-= FRAME_BUTTON_WIDTH
;
3735 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3737 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3738 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3739 specialButtonFlags
: 0);
3740 x
-= FRAME_BUTTON_WIDTH
;
3742 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3744 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3745 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3746 specialButtonFlags
: 0);
3747 x
-= FRAME_BUTTON_WIDTH
;
3749 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3751 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3752 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3753 specialButtonFlags
: 0);
3758 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3762 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3766 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3767 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3768 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3769 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3770 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3773 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3777 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3779 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3780 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3781 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3783 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3784 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3786 DrawBackground(dc
, col
, r
);
3789 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3791 const wxString
& title
,
3794 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3795 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3796 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3798 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3799 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3800 if ( flags
& wxTOPLEVEL_ICON
)
3802 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3803 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3811 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3812 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3813 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3814 r
.width
-= FRAME_BUTTON_WIDTH
;
3815 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3816 r
.width
-= FRAME_BUTTON_WIDTH
;
3817 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3818 r
.width
-= FRAME_BUTTON_WIDTH
;
3819 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3820 r
.width
-= FRAME_BUTTON_WIDTH
;
3822 dc
.SetFont(m_titlebarFont
);
3823 dc
.SetTextForeground(col
);
3826 dc
.GetTextExtent(title
, &textW
, NULL
);
3827 if ( textW
> r
.width
)
3829 // text is too big, let's shorten it and add "..." after it:
3830 size_t len
= title
.length();
3831 wxCoord WSoFar
, letterW
;
3833 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3834 if ( WSoFar
> r
.width
)
3836 // not enough space to draw anything
3842 for (size_t i
= 0; i
< len
; i
++)
3844 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3845 if ( letterW
+ WSoFar
> r
.width
)
3851 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3852 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3855 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3856 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3859 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3866 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3867 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3871 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3872 wxCoord x
, wxCoord y
,
3876 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3881 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3882 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3883 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3884 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3885 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3887 wxFAIL_MSG(wxT("incorrect button specification"));
3890 if ( flags
& wxCONTROL_PRESSED
)
3892 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3893 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3894 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3895 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3899 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3900 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3901 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3902 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3907 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3912 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3914 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3915 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3916 FRAME_BORDER_THICKNESS
;
3919 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3921 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3922 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3928 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3931 wxSize
s(clientSize
);
3933 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3935 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3936 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3937 FRAME_BORDER_THICKNESS
;
3941 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3942 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3947 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3951 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3953 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3954 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3955 FRAME_BORDER_THICKNESS
;
3960 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3962 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3964 if ( flags
& wxTOPLEVEL_ICON
)
3965 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3966 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3967 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3968 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3969 s
.x
+= FRAME_BUTTON_WIDTH
;
3970 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3971 s
.x
+= FRAME_BUTTON_WIDTH
;
3972 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3973 s
.x
+= FRAME_BUTTON_WIDTH
;
3974 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3975 s
.x
+= FRAME_BUTTON_WIDTH
;
3981 wxSize
wxWin32Renderer::GetFrameIconSize() const
3983 return wxSize(16, 16);
3987 // ----------------------------------------------------------------------------
3989 // ----------------------------------------------------------------------------
3991 /* Copyright (c) Julian Smart */
3992 static char *error_xpm
[]={
3993 /* columns rows colors chars-per-pixel */
4070 " $oooooooooooo%& ",
4071 " *=-ooooooooooooo;: ",
4072 " *oooooooooooooooooo> ",
4073 " =ooooooooooooooooooo, ",
4074 " $-ooooooooooooooooooo<1 ",
4075 " .oooooo2334ooo533oooooo6 ",
4076 " +ooooooo789oo2883oooooo0q ",
4077 " oooooooo2w83o78eoooooooor ",
4078 " toooooooooy88u884oooooooori ",
4079 " Xooooooooooe888poooooooooas ",
4080 " ooooooooooo4889doooooooooof ",
4081 " ooooooooooo588w2oooooooooofi ",
4082 " oooooooooodw8887oooooooooofi ",
4083 " goooooooooh8w588jooooooookli ",
4084 " tooooooooz885op8wdooooooorix ",
4085 " oooooood98cood98cooooooori ",
4086 " @oooooop8w2ooo5885ooooovbi ",
4087 " n%ooooooooooooooooooooomiM ",
4088 " &;oooooooooooooooooooNBiV ",
4089 " :ooooooooooooooooooCZiA ",
4090 " nSooooooooooooooooCDiF ",
4091 " nG<oooooooooooooNZiiH ",
4092 " 160ooooooooovmBiFH ",
4093 " nqrraoookrrbiiA ",
4100 /* Copyright (c) Julian Smart */
4101 static char *info_xpm
[]={
4102 /* columns rows colors chars-per-pixel */
4124 " ..XXXXXXXXXXXXX.. ",
4125 " .XXXXXXXXXXXXXXXXX. ",
4126 " .XXXXXXXXoO+XXXXXXXX. ",
4127 " .XXXXXXXXX@#OXXXXXXXXX. ",
4128 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
4129 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
4130 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
4131 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
4132 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
4133 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
4134 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4135 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4136 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
4137 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
4138 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
4139 " .XXXXXXXXXXXXXXXXX.%%%% ",
4140 " ..XXXXXXXXXXXXX..%%%% ",
4141 " %...XXXXXXXX..%%%%% ",
4142 " %%%..XXXXXX.%%%%% ",
4156 /* Copyright (c) Julian Smart */
4157 static char *question_xpm
[]={
4158 /* columns rows colors chars-per-pixel */
4179 " ..XXXXXXXXXXXXX.. ",
4180 " .XXXXXXoO++@XXXXXX. ",
4181 " .XXXXXXO#$$$$#%XXXXX. ",
4182 " .XXXXXX@$$#&&#$#oXXXXX. ",
4183 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
4184 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
4185 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
4186 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
4187 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
4188 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
4189 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
4190 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
4191 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
4192 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
4193 " .XXXXXXXX-$$XXXXXXXX.:::: ",
4194 " .XXXXXXXO++XXXXXXX.:::: ",
4195 " ..XXXXXXXXXXXXX..:::: ",
4196 " :...XXXXXXXX..::::: ",
4197 " :::..XXXXXX.::::: ",
4211 /* Copyright (c) Julian Smart */
4212 static char *warning_xpm
[]={
4213 /* columns rows colors chars-per-pixel */
4239 " ..XXXXO@#XXX... ",
4240 " ...XXXXO@#XXXX.. ",
4241 " ..XXXXXO@#XXXX... ",
4242 " ...XXXXXo@OXXXXX.. ",
4243 " ...XXXXXXo@OXXXXXX.. ",
4244 " ..XXXXXXX$@OXXXXXX... ",
4245 " ...XXXXXXXX@XXXXXXXX.. ",
4246 " ...XXXXXXXXXXXXXXXXXX... ",
4247 " ..XXXXXXXXXXOXXXXXXXXX.. ",
4248 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
4249 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
4250 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
4251 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
4252 " .............................. ",
4253 " .............................. ",
4260 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4261 const wxArtClient
& WXUNUSED(client
),
4262 const wxSize
& WXUNUSED(size
))
4264 if ( id
== wxART_INFORMATION
)
4265 return wxBitmap(info_xpm
);
4266 if ( id
== wxART_ERROR
)
4267 return wxBitmap(error_xpm
);
4268 if ( id
== wxART_WARNING
)
4269 return wxBitmap(warning_xpm
);
4270 if ( id
== wxART_QUESTION
)
4271 return wxBitmap(question_xpm
);
4272 return wxNullBitmap
;
4276 // ----------------------------------------------------------------------------
4277 // text control geometry
4278 // ----------------------------------------------------------------------------
4280 static inline int GetTextBorderWidth()
4286 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4287 const wxRect
& rect
) const
4289 wxRect rectTotal
= rect
;
4291 wxCoord widthBorder
= GetTextBorderWidth();
4292 rectTotal
.Inflate(widthBorder
);
4294 // this is what Windows does
4301 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4303 wxCoord
*extraSpaceBeyond
) const
4305 wxRect rectText
= rect
;
4307 // undo GetTextTotalArea()
4308 if ( rectText
.height
> 0 )
4311 wxCoord widthBorder
= GetTextBorderWidth();
4312 rectText
.Inflate(-widthBorder
);
4314 if ( extraSpaceBeyond
)
4315 *extraSpaceBeyond
= 0;
4320 // ----------------------------------------------------------------------------
4322 // ----------------------------------------------------------------------------
4324 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4327 if ( wxDynamicCast(window
, wxScrollBar
) )
4329 // we only set the width of vert scrollbars and height of the
4331 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4332 size
->y
= m_sizeScrollbarArrow
.y
;
4334 size
->x
= m_sizeScrollbarArrow
.x
;
4336 // skip border width adjustments, they don't make sense for us
4339 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4342 if ( wxDynamicCast(window
, wxBitmapButton
) )
4346 #endif // wxUSE_BMPBUTTON
4347 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
4350 || wxDynamicCast(window
, wxButton
)
4351 # endif // wxUSE_BUTTON
4352 # if wxUSE_TOGGLEBTN
4353 || wxDynamicCast(window
, wxToggleButton
)
4354 # endif // wxUSE_TOGGLEBTN
4357 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4359 // TODO: don't harcode all this
4360 size
->x
+= 3*window
->GetCharWidth();
4362 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4363 if ( size
->y
< heightBtn
- 8 )
4364 size
->y
= heightBtn
;
4369 // for compatibility with other ports, the buttons default size is never
4370 // less than the standard one, but not when display not PDAs.
4371 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4373 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4375 wxSize szDef
= wxButton::GetDefaultSize();
4376 if ( size
->x
< szDef
.x
)
4381 // no border width adjustments for buttons
4384 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
4386 // take into account the border width
4387 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4388 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4389 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4392 // ============================================================================
4394 // ============================================================================
4396 // ----------------------------------------------------------------------------
4397 // wxWin32InputHandler
4398 // ----------------------------------------------------------------------------
4400 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4402 m_renderer
= renderer
;
4405 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4406 const wxKeyEvent
& WXUNUSED(event
),
4407 bool WXUNUSED(pressed
))
4412 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4413 const wxMouseEvent
& event
)
4415 // clicking on the control gives it focus
4416 if ( event
.ButtonDown() )
4418 wxWindow
*win
= control
->GetInputWindow();
4420 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4421 ( win
->AcceptsFocus() ) )
4432 // ----------------------------------------------------------------------------
4433 // wxWin32ScrollBarInputHandler
4434 // ----------------------------------------------------------------------------
4436 wxWin32ScrollBarInputHandler::
4437 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4438 wxInputHandler
*handler
)
4439 : wxStdScrollBarInputHandler(renderer
, handler
)
4441 m_scrollPaused
= false;
4445 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4446 const wxControlAction
& action
)
4448 // stop if went beyond the position of the original click (this can only
4449 // happen when we scroll by pages)
4451 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4453 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4454 != wxHT_SCROLLBAR_BAR_2
;
4456 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4458 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4459 != wxHT_SCROLLBAR_BAR_1
;
4464 StopScrolling(scrollbar
);
4466 scrollbar
->Refresh();
4471 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4474 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4475 const wxMouseEvent
& event
)
4477 // remember the current state
4478 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4480 // do process the message
4481 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4483 // analyse the changes
4484 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4486 // we just started dragging the thumb, remember its initial position to
4487 // be able to restore it if the drag is cancelled later
4488 m_eventStartDrag
= event
;
4494 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4495 const wxMouseEvent
& event
)
4497 // we don't highlight scrollbar elements, so there is no need to process
4498 // mouse move events normally - only do it while mouse is captured (i.e.
4499 // when we're dragging the thumb or pressing on something)
4500 if ( !m_winCapture
)
4503 if ( event
.Entering() )
4505 // we're not interested in this at all
4509 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4511 if ( m_scrollPaused
)
4513 // check if the mouse returned to its original location
4515 if ( event
.Leaving() )
4521 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4522 if ( ht
== m_htLast
)
4524 // yes it did, resume scrolling
4525 m_scrollPaused
= false;
4526 if ( m_timerScroll
)
4528 // we were scrolling by line/page, restart timer
4529 m_timerScroll
->Start(m_interval
);
4531 Press(scrollbar
, true);
4533 else // we were dragging the thumb
4535 // restore its last location
4536 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4542 else // normal case, scrolling hasn't been paused
4544 // if we're scrolling the scrollbar because the arrow or the shaft was
4545 // pressed, check that the mouse stays on the same scrollbar element
4548 // Always let thumb jump back if we leave the scrollbar
4549 if ( event
.Moving() )
4551 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4553 else // event.Leaving()
4558 // Jump back only if we get far away from it
4559 wxPoint pos
= event
.GetPosition();
4560 if (scrollbar
->HasFlag( wxVERTICAL
))
4562 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4567 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4570 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4573 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4574 // is still ok - we only want to catch the case when the mouse leaves
4575 // the scrollbar here
4576 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4578 ht
= wxHT_SCROLLBAR_THUMB
;
4581 if ( ht
!= m_htLast
)
4583 // what were we doing? 2 possibilities: either an arrow/shaft was
4584 // pressed in which case we have a timer and so we just stop it or
4585 // we were dragging the thumb
4586 if ( m_timerScroll
)
4589 m_interval
= m_timerScroll
->GetInterval();
4590 m_timerScroll
->Stop();
4591 m_scrollPaused
= true;
4593 // unpress the arrow
4594 Press(scrollbar
, false);
4596 else // we were dragging the thumb
4598 // remember the current thumb position to be able to restore it
4599 // if the mouse returns to it later
4600 m_eventLastDrag
= event
;
4602 // and restore the original position (before dragging) of the
4604 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4611 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4614 // ----------------------------------------------------------------------------
4615 // wxWin32CheckboxInputHandler
4616 // ----------------------------------------------------------------------------
4618 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4619 const wxKeyEvent
& event
,
4624 wxControlAction action
;
4625 int keycode
= event
.GetKeyCode();
4629 action
= wxACTION_CHECKBOX_TOGGLE
;
4633 case WXK_NUMPAD_SUBTRACT
:
4634 action
= wxACTION_CHECKBOX_CHECK
;
4638 case WXK_NUMPAD_ADD
:
4639 case WXK_NUMPAD_EQUAL
:
4640 action
= wxACTION_CHECKBOX_CLEAR
;
4644 if ( !action
.IsEmpty() )
4646 control
->PerformAction(action
);
4655 // ----------------------------------------------------------------------------
4656 // wxWin32TextCtrlInputHandler
4657 // ----------------------------------------------------------------------------
4659 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4660 const wxKeyEvent
& event
,
4663 // handle only MSW-specific text bindings here, the others are handled in
4667 int keycode
= event
.GetKeyCode();
4669 wxControlAction action
;
4670 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4672 action
= wxACTION_TEXT_CUT
;
4674 else if ( keycode
== WXK_INSERT
)
4676 if ( event
.ControlDown() )
4677 action
= wxACTION_TEXT_COPY
;
4678 else if ( event
.ShiftDown() )
4679 action
= wxACTION_TEXT_PASTE
;
4682 if ( action
!= wxACTION_NONE
)
4684 control
->PerformAction(action
);
4690 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4693 // ----------------------------------------------------------------------------
4694 // wxWin32StatusBarInputHandler
4695 // ----------------------------------------------------------------------------
4697 wxWin32StatusBarInputHandler::
4698 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4699 : wxStdInputHandler(handler
)
4704 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4705 const wxPoint
& pt
) const
4707 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4708 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4711 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4713 wxCHECK_MSG( parentTLW
, false,
4714 _T("the status bar should be a child of a TLW") );
4716 // a maximized window can't be resized anyhow
4717 if ( !parentTLW
->IsMaximized() )
4719 // VZ: I think that the standard Windows behaviour is to only
4720 // show the resizing cursor when the mouse is on top of the
4721 // grip itself but apparently different Windows versions behave
4722 // differently (?) and it seems a better UI to allow resizing
4723 // the status bar even when the mouse is above the grip
4724 wxSize sizeSbar
= statbar
->GetSize();
4726 int diff
= sizeSbar
.x
- pt
.x
;
4727 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4734 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4735 const wxMouseEvent
& event
)
4737 if ( event
.Button(1) )
4739 if ( event
.ButtonDown(1) )
4741 wxWindow
*statbar
= consumer
->GetInputWindow();
4743 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4745 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4749 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4750 wxHT_TOPLEVEL_BORDER_SE
);
4752 statbar
->SetCursor(m_cursorOld
);
4760 return wxStdInputHandler::HandleMouse(consumer
, event
);
4763 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4764 const wxMouseEvent
& event
)
4766 wxWindow
*statbar
= consumer
->GetInputWindow();
4768 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4769 if ( isOnGrip
!= m_isOnGrip
)
4771 m_isOnGrip
= isOnGrip
;
4774 m_cursorOld
= statbar
->GetCursor();
4775 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4779 statbar
->SetCursor(m_cursorOld
);
4783 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4786 // ----------------------------------------------------------------------------
4787 // wxWin32FrameInputHandler
4788 // ----------------------------------------------------------------------------
4790 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4793 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4795 void Attach(wxInputConsumer
*consumer
);
4799 DECLARE_EVENT_TABLE()
4800 void OnSystemMenu(wxCommandEvent
&event
);
4801 void OnCloseFrame(wxCommandEvent
&event
);
4802 void OnClose(wxCloseEvent
&event
);
4804 wxWin32FrameInputHandler
*m_inputHnd
;
4805 wxTopLevelWindow
*m_wnd
;
4807 wxAcceleratorTable m_oldAccelTable
;
4811 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4812 wxWin32FrameInputHandler
*handler
)
4814 m_inputHnd
= handler
;
4818 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4820 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4822 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4823 m_wnd
->PushEventHandler(this);
4826 // VS: This code relies on using generic implementation of
4827 // wxAcceleratorTable in wxUniv!
4828 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4829 m_oldAccelTable
= table
;
4830 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4831 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4832 m_wnd
->SetAcceleratorTable(table
);
4836 void wxWin32SystemMenuEvtHandler::Detach()
4841 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4843 m_wnd
->RemoveEventHandler(this);
4848 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4849 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4850 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4851 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4854 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4856 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4857 !m_wnd
->IsMaximized()) ?
4858 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4859 FRAME_BORDER_THICKNESS
;
4860 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4861 pt
.x
= -pt
.x
+ border
;
4862 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4865 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4866 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4869 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4872 m_wnd
->SetAcceleratorTable(table
);
4876 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4878 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4879 wxTOPLEVEL_BUTTON_CLOSE
);
4882 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4889 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4890 : wxStdFrameInputHandler(handler
)
4892 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4895 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4897 if ( m_menuHandler
)
4899 m_menuHandler
->Detach();
4900 delete m_menuHandler
;
4904 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4905 const wxMouseEvent
& event
)
4907 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4909 wxTopLevelWindow
*tlw
=
4910 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4912 long hit
= tlw
->HitTest(event
.GetPosition());
4914 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4916 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4917 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4918 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4921 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4923 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4924 (event
.RightDown() &&
4925 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4926 hit
== wxHT_TOPLEVEL_ICON
)) )
4928 PopupSystemMenu(tlw
, event
.GetPosition());
4934 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4937 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4938 const wxPoint
& pos
) const
4940 wxMenu
*menu
= new wxMenu
;
4942 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4943 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4944 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4945 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4946 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4947 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4948 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4949 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4950 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4951 menu
->AppendSeparator();
4952 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4954 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4956 if ( window
->IsMaximized() )
4958 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4959 menu
->Enable(wxID_MOVE_FRAME
, false);
4960 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4961 menu
->Enable(wxID_RESIZE_FRAME
, false);
4964 menu
->Enable(wxID_RESTORE_FRAME
, false);
4967 window
->PopupMenu(menu
, pos
);
4971 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4974 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4976 // always detach if active frame changed:
4977 m_menuHandler
->Detach();
4981 m_menuHandler
->Attach(consumer
);
4985 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);