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/toolbar.h"
44 #include "wx/statusbr.h"
47 // for COLOR_* constants
48 #include "wx/msw/private.h"
51 #include "wx/settings.h"
54 #include "wx/notebook.h"
55 #include "wx/spinbutt.h"
56 #include "wx/artprov.h"
57 #include "wx/toplevel.h"
59 #ifdef wxUSE_TOGGLEBTN
60 #include "wx/tglbtn.h"
61 #endif // wxUSE_TOGGLEBTN
63 #include "wx/univ/scrtimer.h"
64 #include "wx/univ/renderer.h"
65 #include "wx/univ/inphand.h"
66 #include "wx/univ/colschem.h"
67 #include "wx/univ/theme.h"
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 static const int BORDER_THICKNESS
= 2;
75 // the offset between the label and focus rect around it
76 static const int FOCUS_RECT_OFFSET_X
= 1;
77 static const int FOCUS_RECT_OFFSET_Y
= 1;
79 static const int FRAME_BORDER_THICKNESS
= 3;
80 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
81 static const int FRAME_TITLEBAR_HEIGHT
= 18;
82 static const int FRAME_BUTTON_WIDTH
= 16;
83 static const int FRAME_BUTTON_HEIGHT
= 14;
85 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
86 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
87 static const size_t STATUSBAR_GRIP_SIZE
=
88 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
90 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
91 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
92 static const wxCoord SLIDER_TICK_LENGTH
= 6;
104 IndicatorState_Normal
,
105 IndicatorState_Pressed
, // this one is for check/radioboxes
106 IndicatorState_Selected
= IndicatorState_Pressed
, // for menus
107 IndicatorState_Disabled
,
108 IndicatorState_SelectedDisabled
, // only for the menus
114 IndicatorStatus_Checked
,
115 IndicatorStatus_Unchecked
,
116 IndicatorStatus_Undeterminated
,
120 // wxWin32Renderer: draw the GUI elements in Win32 style
121 // ----------------------------------------------------------------------------
123 class wxWin32Renderer
: public wxRenderer
127 enum wxArrowDirection
142 Arrow_InvertedDisabled
,
146 enum wxFrameButtonType
149 FrameButton_Minimize
,
150 FrameButton_Maximize
,
157 wxWin32Renderer(const wxColourScheme
*scheme
);
159 // implement the base class pure virtuals
160 virtual void DrawBackground(wxDC
& dc
,
164 wxWindow
*window
= NULL
);
165 virtual void DrawLabel(wxDC
& dc
,
166 const wxString
& label
,
169 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
171 wxRect
*rectBounds
= NULL
);
172 virtual void DrawButtonLabel(wxDC
& dc
,
173 const wxString
& label
,
174 const wxBitmap
& image
,
177 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
179 wxRect
*rectBounds
= NULL
);
180 virtual void DrawBorder(wxDC
& dc
,
184 wxRect
*rectIn
= (wxRect
*)NULL
);
185 virtual void DrawHorizontalLine(wxDC
& dc
,
186 wxCoord y
, wxCoord x1
, wxCoord x2
);
187 virtual void DrawVerticalLine(wxDC
& dc
,
188 wxCoord x
, wxCoord y1
, wxCoord y2
);
189 virtual void DrawFrame(wxDC
& dc
,
190 const wxString
& label
,
193 int alignment
= wxALIGN_LEFT
,
194 int indexAccel
= -1);
195 virtual void DrawTextBorder(wxDC
& dc
,
199 wxRect
*rectIn
= (wxRect
*)NULL
);
200 virtual void DrawButtonBorder(wxDC
& dc
,
203 wxRect
*rectIn
= (wxRect
*)NULL
);
204 virtual void DrawArrow(wxDC
& dc
,
208 virtual void DrawScrollbarArrow(wxDC
& dc
,
212 { DrawArrow(dc
, dir
, rect
, flags
); }
213 virtual void DrawScrollbarThumb(wxDC
& dc
,
214 wxOrientation orient
,
217 virtual void DrawScrollbarShaft(wxDC
& dc
,
218 wxOrientation orient
,
221 virtual void DrawScrollCorner(wxDC
& dc
,
223 virtual void DrawItem(wxDC
& dc
,
224 const wxString
& label
,
227 virtual void DrawCheckItem(wxDC
& dc
,
228 const wxString
& label
,
229 const wxBitmap
& bitmap
,
232 virtual void DrawCheckButton(wxDC
& dc
,
233 const wxString
& label
,
234 const wxBitmap
& bitmap
,
237 wxAlignment align
= wxALIGN_LEFT
,
238 int indexAccel
= -1);
239 virtual void DrawRadioButton(wxDC
& dc
,
240 const wxString
& label
,
241 const wxBitmap
& bitmap
,
244 wxAlignment align
= wxALIGN_LEFT
,
245 int indexAccel
= -1);
246 virtual void DrawToolBarButton(wxDC
& dc
,
247 const wxString
& label
,
248 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
,
2486 if (style
== wxTOOL_STYLE_BUTTON
)
2488 wxRect rect
= rectOrig
;
2489 rect
.Deflate(BORDER_THICKNESS
);
2491 if ( flags
& wxCONTROL_PRESSED
)
2493 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
2495 else if ( flags
& wxCONTROL_CURRENT
)
2497 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
2500 if(tbarStyle
& wxTB_TEXT
)
2502 if(tbarStyle
& wxTB_HORIZONTAL
)
2504 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
2508 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
2513 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
2514 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
2515 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
2518 else if (style
== wxTOOL_STYLE_SEPARATOR
)
2520 // leave a small gap aroudn the line, also account for the toolbar
2522 if(rectOrig
.height
> rectOrig
.width
)
2525 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
2526 rectOrig
.y
+ 2*BORDER_THICKNESS
,
2527 rectOrig
.GetBottom() - BORDER_THICKNESS
);
2532 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
2533 rectOrig
.x
+ 2*BORDER_THICKNESS
,
2534 rectOrig
.GetRight() - BORDER_THICKNESS
);
2537 // don't draw wxTOOL_STYLE_CONTROL
2540 // ----------------------------------------------------------------------------
2542 // ----------------------------------------------------------------------------
2544 void wxWin32Renderer::DrawTextLine(wxDC
& dc
,
2545 const wxString
& text
,
2551 // nothing special to do here
2552 StandardDrawTextLine(dc
, text
, rect
, selStart
, selEnd
, flags
);
2556 wxWin32Renderer::DrawLineWrapMark(wxDC
& WXUNUSED(dc
),
2557 const wxRect
& WXUNUSED(rect
))
2559 // we don't draw them
2562 // ----------------------------------------------------------------------------
2564 // ----------------------------------------------------------------------------
2566 void wxWin32Renderer::DrawTab(wxDC
& dc
,
2567 const wxRect
& rectOrig
,
2569 const wxString
& label
,
2570 const wxBitmap
& bitmap
,
2574 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
2575 #define REVERSE_FOR_VERTICAL(X,Y) \
2576 SELECT_FOR_VERTICAL(X,Y) \
2578 SELECT_FOR_VERTICAL(Y,X)
2580 wxRect rect
= rectOrig
;
2582 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
2584 // the current tab is drawn indented (to the top for default case) and
2585 // bigger than the other ones
2586 const wxSize indent
= GetTabIndent();
2587 if ( flags
& wxCONTROL_SELECTED
)
2589 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
2590 SELECT_FOR_VERTICAL( 0, indent
.y
));
2594 wxFAIL_MSG(_T("invaild notebook tab orientation"));
2601 rect
.height
+= indent
.y
;
2608 rect
.width
+= indent
.x
;
2613 // draw the text, image and the focus around them (if necessary)
2614 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
2615 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
2617 rectLabel
.Deflate(1, 1);
2620 // draw it horizontally into memory and rotate for screen
2622 wxBitmap bitmapRotated
,
2623 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
2624 rectLabel
.y
+ rectLabel
.height
);
2625 dcMem
.SelectObject(bitmapMem
);
2626 dcMem
.SetBackground(dc
.GetBackground());
2627 dcMem
.SetFont(dc
.GetFont());
2628 dcMem
.SetTextForeground(dc
.GetTextForeground());
2630 bitmapRotated
= wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) );
2631 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
2632 flags
, wxALIGN_CENTRE
, indexAccel
);
2633 dcMem
.SelectObject(wxNullBitmap
);
2634 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
2635 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
2636 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
2640 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
2641 flags
, wxALIGN_CENTRE
, indexAccel
);
2644 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
2645 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
2646 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
2647 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
2648 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
2649 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
2651 // FIXME: all this code will break if the tab indent or the border width,
2652 // it is tied to the fact that both of them are equal to 2
2658 // left orientation looks like top but IsVertical makes x and y reversed
2660 // top is not vertical so use coordinates in written order
2661 dc
.SetPen(m_penHighlight
);
2662 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
2663 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
2664 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
2665 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
2666 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
2667 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
2669 dc
.SetPen(m_penBlack
);
2670 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
2671 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
2672 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
2673 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
2675 dc
.SetPen(m_penDarkGrey
);
2676 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
2677 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
2679 if ( flags
& wxCONTROL_SELECTED
)
2681 dc
.SetPen(m_penLightGrey
);
2683 // overwrite the part of the border below this tab
2684 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
2685 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
2687 // and the shadow of the tab to the left of us
2688 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
2689 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
2694 // right orientation looks like bottom but IsVertical makes x and y reversed
2696 // bottom is not vertical so use coordinates in written order
2697 dc
.SetPen(m_penHighlight
);
2698 // we need to continue one pixel further to overwrite the corner of
2699 // the border for the selected tab
2700 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
2701 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
2702 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
2703 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
2705 dc
.SetPen(m_penBlack
);
2706 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
2707 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
2708 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2709 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2710 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2711 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2713 dc
.SetPen(m_penDarkGrey
);
2714 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2715 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2716 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2717 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2719 if ( flags
& wxCONTROL_SELECTED
)
2721 dc
.SetPen(m_penLightGrey
);
2723 // overwrite the part of the (double!) border above this tab
2724 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2725 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2726 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2727 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2729 // and the shadow of the tab to the left of us
2730 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2731 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2736 #undef SELECT_FOR_VERTICAL
2737 #undef REVERSE_FOR_VERTICAL
2740 // ----------------------------------------------------------------------------
2742 // ----------------------------------------------------------------------------
2745 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2747 wxOrientation orient
) const
2750 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2751 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2753 if (orient
== wxHORIZONTAL
)
2767 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2769 wxOrientation orient
,
2772 bool transpose
= (orient
== wxVERTICAL
);
2773 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2774 (((style
& wxSL_TOP
) != 0) & !transpose
|
2775 ((style
& wxSL_LEFT
) != 0) & transpose
|
2776 ((style
& wxSL_BOTH
) != 0));
2777 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2778 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2779 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2780 ((style
& wxSL_BOTH
) != 0));
2782 wxRect rect
= rectOrig
;
2784 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2786 if (orient
== wxHORIZONTAL
) {
2787 rect
.x
+= SLIDER_MARGIN
;
2790 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2794 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2798 rect
.y
+= sizeThumb
.y
/2;
2800 rect
.width
-= 2*SLIDER_MARGIN
;
2801 rect
.height
= 2*BORDER_THICKNESS
;
2805 rect
.y
+= SLIDER_MARGIN
;
2808 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2812 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2816 rect
.x
+= sizeThumb
.x
/2;
2818 rect
.width
= 2*BORDER_THICKNESS
;
2819 rect
.height
-= 2*SLIDER_MARGIN
;
2825 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2826 const wxRect
& rectOrig
,
2828 wxOrientation orient
,
2833 /* show shaft geometry
2851 if (flags
& wxCONTROL_FOCUSED
) {
2852 DrawFocusRect(dc
, rectOrig
);
2855 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2857 if (rectShaft
) *rectShaft
= rect
;
2859 DrawSunkenBorder(dc
, &rect
);
2862 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2864 wxOrientation orient
,
2868 /* show thumb geometry
2877 H D B where H is highlight colour
2891 The interior of this shape is filled with the hatched brush if the thumb
2895 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2897 bool transpose
= (orient
== wxVERTICAL
);
2898 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2899 (((style
& wxSL_TOP
) != 0) & !transpose
|
2900 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2901 ((style
& wxSL_BOTH
) == 0);
2902 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2903 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2904 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2905 ((style
& wxSL_BOTH
) == 0);
2907 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2908 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2910 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2911 x1
= (transpose
? rect
.y
: rect
.x
);
2912 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2913 x3
= (x1
-1+c
) + sizeArrow
;
2914 y1
= (transpose
? rect
.x
: rect
.y
);
2915 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2916 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2917 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2919 dc
.SetPen(m_penBlack
);
2921 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2923 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2926 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2930 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2933 dc
.SetPen(m_penDarkGrey
);
2934 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2936 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2940 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2943 dc
.SetPen(m_penHighlight
);
2946 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2947 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2951 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2953 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2956 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2959 if (flags
& wxCONTROL_PRESSED
) {
2960 // TODO: MSW fills the entire area inside, not just the rect
2961 wxRect rectInt
= rect
;
2964 rectInt
.SetLeft(y3
);
2965 rectInt
.SetRight(y4
);
2970 rectInt
.SetBottom(y4
);
2974 #if !defined(__WXMGL__)
2975 static const char *stipple_xpm
[] = {
2976 /* columns rows colors chars-per-pixel */
2985 // VS: MGL can only do 8x8 stipple brushes
2986 static const char *stipple_xpm
[] = {
2987 /* columns rows colors chars-per-pixel */
3002 dc
.SetBrush(wxBrush(stipple_xpm
));
3004 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
3005 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
3006 dc
.SetPen(*wxTRANSPARENT_PEN
);
3007 dc
.DrawRectangle(rectInt
);
3011 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
3014 wxOrientation orient
,
3018 int WXUNUSED(flags
),
3021 /* show ticks geometry
3036 if (end
== start
) return;
3038 bool transpose
= (orient
== wxVERTICAL
);
3039 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
3040 (((style
& wxSL_TOP
) != 0) & !transpose
|
3041 ((style
& wxSL_LEFT
) != 0) & transpose
|
3042 ((style
& wxSL_BOTH
) != 0));
3043 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
3044 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
3045 ((style
& wxSL_RIGHT
) != 0) & transpose
|
3046 ((style
& wxSL_BOTH
) != 0));
3048 // default thumb size
3049 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
3050 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
3052 // normal thumb size
3053 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
3054 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
3056 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
3058 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
3059 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
3060 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
3061 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
3062 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
3063 y3
= (transpose
? rect
.x
: rect
.y
);
3064 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
3067 dc
.SetPen(m_penBlack
);
3069 int range
= end
- start
;
3070 for ( int n
= 0; n
< range
; n
+= step
) {
3071 wxCoord x
= x1
+ (len
*n
) / range
;
3073 if (left
& (y1
> y3
)) {
3074 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
3076 if (right
& (y4
> y2
)) {
3077 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
3080 // always draw the line at the end position
3081 if (left
& (y1
> y3
)) {
3082 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
3084 if (right
& (y4
> y2
)) {
3085 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
3089 // ----------------------------------------------------------------------------
3091 // ----------------------------------------------------------------------------
3093 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
3094 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
3097 virtual wxSize
GetSize() const { return m_size
; }
3099 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
3100 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
3102 wxCoord
GetItemHeight() const { return m_heightItem
; }
3105 // the total size of the menu
3108 // the offset of the start of the menu item label
3111 // the offset of the start of the accel label
3114 // the height of a normal (not separator) item
3115 wxCoord m_heightItem
;
3117 friend wxMenuGeometryInfo
*
3118 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
3121 // FIXME: all constants are hardcoded but shouldn't be
3122 static const wxCoord MENU_LEFT_MARGIN
= 9;
3123 static const wxCoord MENU_RIGHT_MARGIN
= 18;
3124 static const wxCoord MENU_VERT_MARGIN
= 3;
3126 // the margin around bitmap/check marks (on each side)
3127 static const wxCoord MENU_BMP_MARGIN
= 2;
3129 // the margin between the labels and accel strings
3130 static const wxCoord MENU_ACCEL_MARGIN
= 8;
3132 // the separator height in pixels: in fact, strangely enough, the real height
3133 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
3135 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
3137 // the size of the standard checkmark bitmap
3138 static const wxCoord MENU_CHECK_SIZE
= 9;
3140 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
3141 const wxRect
& rectOrig
,
3142 const wxString
& label
,
3146 wxRect rect
= rectOrig
;
3149 wxDCTextColourChanger
colChanger(dc
);
3151 if ( flags
& wxCONTROL_SELECTED
)
3153 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3155 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3156 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3157 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3158 dc
.DrawRectangle(rect
);
3161 // don't draw the focus rect around menu bar items
3162 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
3163 wxALIGN_CENTRE
, indexAccel
);
3166 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
3168 const wxMenuGeometryInfo
& gi
,
3169 const wxString
& label
,
3170 const wxString
& accel
,
3171 const wxBitmap
& bitmap
,
3175 const wxWin32MenuGeometryInfo
& geometryInfo
=
3176 (const wxWin32MenuGeometryInfo
&)gi
;
3181 rect
.width
= geometryInfo
.GetSize().x
;
3182 rect
.height
= geometryInfo
.GetItemHeight();
3184 // draw the selected item specially
3185 wxDCTextColourChanger
colChanger(dc
);
3186 if ( flags
& wxCONTROL_SELECTED
)
3188 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
3190 wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
3191 dc
.SetBrush(wxBrush(colBg
, wxSOLID
));
3192 dc
.SetPen(wxPen(colBg
, 0, wxSOLID
));
3193 dc
.DrawRectangle(rect
);
3196 // draw the bitmap: use the bitmap provided or the standard checkmark for
3197 // the checkable items
3198 wxBitmap bmp
= bitmap
;
3199 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
3201 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
3206 rect
.SetRight(geometryInfo
.GetLabelOffset());
3207 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
3211 rect
.x
= geometryInfo
.GetLabelOffset();
3212 rect
.SetRight(geometryInfo
.GetAccelOffset());
3214 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
3216 // draw the accel string
3217 rect
.x
= geometryInfo
.GetAccelOffset();
3218 rect
.SetRight(geometryInfo
.GetSize().x
);
3220 // NB: no accel index here
3221 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
3223 // draw the submenu indicator
3224 if ( flags
& wxCONTROL_ISSUBMENU
)
3226 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
3227 rect
.width
= MENU_RIGHT_MARGIN
;
3229 wxArrowStyle arrowStyle
;
3230 if ( flags
& wxCONTROL_DISABLED
)
3231 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
3233 else if ( flags
& wxCONTROL_SELECTED
)
3234 arrowStyle
= Arrow_Inverted
;
3236 arrowStyle
= Arrow_Normal
;
3238 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
3242 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
3244 const wxMenuGeometryInfo
& geomInfo
)
3246 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
3249 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
3251 wxSize size
= sizeText
;
3253 // FIXME: menubar height is configurable under Windows
3260 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
3261 const wxMenu
& menu
) const
3263 // prepare the dc: for now we draw all the items with the system font
3265 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
3267 // the height of a normal item
3268 wxCoord heightText
= dc
.GetCharHeight();
3273 // the max length of label and accel strings: the menu width is the sum of
3274 // them, even if they're for different items (as the accels should be
3277 // the max length of the bitmap is never 0 as Windows always leaves enough
3278 // space for a check mark indicator
3279 wxCoord widthLabelMax
= 0,
3281 widthBmpMax
= MENU_LEFT_MARGIN
;
3283 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
3285 node
= node
->GetNext() )
3287 // height of this item
3290 wxMenuItem
*item
= node
->GetData();
3291 if ( item
->IsSeparator() )
3293 h
= MENU_SEPARATOR_HEIGHT
;
3295 else // not separator
3300 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
3301 if ( widthLabel
> widthLabelMax
)
3303 widthLabelMax
= widthLabel
;
3307 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
3308 if ( widthAccel
> widthAccelMax
)
3310 widthAccelMax
= widthAccel
;
3313 const wxBitmap
& bmp
= item
->GetBitmap();
3316 wxCoord widthBmp
= bmp
.GetWidth();
3317 if ( widthBmp
> widthBmpMax
)
3318 widthBmpMax
= widthBmp
;
3320 //else if ( item->IsCheckable() ): no need to check for this as
3321 // MENU_LEFT_MARGIN is big enough to show the check mark
3324 h
+= 2*MENU_VERT_MARGIN
;
3326 // remember the item position and height
3327 item
->SetGeometry(height
, h
);
3332 // bundle the metrics into a struct and return it
3333 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
3335 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
3336 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
3337 if ( widthAccelMax
> 0 )
3339 // if we actually have any accesl, add a margin
3340 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
3343 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
3345 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
3346 gi
->m_size
.y
= height
;
3351 // ----------------------------------------------------------------------------
3353 // ----------------------------------------------------------------------------
3355 static const wxCoord STATBAR_BORDER_X
= 2;
3356 static const wxCoord STATBAR_BORDER_Y
= 2;
3358 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
3360 if ( borderBetweenFields
)
3361 *borderBetweenFields
= 2;
3363 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3366 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
3368 const wxString
& label
,
3369 int flags
, int style
/*=0*/)
3373 if ( flags
& wxCONTROL_ISDEFAULT
)
3375 // draw the size grip: it is a normal rect except that in the lower
3376 // right corner we have several bands which may be used for dragging
3377 // the status bar corner
3379 // each band consists of 4 stripes: m_penHighlight, double
3380 // m_penDarkGrey and transparent one
3381 wxCoord x2
= rect
.GetRight(),
3382 y2
= rect
.GetBottom();
3384 // draw the upper left part of the rect normally
3385 if (style
!= wxSB_FLAT
)
3387 if (style
== wxSB_RAISED
)
3388 dc
.SetPen(m_penHighlight
);
3390 dc
.SetPen(m_penDarkGrey
);
3391 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
3392 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
3395 // draw the grey stripes of the grip
3397 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
3398 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3400 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3401 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
3404 // draw the white stripes
3405 dc
.SetPen(m_penHighlight
);
3406 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
3407 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
3409 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
3412 // draw the remaining rect boundaries
3413 if (style
!= wxSB_FLAT
)
3415 if (style
== wxSB_RAISED
)
3416 dc
.SetPen(m_penDarkGrey
);
3418 dc
.SetPen(m_penHighlight
);
3419 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
3420 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
3421 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
3427 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
3431 if (style
== wxSB_RAISED
)
3432 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
3433 else if (style
!= wxSB_FLAT
)
3434 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
3437 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
3439 wxDCClipper
clipper(dc
, rectIn
);
3440 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3443 // ----------------------------------------------------------------------------
3445 // ----------------------------------------------------------------------------
3447 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
3448 wxBitmap
* WXUNUSED(bmpFocus
),
3449 wxBitmap
*bmpPressed
,
3450 wxBitmap
*bmpDisabled
)
3452 static const wxCoord widthCombo
= 16;
3453 static const wxCoord heightCombo
= 17;
3459 bmpNormal
->Create(widthCombo
, heightCombo
);
3460 dcMem
.SelectObject(*bmpNormal
);
3461 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3462 Arrow_Down
, Arrow_Normal
);
3467 bmpPressed
->Create(widthCombo
, heightCombo
);
3468 dcMem
.SelectObject(*bmpPressed
);
3469 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3470 Arrow_Down
, Arrow_Pressed
);
3475 bmpDisabled
->Create(widthCombo
, heightCombo
);
3476 dcMem
.SelectObject(*bmpDisabled
);
3477 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
3478 Arrow_Down
, Arrow_Disabled
);
3482 // ----------------------------------------------------------------------------
3484 // ----------------------------------------------------------------------------
3486 void wxWin32Renderer::DoDrawBackground(wxDC
& dc
,
3487 const wxColour
& col
,
3489 wxWindow
* WXUNUSED(window
))
3491 wxBrush
brush(col
, wxSOLID
);
3493 dc
.SetPen(*wxTRANSPARENT_PEN
);
3494 dc
.DrawRectangle(rect
);
3497 void wxWin32Renderer::DrawBackground(wxDC
& dc
,
3498 const wxColour
& col
,
3500 int WXUNUSED(flags
),
3503 // just fill it with the given or default bg colour
3504 wxColour colBg
= col
.Ok() ? col
: wxSCHEME_COLOUR(m_scheme
, CONTROL
);
3505 DoDrawBackground(dc
, colBg
, rect
, window
);
3508 // ----------------------------------------------------------------------------
3510 // ----------------------------------------------------------------------------
3512 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3517 // get the bitmap for this arrow
3518 wxArrowDirection arrowDir
;
3521 case wxLEFT
: arrowDir
= Arrow_Left
; break;
3522 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
3523 case wxUP
: arrowDir
= Arrow_Up
; break;
3524 case wxDOWN
: arrowDir
= Arrow_Down
; break;
3527 wxFAIL_MSG(_T("unknown arrow direction"));
3531 wxArrowStyle arrowStyle
;
3532 if ( flags
& wxCONTROL_PRESSED
)
3534 // can't be pressed and disabled
3535 arrowStyle
= Arrow_Pressed
;
3539 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
3542 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
3545 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
3547 wxArrowDirection arrowDir
,
3548 wxArrowStyle arrowStyle
)
3550 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
3552 // under Windows the arrows always have the same size so just centre it in
3553 // the provided rectangle
3554 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
3555 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
3557 // Windows does it like this...
3558 if ( arrowDir
== Arrow_Left
)
3562 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
3565 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
3566 const wxRect
& rectAll
,
3567 wxArrowDirection arrowDir
,
3568 wxArrowStyle arrowStyle
)
3570 wxRect rect
= rectAll
;
3571 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3572 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
3573 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
3576 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
3577 wxOrientation
WXUNUSED(orient
),
3579 int WXUNUSED(flags
))
3581 // we don't use the flags, the thumb never changes appearance
3582 wxRect rectThumb
= rect
;
3583 DrawArrowBorder(dc
, &rectThumb
);
3584 DrawBackground(dc
, wxNullColour
, rectThumb
);
3587 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
3588 wxOrientation
WXUNUSED(orient
),
3589 const wxRect
& rectBar
,
3592 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
3593 ? wxColourScheme::SCROLLBAR_PRESSED
3594 : wxColourScheme::SCROLLBAR
;
3595 DoDrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
3598 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
3600 DoDrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
3603 wxRect
wxWin32Renderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
3604 wxScrollBar::Element elem
,
3607 return StandardGetScrollbarRect(scrollbar
, elem
,
3608 thumbPos
, m_sizeScrollbarArrow
);
3611 wxCoord
wxWin32Renderer::GetScrollbarSize(const wxScrollBar
*scrollbar
)
3613 return StandardScrollBarSize(scrollbar
, m_sizeScrollbarArrow
);
3616 wxHitTest
wxWin32Renderer::HitTestScrollbar(const wxScrollBar
*scrollbar
,
3617 const wxPoint
& pt
) const
3619 return StandardHitTestScrollbar(scrollbar
, pt
, m_sizeScrollbarArrow
);
3622 wxCoord
wxWin32Renderer::ScrollbarToPixel(const wxScrollBar
*scrollbar
,
3625 return StandardScrollbarToPixel(scrollbar
, thumbPos
, m_sizeScrollbarArrow
);
3628 int wxWin32Renderer::PixelToScrollbar(const wxScrollBar
*scrollbar
,
3631 return StandardPixelToScrollbar(scrollbar
, coord
, m_sizeScrollbarArrow
);
3634 // ----------------------------------------------------------------------------
3635 // top level windows
3636 // ----------------------------------------------------------------------------
3638 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
3640 wxRect client
= GetFrameClientArea(rect
, flags
);
3642 if ( client
.Inside(pt
) )
3643 return wxHT_TOPLEVEL_CLIENT_AREA
;
3645 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3647 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3649 if ( flags
& wxTOPLEVEL_ICON
)
3651 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Inside(pt
) )
3652 return wxHT_TOPLEVEL_ICON
;
3655 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
3656 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
3657 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3659 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3661 if ( btnRect
.Inside(pt
) )
3662 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
3663 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
3665 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3667 if ( btnRect
.Inside(pt
) )
3668 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
3669 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3671 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3673 if ( btnRect
.Inside(pt
) )
3674 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
3675 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3677 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3679 if ( btnRect
.Inside(pt
) )
3680 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
3681 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3683 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3685 if ( btnRect
.Inside(pt
) )
3686 return wxHT_TOPLEVEL_BUTTON_HELP
;
3687 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
3690 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
3691 return wxHT_TOPLEVEL_TITLEBAR
;
3694 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3696 // we are certainly at one of borders, lets decide which one:
3699 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
3700 if ( pt
.x
< client
.x
)
3701 border
|= wxHT_TOPLEVEL_BORDER_W
;
3702 else if ( pt
.x
>= client
.width
+ client
.x
)
3703 border
|= wxHT_TOPLEVEL_BORDER_E
;
3704 if ( pt
.y
< client
.y
)
3705 border
|= wxHT_TOPLEVEL_BORDER_N
;
3706 else if ( pt
.y
>= client
.height
+ client
.y
)
3707 border
|= wxHT_TOPLEVEL_BORDER_S
;
3711 return wxHT_NOWHERE
;
3714 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
3716 const wxString
& title
,
3720 int specialButtonFlags
)
3722 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3724 DrawFrameBorder(dc
, rect
, flags
);
3726 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3728 DrawFrameBackground(dc
, rect
, flags
);
3729 if ( flags
& wxTOPLEVEL_ICON
)
3730 DrawFrameIcon(dc
, rect
, icon
, flags
);
3731 DrawFrameTitle(dc
, rect
, title
, flags
);
3733 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3735 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3736 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3738 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3740 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3741 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3742 specialButtonFlags
: 0);
3743 x
-= FRAME_BUTTON_WIDTH
+ 2;
3745 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3747 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3748 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3749 specialButtonFlags
: 0);
3750 x
-= FRAME_BUTTON_WIDTH
;
3752 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3754 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3755 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3756 specialButtonFlags
: 0);
3757 x
-= FRAME_BUTTON_WIDTH
;
3759 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3761 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3762 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3763 specialButtonFlags
: 0);
3764 x
-= FRAME_BUTTON_WIDTH
;
3766 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3768 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3769 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3770 specialButtonFlags
: 0);
3775 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3779 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3783 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3784 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3785 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3786 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3787 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3790 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3794 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3796 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3797 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3798 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3800 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3801 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3803 DrawBackground(dc
, col
, r
);
3806 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3808 const wxString
& title
,
3811 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3812 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3813 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3815 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3816 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3817 if ( flags
& wxTOPLEVEL_ICON
)
3819 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3820 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3828 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3829 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3830 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3831 r
.width
-= FRAME_BUTTON_WIDTH
;
3832 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3833 r
.width
-= FRAME_BUTTON_WIDTH
;
3834 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3835 r
.width
-= FRAME_BUTTON_WIDTH
;
3836 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3837 r
.width
-= FRAME_BUTTON_WIDTH
;
3839 dc
.SetFont(m_titlebarFont
);
3840 dc
.SetTextForeground(col
);
3843 dc
.GetTextExtent(title
, &textW
, NULL
);
3844 if ( textW
> r
.width
)
3846 // text is too big, let's shorten it and add "..." after it:
3847 size_t len
= title
.length();
3848 wxCoord WSoFar
, letterW
;
3850 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3851 if ( WSoFar
> r
.width
)
3853 // not enough space to draw anything
3859 for (size_t i
= 0; i
< len
; i
++)
3861 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3862 if ( letterW
+ WSoFar
> r
.width
)
3868 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3869 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3872 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3873 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3876 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3883 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3884 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3888 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3889 wxCoord x
, wxCoord y
,
3893 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3898 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3899 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3900 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3901 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3902 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3904 wxFAIL_MSG(wxT("incorrect button specification"));
3907 if ( flags
& wxCONTROL_PRESSED
)
3909 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3910 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3911 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3912 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3916 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3917 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3918 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3919 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3924 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3929 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3931 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3932 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3933 FRAME_BORDER_THICKNESS
;
3936 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3938 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3939 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3945 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3948 wxSize
s(clientSize
);
3950 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3952 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3953 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3954 FRAME_BORDER_THICKNESS
;
3958 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3959 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3964 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3968 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3970 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3971 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3972 FRAME_BORDER_THICKNESS
;
3977 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3979 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3981 if ( flags
& wxTOPLEVEL_ICON
)
3982 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3983 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3984 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3985 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3986 s
.x
+= FRAME_BUTTON_WIDTH
;
3987 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3988 s
.x
+= FRAME_BUTTON_WIDTH
;
3989 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3990 s
.x
+= FRAME_BUTTON_WIDTH
;
3991 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3992 s
.x
+= FRAME_BUTTON_WIDTH
;
3998 wxSize
wxWin32Renderer::GetFrameIconSize() const
4000 return wxSize(16, 16);
4004 // ----------------------------------------------------------------------------
4006 // ----------------------------------------------------------------------------
4008 /* Copyright (c) Julian Smart */
4009 static char *error_xpm
[]={
4010 /* columns rows colors chars-per-pixel */
4087 " $oooooooooooo%& ",
4088 " *=-ooooooooooooo;: ",
4089 " *oooooooooooooooooo> ",
4090 " =ooooooooooooooooooo, ",
4091 " $-ooooooooooooooooooo<1 ",
4092 " .oooooo2334ooo533oooooo6 ",
4093 " +ooooooo789oo2883oooooo0q ",
4094 " oooooooo2w83o78eoooooooor ",
4095 " toooooooooy88u884oooooooori ",
4096 " Xooooooooooe888poooooooooas ",
4097 " ooooooooooo4889doooooooooof ",
4098 " ooooooooooo588w2oooooooooofi ",
4099 " oooooooooodw8887oooooooooofi ",
4100 " goooooooooh8w588jooooooookli ",
4101 " tooooooooz885op8wdooooooorix ",
4102 " oooooood98cood98cooooooori ",
4103 " @oooooop8w2ooo5885ooooovbi ",
4104 " n%ooooooooooooooooooooomiM ",
4105 " &;oooooooooooooooooooNBiV ",
4106 " :ooooooooooooooooooCZiA ",
4107 " nSooooooooooooooooCDiF ",
4108 " nG<oooooooooooooNZiiH ",
4109 " 160ooooooooovmBiFH ",
4110 " nqrraoookrrbiiA ",
4117 /* Copyright (c) Julian Smart */
4118 static char *info_xpm
[]={
4119 /* columns rows colors chars-per-pixel */
4141 " ..XXXXXXXXXXXXX.. ",
4142 " .XXXXXXXXXXXXXXXXX. ",
4143 " .XXXXXXXXoO+XXXXXXXX. ",
4144 " .XXXXXXXXX@#OXXXXXXXXX. ",
4145 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
4146 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
4147 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
4148 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
4149 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
4150 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
4151 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4152 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
4153 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
4154 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
4155 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
4156 " .XXXXXXXXXXXXXXXXX.%%%% ",
4157 " ..XXXXXXXXXXXXX..%%%% ",
4158 " %...XXXXXXXX..%%%%% ",
4159 " %%%..XXXXXX.%%%%% ",
4173 /* Copyright (c) Julian Smart */
4174 static char *question_xpm
[]={
4175 /* columns rows colors chars-per-pixel */
4196 " ..XXXXXXXXXXXXX.. ",
4197 " .XXXXXXoO++@XXXXXX. ",
4198 " .XXXXXXO#$$$$#%XXXXX. ",
4199 " .XXXXXX@$$#&&#$#oXXXXX. ",
4200 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
4201 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
4202 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
4203 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
4204 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
4205 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
4206 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
4207 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
4208 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
4209 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
4210 " .XXXXXXXX-$$XXXXXXXX.:::: ",
4211 " .XXXXXXXO++XXXXXXX.:::: ",
4212 " ..XXXXXXXXXXXXX..:::: ",
4213 " :...XXXXXXXX..::::: ",
4214 " :::..XXXXXX.::::: ",
4228 /* Copyright (c) Julian Smart */
4229 static char *warning_xpm
[]={
4230 /* columns rows colors chars-per-pixel */
4256 " ..XXXXO@#XXX... ",
4257 " ...XXXXO@#XXXX.. ",
4258 " ..XXXXXO@#XXXX... ",
4259 " ...XXXXXo@OXXXXX.. ",
4260 " ...XXXXXXo@OXXXXXX.. ",
4261 " ..XXXXXXX$@OXXXXXX... ",
4262 " ...XXXXXXXX@XXXXXXXX.. ",
4263 " ...XXXXXXXXXXXXXXXXXX... ",
4264 " ..XXXXXXXXXXOXXXXXXXXX.. ",
4265 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
4266 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
4267 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
4268 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
4269 " .............................. ",
4270 " .............................. ",
4277 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
4278 const wxArtClient
& WXUNUSED(client
),
4279 const wxSize
& WXUNUSED(size
))
4281 if ( id
== wxART_INFORMATION
)
4282 return wxBitmap(info_xpm
);
4283 if ( id
== wxART_ERROR
)
4284 return wxBitmap(error_xpm
);
4285 if ( id
== wxART_WARNING
)
4286 return wxBitmap(warning_xpm
);
4287 if ( id
== wxART_QUESTION
)
4288 return wxBitmap(question_xpm
);
4289 return wxNullBitmap
;
4293 // ----------------------------------------------------------------------------
4294 // text control geometry
4295 // ----------------------------------------------------------------------------
4297 static inline int GetTextBorderWidth()
4303 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
4304 const wxRect
& rect
) const
4306 wxRect rectTotal
= rect
;
4308 wxCoord widthBorder
= GetTextBorderWidth();
4309 rectTotal
.Inflate(widthBorder
);
4311 // this is what Windows does
4318 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
4320 wxCoord
*extraSpaceBeyond
) const
4322 wxRect rectText
= rect
;
4324 // undo GetTextTotalArea()
4325 if ( rectText
.height
> 0 )
4328 wxCoord widthBorder
= GetTextBorderWidth();
4329 rectText
.Inflate(-widthBorder
);
4331 if ( extraSpaceBeyond
)
4332 *extraSpaceBeyond
= 0;
4337 // ----------------------------------------------------------------------------
4339 // ----------------------------------------------------------------------------
4341 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
4344 if ( wxDynamicCast(window
, wxScrollBar
) )
4346 // we only set the width of vert scrollbars and height of the
4348 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
4349 size
->y
= m_sizeScrollbarArrow
.y
;
4351 size
->x
= m_sizeScrollbarArrow
.x
;
4353 // skip border width adjustments, they don't make sense for us
4356 #endif // wxUSE_SCROLLBAR/!wxUSE_SCROLLBAR
4359 if ( wxDynamicCast(window
, wxBitmapButton
) )
4363 #endif // wxUSE_BMPBUTTON
4364 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
4367 || wxDynamicCast(window
, wxButton
)
4368 # endif // wxUSE_BUTTON
4369 # if wxUSE_TOGGLEBTN
4370 || wxDynamicCast(window
, wxToggleButton
)
4371 # endif // wxUSE_TOGGLEBTN
4374 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4376 // TODO: don't harcode all this
4377 size
->x
+= 3*window
->GetCharWidth();
4379 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
4380 if ( size
->y
< heightBtn
- 8 )
4381 size
->y
= heightBtn
;
4386 // for compatibility with other ports, the buttons default size is never
4387 // less than the standard one, but not when display not PDAs.
4388 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
4390 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
4392 wxSize szDef
= wxButton::GetDefaultSize();
4393 if ( size
->x
< szDef
.x
)
4398 // no border width adjustments for buttons
4401 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
4403 // take into account the border width
4404 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
4405 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
4406 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
4409 // ============================================================================
4411 // ============================================================================
4413 // ----------------------------------------------------------------------------
4414 // wxWin32InputHandler
4415 // ----------------------------------------------------------------------------
4417 wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer
*renderer
)
4419 m_renderer
= renderer
;
4422 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
4423 const wxKeyEvent
& WXUNUSED(event
),
4424 bool WXUNUSED(pressed
))
4429 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
4430 const wxMouseEvent
& event
)
4432 // clicking on the control gives it focus
4433 if ( event
.ButtonDown() )
4435 wxWindow
*win
= control
->GetInputWindow();
4437 if (( wxWindow::FindFocus() != control
->GetInputWindow() ) &&
4438 ( win
->AcceptsFocus() ) )
4449 // ----------------------------------------------------------------------------
4450 // wxWin32ScrollBarInputHandler
4451 // ----------------------------------------------------------------------------
4453 wxWin32ScrollBarInputHandler::
4454 wxWin32ScrollBarInputHandler(wxWin32Renderer
*renderer
,
4455 wxInputHandler
*handler
)
4456 : wxStdScrollBarInputHandler(renderer
, handler
)
4458 m_scrollPaused
= false;
4462 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
4463 const wxControlAction
& action
)
4465 // stop if went beyond the position of the original click (this can only
4466 // happen when we scroll by pages)
4468 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
4470 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4471 != wxHT_SCROLLBAR_BAR_2
;
4473 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
4475 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
4476 != wxHT_SCROLLBAR_BAR_1
;
4481 StopScrolling(scrollbar
);
4483 scrollbar
->Refresh();
4488 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
4491 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
4492 const wxMouseEvent
& event
)
4494 // remember the current state
4495 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
4497 // do process the message
4498 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
4500 // analyse the changes
4501 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
4503 // we just started dragging the thumb, remember its initial position to
4504 // be able to restore it if the drag is cancelled later
4505 m_eventStartDrag
= event
;
4511 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
4512 const wxMouseEvent
& event
)
4514 // we don't highlight scrollbar elements, so there is no need to process
4515 // mouse move events normally - only do it while mouse is captured (i.e.
4516 // when we're dragging the thumb or pressing on something)
4517 if ( !m_winCapture
)
4520 if ( event
.Entering() )
4522 // we're not interested in this at all
4526 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
4528 if ( m_scrollPaused
)
4530 // check if the mouse returned to its original location
4532 if ( event
.Leaving() )
4538 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4539 if ( ht
== m_htLast
)
4541 // yes it did, resume scrolling
4542 m_scrollPaused
= false;
4543 if ( m_timerScroll
)
4545 // we were scrolling by line/page, restart timer
4546 m_timerScroll
->Start(m_interval
);
4548 Press(scrollbar
, true);
4550 else // we were dragging the thumb
4552 // restore its last location
4553 HandleThumbMove(scrollbar
, m_eventLastDrag
);
4559 else // normal case, scrolling hasn't been paused
4561 // if we're scrolling the scrollbar because the arrow or the shaft was
4562 // pressed, check that the mouse stays on the same scrollbar element
4565 // Always let thumb jump back if we leave the scrollbar
4566 if ( event
.Moving() )
4568 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
4570 else // event.Leaving()
4575 // Jump back only if we get far away from it
4576 wxPoint pos
= event
.GetPosition();
4577 if (scrollbar
->HasFlag( wxVERTICAL
))
4579 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
4584 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
4587 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
4590 // if we're dragging the thumb and the mouse stays in the scrollbar, it
4591 // is still ok - we only want to catch the case when the mouse leaves
4592 // the scrollbar here
4593 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
4595 ht
= wxHT_SCROLLBAR_THUMB
;
4598 if ( ht
!= m_htLast
)
4600 // what were we doing? 2 possibilities: either an arrow/shaft was
4601 // pressed in which case we have a timer and so we just stop it or
4602 // we were dragging the thumb
4603 if ( m_timerScroll
)
4606 m_interval
= m_timerScroll
->GetInterval();
4607 m_timerScroll
->Stop();
4608 m_scrollPaused
= true;
4610 // unpress the arrow
4611 Press(scrollbar
, false);
4613 else // we were dragging the thumb
4615 // remember the current thumb position to be able to restore it
4616 // if the mouse returns to it later
4617 m_eventLastDrag
= event
;
4619 // and restore the original position (before dragging) of the
4621 HandleThumbMove(scrollbar
, m_eventStartDrag
);
4628 return wxStdScrollBarInputHandler::HandleMouseMove(control
, event
);
4631 // ----------------------------------------------------------------------------
4632 // wxWin32CheckboxInputHandler
4633 // ----------------------------------------------------------------------------
4635 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
4636 const wxKeyEvent
& event
,
4641 wxControlAction action
;
4642 int keycode
= event
.GetKeyCode();
4646 action
= wxACTION_CHECKBOX_TOGGLE
;
4650 case WXK_NUMPAD_SUBTRACT
:
4651 action
= wxACTION_CHECKBOX_CHECK
;
4655 case WXK_NUMPAD_ADD
:
4656 case WXK_NUMPAD_EQUAL
:
4657 action
= wxACTION_CHECKBOX_CLEAR
;
4661 if ( !action
.IsEmpty() )
4663 control
->PerformAction(action
);
4672 // ----------------------------------------------------------------------------
4673 // wxWin32TextCtrlInputHandler
4674 // ----------------------------------------------------------------------------
4676 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
4677 const wxKeyEvent
& event
,
4680 // handle only MSW-specific text bindings here, the others are handled in
4684 int keycode
= event
.GetKeyCode();
4686 wxControlAction action
;
4687 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
4689 action
= wxACTION_TEXT_CUT
;
4691 else if ( keycode
== WXK_INSERT
)
4693 if ( event
.ControlDown() )
4694 action
= wxACTION_TEXT_COPY
;
4695 else if ( event
.ShiftDown() )
4696 action
= wxACTION_TEXT_PASTE
;
4699 if ( action
!= wxACTION_NONE
)
4701 control
->PerformAction(action
);
4707 return wxStdTextCtrlInputHandler::HandleKey(control
, event
, pressed
);
4710 // ----------------------------------------------------------------------------
4711 // wxWin32StatusBarInputHandler
4712 // ----------------------------------------------------------------------------
4714 wxWin32StatusBarInputHandler::
4715 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
4716 : wxStdInputHandler(handler
)
4721 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4722 const wxPoint
& pt
) const
4724 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4725 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4728 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4730 wxCHECK_MSG( parentTLW
, false,
4731 _T("the status bar should be a child of a TLW") );
4733 // a maximized window can't be resized anyhow
4734 if ( !parentTLW
->IsMaximized() )
4736 // VZ: I think that the standard Windows behaviour is to only
4737 // show the resizing cursor when the mouse is on top of the
4738 // grip itself but apparently different Windows versions behave
4739 // differently (?) and it seems a better UI to allow resizing
4740 // the status bar even when the mouse is above the grip
4741 wxSize sizeSbar
= statbar
->GetSize();
4743 int diff
= sizeSbar
.x
- pt
.x
;
4744 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4751 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4752 const wxMouseEvent
& event
)
4754 if ( event
.Button(1) )
4756 if ( event
.ButtonDown(1) )
4758 wxWindow
*statbar
= consumer
->GetInputWindow();
4760 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4762 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4766 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4767 wxHT_TOPLEVEL_BORDER_SE
);
4769 statbar
->SetCursor(m_cursorOld
);
4777 return wxStdInputHandler::HandleMouse(consumer
, event
);
4780 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4781 const wxMouseEvent
& event
)
4783 wxWindow
*statbar
= consumer
->GetInputWindow();
4785 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4786 if ( isOnGrip
!= m_isOnGrip
)
4788 m_isOnGrip
= isOnGrip
;
4791 m_cursorOld
= statbar
->GetCursor();
4792 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4796 statbar
->SetCursor(m_cursorOld
);
4800 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4803 // ----------------------------------------------------------------------------
4804 // wxWin32FrameInputHandler
4805 // ----------------------------------------------------------------------------
4807 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4810 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4812 void Attach(wxInputConsumer
*consumer
);
4816 DECLARE_EVENT_TABLE()
4817 void OnSystemMenu(wxCommandEvent
&event
);
4818 void OnCloseFrame(wxCommandEvent
&event
);
4819 void OnClose(wxCloseEvent
&event
);
4821 wxWin32FrameInputHandler
*m_inputHnd
;
4822 wxTopLevelWindow
*m_wnd
;
4824 wxAcceleratorTable m_oldAccelTable
;
4828 wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
4829 wxWin32FrameInputHandler
*handler
)
4831 m_inputHnd
= handler
;
4835 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4837 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4839 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4840 m_wnd
->PushEventHandler(this);
4843 // VS: This code relies on using generic implementation of
4844 // wxAcceleratorTable in wxUniv!
4845 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4846 m_oldAccelTable
= table
;
4847 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4848 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4849 m_wnd
->SetAcceleratorTable(table
);
4853 void wxWin32SystemMenuEvtHandler::Detach()
4858 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4860 m_wnd
->RemoveEventHandler(this);
4865 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4866 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4867 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4868 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4871 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4873 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4874 !m_wnd
->IsMaximized()) ?
4875 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4876 FRAME_BORDER_THICKNESS
;
4877 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4878 pt
.x
= -pt
.x
+ border
;
4879 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4882 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4883 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4886 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4889 m_wnd
->SetAcceleratorTable(table
);
4893 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4895 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4896 wxTOPLEVEL_BUTTON_CLOSE
);
4899 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4906 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4907 : wxStdFrameInputHandler(handler
)
4909 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4912 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4914 if ( m_menuHandler
)
4916 m_menuHandler
->Detach();
4917 delete m_menuHandler
;
4921 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4922 const wxMouseEvent
& event
)
4924 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4926 wxTopLevelWindow
*tlw
=
4927 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4929 long hit
= tlw
->HitTest(event
.GetPosition());
4931 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4933 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4934 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4935 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4938 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4940 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4941 (event
.RightDown() &&
4942 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4943 hit
== wxHT_TOPLEVEL_ICON
)) )
4945 PopupSystemMenu(tlw
, event
.GetPosition());
4951 return wxStdFrameInputHandler::HandleMouse(consumer
, event
);
4954 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4955 const wxPoint
& pos
) const
4957 wxMenu
*menu
= new wxMenu
;
4959 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4960 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4961 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4962 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4963 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4964 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4965 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4966 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4967 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4968 menu
->AppendSeparator();
4969 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4971 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4973 if ( window
->IsMaximized() )
4975 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4976 menu
->Enable(wxID_MOVE_FRAME
, false);
4977 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4978 menu
->Enable(wxID_RESIZE_FRAME
, false);
4981 menu
->Enable(wxID_RESTORE_FRAME
, false);
4984 window
->PopupMenu(menu
, pos
);
4988 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4991 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4993 // always detach if active frame changed:
4994 m_menuHandler
->Detach();
4998 m_menuHandler
->Attach(consumer
);
5002 return wxStdFrameInputHandler::HandleActivation(consumer
, activated
);