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"
52 #include "wx/toplevel.h"
56 #include "wx/notebook.h"
57 #include "wx/spinbutt.h"
58 #include "wx/artprov.h"
59 #ifdef wxUSE_TOGGLEBTN
60 #include "wx/tglbtn.h"
61 #endif // wxUSE_TOGGLEBTN
63 #include "wx/univ/scrtimer.h"
64 #include "wx/univ/stdrend.h"
65 #include "wx/univ/inpcons.h"
66 #include "wx/univ/inphand.h"
67 #include "wx/univ/colschem.h"
68 #include "wx/univ/theme.h"
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 static const int BORDER_THICKNESS
= 2;
76 // the offset between the label and focus rect around it
77 static const int FOCUS_RECT_OFFSET_X
= 1;
78 static const int FOCUS_RECT_OFFSET_Y
= 1;
80 static const int FRAME_BORDER_THICKNESS
= 3;
81 static const int RESIZEABLE_FRAME_BORDER_THICKNESS
= 4;
82 static const int FRAME_TITLEBAR_HEIGHT
= 18;
83 static const int FRAME_BUTTON_WIDTH
= 16;
84 static const int FRAME_BUTTON_HEIGHT
= 14;
86 static const size_t NUM_STATUSBAR_GRIP_BANDS
= 3;
87 static const size_t WIDTH_STATUSBAR_GRIP_BAND
= 4;
88 static const size_t STATUSBAR_GRIP_SIZE
=
89 WIDTH_STATUSBAR_GRIP_BAND
*NUM_STATUSBAR_GRIP_BANDS
;
91 static const wxCoord SLIDER_MARGIN
= 6; // margin around slider
92 static const wxCoord SLIDER_THUMB_LENGTH
= 18;
93 static const wxCoord SLIDER_TICK_LENGTH
= 6;
95 // wxWin32Renderer: draw the GUI elements in Win32 style
96 // ----------------------------------------------------------------------------
98 class wxWin32Renderer
: public wxStdRenderer
102 enum wxArrowDirection
117 Arrow_InvertedDisabled
,
121 enum wxFrameButtonType
124 FrameButton_Minimize
,
125 FrameButton_Maximize
,
132 wxWin32Renderer(const wxColourScheme
*scheme
);
134 // reimplement the renderer methods which are different for this theme
135 virtual void DrawLabel(wxDC
& dc
,
136 const wxString
& label
,
139 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
141 wxRect
*rectBounds
= NULL
);
142 virtual void DrawButtonLabel(wxDC
& dc
,
143 const wxString
& label
,
144 const wxBitmap
& image
,
147 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
149 wxRect
*rectBounds
= NULL
);
150 virtual void DrawButtonBorder(wxDC
& dc
,
153 wxRect
*rectIn
= NULL
);
154 virtual void DrawArrow(wxDC
& dc
,
158 virtual void DrawScrollbarArrow(wxDC
& dc
,
162 { DrawArrow(dc
, dir
, rect
, flags
); }
163 virtual void DrawScrollbarThumb(wxDC
& dc
,
164 wxOrientation orient
,
167 virtual void DrawScrollbarShaft(wxDC
& dc
,
168 wxOrientation orient
,
171 virtual void DrawScrollCorner(wxDC
& dc
,
173 virtual void DrawCheckItem(wxDC
& dc
,
174 const wxString
& label
,
175 const wxBitmap
& bitmap
,
180 virtual void DrawToolBarButton(wxDC
& dc
,
181 const wxString
& label
,
182 const wxBitmap
& bitmap
,
187 #endif // wxUSE_TOOLBAR
190 virtual void DrawTab(wxDC
& dc
,
193 const wxString
& label
,
194 const wxBitmap
& bitmap
= wxNullBitmap
,
196 int indexAccel
= -1);
197 #endif // wxUSE_NOTEBOOK
200 virtual void DrawSliderShaft(wxDC
& dc
,
203 wxOrientation orient
,
206 wxRect
*rectShaft
= NULL
);
207 virtual void DrawSliderThumb(wxDC
& dc
,
209 wxOrientation orient
,
212 virtual void DrawSliderTicks(wxDC
& dc
,
215 wxOrientation orient
,
221 #endif // wxUSE_SLIDER
224 virtual void DrawMenuBarItem(wxDC
& dc
,
226 const wxString
& label
,
228 int indexAccel
= -1);
229 virtual void DrawMenuItem(wxDC
& dc
,
231 const wxMenuGeometryInfo
& geometryInfo
,
232 const wxString
& label
,
233 const wxString
& accel
,
234 const wxBitmap
& bitmap
= wxNullBitmap
,
236 int indexAccel
= -1);
237 virtual void DrawMenuSeparator(wxDC
& dc
,
239 const wxMenuGeometryInfo
& geomInfo
);
240 #endif // wxUSE_MENUS
243 virtual void DrawStatusField(wxDC
& dc
,
245 const wxString
& label
,
246 int flags
= 0, int style
= 0);
247 #endif // wxUSE_STATUSBAR
250 virtual void DrawFrameTitleBar(wxDC
& dc
,
252 const wxString
& title
,
255 int specialButton
= 0,
256 int specialButtonFlags
= 0);
257 virtual void DrawFrameBorder(wxDC
& dc
,
260 virtual void DrawFrameBackground(wxDC
& dc
,
263 virtual void DrawFrameTitle(wxDC
& dc
,
265 const wxString
& title
,
267 virtual void DrawFrameIcon(wxDC
& dc
,
271 virtual void DrawFrameButton(wxDC
& dc
,
272 wxCoord x
, wxCoord y
,
275 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
276 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
277 virtual wxSize
GetFrameMinSize(int flags
) const;
278 virtual wxSize
GetFrameIconSize() const;
279 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
281 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
283 wxBitmap
*bmpPressed
,
284 wxBitmap
*bmpDisabled
);
286 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
287 virtual bool AreScrollbarsInsideBorder() const;
289 virtual wxSize
GetScrollbarArrowSize() const
290 { return m_sizeScrollbarArrow
; }
292 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
293 { return fontHeight
+ 2; }
294 virtual wxSize
GetCheckBitmapSize() const
295 { return wxSize(13, 13); }
296 virtual wxSize
GetRadioBitmapSize() const
297 { return wxSize(12, 12); }
298 virtual wxCoord
GetCheckItemMargin() const
301 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
302 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
303 virtual wxSize
GetToolBarMargin() const
304 { return wxSize(4, 4); }
307 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
308 const wxRect
& rect
) const;
309 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
311 wxCoord
*extraSpaceBeyond
) const;
312 #endif // wxUSE_TEXTCTRL
315 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
316 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
317 #endif // wxUSE_NOTEBOOK
321 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
322 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
323 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
325 wxOrientation orient
,
326 long style
= 0) const;
327 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
329 wxOrientation orient
) const;
330 #endif // wxUSE_SLIDER
332 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
335 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
336 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
337 const wxMenu
& menu
) const;
338 #endif // wxUSE_MENUS
341 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
342 #endif // wxUSE_STATUSBAR
345 virtual void DrawFrameWithLabel(wxDC
& dc
,
346 const wxString
& label
,
347 const wxRect
& rectFrame
,
348 const wxRect
& rectText
,
354 // draw the border used for scrollbar arrows
355 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
357 // public DrawArrow()s helper
358 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
359 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
361 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
362 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
363 wxArrowDirection arrowDir
,
364 wxArrowStyle arrowStyle
);
366 // DrawCheckButton helper
367 void DrawCheckOrRadioButton(wxDC
& dc
,
368 const wxString
& label
,
369 const wxBitmap
& bitmap
,
374 wxCoord focusOffsetY
);
376 // draw a normal or transposed line (useful for using the same code fo both
377 // horizontal and vertical widgets)
378 void DrawLine(wxDC
& dc
,
379 wxCoord x1
, wxCoord y1
,
380 wxCoord x2
, wxCoord y2
,
381 bool transpose
= false)
384 dc
.DrawLine(y1
, x1
, y2
, x2
);
386 dc
.DrawLine(x1
, y1
, x2
, y2
);
389 // get the standard check/radio button bitmap
390 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
391 wxBitmap
GetCheckBitmap(int flags
)
392 { return GetIndicator(IndicatorType_Check
, flags
); }
393 wxBitmap
GetRadioBitmap(int flags
)
394 { return GetIndicator(IndicatorType_Radio
, flags
); }
397 // the sizing parameters (TODO make them changeable)
398 wxSize m_sizeScrollbarArrow
;
400 wxFont m_titlebarFont
;
402 // the checked and unchecked bitmaps for DrawCheckItem()
403 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
405 // the bitmaps returned by GetIndicator()
406 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
407 [IndicatorState_MaxMenu
]
408 [IndicatorStatus_Max
];
410 // standard defaults for m_bmpCheckBitmaps and m_bmpIndicators
411 static const char **ms_xpmChecked
[IndicatorStatus_Max
];
412 static const char **ms_xpmIndicators
[IndicatorType_Max
]
413 [IndicatorState_MaxMenu
]
414 [IndicatorStatus_Max
];
417 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
419 // first row is for the normal state, second - for the disabled
420 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
423 // ----------------------------------------------------------------------------
424 // wxWin32InputHandler and derived classes: process the keyboard and mouse
425 // messages according to Windows standards
426 // ----------------------------------------------------------------------------
428 class wxWin32InputHandler
: public wxInputHandler
431 wxWin32InputHandler() { }
433 virtual bool HandleKey(wxInputConsumer
*control
,
434 const wxKeyEvent
& event
,
436 virtual bool HandleMouse(wxInputConsumer
*control
,
437 const wxMouseEvent
& event
);
441 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
444 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
,
445 wxInputHandler
*handler
);
447 virtual bool HandleMouse(wxInputConsumer
*control
,
448 const wxMouseEvent
& event
);
449 virtual bool HandleMouseMove(wxInputConsumer
*control
,
450 const wxMouseEvent
& event
);
452 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
453 const wxControlAction
& action
);
456 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
459 // we don't highlight anything
462 // the first and last event which caused the thumb to move
463 wxMouseEvent m_eventStartDrag
,
466 // have we paused the scrolling because the mouse moved?
469 // we remember the interval of the timer to be able to restart it
472 #endif // wxUSE_SCROLLBAR
475 class wxWin32CheckboxInputHandler
: public wxStdInputHandler
478 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
479 : wxStdInputHandler(handler
) { }
481 virtual bool HandleKey(wxInputConsumer
*control
,
482 const wxKeyEvent
& event
,
485 #endif // wxUSE_CHECKBOX
488 class wxWin32TextCtrlInputHandler
: public wxStdInputHandler
491 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
492 : wxStdInputHandler(handler
) { }
494 virtual bool HandleKey(wxInputConsumer
*control
,
495 const wxKeyEvent
& event
,
498 #endif // wxUSE_TEXTCTRL
500 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
503 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
505 virtual bool HandleMouse(wxInputConsumer
*consumer
,
506 const wxMouseEvent
& event
);
508 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
509 const wxMouseEvent
& event
);
512 // is the given point over the statusbar grip?
513 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
516 // the cursor we had replaced with the resize one
517 wxCursor m_cursorOld
;
519 // was the mouse over the grip last time we checked?
523 class wxWin32SystemMenuEvtHandler
;
525 class wxWin32FrameInputHandler
: public wxStdInputHandler
528 wxWin32FrameInputHandler(wxInputHandler
*handler
);
529 virtual ~wxWin32FrameInputHandler();
531 virtual bool HandleMouse(wxInputConsumer
*control
,
532 const wxMouseEvent
& event
);
534 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
537 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
538 #endif // wxUSE_MENUS
541 // was the mouse over the grip last time we checked?
542 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
545 // ----------------------------------------------------------------------------
546 // wxWin32ColourScheme: uses (default) Win32 colours
547 // ----------------------------------------------------------------------------
549 class wxWin32ColourScheme
: public wxColourScheme
552 virtual wxColour
Get(StdColour col
) const;
553 virtual wxColour
GetBackground(wxWindow
*win
) const;
556 // ----------------------------------------------------------------------------
557 // wxWin32ArtProvider
558 // ----------------------------------------------------------------------------
560 class wxWin32ArtProvider
: public wxArtProvider
563 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
564 const wxArtClient
& client
,
568 // ----------------------------------------------------------------------------
570 // ----------------------------------------------------------------------------
572 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
574 class wxWin32Theme
: public wxTheme
578 virtual ~wxWin32Theme();
580 virtual wxRenderer
*GetRenderer();
581 virtual wxArtProvider
*GetArtProvider();
582 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
583 wxInputConsumer
*consumer
);
584 virtual wxColourScheme
*GetColourScheme();
587 wxWin32Renderer
*m_renderer
;
589 wxWin32ArtProvider
*m_artProvider
;
591 // the names of the already created handlers and the handlers themselves
592 // (these arrays are synchronized)
593 wxSortedArrayString m_handlerNames
;
594 wxArrayHandlers m_handlers
;
596 wxWin32ColourScheme
*m_scheme
;
598 WX_DECLARE_THEME(win32
)
601 // ----------------------------------------------------------------------------
603 // ----------------------------------------------------------------------------
605 // frame buttons bitmaps
607 static const char *frame_button_close_xpm
[] = {
622 static const char *frame_button_help_xpm
[] = {
637 static const char *frame_button_maximize_xpm
[] = {
652 static const char *frame_button_minimize_xpm
[] = {
667 static const char *frame_button_restore_xpm
[] = {
684 static const char *checked_menu_xpm
[] = {
685 /* columns rows colors chars-per-pixel */
701 static const char *selected_checked_menu_xpm
[] = {
702 /* columns rows colors chars-per-pixel */
718 static const char *disabled_checked_menu_xpm
[] = {
719 /* columns rows colors chars-per-pixel */
736 static const char *selected_disabled_checked_menu_xpm
[] = {
737 /* columns rows colors chars-per-pixel */
753 // checkbox and radiobox bitmaps below
755 static const char *checked_xpm
[] = {
756 /* columns rows colors chars-per-pixel */
779 static const char *pressed_checked_xpm
[] = {
780 /* columns rows colors chars-per-pixel */
802 static const char *pressed_disabled_checked_xpm
[] = {
803 /* columns rows colors chars-per-pixel */
825 static const char *checked_item_xpm
[] = {
826 /* columns rows colors chars-per-pixel */
847 static const char *unchecked_xpm
[] = {
848 /* columns rows colors chars-per-pixel */
871 static const char *pressed_unchecked_xpm
[] = {
872 /* columns rows colors chars-per-pixel */
894 static const char *unchecked_item_xpm
[] = {
895 /* columns rows colors chars-per-pixel */
915 static const char *undetermined_xpm
[] = {
916 /* columns rows colors chars-per-pixel */
939 static const char *pressed_undetermined_xpm
[] = {
940 /* columns rows colors chars-per-pixel */
963 static const char *checked_radio_xpm
[] = {
964 /* columns rows colors chars-per-pixel */
987 static const char *pressed_checked_radio_xpm
[] = {
988 /* columns rows colors chars-per-pixel */
1011 static const char *pressed_disabled_checked_radio_xpm
[] = {
1012 /* columns rows colors chars-per-pixel */
1035 static const char *unchecked_radio_xpm
[] = {
1036 /* columns rows colors chars-per-pixel */
1059 static const char *pressed_unchecked_radio_xpm
[] = {
1060 /* columns rows colors chars-per-pixel */
1083 const char **wxWin32Renderer::ms_xpmIndicators
[IndicatorType_Max
]
1084 [IndicatorState_MaxMenu
]
1085 [IndicatorStatus_Max
] =
1090 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1093 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1096 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1102 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1105 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1108 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1114 { checked_menu_xpm
, NULL
, NULL
},
1117 { selected_checked_menu_xpm
, NULL
, NULL
},
1120 { disabled_checked_menu_xpm
, NULL
, NULL
},
1122 // disabled selected state
1123 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1127 const char **wxWin32Renderer::ms_xpmChecked
[IndicatorStatus_Max
] =
1133 // ============================================================================
1135 // ============================================================================
1137 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1139 // ----------------------------------------------------------------------------
1141 // ----------------------------------------------------------------------------
1143 wxWin32Theme::wxWin32Theme()
1147 m_artProvider
= NULL
;
1150 wxWin32Theme::~wxWin32Theme()
1154 wxArtProvider::RemoveProvider(m_artProvider
);
1157 wxRenderer
*wxWin32Theme::GetRenderer()
1161 m_renderer
= new wxWin32Renderer(GetColourScheme());
1167 wxArtProvider
*wxWin32Theme::GetArtProvider()
1169 if ( !m_artProvider
)
1171 m_artProvider
= new wxWin32ArtProvider
;
1174 return m_artProvider
;
1178 wxWin32Theme::GetInputHandler(const wxString
& control
,
1179 wxInputConsumer
*consumer
)
1181 wxInputHandler
*handler
= NULL
;
1182 int n
= m_handlerNames
.Index(control
);
1183 if ( n
== wxNOT_FOUND
)
1185 static wxWin32InputHandler s_handlerDef
;
1187 wxInputHandler
* const
1188 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
1190 // create a new handler
1191 if ( control
== wxINP_HANDLER_TOPLEVEL
)
1193 static wxWin32FrameInputHandler
s_handler(handlerStd
);
1195 handler
= &s_handler
;
1198 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1200 static wxWin32CheckboxInputHandler
s_handler(handlerStd
);
1202 handler
= &s_handler
;
1204 #endif // wxUSE_CHECKBOX
1206 else if ( control
== wxINP_HANDLER_SCROLLBAR
)
1208 static wxWin32ScrollBarInputHandler
1209 s_handler(GetRenderer(), handlerStd
);
1211 handler
= &s_handler
;
1213 #endif // wxUSE_SCROLLBAR
1215 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1217 static wxWin32StatusBarInputHandler
s_handler(handlerStd
);
1219 handler
= &s_handler
;
1221 #endif // wxUSE_STATUSBAR
1223 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1225 static wxWin32TextCtrlInputHandler
s_handler(handlerStd
);
1227 handler
= &s_handler
;
1229 #endif // wxUSE_TEXTCTRL
1230 else // no special handler for this control
1232 handler
= handlerStd
;
1235 n
= m_handlerNames
.Add(control
);
1236 m_handlers
.Insert(handler
, n
);
1238 else // we already have it
1240 handler
= m_handlers
[n
];
1246 wxColourScheme
*wxWin32Theme::GetColourScheme()
1250 m_scheme
= new wxWin32ColourScheme
;
1255 // ============================================================================
1256 // wxWin32ColourScheme
1257 // ============================================================================
1259 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1262 if ( win
->UseBgCol() )
1264 // use the user specified colour
1265 col
= win
->GetBackgroundColour();
1268 if ( !win
->ShouldInheritColours() )
1271 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1272 #endif // wxUSE_TEXTCTRL
1274 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1275 #endif // wxUSE_LISTBOX
1284 if ( !win
->IsEnabled() ) // not IsEditable()
1290 // doesn't depend on the state
1295 #endif // wxUSE_TEXTCTRL
1298 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1302 int flags
= win
->GetStateFlags();
1304 // the colour set by the user should be used for the normal state
1305 // and for the states for which we don't have any specific colours
1306 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1309 if ( wxDynamicCast(win
, wxScrollBar
) )
1310 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1313 #endif // wxUSE_SCROLLBAR
1321 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1325 // use the system colours under Windows
1326 #if defined(__WXMSW__)
1327 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1329 case CONTROL_PRESSED
:
1330 case CONTROL_CURRENT
:
1331 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1333 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1335 #if defined(COLOR_3DLIGHT)
1336 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1338 case SCROLLBAR
: return wxColour(0xe0e0e0);
1340 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1342 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1343 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1345 #if defined(COLOR_3DDKSHADOW)
1346 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1348 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1351 case CONTROL_TEXT_DISABLED
:
1352 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1354 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1356 case CONTROL_TEXT_DISABLED_SHADOW
:
1357 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1359 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1360 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1361 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1362 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1364 case DESKTOP
: return wxColour(0x808000);
1366 // use the standard Windows colours elsewhere
1367 case WINDOW
: return *wxWHITE
;
1369 case CONTROL_PRESSED
:
1370 case CONTROL_CURRENT
:
1371 case CONTROL
: return wxColour(0xc0c0c0);
1373 case CONTROL_TEXT
: return *wxBLACK
;
1375 case SCROLLBAR
: return wxColour(0xe0e0e0);
1376 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1378 case HIGHLIGHT
: return wxColour(0x800000);
1379 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1381 case SHADOW_DARK
: return *wxBLACK
;
1383 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1384 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1386 case SHADOW_IN
: return wxColour(0xc0c0c0);
1388 case CONTROL_TEXT_DISABLED_SHADOW
:
1389 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1391 case TITLEBAR
: return wxColour(0xaeaaae);
1392 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1393 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1394 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1396 case DESKTOP
: return wxColour(0x808000);
1399 case GAUGE
: return Get(HIGHLIGHT
);
1403 wxFAIL_MSG(_T("invalid standard colour"));
1408 // ============================================================================
1410 // ============================================================================
1412 // ----------------------------------------------------------------------------
1414 // ----------------------------------------------------------------------------
1416 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1417 : wxStdRenderer(scheme
)
1420 m_sizeScrollbarArrow
= wxSize(16, 16);
1422 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1423 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1425 // init the arrow bitmaps
1426 static const size_t ARROW_WIDTH
= 7;
1427 static const size_t ARROW_LENGTH
= 4;
1430 wxMemoryDC dcNormal
,
1433 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1435 bool isVertical
= n
> Arrow_Right
;
1448 // disabled arrow is larger because of the shadow
1449 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1450 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1452 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1453 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1455 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1456 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1460 dcNormal
.SetPen(m_penBlack
);
1461 dcDisabled
.SetPen(m_penDarkGrey
);
1463 // calculate the position of the point of the arrow
1467 x1
= (ARROW_WIDTH
- 1)/2;
1468 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1472 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1473 y1
= (ARROW_WIDTH
- 1)/2;
1484 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1486 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1487 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1494 if ( n
== Arrow_Up
)
1505 else // left or right arrow
1510 if ( n
== Arrow_Left
)
1523 // draw the shadow for the disabled one
1524 dcDisabled
.SetPen(m_penHighlight
);
1529 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1533 x1
= ARROW_LENGTH
- 1;
1534 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1537 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1538 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1543 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1547 x1
= ARROW_WIDTH
- 1;
1549 x2
= (ARROW_WIDTH
- 1)/2;
1551 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1552 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1557 // create the inverted bitmap but only for the right arrow as we only
1558 // use it for the menus
1559 if ( n
== Arrow_Right
)
1561 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1562 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1564 dcInverse
.Blit(0, 0, w
, h
,
1567 dcInverse
.SelectObject(wxNullBitmap
);
1569 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1570 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1572 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1573 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1575 dcInverse
.Blit(0, 0, w
, h
,
1578 dcInverse
.SelectObject(wxNullBitmap
);
1580 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1581 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1584 dcNormal
.SelectObject(wxNullBitmap
);
1585 dcDisabled
.SelectObject(wxNullBitmap
);
1587 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1588 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1589 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1590 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1592 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1595 // init the frame buttons bitmaps
1596 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1597 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1598 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1599 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1600 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1603 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1608 // ----------------------------------------------------------------------------
1610 // ----------------------------------------------------------------------------
1612 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1613 const wxString
& label
,
1620 // the underscores are not drawn for focused controls in wxMSW
1621 if ( flags
& wxCONTROL_FOCUSED
)
1626 if ( flags
& wxCONTROL_DISABLED
)
1628 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
1629 // currently only can happen for a menu item and it seems that Windows
1630 // doesn't draw the shadow in this case, so we don't do it neither
1631 if ( flags
& wxCONTROL_SELECTED
)
1633 // just make the label text greyed out
1634 dc
.SetTextForeground(m_penDarkGrey
.GetColour());
1636 flags
&= ~wxCONTROL_DISABLED
;
1640 wxStdRenderer::DrawLabel(dc
, label
, rect
, flags
, alignment
,
1641 indexAccel
, rectBounds
);
1644 void wxWin32Renderer::DrawFrameWithLabel(wxDC
& dc
,
1645 const wxString
& label
,
1646 const wxRect
& rectFrame
,
1647 const wxRect
& rectText
,
1653 label2
<< _T(' ') << label
<< _T(' ');
1654 if ( indexAccel
!= -1 )
1656 // adjust it as we prepended a space
1660 wxStdRenderer::DrawFrameWithLabel(dc
, label2
, rectFrame
, rectText
,
1661 flags
, alignment
, indexAccel
);
1664 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
1665 const wxString
& label
,
1666 const wxBitmap
& image
,
1673 // the underscores are not drawn for focused controls in wxMSW
1674 if ( flags
& wxCONTROL_PRESSED
)
1679 wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
, alignment
,
1680 indexAccel
, rectBounds
);
1683 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1684 const wxRect
& rectTotal
,
1688 wxRect rect
= rectTotal
;
1690 wxPen
penOut(*wxBLACK
);
1691 if ( flags
& wxCONTROL_PRESSED
)
1693 // button pressed: draw a double border around it
1694 DrawRect(dc
, &rect
, penOut
);
1695 DrawRect(dc
, &rect
, m_penDarkGrey
);
1697 else // button not pressed
1699 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1701 // button either default or focused (or both): add an extra border
1703 DrawRect(dc
, &rect
, penOut
);
1706 // now draw a normal button border
1707 DrawRaisedBorder(dc
, &rect
);
1714 // ----------------------------------------------------------------------------
1715 // (check)listbox items
1716 // ----------------------------------------------------------------------------
1718 void wxWin32Renderer::DrawCheckItem(wxDC
& dc
,
1719 const wxString
& label
,
1720 const wxBitmap
& bitmap
,
1729 else // use default bitmap
1731 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
1732 ? IndicatorStatus_Checked
1733 : IndicatorStatus_Unchecked
;
1735 if ( !m_bmpCheckBitmaps
[i
].Ok() )
1737 m_bmpCheckBitmaps
[i
] = wxBitmap(ms_xpmChecked
[i
]);
1740 bmp
= m_bmpCheckBitmaps
[i
];
1743 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
1744 true /* use mask */);
1746 wxRect rectLabel
= rect
;
1747 int bmpWidth
= bmp
.GetWidth();
1748 rectLabel
.x
+= bmpWidth
;
1749 rectLabel
.width
-= bmpWidth
;
1751 DrawItem(dc
, label
, rectLabel
, flags
);
1754 // ----------------------------------------------------------------------------
1755 // check/radio buttons
1756 // ----------------------------------------------------------------------------
1758 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
1760 IndicatorState indState
;
1761 IndicatorStatus indStatus
;
1762 GetIndicatorsFromFlags(flags
, indState
, indStatus
);
1764 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
1767 const char **xpm
= ms_xpmIndicators
[indType
][indState
][indStatus
];
1770 // create and cache it
1771 bmp
= wxBitmap(xpm
);
1772 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
1780 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
1781 const wxString
& label
,
1782 const wxBitmap
& bitmap
,
1783 const wxRect
& rectOrig
,
1788 if (style
== wxTOOL_STYLE_BUTTON
)
1790 wxRect rect
= rectOrig
;
1791 rect
.Deflate(BORDER_THICKNESS
);
1793 if ( flags
& wxCONTROL_PRESSED
)
1795 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
1797 else if ( flags
& wxCONTROL_CURRENT
)
1799 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
1802 if(tbarStyle
& wxTB_TEXT
)
1804 if(tbarStyle
& wxTB_HORIZONTAL
)
1806 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1810 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1815 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1816 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1817 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1820 else if (style
== wxTOOL_STYLE_SEPARATOR
)
1822 // leave a small gap aroudn the line, also account for the toolbar
1824 if(rectOrig
.height
> rectOrig
.width
)
1827 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
1828 rectOrig
.y
+ 2*BORDER_THICKNESS
,
1829 rectOrig
.GetBottom() - BORDER_THICKNESS
);
1834 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
1835 rectOrig
.x
+ 2*BORDER_THICKNESS
,
1836 rectOrig
.GetRight() - BORDER_THICKNESS
);
1839 // don't draw wxTOOL_STYLE_CONTROL
1841 #endif // wxUSE_TOOLBAR
1843 // ----------------------------------------------------------------------------
1845 // ----------------------------------------------------------------------------
1849 void wxWin32Renderer::DrawTab(wxDC
& dc
,
1850 const wxRect
& rectOrig
,
1852 const wxString
& label
,
1853 const wxBitmap
& bitmap
,
1857 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1858 #define REVERSE_FOR_VERTICAL(X,Y) \
1859 SELECT_FOR_VERTICAL(X,Y) \
1861 SELECT_FOR_VERTICAL(Y,X)
1863 wxRect rect
= rectOrig
;
1865 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1867 // the current tab is drawn indented (to the top for default case) and
1868 // bigger than the other ones
1869 const wxSize indent
= GetTabIndent();
1870 if ( flags
& wxCONTROL_SELECTED
)
1872 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1873 SELECT_FOR_VERTICAL( 0, indent
.y
));
1877 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1884 rect
.height
+= indent
.y
;
1891 rect
.width
+= indent
.x
;
1896 // draw the text, image and the focus around them (if necessary)
1897 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1898 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1900 rectLabel
.Deflate(1, 1);
1903 // draw it horizontally into memory and rotate for screen
1905 wxBitmap bitmapRotated
,
1906 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1907 rectLabel
.y
+ rectLabel
.height
);
1908 dcMem
.SelectObject(bitmapMem
);
1909 dcMem
.SetBackground(dc
.GetBackground());
1910 dcMem
.SetFont(dc
.GetFont());
1911 dcMem
.SetTextForeground(dc
.GetTextForeground());
1915 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1918 #endif // wxUSE_IMAGE
1920 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
1921 flags
, wxALIGN_CENTRE
, indexAccel
);
1922 dcMem
.SelectObject(wxNullBitmap
);
1923 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1925 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
1926 #endif // wxUSE_IMAGE
1927 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1931 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
1932 flags
, wxALIGN_CENTRE
, indexAccel
);
1935 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
1936 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
1937 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1938 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1939 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1940 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1942 // FIXME: all this code will break if the tab indent or the border width,
1943 // it is tied to the fact that both of them are equal to 2
1949 // left orientation looks like top but IsVertical makes x and y reversed
1951 // top is not vertical so use coordinates in written order
1952 dc
.SetPen(m_penHighlight
);
1953 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1954 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
1955 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
1956 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
1957 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
1958 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
1960 dc
.SetPen(m_penBlack
);
1961 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1962 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
1963 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
1964 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
1966 dc
.SetPen(m_penDarkGrey
);
1967 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1968 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
1970 if ( flags
& wxCONTROL_SELECTED
)
1972 dc
.SetPen(m_penLightGrey
);
1974 // overwrite the part of the border below this tab
1975 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1976 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1978 // and the shadow of the tab to the left of us
1979 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
1980 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1985 // right orientation looks like bottom but IsVertical makes x and y reversed
1987 // bottom is not vertical so use coordinates in written order
1988 dc
.SetPen(m_penHighlight
);
1989 // we need to continue one pixel further to overwrite the corner of
1990 // the border for the selected tab
1991 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1992 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
1993 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
1994 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
1996 dc
.SetPen(m_penBlack
);
1997 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
1998 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
1999 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
2000 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
2001 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
2002 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
2004 dc
.SetPen(m_penDarkGrey
);
2005 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
2006 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
2007 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
2008 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
2010 if ( flags
& wxCONTROL_SELECTED
)
2012 dc
.SetPen(m_penLightGrey
);
2014 // overwrite the part of the (double!) border above this tab
2015 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2016 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2017 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2018 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2020 // and the shadow of the tab to the left of us
2021 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2022 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2027 #undef SELECT_FOR_VERTICAL
2028 #undef REVERSE_FOR_VERTICAL
2031 #endif // wxUSE_NOTEBOOK
2035 // ----------------------------------------------------------------------------
2037 // ----------------------------------------------------------------------------
2040 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2042 wxOrientation orient
) const
2045 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2046 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2048 if (orient
== wxHORIZONTAL
)
2062 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2064 wxOrientation orient
,
2067 bool transpose
= (orient
== wxVERTICAL
);
2068 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2069 (((style
& wxSL_TOP
) != 0) & !transpose
|
2070 ((style
& wxSL_LEFT
) != 0) & transpose
|
2071 ((style
& wxSL_BOTH
) != 0));
2072 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2073 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2074 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2075 ((style
& wxSL_BOTH
) != 0));
2077 wxRect rect
= rectOrig
;
2079 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2081 if (orient
== wxHORIZONTAL
) {
2082 rect
.x
+= SLIDER_MARGIN
;
2085 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2089 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2093 rect
.y
+= sizeThumb
.y
/2;
2095 rect
.width
-= 2*SLIDER_MARGIN
;
2096 rect
.height
= 2*BORDER_THICKNESS
;
2100 rect
.y
+= SLIDER_MARGIN
;
2103 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2107 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2111 rect
.x
+= sizeThumb
.x
/2;
2113 rect
.width
= 2*BORDER_THICKNESS
;
2114 rect
.height
-= 2*SLIDER_MARGIN
;
2120 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2121 const wxRect
& rectOrig
,
2123 wxOrientation orient
,
2128 /* show shaft geometry
2146 if (flags
& wxCONTROL_FOCUSED
) {
2147 DrawFocusRect(dc
, rectOrig
);
2150 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2152 if (rectShaft
) *rectShaft
= rect
;
2154 DrawSunkenBorder(dc
, &rect
);
2157 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2159 wxOrientation orient
,
2163 /* show thumb geometry
2172 H D B where H is highlight colour
2186 The interior of this shape is filled with the hatched brush if the thumb
2190 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2192 bool transpose
= (orient
== wxVERTICAL
);
2193 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2194 (((style
& wxSL_TOP
) != 0) & !transpose
|
2195 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2196 ((style
& wxSL_BOTH
) == 0);
2197 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2198 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2199 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2200 ((style
& wxSL_BOTH
) == 0);
2202 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2203 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2205 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2206 x1
= (transpose
? rect
.y
: rect
.x
);
2207 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2208 x3
= (x1
-1+c
) + sizeArrow
;
2209 y1
= (transpose
? rect
.x
: rect
.y
);
2210 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2211 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2212 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2214 dc
.SetPen(m_penBlack
);
2216 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2218 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2221 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2225 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2228 dc
.SetPen(m_penDarkGrey
);
2229 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2231 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2235 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2238 dc
.SetPen(m_penHighlight
);
2241 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2242 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2246 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2248 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2251 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2254 if (flags
& wxCONTROL_PRESSED
) {
2255 // TODO: MSW fills the entire area inside, not just the rect
2256 wxRect rectInt
= rect
;
2259 rectInt
.SetLeft(y3
);
2260 rectInt
.SetRight(y4
);
2265 rectInt
.SetBottom(y4
);
2269 #if !defined(__WXMGL__)
2270 static const char *stipple_xpm
[] = {
2271 /* columns rows colors chars-per-pixel */
2280 // VS: MGL can only do 8x8 stipple brushes
2281 static const char *stipple_xpm
[] = {
2282 /* columns rows colors chars-per-pixel */
2297 dc
.SetBrush(wxBrush(stipple_xpm
));
2299 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2300 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2301 dc
.SetPen(*wxTRANSPARENT_PEN
);
2302 dc
.DrawRectangle(rectInt
);
2306 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2309 wxOrientation orient
,
2313 int WXUNUSED(flags
),
2316 /* show ticks geometry
2331 if (end
== start
) return;
2333 bool transpose
= (orient
== wxVERTICAL
);
2334 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2335 (((style
& wxSL_TOP
) != 0) & !transpose
|
2336 ((style
& wxSL_LEFT
) != 0) & transpose
|
2337 ((style
& wxSL_BOTH
) != 0));
2338 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2339 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2340 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2341 ((style
& wxSL_BOTH
) != 0));
2343 // default thumb size
2344 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2345 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
2347 // normal thumb size
2348 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2349 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
2351 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2353 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2354 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2355 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2356 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2357 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2358 y3
= (transpose
? rect
.x
: rect
.y
);
2359 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2362 dc
.SetPen(m_penBlack
);
2364 int range
= end
- start
;
2365 for ( int n
= 0; n
< range
; n
+= step
) {
2366 wxCoord x
= x1
+ (len
*n
) / range
;
2368 if (left
& (y1
> y3
)) {
2369 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2371 if (right
& (y4
> y2
)) {
2372 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2375 // always draw the line at the end position
2376 if (left
& (y1
> y3
)) {
2377 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2379 if (right
& (y4
> y2
)) {
2380 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2384 #endif // wxUSE_SLIDER
2388 // ----------------------------------------------------------------------------
2390 // ----------------------------------------------------------------------------
2392 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2393 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2396 virtual wxSize
GetSize() const { return m_size
; }
2398 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2399 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2401 wxCoord
GetItemHeight() const { return m_heightItem
; }
2404 // the total size of the menu
2407 // the offset of the start of the menu item label
2410 // the offset of the start of the accel label
2413 // the height of a normal (not separator) item
2414 wxCoord m_heightItem
;
2416 friend wxMenuGeometryInfo
*
2417 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2420 // FIXME: all constants are hardcoded but shouldn't be
2421 static const wxCoord MENU_LEFT_MARGIN
= 9;
2422 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2423 static const wxCoord MENU_VERT_MARGIN
= 3;
2425 // the margin around bitmap/check marks (on each side)
2426 static const wxCoord MENU_BMP_MARGIN
= 2;
2428 // the margin between the labels and accel strings
2429 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2431 // the separator height in pixels: in fact, strangely enough, the real height
2432 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2434 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2436 // the size of the standard checkmark bitmap
2437 static const wxCoord MENU_CHECK_SIZE
= 9;
2439 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2440 const wxRect
& rectOrig
,
2441 const wxString
& label
,
2445 wxRect rect
= rectOrig
;
2448 wxDCTextColourChanger
colChanger(dc
);
2450 if ( flags
& wxCONTROL_SELECTED
)
2452 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2454 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2457 dc
.DrawRectangle(rect
);
2460 // don't draw the focus rect around menu bar items
2461 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2462 wxALIGN_CENTRE
, indexAccel
);
2465 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2467 const wxMenuGeometryInfo
& gi
,
2468 const wxString
& label
,
2469 const wxString
& accel
,
2470 const wxBitmap
& bitmap
,
2474 const wxWin32MenuGeometryInfo
& geometryInfo
=
2475 (const wxWin32MenuGeometryInfo
&)gi
;
2480 rect
.width
= geometryInfo
.GetSize().x
;
2481 rect
.height
= geometryInfo
.GetItemHeight();
2483 // draw the selected item specially
2484 wxDCTextColourChanger
colChanger(dc
);
2485 if ( flags
& wxCONTROL_SELECTED
)
2487 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2489 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2492 dc
.DrawRectangle(rect
);
2495 // draw the bitmap: use the bitmap provided or the standard checkmark for
2496 // the checkable items
2497 wxBitmap bmp
= bitmap
;
2498 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2500 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2505 rect
.SetRight(geometryInfo
.GetLabelOffset());
2506 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2510 rect
.x
= geometryInfo
.GetLabelOffset();
2511 rect
.SetRight(geometryInfo
.GetAccelOffset());
2513 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2515 // draw the accel string
2516 rect
.x
= geometryInfo
.GetAccelOffset();
2517 rect
.SetRight(geometryInfo
.GetSize().x
);
2519 // NB: no accel index here
2520 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2522 // draw the submenu indicator
2523 if ( flags
& wxCONTROL_ISSUBMENU
)
2525 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2526 rect
.width
= MENU_RIGHT_MARGIN
;
2528 wxArrowStyle arrowStyle
;
2529 if ( flags
& wxCONTROL_DISABLED
)
2530 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
2532 else if ( flags
& wxCONTROL_SELECTED
)
2533 arrowStyle
= Arrow_Inverted
;
2535 arrowStyle
= Arrow_Normal
;
2537 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2541 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2543 const wxMenuGeometryInfo
& geomInfo
)
2545 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2548 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2550 wxSize size
= sizeText
;
2552 // FIXME: menubar height is configurable under Windows
2559 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2560 const wxMenu
& menu
) const
2562 // prepare the dc: for now we draw all the items with the system font
2564 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2566 // the height of a normal item
2567 wxCoord heightText
= dc
.GetCharHeight();
2572 // the max length of label and accel strings: the menu width is the sum of
2573 // them, even if they're for different items (as the accels should be
2576 // the max length of the bitmap is never 0 as Windows always leaves enough
2577 // space for a check mark indicator
2578 wxCoord widthLabelMax
= 0,
2580 widthBmpMax
= MENU_LEFT_MARGIN
;
2582 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
2584 node
= node
->GetNext() )
2586 // height of this item
2589 wxMenuItem
*item
= node
->GetData();
2590 if ( item
->IsSeparator() )
2592 h
= MENU_SEPARATOR_HEIGHT
;
2594 else // not separator
2599 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2600 if ( widthLabel
> widthLabelMax
)
2602 widthLabelMax
= widthLabel
;
2606 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2607 if ( widthAccel
> widthAccelMax
)
2609 widthAccelMax
= widthAccel
;
2612 const wxBitmap
& bmp
= item
->GetBitmap();
2615 wxCoord widthBmp
= bmp
.GetWidth();
2616 if ( widthBmp
> widthBmpMax
)
2617 widthBmpMax
= widthBmp
;
2619 //else if ( item->IsCheckable() ): no need to check for this as
2620 // MENU_LEFT_MARGIN is big enough to show the check mark
2623 h
+= 2*MENU_VERT_MARGIN
;
2625 // remember the item position and height
2626 item
->SetGeometry(height
, h
);
2631 // bundle the metrics into a struct and return it
2632 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2634 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2635 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2636 if ( widthAccelMax
> 0 )
2638 // if we actually have any accesl, add a margin
2639 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2642 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2644 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2645 gi
->m_size
.y
= height
;
2650 #endif // wxUSE_MENUS
2654 // ----------------------------------------------------------------------------
2656 // ----------------------------------------------------------------------------
2658 static const wxCoord STATBAR_BORDER_X
= 2;
2659 static const wxCoord STATBAR_BORDER_Y
= 2;
2661 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2663 if ( borderBetweenFields
)
2664 *borderBetweenFields
= 2;
2666 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2669 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2671 const wxString
& label
,
2672 int flags
, int style
/*=0*/)
2676 if ( flags
& wxCONTROL_ISDEFAULT
)
2678 // draw the size grip: it is a normal rect except that in the lower
2679 // right corner we have several bands which may be used for dragging
2680 // the status bar corner
2682 // each band consists of 4 stripes: m_penHighlight, double
2683 // m_penDarkGrey and transparent one
2684 wxCoord x2
= rect
.GetRight(),
2685 y2
= rect
.GetBottom();
2687 // draw the upper left part of the rect normally
2688 if (style
!= wxSB_FLAT
)
2690 if (style
== wxSB_RAISED
)
2691 dc
.SetPen(m_penHighlight
);
2693 dc
.SetPen(m_penDarkGrey
);
2694 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
2695 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
2698 // draw the grey stripes of the grip
2700 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
2701 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2703 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2704 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
2707 // draw the white stripes
2708 dc
.SetPen(m_penHighlight
);
2709 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
2710 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2712 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2715 // draw the remaining rect boundaries
2716 if (style
!= wxSB_FLAT
)
2718 if (style
== wxSB_RAISED
)
2719 dc
.SetPen(m_penDarkGrey
);
2721 dc
.SetPen(m_penHighlight
);
2722 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
2723 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
2724 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
2730 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
2734 if (style
== wxSB_RAISED
)
2735 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
2736 else if (style
!= wxSB_FLAT
)
2737 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
2740 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2742 wxDCClipper
clipper(dc
, rectIn
);
2743 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
2746 #endif // wxUSE_STATUSBAR
2748 // ----------------------------------------------------------------------------
2750 // ----------------------------------------------------------------------------
2752 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2753 wxBitmap
* WXUNUSED(bmpFocus
),
2754 wxBitmap
*bmpPressed
,
2755 wxBitmap
*bmpDisabled
)
2757 static const wxCoord widthCombo
= 16;
2758 static const wxCoord heightCombo
= 17;
2764 bmpNormal
->Create(widthCombo
, heightCombo
);
2765 dcMem
.SelectObject(*bmpNormal
);
2766 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2767 Arrow_Down
, Arrow_Normal
);
2772 bmpPressed
->Create(widthCombo
, heightCombo
);
2773 dcMem
.SelectObject(*bmpPressed
);
2774 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2775 Arrow_Down
, Arrow_Pressed
);
2780 bmpDisabled
->Create(widthCombo
, heightCombo
);
2781 dcMem
.SelectObject(*bmpDisabled
);
2782 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2783 Arrow_Down
, Arrow_Disabled
);
2787 // ----------------------------------------------------------------------------
2789 // ----------------------------------------------------------------------------
2791 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
2795 DrawRect(dc
, rect
, m_penDarkGrey
);
2797 // the arrow is usually drawn inside border of width 2 and is offset by
2798 // another pixel in both directions when it's pressed - as the border
2799 // in this case is more narrow as well, we have to adjust rect like
2807 DrawAntiSunkenBorder(dc
, rect
);
2811 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
2816 // get the bitmap for this arrow
2817 wxArrowDirection arrowDir
;
2820 case wxLEFT
: arrowDir
= Arrow_Left
; break;
2821 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
2822 case wxUP
: arrowDir
= Arrow_Up
; break;
2823 case wxDOWN
: arrowDir
= Arrow_Down
; break;
2826 wxFAIL_MSG(_T("unknown arrow direction"));
2830 wxArrowStyle arrowStyle
;
2831 if ( flags
& wxCONTROL_PRESSED
)
2833 // can't be pressed and disabled
2834 arrowStyle
= Arrow_Pressed
;
2838 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
2841 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
2844 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
2846 wxArrowDirection arrowDir
,
2847 wxArrowStyle arrowStyle
)
2849 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
2851 // under Windows the arrows always have the same size so just centre it in
2852 // the provided rectangle
2853 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
2854 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
2856 // Windows does it like this...
2857 if ( arrowDir
== Arrow_Left
)
2861 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
2864 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
2865 const wxRect
& rectAll
,
2866 wxArrowDirection arrowDir
,
2867 wxArrowStyle arrowStyle
)
2869 wxRect rect
= rectAll
;
2870 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2871 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
2872 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
2875 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
2876 wxOrientation
WXUNUSED(orient
),
2878 int WXUNUSED(flags
))
2880 // we don't use the flags, the thumb never changes appearance
2881 wxRect rectThumb
= rect
;
2882 DrawArrowBorder(dc
, &rectThumb
);
2883 DrawBackground(dc
, wxNullColour
, rectThumb
);
2886 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
2887 wxOrientation
WXUNUSED(orient
),
2888 const wxRect
& rectBar
,
2891 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
2892 ? wxColourScheme::SCROLLBAR_PRESSED
2893 : wxColourScheme::SCROLLBAR
;
2894 DrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
2897 void wxWin32Renderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2899 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2902 // ----------------------------------------------------------------------------
2903 // top level windows
2904 // ----------------------------------------------------------------------------
2906 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
2908 wxRect client
= GetFrameClientArea(rect
, flags
);
2910 if ( client
.Contains(pt
) )
2911 return wxHT_TOPLEVEL_CLIENT_AREA
;
2913 if ( flags
& wxTOPLEVEL_TITLEBAR
)
2915 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
2917 if ( flags
& wxTOPLEVEL_ICON
)
2919 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Contains(pt
) )
2920 return wxHT_TOPLEVEL_ICON
;
2923 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
2924 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
2925 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
2927 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
2929 if ( btnRect
.Contains(pt
) )
2930 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
2931 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
2933 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
2935 if ( btnRect
.Contains(pt
) )
2936 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
2937 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2939 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
2941 if ( btnRect
.Contains(pt
) )
2942 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
2943 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2945 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
2947 if ( btnRect
.Contains(pt
) )
2948 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
2949 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2951 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
2953 if ( btnRect
.Contains(pt
) )
2954 return wxHT_TOPLEVEL_BUTTON_HELP
;
2955 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2958 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
2959 return wxHT_TOPLEVEL_TITLEBAR
;
2962 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
2964 // we are certainly at one of borders, lets decide which one:
2967 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
2968 if ( pt
.x
< client
.x
)
2969 border
|= wxHT_TOPLEVEL_BORDER_W
;
2970 else if ( pt
.x
>= client
.width
+ client
.x
)
2971 border
|= wxHT_TOPLEVEL_BORDER_E
;
2972 if ( pt
.y
< client
.y
)
2973 border
|= wxHT_TOPLEVEL_BORDER_N
;
2974 else if ( pt
.y
>= client
.height
+ client
.y
)
2975 border
|= wxHT_TOPLEVEL_BORDER_S
;
2979 return wxHT_NOWHERE
;
2982 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
2984 const wxString
& title
,
2988 int specialButtonFlags
)
2990 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
2992 DrawFrameBorder(dc
, rect
, flags
);
2994 if ( flags
& wxTOPLEVEL_TITLEBAR
)
2996 DrawFrameBackground(dc
, rect
, flags
);
2997 if ( flags
& wxTOPLEVEL_ICON
)
2998 DrawFrameIcon(dc
, rect
, icon
, flags
);
2999 DrawFrameTitle(dc
, rect
, title
, flags
);
3001 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3003 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
3004 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
3006 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3008 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
3009 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
3010 specialButtonFlags
: 0);
3011 x
-= FRAME_BUTTON_WIDTH
+ 2;
3013 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3015 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3016 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3017 specialButtonFlags
: 0);
3018 x
-= FRAME_BUTTON_WIDTH
;
3020 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3022 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3023 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3024 specialButtonFlags
: 0);
3025 x
-= FRAME_BUTTON_WIDTH
;
3027 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3029 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3030 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3031 specialButtonFlags
: 0);
3032 x
-= FRAME_BUTTON_WIDTH
;
3034 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3036 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3037 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3038 specialButtonFlags
: 0);
3043 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
3047 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3051 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3052 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3053 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3054 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3055 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3058 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3062 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3064 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3065 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3066 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3068 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3069 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3071 DrawBackground(dc
, col
, r
);
3074 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3076 const wxString
& title
,
3079 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3080 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3081 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3083 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3084 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3085 if ( flags
& wxTOPLEVEL_ICON
)
3087 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3088 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3096 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3097 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3098 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3099 r
.width
-= FRAME_BUTTON_WIDTH
;
3100 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3101 r
.width
-= FRAME_BUTTON_WIDTH
;
3102 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3103 r
.width
-= FRAME_BUTTON_WIDTH
;
3104 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3105 r
.width
-= FRAME_BUTTON_WIDTH
;
3107 dc
.SetFont(m_titlebarFont
);
3108 dc
.SetTextForeground(col
);
3111 dc
.GetTextExtent(title
, &textW
, NULL
);
3112 if ( textW
> r
.width
)
3114 // text is too big, let's shorten it and add "..." after it:
3115 size_t len
= title
.length();
3116 wxCoord WSoFar
, letterW
;
3118 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3119 if ( WSoFar
> r
.width
)
3121 // not enough space to draw anything
3127 for (size_t i
= 0; i
< len
; i
++)
3129 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3130 if ( letterW
+ WSoFar
> r
.width
)
3136 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3137 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3140 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3141 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3144 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3151 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3152 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3156 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3157 wxCoord x
, wxCoord y
,
3161 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3166 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3167 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3168 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3169 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3170 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3172 wxFAIL_MSG(wxT("incorrect button specification"));
3175 if ( flags
& wxCONTROL_PRESSED
)
3177 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3178 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3179 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3180 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3184 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3185 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3186 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3187 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3192 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3197 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3199 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3200 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3201 FRAME_BORDER_THICKNESS
;
3204 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3206 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3207 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3213 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3216 wxSize
s(clientSize
);
3218 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3220 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3221 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3222 FRAME_BORDER_THICKNESS
;
3226 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3227 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3232 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3236 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3238 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3239 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3240 FRAME_BORDER_THICKNESS
;
3245 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3247 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3249 if ( flags
& wxTOPLEVEL_ICON
)
3250 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3251 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3252 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3253 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3254 s
.x
+= FRAME_BUTTON_WIDTH
;
3255 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3256 s
.x
+= FRAME_BUTTON_WIDTH
;
3257 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3258 s
.x
+= FRAME_BUTTON_WIDTH
;
3259 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3260 s
.x
+= FRAME_BUTTON_WIDTH
;
3266 wxSize
wxWin32Renderer::GetFrameIconSize() const
3268 return wxSize(16, 16);
3272 // ----------------------------------------------------------------------------
3274 // ----------------------------------------------------------------------------
3276 /* Copyright (c) Julian Smart */
3277 static char *error_xpm
[]={
3278 /* columns rows colors chars-per-pixel */
3355 " $oooooooooooo%& ",
3356 " *=-ooooooooooooo;: ",
3357 " *oooooooooooooooooo> ",
3358 " =ooooooooooooooooooo, ",
3359 " $-ooooooooooooooooooo<1 ",
3360 " .oooooo2334ooo533oooooo6 ",
3361 " +ooooooo789oo2883oooooo0q ",
3362 " oooooooo2w83o78eoooooooor ",
3363 " toooooooooy88u884oooooooori ",
3364 " Xooooooooooe888poooooooooas ",
3365 " ooooooooooo4889doooooooooof ",
3366 " ooooooooooo588w2oooooooooofi ",
3367 " oooooooooodw8887oooooooooofi ",
3368 " goooooooooh8w588jooooooookli ",
3369 " tooooooooz885op8wdooooooorix ",
3370 " oooooood98cood98cooooooori ",
3371 " @oooooop8w2ooo5885ooooovbi ",
3372 " n%ooooooooooooooooooooomiM ",
3373 " &;oooooooooooooooooooNBiV ",
3374 " :ooooooooooooooooooCZiA ",
3375 " nSooooooooooooooooCDiF ",
3376 " nG<oooooooooooooNZiiH ",
3377 " 160ooooooooovmBiFH ",
3378 " nqrraoookrrbiiA ",
3385 /* Copyright (c) Julian Smart */
3386 static char *info_xpm
[]={
3387 /* columns rows colors chars-per-pixel */
3409 " ..XXXXXXXXXXXXX.. ",
3410 " .XXXXXXXXXXXXXXXXX. ",
3411 " .XXXXXXXXoO+XXXXXXXX. ",
3412 " .XXXXXXXXX@#OXXXXXXXXX. ",
3413 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
3414 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
3415 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
3416 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
3417 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
3418 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
3419 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
3420 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
3421 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
3422 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
3423 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
3424 " .XXXXXXXXXXXXXXXXX.%%%% ",
3425 " ..XXXXXXXXXXXXX..%%%% ",
3426 " %...XXXXXXXX..%%%%% ",
3427 " %%%..XXXXXX.%%%%% ",
3441 /* Copyright (c) Julian Smart */
3442 static char *question_xpm
[]={
3443 /* columns rows colors chars-per-pixel */
3464 " ..XXXXXXXXXXXXX.. ",
3465 " .XXXXXXoO++@XXXXXX. ",
3466 " .XXXXXXO#$$$$#%XXXXX. ",
3467 " .XXXXXX@$$#&&#$#oXXXXX. ",
3468 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
3469 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
3470 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
3471 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
3472 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
3473 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
3474 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
3475 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
3476 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
3477 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
3478 " .XXXXXXXX-$$XXXXXXXX.:::: ",
3479 " .XXXXXXXO++XXXXXXX.:::: ",
3480 " ..XXXXXXXXXXXXX..:::: ",
3481 " :...XXXXXXXX..::::: ",
3482 " :::..XXXXXX.::::: ",
3496 /* Copyright (c) Julian Smart */
3497 static char *warning_xpm
[]={
3498 /* columns rows colors chars-per-pixel */
3524 " ..XXXXO@#XXX... ",
3525 " ...XXXXO@#XXXX.. ",
3526 " ..XXXXXO@#XXXX... ",
3527 " ...XXXXXo@OXXXXX.. ",
3528 " ...XXXXXXo@OXXXXXX.. ",
3529 " ..XXXXXXX$@OXXXXXX... ",
3530 " ...XXXXXXXX@XXXXXXXX.. ",
3531 " ...XXXXXXXXXXXXXXXXXX... ",
3532 " ..XXXXXXXXXXOXXXXXXXXX.. ",
3533 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
3534 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
3535 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3536 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3537 " .............................. ",
3538 " .............................. ",
3545 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3546 const wxArtClient
& WXUNUSED(client
),
3547 const wxSize
& WXUNUSED(size
))
3549 if ( id
== wxART_INFORMATION
)
3550 return wxBitmap(info_xpm
);
3551 if ( id
== wxART_ERROR
)
3552 return wxBitmap(error_xpm
);
3553 if ( id
== wxART_WARNING
)
3554 return wxBitmap(warning_xpm
);
3555 if ( id
== wxART_QUESTION
)
3556 return wxBitmap(question_xpm
);
3557 return wxNullBitmap
;
3563 // ----------------------------------------------------------------------------
3564 // text control geometry
3565 // ----------------------------------------------------------------------------
3567 static inline int GetTextBorderWidth()
3573 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
3574 const wxRect
& rect
) const
3576 wxRect rectTotal
= rect
;
3578 wxCoord widthBorder
= GetTextBorderWidth();
3579 rectTotal
.Inflate(widthBorder
);
3581 // this is what Windows does
3588 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
* WXUNUSED(text
),
3590 wxCoord
*extraSpaceBeyond
) const
3592 wxRect rectText
= rect
;
3594 // undo GetTextTotalArea()
3595 if ( rectText
.height
> 0 )
3598 wxCoord widthBorder
= GetTextBorderWidth();
3599 rectText
.Inflate(-widthBorder
);
3601 if ( extraSpaceBeyond
)
3602 *extraSpaceBeyond
= 0;
3607 #endif // wxUSE_TEXTCTRL
3609 // ----------------------------------------------------------------------------
3611 // ----------------------------------------------------------------------------
3613 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3616 if ( wxDynamicCast(window
, wxScrollBar
) )
3618 // we only set the width of vert scrollbars and height of the
3620 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3621 size
->y
= m_sizeScrollbarArrow
.y
;
3623 size
->x
= m_sizeScrollbarArrow
.x
;
3625 // skip border width adjustments, they don't make sense for us
3628 #endif // wxUSE_SCROLLBAR
3631 if ( wxDynamicCast(window
, wxBitmapButton
) )
3635 #endif // wxUSE_BMPBUTTON
3636 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
3639 || wxDynamicCast(window
, wxButton
)
3640 # endif // wxUSE_BUTTON
3641 # if wxUSE_TOGGLEBTN
3642 || wxDynamicCast(window
, wxToggleButton
)
3643 # endif // wxUSE_TOGGLEBTN
3646 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3648 // TODO: don't harcode all this
3649 size
->x
+= 3*window
->GetCharWidth();
3651 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3652 if ( size
->y
< heightBtn
- 8 )
3653 size
->y
= heightBtn
;
3658 // for compatibility with other ports, the buttons default size is never
3659 // less than the standard one, but not when display not PDAs.
3660 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
3662 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3664 wxSize szDef
= wxButton::GetDefaultSize();
3665 if ( size
->x
< szDef
.x
)
3670 // no border width adjustments for buttons
3673 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
3675 // take into account the border width
3676 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3677 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3678 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3681 // ============================================================================
3683 // ============================================================================
3685 // ----------------------------------------------------------------------------
3686 // wxWin32InputHandler
3687 // ----------------------------------------------------------------------------
3689 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3690 const wxKeyEvent
& WXUNUSED(event
),
3691 bool WXUNUSED(pressed
))
3696 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3697 const wxMouseEvent
& event
)
3699 // clicking on the control gives it focus
3700 if ( event
.ButtonDown() )
3702 wxWindow
*win
= control
->GetInputWindow();
3704 if ( (wxWindow::FindFocus() != control
->GetInputWindow()) &&
3705 win
->AcceptsFocus() )
3718 // ----------------------------------------------------------------------------
3719 // wxWin32ScrollBarInputHandler
3720 // ----------------------------------------------------------------------------
3722 wxWin32ScrollBarInputHandler::
3723 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
3724 : wxStdScrollBarInputHandler(renderer
, handler
)
3726 m_scrollPaused
= false;
3730 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3731 const wxControlAction
& action
)
3733 // stop if went beyond the position of the original click (this can only
3734 // happen when we scroll by pages)
3736 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3738 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3739 != wxHT_SCROLLBAR_BAR_2
;
3741 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3743 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3744 != wxHT_SCROLLBAR_BAR_1
;
3749 StopScrolling(scrollbar
);
3751 scrollbar
->Refresh();
3756 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3759 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3760 const wxMouseEvent
& event
)
3762 // remember the current state
3763 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3765 // do process the message
3766 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3768 // analyse the changes
3769 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3771 // we just started dragging the thumb, remember its initial position to
3772 // be able to restore it if the drag is cancelled later
3773 m_eventStartDrag
= event
;
3779 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3780 const wxMouseEvent
& event
)
3782 // we don't highlight scrollbar elements, so there is no need to process
3783 // mouse move events normally - only do it while mouse is captured (i.e.
3784 // when we're dragging the thumb or pressing on something)
3785 if ( !m_winCapture
)
3788 if ( event
.Entering() )
3790 // we're not interested in this at all
3794 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3796 if ( m_scrollPaused
)
3798 // check if the mouse returned to its original location
3800 if ( event
.Leaving() )
3806 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3807 if ( ht
== m_htLast
)
3809 // yes it did, resume scrolling
3810 m_scrollPaused
= false;
3811 if ( m_timerScroll
)
3813 // we were scrolling by line/page, restart timer
3814 m_timerScroll
->Start(m_interval
);
3816 Press(scrollbar
, true);
3818 else // we were dragging the thumb
3820 // restore its last location
3821 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3827 else // normal case, scrolling hasn't been paused
3829 // if we're scrolling the scrollbar because the arrow or the shaft was
3830 // pressed, check that the mouse stays on the same scrollbar element
3833 // Always let thumb jump back if we leave the scrollbar
3834 if ( event
.Moving() )
3836 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3838 else // event.Leaving()
3843 // Jump back only if we get far away from it
3844 wxPoint pos
= event
.GetPosition();
3845 if (scrollbar
->HasFlag( wxVERTICAL
))
3847 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
3852 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
3855 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
3858 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3859 // is still ok - we only want to catch the case when the mouse leaves
3860 // the scrollbar here
3861 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3863 ht
= wxHT_SCROLLBAR_THUMB
;
3866 if ( ht
!= m_htLast
)
3868 // what were we doing? 2 possibilities: either an arrow/shaft was
3869 // pressed in which case we have a timer and so we just stop it or
3870 // we were dragging the thumb
3871 if ( m_timerScroll
)
3874 m_interval
= m_timerScroll
->GetInterval();
3875 m_timerScroll
->Stop();
3876 m_scrollPaused
= true;
3878 // unpress the arrow
3879 Press(scrollbar
, false);
3881 else // we were dragging the thumb
3883 // remember the current thumb position to be able to restore it
3884 // if the mouse returns to it later
3885 m_eventLastDrag
= event
;
3887 // and restore the original position (before dragging) of the
3889 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3896 return wxStdInputHandler::HandleMouseMove(control
, event
);
3899 #endif // wxUSE_SCROLLBAR
3903 // ----------------------------------------------------------------------------
3904 // wxWin32CheckboxInputHandler
3905 // ----------------------------------------------------------------------------
3907 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3908 const wxKeyEvent
& event
,
3913 wxControlAction action
;
3914 int keycode
= event
.GetKeyCode();
3918 action
= wxACTION_CHECKBOX_TOGGLE
;
3922 case WXK_NUMPAD_SUBTRACT
:
3923 action
= wxACTION_CHECKBOX_CHECK
;
3927 case WXK_NUMPAD_ADD
:
3928 case WXK_NUMPAD_EQUAL
:
3929 action
= wxACTION_CHECKBOX_CLEAR
;
3933 if ( !action
.IsEmpty() )
3935 control
->PerformAction(action
);
3944 #endif // wxUSE_CHECKBOX
3948 // ----------------------------------------------------------------------------
3949 // wxWin32TextCtrlInputHandler
3950 // ----------------------------------------------------------------------------
3952 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3953 const wxKeyEvent
& event
,
3956 // handle only MSW-specific text bindings here, the others are handled in
3960 int keycode
= event
.GetKeyCode();
3962 wxControlAction action
;
3963 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
3965 action
= wxACTION_TEXT_CUT
;
3967 else if ( keycode
== WXK_INSERT
)
3969 if ( event
.ControlDown() )
3970 action
= wxACTION_TEXT_COPY
;
3971 else if ( event
.ShiftDown() )
3972 action
= wxACTION_TEXT_PASTE
;
3975 if ( action
!= wxACTION_NONE
)
3977 control
->PerformAction(action
);
3983 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
3986 #endif // wxUSE_TEXTCTRL
3990 // ----------------------------------------------------------------------------
3991 // wxWin32StatusBarInputHandler
3992 // ----------------------------------------------------------------------------
3994 wxWin32StatusBarInputHandler::
3995 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
3996 : wxStdInputHandler(handler
)
4001 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
4002 const wxPoint
& pt
) const
4004 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
4005 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
4008 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
4010 wxCHECK_MSG( parentTLW
, false,
4011 _T("the status bar should be a child of a TLW") );
4013 // a maximized window can't be resized anyhow
4014 if ( !parentTLW
->IsMaximized() )
4016 // VZ: I think that the standard Windows behaviour is to only
4017 // show the resizing cursor when the mouse is on top of the
4018 // grip itself but apparently different Windows versions behave
4019 // differently (?) and it seems a better UI to allow resizing
4020 // the status bar even when the mouse is above the grip
4021 wxSize sizeSbar
= statbar
->GetSize();
4023 int diff
= sizeSbar
.x
- pt
.x
;
4024 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4031 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4032 const wxMouseEvent
& event
)
4034 if ( event
.Button(1) )
4036 if ( event
.ButtonDown(1) )
4038 wxWindow
*statbar
= consumer
->GetInputWindow();
4040 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4042 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4046 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4047 wxHT_TOPLEVEL_BORDER_SE
);
4049 statbar
->SetCursor(m_cursorOld
);
4057 return wxStdInputHandler::HandleMouse(consumer
, event
);
4060 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
4061 const wxMouseEvent
& event
)
4063 wxWindow
*statbar
= consumer
->GetInputWindow();
4065 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4066 if ( isOnGrip
!= m_isOnGrip
)
4068 m_isOnGrip
= isOnGrip
;
4071 m_cursorOld
= statbar
->GetCursor();
4072 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4076 statbar
->SetCursor(m_cursorOld
);
4080 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4083 #endif // wxUSE_STATUSBAR
4085 // ----------------------------------------------------------------------------
4086 // wxWin32FrameInputHandler
4087 // ----------------------------------------------------------------------------
4089 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4092 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4094 void Attach(wxInputConsumer
*consumer
);
4098 DECLARE_EVENT_TABLE()
4099 void OnSystemMenu(wxCommandEvent
&event
);
4100 void OnCloseFrame(wxCommandEvent
&event
);
4101 void OnClose(wxCloseEvent
&event
);
4103 wxWin32FrameInputHandler
*m_inputHnd
;
4104 wxTopLevelWindow
*m_wnd
;
4106 wxAcceleratorTable m_oldAccelTable
;
4110 wxWin32SystemMenuEvtHandler::
4111 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
)
4113 m_inputHnd
= handler
;
4117 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4119 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4121 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4122 m_wnd
->PushEventHandler(this);
4125 // VS: This code relies on using generic implementation of
4126 // wxAcceleratorTable in wxUniv!
4127 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4128 m_oldAccelTable
= table
;
4129 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4130 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4131 m_wnd
->SetAcceleratorTable(table
);
4135 void wxWin32SystemMenuEvtHandler::Detach()
4140 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4142 m_wnd
->RemoveEventHandler(this);
4147 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4148 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4149 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4150 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4153 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4155 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4156 !m_wnd
->IsMaximized()) ?
4157 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4158 FRAME_BORDER_THICKNESS
;
4159 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4160 pt
.x
= -pt
.x
+ border
;
4161 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4164 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4165 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4169 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4170 #endif // wxUSE_MENUS
4173 m_wnd
->SetAcceleratorTable(table
);
4177 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4179 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4180 wxTOPLEVEL_BUTTON_CLOSE
);
4183 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4190 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4191 : wxStdInputHandler(handler
)
4193 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4196 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4198 if ( m_menuHandler
)
4200 m_menuHandler
->Detach();
4201 delete m_menuHandler
;
4205 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4206 const wxMouseEvent
& event
)
4208 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4210 wxTopLevelWindow
*tlw
=
4211 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4213 long hit
= tlw
->HitTest(event
.GetPosition());
4215 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4217 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4218 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4219 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4222 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4224 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4225 (event
.RightDown() &&
4226 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4227 hit
== wxHT_TOPLEVEL_ICON
)) )
4230 PopupSystemMenu(tlw
, event
.GetPosition());
4231 #endif // wxUSE_MENUS
4237 return wxStdInputHandler::HandleMouse(consumer
, event
);
4242 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4243 const wxPoint
& pos
) const
4245 wxMenu
*menu
= new wxMenu
;
4247 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4248 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4249 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4250 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4251 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4252 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4253 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4254 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4255 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4256 menu
->AppendSeparator();
4257 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4259 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4261 if ( window
->IsMaximized() )
4263 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4264 menu
->Enable(wxID_MOVE_FRAME
, false);
4265 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4266 menu
->Enable(wxID_RESIZE_FRAME
, false);
4269 menu
->Enable(wxID_RESTORE_FRAME
, false);
4272 window
->PopupMenu(menu
, pos
);
4276 #endif // wxUSE_MENUS
4278 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4281 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4283 // always detach if active frame changed:
4284 m_menuHandler
->Detach();
4288 m_menuHandler
->Attach(consumer
);
4292 return wxStdInputHandler::HandleActivation(consumer
, activated
);