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
,
175 virtual void DrawToolBarButton(wxDC
& dc
,
176 const wxString
& label
,
177 const wxBitmap
& bitmap
,
182 #endif // wxUSE_TOOLBAR
185 virtual void DrawTab(wxDC
& dc
,
188 const wxString
& label
,
189 const wxBitmap
& bitmap
= wxNullBitmap
,
191 int indexAccel
= -1);
192 #endif // wxUSE_NOTEBOOK
195 virtual void DrawSliderShaft(wxDC
& dc
,
198 wxOrientation orient
,
201 wxRect
*rectShaft
= NULL
);
202 virtual void DrawSliderThumb(wxDC
& dc
,
204 wxOrientation orient
,
207 virtual void DrawSliderTicks(wxDC
& dc
,
210 wxOrientation orient
,
216 #endif // wxUSE_SLIDER
219 virtual void DrawMenuBarItem(wxDC
& dc
,
221 const wxString
& label
,
223 int indexAccel
= -1);
224 virtual void DrawMenuItem(wxDC
& dc
,
226 const wxMenuGeometryInfo
& geometryInfo
,
227 const wxString
& label
,
228 const wxString
& accel
,
229 const wxBitmap
& bitmap
= wxNullBitmap
,
231 int indexAccel
= -1);
232 virtual void DrawMenuSeparator(wxDC
& dc
,
234 const wxMenuGeometryInfo
& geomInfo
);
235 #endif // wxUSE_MENUS
238 virtual void DrawStatusField(wxDC
& dc
,
240 const wxString
& label
,
241 int flags
= 0, int style
= 0);
242 #endif // wxUSE_STATUSBAR
245 virtual void DrawFrameTitleBar(wxDC
& dc
,
247 const wxString
& title
,
250 int specialButton
= 0,
251 int specialButtonFlags
= 0);
252 virtual void DrawFrameBorder(wxDC
& dc
,
255 virtual void DrawFrameBackground(wxDC
& dc
,
258 virtual void DrawFrameTitle(wxDC
& dc
,
260 const wxString
& title
,
262 virtual void DrawFrameIcon(wxDC
& dc
,
266 virtual void DrawFrameButton(wxDC
& dc
,
267 wxCoord x
, wxCoord y
,
270 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
271 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
272 virtual wxSize
GetFrameMinSize(int flags
) const;
273 virtual wxSize
GetFrameIconSize() const;
274 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
276 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
278 wxBitmap
*bmpPressed
,
279 wxBitmap
*bmpDisabled
);
281 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
282 virtual bool AreScrollbarsInsideBorder() const;
284 virtual wxSize
GetScrollbarArrowSize() const
285 { return m_sizeScrollbarArrow
; }
287 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
288 { return fontHeight
+ 2; }
289 virtual wxSize
GetCheckBitmapSize() const
290 { return wxSize(13, 13); }
291 virtual wxSize
GetRadioBitmapSize() const
292 { return wxSize(12, 12); }
293 virtual wxCoord
GetCheckItemMargin() const
296 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
297 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
298 virtual wxSize
GetToolBarMargin() const
299 { return wxSize(4, 4); }
302 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
303 const wxRect
& rect
) const;
304 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
306 wxCoord
*extraSpaceBeyond
) const;
307 #endif // wxUSE_TEXTCTRL
310 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
311 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
312 #endif // wxUSE_NOTEBOOK
316 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
317 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
318 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
320 wxOrientation orient
,
321 long style
= 0) const;
322 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
324 wxOrientation orient
) const;
325 #endif // wxUSE_SLIDER
327 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
330 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
331 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
332 const wxMenu
& menu
) const;
333 #endif // wxUSE_MENUS
336 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
337 #endif // wxUSE_STATUSBAR
340 // overridden wxStdRenderer methods
341 virtual void DrawFrameWithLabel(wxDC
& dc
,
342 const wxString
& label
,
343 const wxRect
& rectFrame
,
344 const wxRect
& rectText
,
349 virtual void DrawCheckItemBitmap(wxDC
& dc
,
350 const wxBitmap
& bitmap
,
355 // draw the border used for scrollbar arrows
356 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
358 // public DrawArrow()s helper
359 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
360 wxArrowDirection arrowDir
, wxArrowStyle arrowStyle
);
362 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
363 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
364 wxArrowDirection arrowDir
,
365 wxArrowStyle arrowStyle
);
367 // draw a normal or transposed line (useful for using the same code fo both
368 // horizontal and vertical widgets)
369 void DrawLine(wxDC
& dc
,
370 wxCoord x1
, wxCoord y1
,
371 wxCoord x2
, wxCoord y2
,
372 bool transpose
= false)
375 dc
.DrawLine(y1
, x1
, y2
, x2
);
377 dc
.DrawLine(x1
, y1
, x2
, y2
);
380 // get the standard check/radio button bitmap
381 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
382 virtual wxBitmap
GetCheckBitmap(int flags
)
383 { return GetIndicator(IndicatorType_Check
, flags
); }
384 virtual wxBitmap
GetRadioBitmap(int flags
)
385 { return GetIndicator(IndicatorType_Radio
, flags
); }
388 // the sizing parameters (TODO make them changeable)
389 wxSize m_sizeScrollbarArrow
;
391 wxFont m_titlebarFont
;
393 // the checked and unchecked bitmaps for DrawCheckItemBitmap()
394 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
396 // the bitmaps returned by GetIndicator()
397 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
398 [IndicatorState_MaxMenu
]
399 [IndicatorStatus_Max
];
401 // standard defaults for m_bmpCheckBitmaps and m_bmpIndicators
402 static const char **ms_xpmChecked
[IndicatorStatus_Max
];
403 static const char **ms_xpmIndicators
[IndicatorType_Max
]
404 [IndicatorState_MaxMenu
]
405 [IndicatorStatus_Max
];
408 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
410 // first row is for the normal state, second - for the disabled
411 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
414 // ----------------------------------------------------------------------------
415 // wxWin32InputHandler and derived classes: process the keyboard and mouse
416 // messages according to Windows standards
417 // ----------------------------------------------------------------------------
419 class wxWin32InputHandler
: public wxInputHandler
422 wxWin32InputHandler() { }
424 virtual bool HandleKey(wxInputConsumer
*control
,
425 const wxKeyEvent
& event
,
427 virtual bool HandleMouse(wxInputConsumer
*control
,
428 const wxMouseEvent
& event
);
432 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
435 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
,
436 wxInputHandler
*handler
);
438 virtual bool HandleMouse(wxInputConsumer
*control
,
439 const wxMouseEvent
& event
);
440 virtual bool HandleMouseMove(wxInputConsumer
*control
,
441 const wxMouseEvent
& event
);
443 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
444 const wxControlAction
& action
);
447 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
450 // we don't highlight anything
453 // the first and last event which caused the thumb to move
454 wxMouseEvent m_eventStartDrag
,
457 // have we paused the scrolling because the mouse moved?
460 // we remember the interval of the timer to be able to restart it
463 #endif // wxUSE_SCROLLBAR
466 class wxWin32CheckboxInputHandler
: public wxStdInputHandler
469 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
470 : wxStdInputHandler(handler
) { }
472 virtual bool HandleKey(wxInputConsumer
*control
,
473 const wxKeyEvent
& event
,
476 #endif // wxUSE_CHECKBOX
479 class wxWin32TextCtrlInputHandler
: public wxStdInputHandler
482 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
483 : wxStdInputHandler(handler
) { }
485 virtual bool HandleKey(wxInputConsumer
*control
,
486 const wxKeyEvent
& event
,
489 #endif // wxUSE_TEXTCTRL
491 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
494 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
496 virtual bool HandleMouse(wxInputConsumer
*consumer
,
497 const wxMouseEvent
& event
);
499 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
500 const wxMouseEvent
& event
);
503 // is the given point over the statusbar grip?
504 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
507 // the cursor we had replaced with the resize one
508 wxCursor m_cursorOld
;
510 // was the mouse over the grip last time we checked?
514 class wxWin32SystemMenuEvtHandler
;
516 class wxWin32FrameInputHandler
: public wxStdInputHandler
519 wxWin32FrameInputHandler(wxInputHandler
*handler
);
520 virtual ~wxWin32FrameInputHandler();
522 virtual bool HandleMouse(wxInputConsumer
*control
,
523 const wxMouseEvent
& event
);
525 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
528 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
529 #endif // wxUSE_MENUS
532 // was the mouse over the grip last time we checked?
533 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
536 // ----------------------------------------------------------------------------
537 // wxWin32ColourScheme: uses (default) Win32 colours
538 // ----------------------------------------------------------------------------
540 class wxWin32ColourScheme
: public wxColourScheme
543 virtual wxColour
Get(StdColour col
) const;
544 virtual wxColour
GetBackground(wxWindow
*win
) const;
547 // ----------------------------------------------------------------------------
548 // wxWin32ArtProvider
549 // ----------------------------------------------------------------------------
551 class wxWin32ArtProvider
: public wxArtProvider
554 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
555 const wxArtClient
& client
,
559 // ----------------------------------------------------------------------------
561 // ----------------------------------------------------------------------------
563 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
565 class wxWin32Theme
: public wxTheme
569 virtual ~wxWin32Theme();
571 virtual wxRenderer
*GetRenderer();
572 virtual wxArtProvider
*GetArtProvider();
573 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
574 wxInputConsumer
*consumer
);
575 virtual wxColourScheme
*GetColourScheme();
578 wxWin32Renderer
*m_renderer
;
580 wxWin32ArtProvider
*m_artProvider
;
582 // the names of the already created handlers and the handlers themselves
583 // (these arrays are synchronized)
584 wxSortedArrayString m_handlerNames
;
585 wxArrayHandlers m_handlers
;
587 wxWin32ColourScheme
*m_scheme
;
589 WX_DECLARE_THEME(win32
)
592 // ----------------------------------------------------------------------------
594 // ----------------------------------------------------------------------------
596 // frame buttons bitmaps
598 static const char *frame_button_close_xpm
[] = {
613 static const char *frame_button_help_xpm
[] = {
628 static const char *frame_button_maximize_xpm
[] = {
643 static const char *frame_button_minimize_xpm
[] = {
658 static const char *frame_button_restore_xpm
[] = {
675 static const char *checked_menu_xpm
[] = {
676 /* columns rows colors chars-per-pixel */
692 static const char *selected_checked_menu_xpm
[] = {
693 /* columns rows colors chars-per-pixel */
709 static const char *disabled_checked_menu_xpm
[] = {
710 /* columns rows colors chars-per-pixel */
727 static const char *selected_disabled_checked_menu_xpm
[] = {
728 /* columns rows colors chars-per-pixel */
744 // checkbox and radiobox bitmaps below
746 static const char *checked_xpm
[] = {
747 /* columns rows colors chars-per-pixel */
770 static const char *pressed_checked_xpm
[] = {
771 /* columns rows colors chars-per-pixel */
793 static const char *pressed_disabled_checked_xpm
[] = {
794 /* columns rows colors chars-per-pixel */
816 static const char *checked_item_xpm
[] = {
817 /* columns rows colors chars-per-pixel */
838 static const char *unchecked_xpm
[] = {
839 /* columns rows colors chars-per-pixel */
862 static const char *pressed_unchecked_xpm
[] = {
863 /* columns rows colors chars-per-pixel */
885 static const char *unchecked_item_xpm
[] = {
886 /* columns rows colors chars-per-pixel */
906 static const char *undetermined_xpm
[] = {
907 /* columns rows colors chars-per-pixel */
930 static const char *pressed_undetermined_xpm
[] = {
931 /* columns rows colors chars-per-pixel */
954 static const char *checked_radio_xpm
[] = {
955 /* columns rows colors chars-per-pixel */
978 static const char *pressed_checked_radio_xpm
[] = {
979 /* columns rows colors chars-per-pixel */
1002 static const char *pressed_disabled_checked_radio_xpm
[] = {
1003 /* columns rows colors chars-per-pixel */
1026 static const char *unchecked_radio_xpm
[] = {
1027 /* columns rows colors chars-per-pixel */
1050 static const char *pressed_unchecked_radio_xpm
[] = {
1051 /* columns rows colors chars-per-pixel */
1074 const char **wxWin32Renderer
::ms_xpmIndicators
[IndicatorType_Max
]
1075 [IndicatorState_MaxMenu
]
1076 [IndicatorStatus_Max
] =
1081 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1084 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1087 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1093 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1096 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1099 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1105 { checked_menu_xpm
, NULL
, NULL
},
1108 { selected_checked_menu_xpm
, NULL
, NULL
},
1111 { disabled_checked_menu_xpm
, NULL
, NULL
},
1113 // disabled selected state
1114 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1118 const char **wxWin32Renderer
::ms_xpmChecked
[IndicatorStatus_Max
] =
1124 // ============================================================================
1126 // ============================================================================
1128 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1130 // ----------------------------------------------------------------------------
1132 // ----------------------------------------------------------------------------
1134 wxWin32Theme
::wxWin32Theme()
1138 m_artProvider
= NULL
;
1141 wxWin32Theme
::~wxWin32Theme()
1145 wxArtProvider
::RemoveProvider(m_artProvider
);
1148 wxRenderer
*wxWin32Theme
::GetRenderer()
1152 m_renderer
= new wxWin32Renderer(GetColourScheme());
1158 wxArtProvider
*wxWin32Theme
::GetArtProvider()
1160 if ( !m_artProvider
)
1162 m_artProvider
= new wxWin32ArtProvider
;
1165 return m_artProvider
;
1169 wxWin32Theme
::GetInputHandler(const wxString
& control
,
1170 wxInputConsumer
*consumer
)
1172 wxInputHandler
*handler
= NULL
;
1173 int n
= m_handlerNames
.Index(control
);
1174 if ( n
== wxNOT_FOUND
)
1176 static wxWin32InputHandler s_handlerDef
;
1178 wxInputHandler
* const
1179 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
1181 // create a new handler
1182 if ( control
== wxINP_HANDLER_TOPLEVEL
)
1184 static wxWin32FrameInputHandler
s_handler(handlerStd
);
1186 handler
= &s_handler
;
1189 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1191 static wxWin32CheckboxInputHandler
s_handler(handlerStd
);
1193 handler
= &s_handler
;
1195 #endif // wxUSE_CHECKBOX
1197 else if ( control
== wxINP_HANDLER_SCROLLBAR
)
1199 static wxWin32ScrollBarInputHandler
1200 s_handler(GetRenderer(), handlerStd
);
1202 handler
= &s_handler
;
1204 #endif // wxUSE_SCROLLBAR
1206 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1208 static wxWin32StatusBarInputHandler
s_handler(handlerStd
);
1210 handler
= &s_handler
;
1212 #endif // wxUSE_STATUSBAR
1214 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1216 static wxWin32TextCtrlInputHandler
s_handler(handlerStd
);
1218 handler
= &s_handler
;
1220 #endif // wxUSE_TEXTCTRL
1221 else // no special handler for this control
1223 handler
= handlerStd
;
1226 n
= m_handlerNames
.Add(control
);
1227 m_handlers
.Insert(handler
, n
);
1229 else // we already have it
1231 handler
= m_handlers
[n
];
1237 wxColourScheme
*wxWin32Theme
::GetColourScheme()
1241 m_scheme
= new wxWin32ColourScheme
;
1246 // ============================================================================
1247 // wxWin32ColourScheme
1248 // ============================================================================
1250 wxColour wxWin32ColourScheme
::GetBackground(wxWindow
*win
) const
1253 if ( win
->UseBgCol() )
1255 // use the user specified colour
1256 col
= win
->GetBackgroundColour();
1259 if ( !win
->ShouldInheritColours() )
1262 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1263 #endif // wxUSE_TEXTCTRL
1265 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1266 #endif // wxUSE_LISTBOX
1275 if ( !win
->IsEnabled() ) // not IsEditable()
1281 // doesn't depend on the state
1286 #endif // wxUSE_TEXTCTRL
1289 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1293 int flags
= win
->GetStateFlags();
1295 // the colour set by the user should be used for the normal state
1296 // and for the states for which we don't have any specific colours
1297 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1300 if ( wxDynamicCast(win
, wxScrollBar
) )
1301 col
= Get(flags
& wxCONTROL_PRESSED ? SCROLLBAR_PRESSED
1304 #endif // wxUSE_SCROLLBAR
1312 wxColour wxWin32ColourScheme
::Get(wxWin32ColourScheme
::StdColour col
) const
1316 // use the system colours under Windows
1317 #if defined(__WXMSW__)
1318 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1320 case CONTROL_PRESSED
:
1321 case CONTROL_CURRENT
:
1322 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1324 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1326 #if defined(COLOR_3DLIGHT)
1327 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1329 case SCROLLBAR
: return wxColour(0xe0e0e0);
1331 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1333 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1334 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1336 #if defined(COLOR_3DDKSHADOW)
1337 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1339 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1342 case CONTROL_TEXT_DISABLED
:
1343 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1345 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1347 case CONTROL_TEXT_DISABLED_SHADOW
:
1348 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1350 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1351 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1352 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1353 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1355 case DESKTOP
: return wxColour(0x808000);
1357 // use the standard Windows colours elsewhere
1358 case WINDOW
: return *wxWHITE
;
1360 case CONTROL_PRESSED
:
1361 case CONTROL_CURRENT
:
1362 case CONTROL
: return wxColour(0xc0c0c0);
1364 case CONTROL_TEXT
: return *wxBLACK
;
1366 case SCROLLBAR
: return wxColour(0xe0e0e0);
1367 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1369 case HIGHLIGHT
: return wxColour(0x800000);
1370 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1372 case SHADOW_DARK
: return *wxBLACK
;
1374 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1375 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1377 case SHADOW_IN
: return wxColour(0xc0c0c0);
1379 case CONTROL_TEXT_DISABLED_SHADOW
:
1380 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1382 case TITLEBAR
: return wxColour(0xaeaaae);
1383 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1384 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1385 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1387 case DESKTOP
: return wxColour(0x808000);
1390 case GAUGE
: return Get(HIGHLIGHT
);
1394 wxFAIL_MSG(_T("invalid standard colour"));
1399 // ============================================================================
1401 // ============================================================================
1403 // ----------------------------------------------------------------------------
1405 // ----------------------------------------------------------------------------
1407 wxWin32Renderer
::wxWin32Renderer(const wxColourScheme
*scheme
)
1408 : wxStdRenderer(scheme
)
1411 m_sizeScrollbarArrow
= wxSize(16, 16);
1413 m_titlebarFont
= wxSystemSettings
::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1414 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1416 // init the arrow bitmaps
1417 static const size_t ARROW_WIDTH
= 7;
1418 static const size_t ARROW_LENGTH
= 4;
1421 wxMemoryDC dcNormal
,
1424 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1426 bool isVertical
= n
> Arrow_Right
;
1439 // disabled arrow is larger because of the shadow
1440 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1441 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1443 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1444 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1446 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1447 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1451 dcNormal
.SetPen(m_penBlack
);
1452 dcDisabled
.SetPen(m_penDarkGrey
);
1454 // calculate the position of the point of the arrow
1458 x1
= (ARROW_WIDTH
- 1)/2;
1459 y1
= n
== Arrow_Up ?
0 : ARROW_LENGTH
- 1;
1463 x1
= n
== Arrow_Left ?
0 : ARROW_LENGTH
- 1;
1464 y1
= (ARROW_WIDTH
- 1)/2;
1475 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1477 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1478 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1485 if ( n
== Arrow_Up
)
1496 else // left or right arrow
1501 if ( n
== Arrow_Left
)
1514 // draw the shadow for the disabled one
1515 dcDisabled
.SetPen(m_penHighlight
);
1520 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1524 x1
= ARROW_LENGTH
- 1;
1525 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1528 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1529 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1534 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1538 x1
= ARROW_WIDTH
- 1;
1540 x2
= (ARROW_WIDTH
- 1)/2;
1542 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1543 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1548 // create the inverted bitmap but only for the right arrow as we only
1549 // use it for the menus
1550 if ( n
== Arrow_Right
)
1552 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1553 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1555 dcInverse
.Blit(0, 0, w
, h
,
1558 dcInverse
.SelectObject(wxNullBitmap
);
1560 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1561 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1563 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1564 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1566 dcInverse
.Blit(0, 0, w
, h
,
1569 dcInverse
.SelectObject(wxNullBitmap
);
1571 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1572 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1575 dcNormal
.SelectObject(wxNullBitmap
);
1576 dcDisabled
.SelectObject(wxNullBitmap
);
1578 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1579 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1580 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1581 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1583 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1586 // init the frame buttons bitmaps
1587 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1588 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1589 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1590 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1591 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1594 bool wxWin32Renderer
::AreScrollbarsInsideBorder() const
1599 // ----------------------------------------------------------------------------
1601 // ----------------------------------------------------------------------------
1603 void wxWin32Renderer
::DrawLabel(wxDC
& dc
,
1604 const wxString
& label
,
1611 // the underscores are not drawn for focused controls in wxMSW
1612 if ( flags
& wxCONTROL_FOCUSED
)
1617 if ( flags
& wxCONTROL_DISABLED
)
1619 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
1620 // currently only can happen for a menu item and it seems that Windows
1621 // doesn't draw the shadow in this case, so we don't do it neither
1622 if ( flags
& wxCONTROL_SELECTED
)
1624 // just make the label text greyed out
1625 dc
.SetTextForeground(m_penDarkGrey
.GetColour());
1627 flags
&= ~wxCONTROL_DISABLED
;
1631 wxStdRenderer
::DrawLabel(dc
, label
, rect
, flags
, alignment
,
1632 indexAccel
, rectBounds
);
1635 void wxWin32Renderer
::DrawFrameWithLabel(wxDC
& dc
,
1636 const wxString
& label
,
1637 const wxRect
& rectFrame
,
1638 const wxRect
& rectText
,
1644 label2
<< _T(' ') << label
<< _T(' ');
1645 if ( indexAccel
!= -1 )
1647 // adjust it as we prepended a space
1651 wxStdRenderer
::DrawFrameWithLabel(dc
, label2
, rectFrame
, rectText
,
1652 flags
, alignment
, indexAccel
);
1655 void wxWin32Renderer
::DrawButtonLabel(wxDC
& dc
,
1656 const wxString
& label
,
1657 const wxBitmap
& image
,
1664 // the underscores are not drawn for focused controls in wxMSW
1665 if ( flags
& wxCONTROL_PRESSED
)
1670 wxStdRenderer
::DrawButtonLabel(dc
, label
, image
, rect
, flags
, alignment
,
1671 indexAccel
, rectBounds
);
1674 void wxWin32Renderer
::DrawButtonBorder(wxDC
& dc
,
1675 const wxRect
& rectTotal
,
1679 wxRect rect
= rectTotal
;
1681 wxPen
penOut(*wxBLACK
);
1682 if ( flags
& wxCONTROL_PRESSED
)
1684 // button pressed: draw a double border around it
1685 DrawRect(dc
, &rect
, penOut
);
1686 DrawRect(dc
, &rect
, m_penDarkGrey
);
1688 else // button not pressed
1690 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1692 // button either default or focused (or both): add an extra border
1694 DrawRect(dc
, &rect
, penOut
);
1697 // now draw a normal button border
1698 DrawRaisedBorder(dc
, &rect
);
1705 // ----------------------------------------------------------------------------
1706 // (check)listbox items
1707 // ----------------------------------------------------------------------------
1709 void wxWin32Renderer
::DrawCheckItemBitmap(wxDC
& dc
,
1710 const wxBitmap
& bitmap
,
1719 else // use default bitmap
1721 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
1722 ? IndicatorStatus_Checked
1723 : IndicatorStatus_Unchecked
;
1725 if ( !m_bmpCheckBitmaps
[i
].Ok() )
1727 m_bmpCheckBitmaps
[i
] = wxBitmap(ms_xpmChecked
[i
]);
1730 bmp
= m_bmpCheckBitmaps
[i
];
1733 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
1734 true /* use mask */);
1737 // ----------------------------------------------------------------------------
1738 // check/radio buttons
1739 // ----------------------------------------------------------------------------
1741 wxBitmap wxWin32Renderer
::GetIndicator(IndicatorType indType
, int flags
)
1743 IndicatorState indState
;
1744 IndicatorStatus indStatus
;
1745 GetIndicatorsFromFlags(flags
, indState
, indStatus
);
1747 wxBitmap bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
1750 const char **xpm
= ms_xpmIndicators
[indType
][indState
][indStatus
];
1753 // create and cache it
1754 bmp
= wxBitmap(xpm
);
1755 m_bmpIndicators
[indType
][indState
][indStatus
] = bmp
;
1762 // ----------------------------------------------------------------------------
1764 // ----------------------------------------------------------------------------
1767 void wxWin32Renderer
::DrawToolBarButton(wxDC
& dc
,
1768 const wxString
& label
,
1769 const wxBitmap
& bitmap
,
1770 const wxRect
& rectOrig
,
1775 if (style
== wxTOOL_STYLE_BUTTON
)
1777 wxRect rect
= rectOrig
;
1778 rect
.Deflate(BORDER_THICKNESS
);
1780 if ( flags
& wxCONTROL_PRESSED
)
1782 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
1784 else if ( flags
& wxCONTROL_CURRENT
)
1786 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
1789 if(tbarStyle
& wxTB_TEXT
)
1791 if(tbarStyle
& wxTB_HORIZONTAL
)
1793 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1797 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1802 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1803 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1804 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1807 else if (style
== wxTOOL_STYLE_SEPARATOR
)
1809 // leave a small gap aroudn the line, also account for the toolbar
1811 if(rectOrig
.height
> rectOrig
.width
)
1814 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
1815 rectOrig
.y
+ 2*BORDER_THICKNESS
,
1816 rectOrig
.GetBottom() - BORDER_THICKNESS
);
1821 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
1822 rectOrig
.x
+ 2*BORDER_THICKNESS
,
1823 rectOrig
.GetRight() - BORDER_THICKNESS
);
1826 // don't draw wxTOOL_STYLE_CONTROL
1828 #endif // wxUSE_TOOLBAR
1830 // ----------------------------------------------------------------------------
1832 // ----------------------------------------------------------------------------
1836 void wxWin32Renderer
::DrawTab(wxDC
& dc
,
1837 const wxRect
& rectOrig
,
1839 const wxString
& label
,
1840 const wxBitmap
& bitmap
,
1844 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1845 #define REVERSE_FOR_VERTICAL(X,Y) \
1846 SELECT_FOR_VERTICAL(X,Y) \
1848 SELECT_FOR_VERTICAL(Y,X)
1850 wxRect rect
= rectOrig
;
1852 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1854 // the current tab is drawn indented (to the top for default case) and
1855 // bigger than the other ones
1856 const wxSize indent
= GetTabIndent();
1857 if ( flags
& wxCONTROL_SELECTED
)
1859 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1860 SELECT_FOR_VERTICAL( 0, indent
.y
));
1864 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1871 rect
.height
+= indent
.y
;
1878 rect
.width
+= indent
.x
;
1883 // draw the text, image and the focus around them (if necessary)
1884 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1885 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1887 rectLabel
.Deflate(1, 1);
1890 // draw it horizontally into memory and rotate for screen
1892 wxBitmap bitmapRotated
,
1893 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1894 rectLabel
.y
+ rectLabel
.height
);
1895 dcMem
.SelectObject(bitmapMem
);
1896 dcMem
.SetBackground(dc
.GetBackground());
1897 dcMem
.SetFont(dc
.GetFont());
1898 dcMem
.SetTextForeground(dc
.GetTextForeground());
1902 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1905 #endif // wxUSE_IMAGE
1907 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
1908 flags
, wxALIGN_CENTRE
, indexAccel
);
1909 dcMem
.SelectObject(wxNullBitmap
);
1910 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1912 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
1913 #endif // wxUSE_IMAGE
1914 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1918 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
1919 flags
, wxALIGN_CENTRE
, indexAccel
);
1922 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
1923 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
1924 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1925 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1926 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1927 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1929 // FIXME: all this code will break if the tab indent or the border width,
1930 // it is tied to the fact that both of them are equal to 2
1936 // left orientation looks like top but IsVertical makes x and y reversed
1938 // top is not vertical so use coordinates in written order
1939 dc
.SetPen(m_penHighlight
);
1940 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1941 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
1942 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
1943 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
1944 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
1945 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
1947 dc
.SetPen(m_penBlack
);
1948 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1949 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
1950 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
1951 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
1953 dc
.SetPen(m_penDarkGrey
);
1954 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1955 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
1957 if ( flags
& wxCONTROL_SELECTED
)
1959 dc
.SetPen(m_penLightGrey
);
1961 // overwrite the part of the border below this tab
1962 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1963 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1965 // and the shadow of the tab to the left of us
1966 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
1967 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1972 // right orientation looks like bottom but IsVertical makes x and y reversed
1974 // bottom is not vertical so use coordinates in written order
1975 dc
.SetPen(m_penHighlight
);
1976 // we need to continue one pixel further to overwrite the corner of
1977 // the border for the selected tab
1978 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED ?
1 : 0)),
1979 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
1980 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
1981 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
1983 dc
.SetPen(m_penBlack
);
1984 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
1985 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
1986 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1987 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
1988 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
1989 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
1991 dc
.SetPen(m_penDarkGrey
);
1992 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
1993 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
1994 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1995 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
1997 if ( flags
& wxCONTROL_SELECTED
)
1999 dc
.SetPen(m_penLightGrey
);
2001 // overwrite the part of the (double!) border above this tab
2002 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
2003 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
2004 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
2005 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
2007 // and the shadow of the tab to the left of us
2008 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
2009 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
2014 #undef SELECT_FOR_VERTICAL
2015 #undef REVERSE_FOR_VERTICAL
2018 #endif // wxUSE_NOTEBOOK
2022 // ----------------------------------------------------------------------------
2024 // ----------------------------------------------------------------------------
2027 wxWin32Renderer
::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2029 wxOrientation orient
) const
2032 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2033 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2035 if (orient
== wxHORIZONTAL
)
2049 wxRect wxWin32Renderer
::GetSliderShaftRect(const wxRect
& rectOrig
,
2051 wxOrientation orient
,
2054 bool transpose
= (orient
== wxVERTICAL
);
2055 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2056 (((style
& wxSL_TOP
) != 0) & !transpose
|
2057 ((style
& wxSL_LEFT
) != 0) & transpose
|
2058 ((style
& wxSL_BOTH
) != 0));
2059 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2060 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2061 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2062 ((style
& wxSL_BOTH
) != 0));
2064 wxRect rect
= rectOrig
;
2066 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2068 if (orient
== wxHORIZONTAL
) {
2069 rect
.x
+= SLIDER_MARGIN
;
2072 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2076 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2080 rect
.y
+= sizeThumb
.y
/2;
2082 rect
.width
-= 2*SLIDER_MARGIN
;
2083 rect
.height
= 2*BORDER_THICKNESS
;
2087 rect
.y
+= SLIDER_MARGIN
;
2090 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2094 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2098 rect
.x
+= sizeThumb
.x
/2;
2100 rect
.width
= 2*BORDER_THICKNESS
;
2101 rect
.height
-= 2*SLIDER_MARGIN
;
2107 void wxWin32Renderer
::DrawSliderShaft(wxDC
& dc
,
2108 const wxRect
& rectOrig
,
2110 wxOrientation orient
,
2115 /* show shaft geometry
2133 if (flags
& wxCONTROL_FOCUSED
) {
2134 DrawFocusRect(dc
, rectOrig
);
2137 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2139 if (rectShaft
) *rectShaft
= rect
;
2141 DrawSunkenBorder(dc
, &rect
);
2144 void wxWin32Renderer
::DrawSliderThumb(wxDC
& dc
,
2146 wxOrientation orient
,
2150 /* show thumb geometry
2159 H D B where H is highlight colour
2173 The interior of this shape is filled with the hatched brush if the thumb
2177 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2179 bool transpose
= (orient
== wxVERTICAL
);
2180 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2181 (((style
& wxSL_TOP
) != 0) & !transpose
|
2182 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2183 ((style
& wxSL_BOTH
) == 0);
2184 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2185 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2186 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2187 ((style
& wxSL_BOTH
) == 0);
2189 wxCoord sizeArrow
= (transpose ? rect
.height
: rect
.width
) / 2;
2190 wxCoord c
= ((transpose ? rect
.height
: rect
.width
) - 2*sizeArrow
);
2192 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2193 x1
= (transpose ? rect
.y
: rect
.x
);
2194 x2
= (transpose ? rect
.GetBottom() : rect
.GetRight());
2195 x3
= (x1
-1+c
) + sizeArrow
;
2196 y1
= (transpose ? rect
.x
: rect
.y
);
2197 y2
= (transpose ? rect
.GetRight() : rect
.GetBottom());
2198 y3
= (left ?
(y1
-1+c
) + sizeArrow
: y1
);
2199 y4
= (right ?
(y2
+1-c
) - sizeArrow
: y2
);
2201 dc
.SetPen(m_penBlack
);
2203 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2205 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2208 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2212 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2215 dc
.SetPen(m_penDarkGrey
);
2216 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2218 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2222 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2225 dc
.SetPen(m_penHighlight
);
2228 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2229 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2233 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2235 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2238 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2241 if (flags
& wxCONTROL_PRESSED
) {
2242 // TODO: MSW fills the entire area inside, not just the rect
2243 wxRect rectInt
= rect
;
2246 rectInt
.SetLeft(y3
);
2247 rectInt
.SetRight(y4
);
2252 rectInt
.SetBottom(y4
);
2256 #if !defined(__WXMGL__)
2257 static const char *stipple_xpm
[] = {
2258 /* columns rows colors chars-per-pixel */
2267 // VS: MGL can only do 8x8 stipple brushes
2268 static const char *stipple_xpm
[] = {
2269 /* columns rows colors chars-per-pixel */
2284 dc
.SetBrush(wxBrush(stipple_xpm
));
2286 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2287 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2288 dc
.SetPen(*wxTRANSPARENT_PEN
);
2289 dc
.DrawRectangle(rectInt
);
2293 void wxWin32Renderer
::DrawSliderTicks(wxDC
& dc
,
2296 wxOrientation orient
,
2300 int WXUNUSED(flags
),
2303 /* show ticks geometry
2318 if (end
== start
) return;
2320 bool transpose
= (orient
== wxVERTICAL
);
2321 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2322 (((style
& wxSL_TOP
) != 0) & !transpose
|
2323 ((style
& wxSL_LEFT
) != 0) & transpose
|
2324 ((style
& wxSL_BOTH
) != 0));
2325 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2326 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2327 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2328 ((style
& wxSL_BOTH
) != 0));
2330 // default thumb size
2331 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2332 wxCoord defaultLen
= (transpose ? sizeThumb
.x
: sizeThumb
.y
);
2334 // normal thumb size
2335 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2336 wxCoord widthThumb
= (transpose ? sizeThumb
.y
: sizeThumb
.x
);
2338 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2340 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2341 x1
= (transpose ? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2342 x2
= (transpose ? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2343 y1
= (transpose ? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2344 y2
= (transpose ? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2345 y3
= (transpose ? rect
.x
: rect
.y
);
2346 y4
= (transpose ? rect
.GetRight() : rect
.GetBottom());
2349 dc
.SetPen(m_penBlack
);
2351 int range
= end
- start
;
2352 for ( int n
= 0; n
< range
; n
+= step
) {
2353 wxCoord x
= x1
+ (len
*n
) / range
;
2355 if (left
& (y1
> y3
)) {
2356 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2358 if (right
& (y4
> y2
)) {
2359 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2362 // always draw the line at the end position
2363 if (left
& (y1
> y3
)) {
2364 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2366 if (right
& (y4
> y2
)) {
2367 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2371 #endif // wxUSE_SLIDER
2375 // ----------------------------------------------------------------------------
2377 // ----------------------------------------------------------------------------
2379 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2380 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2383 virtual wxSize
GetSize() const { return m_size
; }
2385 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2386 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2388 wxCoord
GetItemHeight() const { return m_heightItem
; }
2391 // the total size of the menu
2394 // the offset of the start of the menu item label
2397 // the offset of the start of the accel label
2400 // the height of a normal (not separator) item
2401 wxCoord m_heightItem
;
2403 friend wxMenuGeometryInfo
*
2404 wxWin32Renderer
::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2407 // FIXME: all constants are hardcoded but shouldn't be
2408 static const wxCoord MENU_LEFT_MARGIN
= 9;
2409 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2410 static const wxCoord MENU_VERT_MARGIN
= 3;
2412 // the margin around bitmap/check marks (on each side)
2413 static const wxCoord MENU_BMP_MARGIN
= 2;
2415 // the margin between the labels and accel strings
2416 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2418 // the separator height in pixels: in fact, strangely enough, the real height
2419 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2421 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2423 // the size of the standard checkmark bitmap
2424 static const wxCoord MENU_CHECK_SIZE
= 9;
2426 void wxWin32Renderer
::DrawMenuBarItem(wxDC
& dc
,
2427 const wxRect
& rectOrig
,
2428 const wxString
& label
,
2432 wxRect rect
= rectOrig
;
2435 wxDCTextColourChanger
colChanger(dc
);
2437 if ( flags
& wxCONTROL_SELECTED
)
2439 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2441 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2444 dc
.DrawRectangle(rect
);
2447 // don't draw the focus rect around menu bar items
2448 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2449 wxALIGN_CENTRE
, indexAccel
);
2452 void wxWin32Renderer
::DrawMenuItem(wxDC
& dc
,
2454 const wxMenuGeometryInfo
& gi
,
2455 const wxString
& label
,
2456 const wxString
& accel
,
2457 const wxBitmap
& bitmap
,
2461 const wxWin32MenuGeometryInfo
& geometryInfo
=
2462 (const wxWin32MenuGeometryInfo
&)gi
;
2467 rect
.width
= geometryInfo
.GetSize().x
;
2468 rect
.height
= geometryInfo
.GetItemHeight();
2470 // draw the selected item specially
2471 wxDCTextColourChanger
colChanger(dc
);
2472 if ( flags
& wxCONTROL_SELECTED
)
2474 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2476 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2479 dc
.DrawRectangle(rect
);
2482 // draw the bitmap: use the bitmap provided or the standard checkmark for
2483 // the checkable items
2484 wxBitmap bmp
= bitmap
;
2485 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2487 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2492 rect
.SetRight(geometryInfo
.GetLabelOffset());
2493 wxControlRenderer
::DrawBitmap(dc
, bmp
, rect
);
2497 rect
.x
= geometryInfo
.GetLabelOffset();
2498 rect
.SetRight(geometryInfo
.GetAccelOffset());
2500 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2502 // draw the accel string
2503 rect
.x
= geometryInfo
.GetAccelOffset();
2504 rect
.SetRight(geometryInfo
.GetSize().x
);
2506 // NB: no accel index here
2507 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2509 // draw the submenu indicator
2510 if ( flags
& wxCONTROL_ISSUBMENU
)
2512 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2513 rect
.width
= MENU_RIGHT_MARGIN
;
2515 wxArrowStyle arrowStyle
;
2516 if ( flags
& wxCONTROL_DISABLED
)
2517 arrowStyle
= flags
& wxCONTROL_SELECTED ? Arrow_InvertedDisabled
2519 else if ( flags
& wxCONTROL_SELECTED
)
2520 arrowStyle
= Arrow_Inverted
;
2522 arrowStyle
= Arrow_Normal
;
2524 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2528 void wxWin32Renderer
::DrawMenuSeparator(wxDC
& dc
,
2530 const wxMenuGeometryInfo
& geomInfo
)
2532 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2535 wxSize wxWin32Renderer
::GetMenuBarItemSize(const wxSize
& sizeText
) const
2537 wxSize size
= sizeText
;
2539 // FIXME: menubar height is configurable under Windows
2546 wxMenuGeometryInfo
*wxWin32Renderer
::GetMenuGeometry(wxWindow
*win
,
2547 const wxMenu
& menu
) const
2549 // prepare the dc: for now we draw all the items with the system font
2551 dc
.SetFont(wxSystemSettings
::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2553 // the height of a normal item
2554 wxCoord heightText
= dc
.GetCharHeight();
2559 // the max length of label and accel strings: the menu width is the sum of
2560 // them, even if they're for different items (as the accels should be
2563 // the max length of the bitmap is never 0 as Windows always leaves enough
2564 // space for a check mark indicator
2565 wxCoord widthLabelMax
= 0,
2567 widthBmpMax
= MENU_LEFT_MARGIN
;
2569 for ( wxMenuItemList
::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
2571 node
= node
->GetNext() )
2573 // height of this item
2576 wxMenuItem
*item
= node
->GetData();
2577 if ( item
->IsSeparator() )
2579 h
= MENU_SEPARATOR_HEIGHT
;
2581 else // not separator
2586 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2587 if ( widthLabel
> widthLabelMax
)
2589 widthLabelMax
= widthLabel
;
2593 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2594 if ( widthAccel
> widthAccelMax
)
2596 widthAccelMax
= widthAccel
;
2599 const wxBitmap
& bmp
= item
->GetBitmap();
2602 wxCoord widthBmp
= bmp
.GetWidth();
2603 if ( widthBmp
> widthBmpMax
)
2604 widthBmpMax
= widthBmp
;
2606 //else if ( item->IsCheckable() ): no need to check for this as
2607 // MENU_LEFT_MARGIN is big enough to show the check mark
2610 h
+= 2*MENU_VERT_MARGIN
;
2612 // remember the item position and height
2613 item
->SetGeometry(height
, h
);
2618 // bundle the metrics into a struct and return it
2619 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2621 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2622 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2623 if ( widthAccelMax
> 0 )
2625 // if we actually have any accesl, add a margin
2626 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2629 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2631 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2632 gi
->m_size
.y
= height
;
2637 #endif // wxUSE_MENUS
2641 // ----------------------------------------------------------------------------
2643 // ----------------------------------------------------------------------------
2645 static const wxCoord STATBAR_BORDER_X
= 2;
2646 static const wxCoord STATBAR_BORDER_Y
= 2;
2648 wxSize wxWin32Renderer
::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2650 if ( borderBetweenFields
)
2651 *borderBetweenFields
= 2;
2653 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2656 void wxWin32Renderer
::DrawStatusField(wxDC
& dc
,
2658 const wxString
& label
,
2659 int flags
, int style
/*=0*/)
2663 if ( flags
& wxCONTROL_ISDEFAULT
)
2665 // draw the size grip: it is a normal rect except that in the lower
2666 // right corner we have several bands which may be used for dragging
2667 // the status bar corner
2669 // each band consists of 4 stripes: m_penHighlight, double
2670 // m_penDarkGrey and transparent one
2671 wxCoord x2
= rect
.GetRight(),
2672 y2
= rect
.GetBottom();
2674 // draw the upper left part of the rect normally
2675 if (style
!= wxSB_FLAT
)
2677 if (style
== wxSB_RAISED
)
2678 dc
.SetPen(m_penHighlight
);
2680 dc
.SetPen(m_penDarkGrey
);
2681 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
2682 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
2685 // draw the grey stripes of the grip
2687 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
2688 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2690 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2691 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
2694 // draw the white stripes
2695 dc
.SetPen(m_penHighlight
);
2696 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
2697 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2699 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2702 // draw the remaining rect boundaries
2703 if (style
!= wxSB_FLAT
)
2705 if (style
== wxSB_RAISED
)
2706 dc
.SetPen(m_penDarkGrey
);
2708 dc
.SetPen(m_penHighlight
);
2709 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
2710 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
2711 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
2717 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
2721 if (style
== wxSB_RAISED
)
2722 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
2723 else if (style
!= wxSB_FLAT
)
2724 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
2727 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2729 wxDCClipper
clipper(dc
, rectIn
);
2730 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
2733 #endif // wxUSE_STATUSBAR
2735 // ----------------------------------------------------------------------------
2737 // ----------------------------------------------------------------------------
2739 void wxWin32Renderer
::GetComboBitmaps(wxBitmap
*bmpNormal
,
2740 wxBitmap
* WXUNUSED(bmpFocus
),
2741 wxBitmap
*bmpPressed
,
2742 wxBitmap
*bmpDisabled
)
2744 static const wxCoord widthCombo
= 16;
2745 static const wxCoord heightCombo
= 17;
2751 bmpNormal
->Create(widthCombo
, heightCombo
);
2752 dcMem
.SelectObject(*bmpNormal
);
2753 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2754 Arrow_Down
, Arrow_Normal
);
2759 bmpPressed
->Create(widthCombo
, heightCombo
);
2760 dcMem
.SelectObject(*bmpPressed
);
2761 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2762 Arrow_Down
, Arrow_Pressed
);
2767 bmpDisabled
->Create(widthCombo
, heightCombo
);
2768 dcMem
.SelectObject(*bmpDisabled
);
2769 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2770 Arrow_Down
, Arrow_Disabled
);
2774 // ----------------------------------------------------------------------------
2776 // ----------------------------------------------------------------------------
2778 void wxWin32Renderer
::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
2782 DrawRect(dc
, rect
, m_penDarkGrey
);
2784 // the arrow is usually drawn inside border of width 2 and is offset by
2785 // another pixel in both directions when it's pressed - as the border
2786 // in this case is more narrow as well, we have to adjust rect like
2794 DrawAntiSunkenBorder(dc
, rect
);
2798 void wxWin32Renderer
::DrawArrow(wxDC
& dc
,
2803 // get the bitmap for this arrow
2804 wxArrowDirection arrowDir
;
2807 case wxLEFT
: arrowDir
= Arrow_Left
; break;
2808 case wxRIGHT
: arrowDir
= Arrow_Right
; break;
2809 case wxUP
: arrowDir
= Arrow_Up
; break;
2810 case wxDOWN
: arrowDir
= Arrow_Down
; break;
2813 wxFAIL_MSG(_T("unknown arrow direction"));
2817 wxArrowStyle arrowStyle
;
2818 if ( flags
& wxCONTROL_PRESSED
)
2820 // can't be pressed and disabled
2821 arrowStyle
= Arrow_Pressed
;
2825 arrowStyle
= flags
& wxCONTROL_DISABLED ? Arrow_Disabled
: Arrow_Normal
;
2828 DrawArrowButton(dc
, rect
, arrowDir
, arrowStyle
);
2831 void wxWin32Renderer
::DrawArrow(wxDC
& dc
,
2833 wxArrowDirection arrowDir
,
2834 wxArrowStyle arrowStyle
)
2836 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
2838 // under Windows the arrows always have the same size so just centre it in
2839 // the provided rectangle
2840 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
2841 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
2843 // Windows does it like this...
2844 if ( arrowDir
== Arrow_Left
)
2848 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
2851 void wxWin32Renderer
::DrawArrowButton(wxDC
& dc
,
2852 const wxRect
& rectAll
,
2853 wxArrowDirection arrowDir
,
2854 wxArrowStyle arrowStyle
)
2856 wxRect rect
= rectAll
;
2857 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2858 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
2859 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
2862 void wxWin32Renderer
::DrawScrollbarThumb(wxDC
& dc
,
2863 wxOrientation
WXUNUSED(orient
),
2865 int WXUNUSED(flags
))
2867 // we don't use the flags, the thumb never changes appearance
2868 wxRect rectThumb
= rect
;
2869 DrawArrowBorder(dc
, &rectThumb
);
2870 DrawBackground(dc
, wxNullColour
, rectThumb
);
2873 void wxWin32Renderer
::DrawScrollbarShaft(wxDC
& dc
,
2874 wxOrientation
WXUNUSED(orient
),
2875 const wxRect
& rectBar
,
2878 wxColourScheme
::StdColour col
= flags
& wxCONTROL_PRESSED
2879 ? wxColourScheme
::SCROLLBAR_PRESSED
2880 : wxColourScheme
::SCROLLBAR
;
2881 DrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
2884 void wxWin32Renderer
::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2886 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2889 // ----------------------------------------------------------------------------
2890 // top level windows
2891 // ----------------------------------------------------------------------------
2893 int wxWin32Renderer
::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
2895 wxRect client
= GetFrameClientArea(rect
, flags
);
2897 if ( client
.Contains(pt
) )
2898 return wxHT_TOPLEVEL_CLIENT_AREA
;
2900 if ( flags
& wxTOPLEVEL_TITLEBAR
)
2902 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
2904 if ( flags
& wxTOPLEVEL_ICON
)
2906 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Contains(pt
) )
2907 return wxHT_TOPLEVEL_ICON
;
2910 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
2911 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
2912 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
2914 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
2916 if ( btnRect
.Contains(pt
) )
2917 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
2918 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
2920 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
2922 if ( btnRect
.Contains(pt
) )
2923 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
2924 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2926 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
2928 if ( btnRect
.Contains(pt
) )
2929 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
2930 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2932 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
2934 if ( btnRect
.Contains(pt
) )
2935 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
2936 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2938 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
2940 if ( btnRect
.Contains(pt
) )
2941 return wxHT_TOPLEVEL_BUTTON_HELP
;
2942 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2945 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
2946 return wxHT_TOPLEVEL_TITLEBAR
;
2949 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
2951 // we are certainly at one of borders, lets decide which one:
2954 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
2955 if ( pt
.x
< client
.x
)
2956 border
|= wxHT_TOPLEVEL_BORDER_W
;
2957 else if ( pt
.x
>= client
.width
+ client
.x
)
2958 border
|= wxHT_TOPLEVEL_BORDER_E
;
2959 if ( pt
.y
< client
.y
)
2960 border
|= wxHT_TOPLEVEL_BORDER_N
;
2961 else if ( pt
.y
>= client
.height
+ client
.y
)
2962 border
|= wxHT_TOPLEVEL_BORDER_S
;
2966 return wxHT_NOWHERE
;
2969 void wxWin32Renderer
::DrawFrameTitleBar(wxDC
& dc
,
2971 const wxString
& title
,
2975 int specialButtonFlags
)
2977 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
2979 DrawFrameBorder(dc
, rect
, flags
);
2981 if ( flags
& wxTOPLEVEL_TITLEBAR
)
2983 DrawFrameBackground(dc
, rect
, flags
);
2984 if ( flags
& wxTOPLEVEL_ICON
)
2985 DrawFrameIcon(dc
, rect
, icon
, flags
);
2986 DrawFrameTitle(dc
, rect
, title
, flags
);
2988 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
2990 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
2991 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
2993 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
2995 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
2996 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
2997 specialButtonFlags
: 0);
2998 x
-= FRAME_BUTTON_WIDTH
+ 2;
3000 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3002 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
3003 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
3004 specialButtonFlags
: 0);
3005 x
-= FRAME_BUTTON_WIDTH
;
3007 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3009 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
3010 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
3011 specialButtonFlags
: 0);
3012 x
-= FRAME_BUTTON_WIDTH
;
3014 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3016 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
3017 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
3018 specialButtonFlags
: 0);
3019 x
-= FRAME_BUTTON_WIDTH
;
3021 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3023 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
3024 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
3025 specialButtonFlags
: 0);
3030 void wxWin32Renderer
::DrawFrameBorder(wxDC
& dc
,
3034 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
3038 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
3039 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
3040 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3041 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
3042 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
3045 void wxWin32Renderer
::DrawFrameBackground(wxDC
& dc
,
3049 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3051 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3052 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3053 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3055 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3056 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3058 DrawBackground(dc
, col
, r
);
3061 void wxWin32Renderer
::DrawFrameTitle(wxDC
& dc
,
3063 const wxString
& title
,
3066 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3067 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3068 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3070 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3071 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3072 if ( flags
& wxTOPLEVEL_ICON
)
3074 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3075 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3083 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3084 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3085 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3086 r
.width
-= FRAME_BUTTON_WIDTH
;
3087 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3088 r
.width
-= FRAME_BUTTON_WIDTH
;
3089 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3090 r
.width
-= FRAME_BUTTON_WIDTH
;
3091 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3092 r
.width
-= FRAME_BUTTON_WIDTH
;
3094 dc
.SetFont(m_titlebarFont
);
3095 dc
.SetTextForeground(col
);
3098 dc
.GetTextExtent(title
, &textW
, NULL
);
3099 if ( textW
> r
.width
)
3101 // text is too big, let's shorten it and add "..." after it:
3102 size_t len
= title
.length();
3103 wxCoord WSoFar
, letterW
;
3105 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3106 if ( WSoFar
> r
.width
)
3108 // not enough space to draw anything
3114 for (size_t i
= 0; i
< len
; i
++)
3116 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3117 if ( letterW
+ WSoFar
> r
.width
)
3123 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3124 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3127 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3128 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3131 void wxWin32Renderer
::DrawFrameIcon(wxDC
& dc
,
3138 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3139 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3143 void wxWin32Renderer
::DrawFrameButton(wxDC
& dc
,
3144 wxCoord x
, wxCoord y
,
3148 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3153 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3154 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3155 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3156 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3157 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3159 wxFAIL_MSG(wxT("incorrect button specification"));
3162 if ( flags
& wxCONTROL_PRESSED
)
3164 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3165 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3166 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3167 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3171 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3172 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3173 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3174 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3179 wxRect wxWin32Renderer
::GetFrameClientArea(const wxRect
& rect
,
3184 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3186 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3187 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3188 FRAME_BORDER_THICKNESS
;
3191 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3193 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3194 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3200 wxSize wxWin32Renderer
::GetFrameTotalSize(const wxSize
& clientSize
,
3203 wxSize
s(clientSize
);
3205 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3207 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3208 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3209 FRAME_BORDER_THICKNESS
;
3213 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3214 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3219 wxSize wxWin32Renderer
::GetFrameMinSize(int flags
) const
3223 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3225 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3226 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3227 FRAME_BORDER_THICKNESS
;
3232 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3234 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3236 if ( flags
& wxTOPLEVEL_ICON
)
3237 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3238 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3239 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3240 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3241 s
.x
+= FRAME_BUTTON_WIDTH
;
3242 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3243 s
.x
+= FRAME_BUTTON_WIDTH
;
3244 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3245 s
.x
+= FRAME_BUTTON_WIDTH
;
3246 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3247 s
.x
+= FRAME_BUTTON_WIDTH
;
3253 wxSize wxWin32Renderer
::GetFrameIconSize() const
3255 return wxSize(16, 16);
3259 // ----------------------------------------------------------------------------
3261 // ----------------------------------------------------------------------------
3263 /* Copyright (c) Julian Smart */
3264 static char *error_xpm
[]={
3265 /* columns rows colors chars-per-pixel */
3342 " $oooooooooooo%& ",
3343 " *=-ooooooooooooo;: ",
3344 " *oooooooooooooooooo> ",
3345 " =ooooooooooooooooooo, ",
3346 " $-ooooooooooooooooooo<1 ",
3347 " .oooooo2334ooo533oooooo6 ",
3348 " +ooooooo789oo2883oooooo0q ",
3349 " oooooooo2w83o78eoooooooor ",
3350 " toooooooooy88u884oooooooori ",
3351 " Xooooooooooe888poooooooooas ",
3352 " ooooooooooo4889doooooooooof ",
3353 " ooooooooooo588w2oooooooooofi ",
3354 " oooooooooodw8887oooooooooofi ",
3355 " goooooooooh8w588jooooooookli ",
3356 " tooooooooz885op8wdooooooorix ",
3357 " oooooood98cood98cooooooori ",
3358 " @oooooop8w2ooo5885ooooovbi ",
3359 " n%ooooooooooooooooooooomiM ",
3360 " &;oooooooooooooooooooNBiV ",
3361 " :ooooooooooooooooooCZiA ",
3362 " nSooooooooooooooooCDiF ",
3363 " nG<oooooooooooooNZiiH ",
3364 " 160ooooooooovmBiFH ",
3365 " nqrraoookrrbiiA ",
3372 /* Copyright (c) Julian Smart */
3373 static char *info_xpm
[]={
3374 /* columns rows colors chars-per-pixel */
3396 " ..XXXXXXXXXXXXX.. ",
3397 " .XXXXXXXXXXXXXXXXX. ",
3398 " .XXXXXXXXoO+XXXXXXXX. ",
3399 " .XXXXXXXXX@#OXXXXXXXXX. ",
3400 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
3401 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
3402 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
3403 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
3404 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
3405 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
3406 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
3407 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
3408 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
3409 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
3410 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
3411 " .XXXXXXXXXXXXXXXXX.%%%% ",
3412 " ..XXXXXXXXXXXXX..%%%% ",
3413 " %...XXXXXXXX..%%%%% ",
3414 " %%%..XXXXXX.%%%%% ",
3428 /* Copyright (c) Julian Smart */
3429 static char *question_xpm
[]={
3430 /* columns rows colors chars-per-pixel */
3451 " ..XXXXXXXXXXXXX.. ",
3452 " .XXXXXXoO++@XXXXXX. ",
3453 " .XXXXXXO#$$$$#%XXXXX. ",
3454 " .XXXXXX@$$#&&#$#oXXXXX. ",
3455 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
3456 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
3457 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
3458 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
3459 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
3460 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
3461 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
3462 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
3463 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
3464 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
3465 " .XXXXXXXX-$$XXXXXXXX.:::: ",
3466 " .XXXXXXXO++XXXXXXX.:::: ",
3467 " ..XXXXXXXXXXXXX..:::: ",
3468 " :...XXXXXXXX..::::: ",
3469 " :::..XXXXXX.::::: ",
3483 /* Copyright (c) Julian Smart */
3484 static char *warning_xpm
[]={
3485 /* columns rows colors chars-per-pixel */
3511 " ..XXXXO@#XXX... ",
3512 " ...XXXXO@#XXXX.. ",
3513 " ..XXXXXO@#XXXX... ",
3514 " ...XXXXXo@OXXXXX.. ",
3515 " ...XXXXXXo@OXXXXXX.. ",
3516 " ..XXXXXXX$@OXXXXXX... ",
3517 " ...XXXXXXXX@XXXXXXXX.. ",
3518 " ...XXXXXXXXXXXXXXXXXX... ",
3519 " ..XXXXXXXXXXOXXXXXXXXX.. ",
3520 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
3521 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
3522 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3523 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3524 " .............................. ",
3525 " .............................. ",
3532 wxBitmap wxWin32ArtProvider
::CreateBitmap(const wxArtID
& id
,
3533 const wxArtClient
& WXUNUSED(client
),
3534 const wxSize
& WXUNUSED(size
))
3536 if ( id
== wxART_INFORMATION
)
3537 return wxBitmap(info_xpm
);
3538 if ( id
== wxART_ERROR
)
3539 return wxBitmap(error_xpm
);
3540 if ( id
== wxART_WARNING
)
3541 return wxBitmap(warning_xpm
);
3542 if ( id
== wxART_QUESTION
)
3543 return wxBitmap(question_xpm
);
3544 return wxNullBitmap
;
3550 // ----------------------------------------------------------------------------
3551 // text control geometry
3552 // ----------------------------------------------------------------------------
3555 wxWin32Renderer
::GetTextTotalArea(const wxTextCtrl
*text
,
3556 const wxRect
& rect
) const
3558 wxRect rectTotal
= wxStdRenderer
::GetTextTotalArea(text
, rect
);
3560 // this is strange but it's what Windows does
3567 wxWin32Renderer
::GetTextClientArea(const wxTextCtrl
*text
,
3569 wxCoord
*extraSpaceBeyond
) const
3571 wxRect rectText
= rect
;
3573 // undo GetTextTotalArea()
3574 if ( rectText
.height
> 0 )
3577 return wxStdRenderer
::GetTextClientArea(text
, rect
, extraSpaceBeyond
);
3580 #endif // wxUSE_TEXTCTRL
3582 // ----------------------------------------------------------------------------
3584 // ----------------------------------------------------------------------------
3586 void wxWin32Renderer
::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3589 if ( wxDynamicCast(window
, wxScrollBar
) )
3591 // we only set the width of vert scrollbars and height of the
3593 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3594 size
->y
= m_sizeScrollbarArrow
.y
;
3596 size
->x
= m_sizeScrollbarArrow
.x
;
3598 // skip border width adjustments, they don't make sense for us
3601 #endif // wxUSE_SCROLLBAR
3604 if ( wxDynamicCast(window
, wxBitmapButton
) )
3608 #endif // wxUSE_BMPBUTTON
3609 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
3612 || wxDynamicCast(window
, wxButton
)
3613 # endif // wxUSE_BUTTON
3614 # if wxUSE_TOGGLEBTN
3615 || wxDynamicCast(window
, wxToggleButton
)
3616 # endif // wxUSE_TOGGLEBTN
3619 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3621 // TODO: don't harcode all this
3622 size
->x
+= 3*window
->GetCharWidth();
3624 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3625 if ( size
->y
< heightBtn
- 8 )
3626 size
->y
= heightBtn
;
3631 // for compatibility with other ports, the buttons default size is never
3632 // less than the standard one, but not when display not PDAs.
3633 if (wxSystemSettings
::GetScreenType() > wxSYS_SCREEN_PDA
)
3635 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3637 wxSize szDef
= wxButton
::GetDefaultSize();
3638 if ( size
->x
< szDef
.x
)
3643 // no border width adjustments for buttons
3646 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
3648 // take into account the border width
3649 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3650 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3651 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3654 // ============================================================================
3656 // ============================================================================
3658 // ----------------------------------------------------------------------------
3659 // wxWin32InputHandler
3660 // ----------------------------------------------------------------------------
3662 bool wxWin32InputHandler
::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3663 const wxKeyEvent
& WXUNUSED(event
),
3664 bool WXUNUSED(pressed
))
3669 bool wxWin32InputHandler
::HandleMouse(wxInputConsumer
*control
,
3670 const wxMouseEvent
& event
)
3672 // clicking on the control gives it focus
3673 if ( event
.ButtonDown() )
3675 wxWindow
*win
= control
->GetInputWindow();
3677 if ( (wxWindow
::FindFocus() != control
->GetInputWindow()) &&
3678 win
->AcceptsFocus() )
3691 // ----------------------------------------------------------------------------
3692 // wxWin32ScrollBarInputHandler
3693 // ----------------------------------------------------------------------------
3695 wxWin32ScrollBarInputHandler
::
3696 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
3697 : wxStdScrollBarInputHandler(renderer
, handler
)
3699 m_scrollPaused
= false;
3703 bool wxWin32ScrollBarInputHandler
::OnScrollTimer(wxScrollBar
*scrollbar
,
3704 const wxControlAction
& action
)
3706 // stop if went beyond the position of the original click (this can only
3707 // happen when we scroll by pages)
3709 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3711 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3712 != wxHT_SCROLLBAR_BAR_2
;
3714 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3716 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3717 != wxHT_SCROLLBAR_BAR_1
;
3722 StopScrolling(scrollbar
);
3724 scrollbar
->Refresh();
3729 return wxStdScrollBarInputHandler
::OnScrollTimer(scrollbar
, action
);
3732 bool wxWin32ScrollBarInputHandler
::HandleMouse(wxInputConsumer
*control
,
3733 const wxMouseEvent
& event
)
3735 // remember the current state
3736 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3738 // do process the message
3739 bool rc
= wxStdScrollBarInputHandler
::HandleMouse(control
, event
);
3741 // analyse the changes
3742 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3744 // we just started dragging the thumb, remember its initial position to
3745 // be able to restore it if the drag is cancelled later
3746 m_eventStartDrag
= event
;
3752 bool wxWin32ScrollBarInputHandler
::HandleMouseMove(wxInputConsumer
*control
,
3753 const wxMouseEvent
& event
)
3755 // we don't highlight scrollbar elements, so there is no need to process
3756 // mouse move events normally - only do it while mouse is captured (i.e.
3757 // when we're dragging the thumb or pressing on something)
3758 if ( !m_winCapture
)
3761 if ( event
.Entering() )
3763 // we're not interested in this at all
3767 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3769 if ( m_scrollPaused
)
3771 // check if the mouse returned to its original location
3773 if ( event
.Leaving() )
3779 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3780 if ( ht
== m_htLast
)
3782 // yes it did, resume scrolling
3783 m_scrollPaused
= false;
3784 if ( m_timerScroll
)
3786 // we were scrolling by line/page, restart timer
3787 m_timerScroll
->Start(m_interval
);
3789 Press(scrollbar
, true);
3791 else // we were dragging the thumb
3793 // restore its last location
3794 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3800 else // normal case, scrolling hasn't been paused
3802 // if we're scrolling the scrollbar because the arrow or the shaft was
3803 // pressed, check that the mouse stays on the same scrollbar element
3806 // Always let thumb jump back if we leave the scrollbar
3807 if ( event
.Moving() )
3809 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3811 else // event.Leaving()
3816 // Jump back only if we get far away from it
3817 wxPoint pos
= event
.GetPosition();
3818 if (scrollbar
->HasFlag( wxVERTICAL
))
3820 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
3825 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
3828 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
3831 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3832 // is still ok - we only want to catch the case when the mouse leaves
3833 // the scrollbar here
3834 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3836 ht
= wxHT_SCROLLBAR_THUMB
;
3839 if ( ht
!= m_htLast
)
3841 // what were we doing? 2 possibilities: either an arrow/shaft was
3842 // pressed in which case we have a timer and so we just stop it or
3843 // we were dragging the thumb
3844 if ( m_timerScroll
)
3847 m_interval
= m_timerScroll
->GetInterval();
3848 m_timerScroll
->Stop();
3849 m_scrollPaused
= true;
3851 // unpress the arrow
3852 Press(scrollbar
, false);
3854 else // we were dragging the thumb
3856 // remember the current thumb position to be able to restore it
3857 // if the mouse returns to it later
3858 m_eventLastDrag
= event
;
3860 // and restore the original position (before dragging) of the
3862 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3869 return wxStdInputHandler
::HandleMouseMove(control
, event
);
3872 #endif // wxUSE_SCROLLBAR
3876 // ----------------------------------------------------------------------------
3877 // wxWin32CheckboxInputHandler
3878 // ----------------------------------------------------------------------------
3880 bool wxWin32CheckboxInputHandler
::HandleKey(wxInputConsumer
*control
,
3881 const wxKeyEvent
& event
,
3886 wxControlAction action
;
3887 int keycode
= event
.GetKeyCode();
3891 action
= wxACTION_CHECKBOX_TOGGLE
;
3895 case WXK_NUMPAD_SUBTRACT
:
3896 action
= wxACTION_CHECKBOX_CHECK
;
3900 case WXK_NUMPAD_ADD
:
3901 case WXK_NUMPAD_EQUAL
:
3902 action
= wxACTION_CHECKBOX_CLEAR
;
3906 if ( !action
.IsEmpty() )
3908 control
->PerformAction(action
);
3917 #endif // wxUSE_CHECKBOX
3921 // ----------------------------------------------------------------------------
3922 // wxWin32TextCtrlInputHandler
3923 // ----------------------------------------------------------------------------
3925 bool wxWin32TextCtrlInputHandler
::HandleKey(wxInputConsumer
*control
,
3926 const wxKeyEvent
& event
,
3929 // handle only MSW-specific text bindings here, the others are handled in
3933 int keycode
= event
.GetKeyCode();
3935 wxControlAction action
;
3936 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
3938 action
= wxACTION_TEXT_CUT
;
3940 else if ( keycode
== WXK_INSERT
)
3942 if ( event
.ControlDown() )
3943 action
= wxACTION_TEXT_COPY
;
3944 else if ( event
.ShiftDown() )
3945 action
= wxACTION_TEXT_PASTE
;
3948 if ( action
!= wxACTION_NONE
)
3950 control
->PerformAction(action
);
3956 return wxStdInputHandler
::HandleKey(control
, event
, pressed
);
3959 #endif // wxUSE_TEXTCTRL
3963 // ----------------------------------------------------------------------------
3964 // wxWin32StatusBarInputHandler
3965 // ----------------------------------------------------------------------------
3967 wxWin32StatusBarInputHandler
::
3968 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
3969 : wxStdInputHandler(handler
)
3974 bool wxWin32StatusBarInputHandler
::IsOnGrip(wxWindow
*statbar
,
3975 const wxPoint
& pt
) const
3977 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
3978 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
3981 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
3983 wxCHECK_MSG( parentTLW
, false,
3984 _T("the status bar should be a child of a TLW") );
3986 // a maximized window can't be resized anyhow
3987 if ( !parentTLW
->IsMaximized() )
3989 // VZ: I think that the standard Windows behaviour is to only
3990 // show the resizing cursor when the mouse is on top of the
3991 // grip itself but apparently different Windows versions behave
3992 // differently (?) and it seems a better UI to allow resizing
3993 // the status bar even when the mouse is above the grip
3994 wxSize sizeSbar
= statbar
->GetSize();
3996 int diff
= sizeSbar
.x
- pt
.x
;
3997 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
4004 bool wxWin32StatusBarInputHandler
::HandleMouse(wxInputConsumer
*consumer
,
4005 const wxMouseEvent
& event
)
4007 if ( event
.Button(1) )
4009 if ( event
.ButtonDown(1) )
4011 wxWindow
*statbar
= consumer
->GetInputWindow();
4013 if ( IsOnGrip(statbar
, event
.GetPosition()) )
4015 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
4019 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
4020 wxHT_TOPLEVEL_BORDER_SE
);
4022 statbar
->SetCursor(m_cursorOld
);
4030 return wxStdInputHandler
::HandleMouse(consumer
, event
);
4033 bool wxWin32StatusBarInputHandler
::HandleMouseMove(wxInputConsumer
*consumer
,
4034 const wxMouseEvent
& event
)
4036 wxWindow
*statbar
= consumer
->GetInputWindow();
4038 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
4039 if ( isOnGrip
!= m_isOnGrip
)
4041 m_isOnGrip
= isOnGrip
;
4044 m_cursorOld
= statbar
->GetCursor();
4045 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4049 statbar
->SetCursor(m_cursorOld
);
4053 return wxStdInputHandler
::HandleMouseMove(consumer
, event
);
4056 #endif // wxUSE_STATUSBAR
4058 // ----------------------------------------------------------------------------
4059 // wxWin32FrameInputHandler
4060 // ----------------------------------------------------------------------------
4062 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4065 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4067 void Attach(wxInputConsumer
*consumer
);
4071 DECLARE_EVENT_TABLE()
4072 void OnSystemMenu(wxCommandEvent
&event
);
4073 void OnCloseFrame(wxCommandEvent
&event
);
4074 void OnClose(wxCloseEvent
&event
);
4076 wxWin32FrameInputHandler
*m_inputHnd
;
4077 wxTopLevelWindow
*m_wnd
;
4079 wxAcceleratorTable m_oldAccelTable
;
4083 wxWin32SystemMenuEvtHandler
::
4084 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
)
4086 m_inputHnd
= handler
;
4090 void wxWin32SystemMenuEvtHandler
::Attach(wxInputConsumer
*consumer
)
4092 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4094 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4095 m_wnd
->PushEventHandler(this);
4098 // VS: This code relies on using generic implementation of
4099 // wxAcceleratorTable in wxUniv!
4100 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4101 m_oldAccelTable
= table
;
4102 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4103 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4104 m_wnd
->SetAcceleratorTable(table
);
4108 void wxWin32SystemMenuEvtHandler
::Detach()
4113 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4115 m_wnd
->RemoveEventHandler(this);
4120 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4121 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler
::OnSystemMenu
)
4122 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler
::OnCloseFrame
)
4123 EVT_CLOSE(wxWin32SystemMenuEvtHandler
::OnClose
)
4126 void wxWin32SystemMenuEvtHandler
::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4128 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4129 !m_wnd
->IsMaximized()) ?
4130 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4131 FRAME_BORDER_THICKNESS
;
4132 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4133 pt
.x
= -pt
.x
+ border
;
4134 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4137 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4138 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4142 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4143 #endif // wxUSE_MENUS
4146 m_wnd
->SetAcceleratorTable(table
);
4150 void wxWin32SystemMenuEvtHandler
::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4152 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4153 wxTOPLEVEL_BUTTON_CLOSE
);
4156 void wxWin32SystemMenuEvtHandler
::OnClose(wxCloseEvent
&event
)
4163 wxWin32FrameInputHandler
::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4164 : wxStdInputHandler(handler
)
4166 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4169 wxWin32FrameInputHandler
::~wxWin32FrameInputHandler()
4171 if ( m_menuHandler
)
4173 m_menuHandler
->Detach();
4174 delete m_menuHandler
;
4178 bool wxWin32FrameInputHandler
::HandleMouse(wxInputConsumer
*consumer
,
4179 const wxMouseEvent
& event
)
4181 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4183 wxTopLevelWindow
*tlw
=
4184 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4186 long hit
= tlw
->HitTest(event
.GetPosition());
4188 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4190 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4191 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4192 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4195 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4197 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4198 (event
.RightDown() &&
4199 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4200 hit
== wxHT_TOPLEVEL_ICON
)) )
4203 PopupSystemMenu(tlw
, event
.GetPosition());
4204 #endif // wxUSE_MENUS
4210 return wxStdInputHandler
::HandleMouse(consumer
, event
);
4215 void wxWin32FrameInputHandler
::PopupSystemMenu(wxTopLevelWindow
*window
,
4216 const wxPoint
& pos
) const
4218 wxMenu
*menu
= new wxMenu
;
4220 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4221 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4222 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4223 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4224 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4225 if ( wxSystemSettings
::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4226 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4227 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4228 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4229 menu
->AppendSeparator();
4230 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4232 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4234 if ( window
->IsMaximized() )
4236 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4237 menu
->Enable(wxID_MOVE_FRAME
, false);
4238 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4239 menu
->Enable(wxID_RESIZE_FRAME
, false);
4242 menu
->Enable(wxID_RESTORE_FRAME
, false);
4245 window
->PopupMenu(menu
, pos
);
4249 #endif // wxUSE_MENUS
4251 bool wxWin32FrameInputHandler
::HandleActivation(wxInputConsumer
*consumer
,
4254 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4256 // always detach if active frame changed:
4257 m_menuHandler
->Detach();
4261 m_menuHandler
->Attach(consumer
);
4265 return wxStdInputHandler
::HandleActivation(consumer
, activated
);