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
101 enum wxFrameButtonType
104 FrameButton_Minimize
,
105 FrameButton_Maximize
,
112 wxWin32Renderer(const wxColourScheme
*scheme
);
114 // reimplement the renderer methods which are different for this theme
115 virtual void DrawLabel(wxDC
& dc
,
116 const wxString
& label
,
119 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
121 wxRect
*rectBounds
= NULL
);
122 virtual void DrawButtonLabel(wxDC
& dc
,
123 const wxString
& label
,
124 const wxBitmap
& image
,
127 int alignment
= wxALIGN_LEFT
| wxALIGN_TOP
,
129 wxRect
*rectBounds
= NULL
);
130 virtual void DrawButtonBorder(wxDC
& dc
,
133 wxRect
*rectIn
= NULL
);
135 virtual void DrawArrow(wxDC
& dc
,
139 virtual void DrawScrollbarThumb(wxDC
& dc
,
140 wxOrientation orient
,
143 virtual void DrawScrollbarShaft(wxDC
& dc
,
144 wxOrientation orient
,
149 virtual void DrawToolBarButton(wxDC
& dc
,
150 const wxString
& label
,
151 const wxBitmap
& bitmap
,
156 #endif // wxUSE_TOOLBAR
159 virtual void DrawTab(wxDC
& dc
,
162 const wxString
& label
,
163 const wxBitmap
& bitmap
= wxNullBitmap
,
165 int indexAccel
= -1);
166 #endif // wxUSE_NOTEBOOK
169 virtual void DrawSliderShaft(wxDC
& dc
,
172 wxOrientation orient
,
175 wxRect
*rectShaft
= NULL
);
176 virtual void DrawSliderThumb(wxDC
& dc
,
178 wxOrientation orient
,
181 virtual void DrawSliderTicks(wxDC
& dc
,
184 wxOrientation orient
,
190 #endif // wxUSE_SLIDER
193 virtual void DrawMenuBarItem(wxDC
& dc
,
195 const wxString
& label
,
197 int indexAccel
= -1);
198 virtual void DrawMenuItem(wxDC
& dc
,
200 const wxMenuGeometryInfo
& geometryInfo
,
201 const wxString
& label
,
202 const wxString
& accel
,
203 const wxBitmap
& bitmap
= wxNullBitmap
,
205 int indexAccel
= -1);
206 virtual void DrawMenuSeparator(wxDC
& dc
,
208 const wxMenuGeometryInfo
& geomInfo
);
209 #endif // wxUSE_MENUS
212 virtual void DrawStatusField(wxDC
& dc
,
214 const wxString
& label
,
215 int flags
= 0, int style
= 0);
216 #endif // wxUSE_STATUSBAR
219 virtual void DrawFrameTitleBar(wxDC
& dc
,
221 const wxString
& title
,
224 int specialButton
= 0,
225 int specialButtonFlags
= 0);
226 virtual void DrawFrameBorder(wxDC
& dc
,
229 virtual void DrawFrameBackground(wxDC
& dc
,
232 virtual void DrawFrameTitle(wxDC
& dc
,
234 const wxString
& title
,
236 virtual void DrawFrameIcon(wxDC
& dc
,
240 virtual void DrawFrameButton(wxDC
& dc
,
241 wxCoord x
, wxCoord y
,
244 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
245 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
246 virtual wxSize
GetFrameMinSize(int flags
) const;
247 virtual wxSize
GetFrameIconSize() const;
248 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
250 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
252 wxBitmap
*bmpPressed
,
253 wxBitmap
*bmpDisabled
);
255 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
256 virtual bool AreScrollbarsInsideBorder() const;
258 virtual wxSize
GetScrollbarArrowSize() const
259 { return m_sizeScrollbarArrow
; }
261 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
262 { return fontHeight
+ 2; }
263 virtual wxSize
GetCheckBitmapSize() const
264 { return wxSize(13, 13); }
265 virtual wxSize
GetRadioBitmapSize() const
266 { return wxSize(12, 12); }
267 virtual wxCoord
GetCheckItemMargin() const
270 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
271 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
272 virtual wxSize
GetToolBarMargin() const
273 { return wxSize(4, 4); }
276 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
277 const wxRect
& rect
) const;
278 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
280 wxCoord
*extraSpaceBeyond
) const;
281 #endif // wxUSE_TEXTCTRL
284 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
285 virtual wxSize
GetTabPadding() const { return wxSize(6, 5); }
286 #endif // wxUSE_NOTEBOOK
290 virtual wxCoord
GetSliderDim() const { return SLIDER_THUMB_LENGTH
+ 2*BORDER_THICKNESS
; }
291 virtual wxCoord
GetSliderTickLen() const { return SLIDER_TICK_LENGTH
; }
292 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
294 wxOrientation orient
,
295 long style
= 0) const;
296 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
298 wxOrientation orient
) const;
299 #endif // wxUSE_SLIDER
301 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
304 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
305 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
306 const wxMenu
& menu
) const;
307 #endif // wxUSE_MENUS
310 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
311 #endif // wxUSE_STATUSBAR
314 // overridden wxStdRenderer methods
315 virtual void DrawFrameWithLabel(wxDC
& dc
,
316 const wxString
& label
,
317 const wxRect
& rectFrame
,
318 const wxRect
& rectText
,
323 virtual void DrawCheckItemBitmap(wxDC
& dc
,
324 const wxBitmap
& bitmap
,
329 // draw the border used for scrollbar arrows
330 void DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
= false);
332 // public DrawArrow()s helper
333 void DrawArrow(wxDC
& dc
, const wxRect
& rect
,
334 ArrowDirection arrowDir
, ArrowStyle arrowStyle
);
336 // DrawArrowButton is used by DrawScrollbar and DrawComboButton
337 void DrawArrowButton(wxDC
& dc
, const wxRect
& rect
,
338 ArrowDirection arrowDir
,
339 ArrowStyle arrowStyle
);
341 // draw a normal or transposed line (useful for using the same code fo both
342 // horizontal and vertical widgets)
343 void DrawLine(wxDC
& dc
,
344 wxCoord x1
, wxCoord y1
,
345 wxCoord x2
, wxCoord y2
,
346 bool transpose
= false)
349 dc
.DrawLine(y1
, x1
, y2
, x2
);
351 dc
.DrawLine(x1
, y1
, x2
, y2
);
354 // get the standard check/radio button bitmap
355 wxBitmap
GetIndicator(IndicatorType indType
, int flags
);
356 virtual wxBitmap
GetCheckBitmap(int flags
)
357 { return GetIndicator(IndicatorType_Check
, flags
); }
358 virtual wxBitmap
GetRadioBitmap(int flags
)
359 { return GetIndicator(IndicatorType_Radio
, flags
); }
362 // the sizing parameters (TODO make them changeable)
363 wxSize m_sizeScrollbarArrow
;
365 wxFont m_titlebarFont
;
367 // the checked and unchecked bitmaps for DrawCheckItemBitmap()
368 wxBitmap m_bmpCheckBitmaps
[IndicatorStatus_Max
];
370 // the bitmaps returned by GetIndicator()
371 wxBitmap m_bmpIndicators
[IndicatorType_Max
]
372 [IndicatorState_MaxMenu
]
373 [IndicatorStatus_Max
];
375 // standard defaults for m_bmpCheckBitmaps and m_bmpIndicators
376 static const char **ms_xpmChecked
[IndicatorStatus_Max
];
377 static const char **ms_xpmIndicators
[IndicatorType_Max
]
378 [IndicatorState_MaxMenu
]
379 [IndicatorStatus_Max
];
382 wxBitmap m_bmpFrameButtons
[FrameButton_Max
];
384 // first row is for the normal state, second - for the disabled
385 wxBitmap m_bmpArrows
[Arrow_StateMax
][Arrow_Max
];
388 // ----------------------------------------------------------------------------
389 // wxWin32InputHandler and derived classes: process the keyboard and mouse
390 // messages according to Windows standards
391 // ----------------------------------------------------------------------------
393 class wxWin32InputHandler
: public wxInputHandler
396 wxWin32InputHandler() { }
398 virtual bool HandleKey(wxInputConsumer
*control
,
399 const wxKeyEvent
& event
,
401 virtual bool HandleMouse(wxInputConsumer
*control
,
402 const wxMouseEvent
& event
);
406 class wxWin32ScrollBarInputHandler
: public wxStdScrollBarInputHandler
409 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
,
410 wxInputHandler
*handler
);
412 virtual bool HandleMouse(wxInputConsumer
*control
,
413 const wxMouseEvent
& event
);
414 virtual bool HandleMouseMove(wxInputConsumer
*control
,
415 const wxMouseEvent
& event
);
417 virtual bool OnScrollTimer(wxScrollBar
*scrollbar
,
418 const wxControlAction
& action
);
421 virtual void Highlight(wxScrollBar
* WXUNUSED(scrollbar
),
424 // we don't highlight anything
427 // the first and last event which caused the thumb to move
428 wxMouseEvent m_eventStartDrag
,
431 // have we paused the scrolling because the mouse moved?
434 // we remember the interval of the timer to be able to restart it
437 #endif // wxUSE_SCROLLBAR
440 class wxWin32CheckboxInputHandler
: public wxStdInputHandler
443 wxWin32CheckboxInputHandler(wxInputHandler
*handler
)
444 : wxStdInputHandler(handler
) { }
446 virtual bool HandleKey(wxInputConsumer
*control
,
447 const wxKeyEvent
& event
,
450 #endif // wxUSE_CHECKBOX
453 class wxWin32TextCtrlInputHandler
: public wxStdInputHandler
456 wxWin32TextCtrlInputHandler(wxInputHandler
*handler
)
457 : wxStdInputHandler(handler
) { }
459 virtual bool HandleKey(wxInputConsumer
*control
,
460 const wxKeyEvent
& event
,
463 #endif // wxUSE_TEXTCTRL
465 class wxWin32StatusBarInputHandler
: public wxStdInputHandler
468 wxWin32StatusBarInputHandler(wxInputHandler
*handler
);
470 virtual bool HandleMouse(wxInputConsumer
*consumer
,
471 const wxMouseEvent
& event
);
473 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
474 const wxMouseEvent
& event
);
477 // is the given point over the statusbar grip?
478 bool IsOnGrip(wxWindow
*statbar
, const wxPoint
& pt
) const;
481 // the cursor we had replaced with the resize one
482 wxCursor m_cursorOld
;
484 // was the mouse over the grip last time we checked?
488 class wxWin32SystemMenuEvtHandler
;
490 class wxWin32FrameInputHandler
: public wxStdInputHandler
493 wxWin32FrameInputHandler(wxInputHandler
*handler
);
494 virtual ~wxWin32FrameInputHandler();
496 virtual bool HandleMouse(wxInputConsumer
*control
,
497 const wxMouseEvent
& event
);
499 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
502 void PopupSystemMenu(wxTopLevelWindow
*window
, const wxPoint
& pos
) const;
503 #endif // wxUSE_MENUS
506 // was the mouse over the grip last time we checked?
507 wxWin32SystemMenuEvtHandler
*m_menuHandler
;
510 // ----------------------------------------------------------------------------
511 // wxWin32ColourScheme: uses (default) Win32 colours
512 // ----------------------------------------------------------------------------
514 class wxWin32ColourScheme
: public wxColourScheme
517 virtual wxColour
Get(StdColour col
) const;
518 virtual wxColour
GetBackground(wxWindow
*win
) const;
521 // ----------------------------------------------------------------------------
522 // wxWin32ArtProvider
523 // ----------------------------------------------------------------------------
525 class wxWin32ArtProvider
: public wxArtProvider
528 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
529 const wxArtClient
& client
,
533 // ----------------------------------------------------------------------------
535 // ----------------------------------------------------------------------------
537 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
539 class wxWin32Theme
: public wxTheme
543 virtual ~wxWin32Theme();
545 virtual wxRenderer
*GetRenderer();
546 virtual wxArtProvider
*GetArtProvider();
547 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
548 wxInputConsumer
*consumer
);
549 virtual wxColourScheme
*GetColourScheme();
552 wxWin32Renderer
*m_renderer
;
554 wxWin32ArtProvider
*m_artProvider
;
556 // the names of the already created handlers and the handlers themselves
557 // (these arrays are synchronized)
558 wxSortedArrayString m_handlerNames
;
559 wxArrayHandlers m_handlers
;
561 wxWin32ColourScheme
*m_scheme
;
563 WX_DECLARE_THEME(win32
)
566 // ----------------------------------------------------------------------------
568 // ----------------------------------------------------------------------------
570 // frame buttons bitmaps
572 static const char *frame_button_close_xpm
[] = {
587 static const char *frame_button_help_xpm
[] = {
602 static const char *frame_button_maximize_xpm
[] = {
617 static const char *frame_button_minimize_xpm
[] = {
632 static const char *frame_button_restore_xpm
[] = {
649 static const char *checked_menu_xpm
[] = {
650 /* columns rows colors chars-per-pixel */
666 static const char *selected_checked_menu_xpm
[] = {
667 /* columns rows colors chars-per-pixel */
683 static const char *disabled_checked_menu_xpm
[] = {
684 /* columns rows colors chars-per-pixel */
701 static const char *selected_disabled_checked_menu_xpm
[] = {
702 /* columns rows colors chars-per-pixel */
718 // checkbox and radiobox bitmaps below
720 static const char *checked_xpm
[] = {
721 /* columns rows colors chars-per-pixel */
744 static const char *pressed_checked_xpm
[] = {
745 /* columns rows colors chars-per-pixel */
767 static const char *pressed_disabled_checked_xpm
[] = {
768 /* columns rows colors chars-per-pixel */
790 static const char *checked_item_xpm
[] = {
791 /* columns rows colors chars-per-pixel */
812 static const char *unchecked_xpm
[] = {
813 /* columns rows colors chars-per-pixel */
836 static const char *pressed_unchecked_xpm
[] = {
837 /* columns rows colors chars-per-pixel */
859 static const char *unchecked_item_xpm
[] = {
860 /* columns rows colors chars-per-pixel */
880 static const char *undetermined_xpm
[] = {
881 /* columns rows colors chars-per-pixel */
904 static const char *pressed_undetermined_xpm
[] = {
905 /* columns rows colors chars-per-pixel */
928 static const char *checked_radio_xpm
[] = {
929 /* columns rows colors chars-per-pixel */
952 static const char *pressed_checked_radio_xpm
[] = {
953 /* columns rows colors chars-per-pixel */
976 static const char *pressed_disabled_checked_radio_xpm
[] = {
977 /* columns rows colors chars-per-pixel */
1000 static const char *unchecked_radio_xpm
[] = {
1001 /* columns rows colors chars-per-pixel */
1024 static const char *pressed_unchecked_radio_xpm
[] = {
1025 /* columns rows colors chars-per-pixel */
1048 const char **wxWin32Renderer::ms_xpmIndicators
[IndicatorType_Max
]
1049 [IndicatorState_MaxMenu
]
1050 [IndicatorStatus_Max
] =
1055 { checked_xpm
, unchecked_xpm
, undetermined_xpm
},
1058 { pressed_checked_xpm
, pressed_unchecked_xpm
, pressed_undetermined_xpm
},
1061 { pressed_disabled_checked_xpm
, pressed_unchecked_xpm
, pressed_disabled_checked_xpm
},
1067 { checked_radio_xpm
, unchecked_radio_xpm
, NULL
},
1070 { pressed_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1073 { pressed_disabled_checked_radio_xpm
, pressed_unchecked_radio_xpm
, NULL
},
1079 { checked_menu_xpm
, NULL
, NULL
},
1082 { selected_checked_menu_xpm
, NULL
, NULL
},
1085 { disabled_checked_menu_xpm
, NULL
, NULL
},
1087 // disabled selected state
1088 { selected_disabled_checked_menu_xpm
, NULL
, NULL
},
1092 const char **wxWin32Renderer::ms_xpmChecked
[IndicatorStatus_Max
] =
1098 // ============================================================================
1100 // ============================================================================
1102 WX_IMPLEMENT_THEME(wxWin32Theme
, win32
, wxTRANSLATE("Win32 theme"));
1104 // ----------------------------------------------------------------------------
1106 // ----------------------------------------------------------------------------
1108 wxWin32Theme::wxWin32Theme()
1112 m_artProvider
= NULL
;
1115 wxWin32Theme::~wxWin32Theme()
1119 wxArtProvider::RemoveProvider(m_artProvider
);
1122 wxRenderer
*wxWin32Theme::GetRenderer()
1126 m_renderer
= new wxWin32Renderer(GetColourScheme());
1132 wxArtProvider
*wxWin32Theme::GetArtProvider()
1134 if ( !m_artProvider
)
1136 m_artProvider
= new wxWin32ArtProvider
;
1139 return m_artProvider
;
1143 wxWin32Theme::GetInputHandler(const wxString
& control
,
1144 wxInputConsumer
*consumer
)
1146 wxInputHandler
*handler
= NULL
;
1147 int n
= m_handlerNames
.Index(control
);
1148 if ( n
== wxNOT_FOUND
)
1150 static wxWin32InputHandler s_handlerDef
;
1152 wxInputHandler
* const
1153 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
1155 // create a new handler
1156 if ( control
== wxINP_HANDLER_TOPLEVEL
)
1158 static wxWin32FrameInputHandler
s_handler(handlerStd
);
1160 handler
= &s_handler
;
1163 else if ( control
== wxINP_HANDLER_CHECKBOX
)
1165 static wxWin32CheckboxInputHandler
s_handler(handlerStd
);
1167 handler
= &s_handler
;
1169 #endif // wxUSE_CHECKBOX
1171 else if ( control
== wxINP_HANDLER_SCROLLBAR
)
1173 static wxWin32ScrollBarInputHandler
1174 s_handler(GetRenderer(), handlerStd
);
1176 handler
= &s_handler
;
1178 #endif // wxUSE_SCROLLBAR
1180 else if ( control
== wxINP_HANDLER_STATUSBAR
)
1182 static wxWin32StatusBarInputHandler
s_handler(handlerStd
);
1184 handler
= &s_handler
;
1186 #endif // wxUSE_STATUSBAR
1188 else if ( control
== wxINP_HANDLER_TEXTCTRL
)
1190 static wxWin32TextCtrlInputHandler
s_handler(handlerStd
);
1192 handler
= &s_handler
;
1194 #endif // wxUSE_TEXTCTRL
1195 else // no special handler for this control
1197 handler
= handlerStd
;
1200 n
= m_handlerNames
.Add(control
);
1201 m_handlers
.Insert(handler
, n
);
1203 else // we already have it
1205 handler
= m_handlers
[n
];
1211 wxColourScheme
*wxWin32Theme::GetColourScheme()
1215 m_scheme
= new wxWin32ColourScheme
;
1220 // ============================================================================
1221 // wxWin32ColourScheme
1222 // ============================================================================
1224 wxColour
wxWin32ColourScheme::GetBackground(wxWindow
*win
) const
1227 if ( win
->UseBgCol() )
1229 // use the user specified colour
1230 col
= win
->GetBackgroundColour();
1233 if ( !win
->ShouldInheritColours() )
1236 wxTextCtrl
*text
= wxDynamicCast(win
, wxTextCtrl
);
1237 #endif // wxUSE_TEXTCTRL
1239 wxListBox
* listBox
= wxDynamicCast(win
, wxListBox
);
1240 #endif // wxUSE_LISTBOX
1249 if ( !win
->IsEnabled() ) // not IsEditable()
1255 // doesn't depend on the state
1260 #endif // wxUSE_TEXTCTRL
1263 col
= Get(CONTROL
); // Most controls should be this colour, not WINDOW
1267 int flags
= win
->GetStateFlags();
1269 // the colour set by the user should be used for the normal state
1270 // and for the states for which we don't have any specific colours
1271 if ( !col
.Ok() || (flags
& wxCONTROL_PRESSED
) != 0 )
1274 if ( wxDynamicCast(win
, wxScrollBar
) )
1275 col
= Get(flags
& wxCONTROL_PRESSED
? SCROLLBAR_PRESSED
1278 #endif // wxUSE_SCROLLBAR
1286 wxColour
wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col
) const
1290 // use the system colours under Windows
1291 #if defined(__WXMSW__)
1292 case WINDOW
: return wxColour(GetSysColor(COLOR_WINDOW
));
1294 case CONTROL_PRESSED
:
1295 case CONTROL_CURRENT
:
1296 case CONTROL
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1298 case CONTROL_TEXT
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1300 #if defined(COLOR_3DLIGHT)
1301 case SCROLLBAR
: return wxColour(GetSysColor(COLOR_3DLIGHT
));
1303 case SCROLLBAR
: return wxColour(0xe0e0e0);
1305 case SCROLLBAR_PRESSED
: return wxColour(GetSysColor(COLOR_BTNTEXT
));
1307 case HIGHLIGHT
: return wxColour(GetSysColor(COLOR_HIGHLIGHT
));
1308 case HIGHLIGHT_TEXT
: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT
));
1310 #if defined(COLOR_3DDKSHADOW)
1311 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DDKSHADOW
));
1313 case SHADOW_DARK
: return wxColour(GetSysColor(COLOR_3DHADOW
));
1316 case CONTROL_TEXT_DISABLED
:
1317 case SHADOW_HIGHLIGHT
: return wxColour(GetSysColor(COLOR_BTNHIGHLIGHT
));
1319 case SHADOW_IN
: return wxColour(GetSysColor(COLOR_BTNFACE
));
1321 case CONTROL_TEXT_DISABLED_SHADOW
:
1322 case SHADOW_OUT
: return wxColour(GetSysColor(COLOR_BTNSHADOW
));
1324 case TITLEBAR
: return wxColour(GetSysColor(COLOR_INACTIVECAPTION
));
1325 case TITLEBAR_ACTIVE
: return wxColour(GetSysColor(COLOR_ACTIVECAPTION
));
1326 case TITLEBAR_TEXT
: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT
));
1327 case TITLEBAR_ACTIVE_TEXT
: return wxColour(GetSysColor(COLOR_CAPTIONTEXT
));
1329 case DESKTOP
: return wxColour(0x808000);
1331 // use the standard Windows colours elsewhere
1332 case WINDOW
: return *wxWHITE
;
1334 case CONTROL_PRESSED
:
1335 case CONTROL_CURRENT
:
1336 case CONTROL
: return wxColour(0xc0c0c0);
1338 case CONTROL_TEXT
: return *wxBLACK
;
1340 case SCROLLBAR
: return wxColour(0xe0e0e0);
1341 case SCROLLBAR_PRESSED
: return *wxBLACK
;
1343 case HIGHLIGHT
: return wxColour(0x800000);
1344 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
1346 case SHADOW_DARK
: return *wxBLACK
;
1348 case CONTROL_TEXT_DISABLED
:return wxColour(0xe0e0e0);
1349 case SHADOW_HIGHLIGHT
: return wxColour(0xffffff);
1351 case SHADOW_IN
: return wxColour(0xc0c0c0);
1353 case CONTROL_TEXT_DISABLED_SHADOW
:
1354 case SHADOW_OUT
: return wxColour(0x7f7f7f);
1356 case TITLEBAR
: return wxColour(0xaeaaae);
1357 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
1358 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
1359 case TITLEBAR_ACTIVE_TEXT
:return *wxWHITE
;
1361 case DESKTOP
: return wxColour(0x808000);
1364 case GAUGE
: return Get(HIGHLIGHT
);
1368 wxFAIL_MSG(_T("invalid standard colour"));
1373 // ============================================================================
1375 // ============================================================================
1377 // ----------------------------------------------------------------------------
1379 // ----------------------------------------------------------------------------
1381 wxWin32Renderer::wxWin32Renderer(const wxColourScheme
*scheme
)
1382 : wxStdRenderer(scheme
)
1385 m_sizeScrollbarArrow
= wxSize(16, 16);
1387 m_titlebarFont
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
1388 m_titlebarFont
.SetWeight(wxFONTWEIGHT_BOLD
);
1390 // init the arrow bitmaps
1391 static const size_t ARROW_WIDTH
= 7;
1392 static const size_t ARROW_LENGTH
= 4;
1395 wxMemoryDC dcNormal
,
1398 for ( size_t n
= 0; n
< Arrow_Max
; n
++ )
1400 bool isVertical
= n
> Arrow_Right
;
1413 // disabled arrow is larger because of the shadow
1414 m_bmpArrows
[Arrow_Normal
][n
].Create(w
, h
);
1415 m_bmpArrows
[Arrow_Disabled
][n
].Create(w
+ 1, h
+ 1);
1417 dcNormal
.SelectObject(m_bmpArrows
[Arrow_Normal
][n
]);
1418 dcDisabled
.SelectObject(m_bmpArrows
[Arrow_Disabled
][n
]);
1420 dcNormal
.SetBackground(*wxWHITE_BRUSH
);
1421 dcDisabled
.SetBackground(*wxWHITE_BRUSH
);
1425 dcNormal
.SetPen(m_penBlack
);
1426 dcDisabled
.SetPen(m_penDarkGrey
);
1428 // calculate the position of the point of the arrow
1432 x1
= (ARROW_WIDTH
- 1)/2;
1433 y1
= n
== Arrow_Up
? 0 : ARROW_LENGTH
- 1;
1437 x1
= n
== Arrow_Left
? 0 : ARROW_LENGTH
- 1;
1438 y1
= (ARROW_WIDTH
- 1)/2;
1449 for ( size_t i
= 0; i
< ARROW_LENGTH
; i
++ )
1451 dcNormal
.DrawLine(x1
, y1
, x2
, y2
);
1452 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1459 if ( n
== Arrow_Up
)
1470 else // left or right arrow
1475 if ( n
== Arrow_Left
)
1488 // draw the shadow for the disabled one
1489 dcDisabled
.SetPen(m_penHighlight
);
1494 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1498 x1
= ARROW_LENGTH
- 1;
1499 y1
= (ARROW_WIDTH
- 1)/2 + 1;
1502 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1503 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1508 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1512 x1
= ARROW_WIDTH
- 1;
1514 x2
= (ARROW_WIDTH
- 1)/2;
1516 dcDisabled
.DrawLine(x1
, y1
, x2
, y2
);
1517 dcDisabled
.DrawLine(++x1
, y1
, x2
, ++y2
);
1522 // create the inverted bitmap but only for the right arrow as we only
1523 // use it for the menus
1524 if ( n
== Arrow_Right
)
1526 m_bmpArrows
[Arrow_Inverted
][n
].Create(w
, h
);
1527 dcInverse
.SelectObject(m_bmpArrows
[Arrow_Inverted
][n
]);
1529 dcInverse
.Blit(0, 0, w
, h
,
1532 dcInverse
.SelectObject(wxNullBitmap
);
1534 mask
= new wxMask(m_bmpArrows
[Arrow_Inverted
][n
], *wxBLACK
);
1535 m_bmpArrows
[Arrow_Inverted
][n
].SetMask(mask
);
1537 m_bmpArrows
[Arrow_InvertedDisabled
][n
].Create(w
, h
);
1538 dcInverse
.SelectObject(m_bmpArrows
[Arrow_InvertedDisabled
][n
]);
1540 dcInverse
.Blit(0, 0, w
, h
,
1543 dcInverse
.SelectObject(wxNullBitmap
);
1545 mask
= new wxMask(m_bmpArrows
[Arrow_InvertedDisabled
][n
], *wxBLACK
);
1546 m_bmpArrows
[Arrow_InvertedDisabled
][n
].SetMask(mask
);
1549 dcNormal
.SelectObject(wxNullBitmap
);
1550 dcDisabled
.SelectObject(wxNullBitmap
);
1552 mask
= new wxMask(m_bmpArrows
[Arrow_Normal
][n
], *wxWHITE
);
1553 m_bmpArrows
[Arrow_Normal
][n
].SetMask(mask
);
1554 mask
= new wxMask(m_bmpArrows
[Arrow_Disabled
][n
], *wxWHITE
);
1555 m_bmpArrows
[Arrow_Disabled
][n
].SetMask(mask
);
1557 m_bmpArrows
[Arrow_Pressed
][n
] = m_bmpArrows
[Arrow_Normal
][n
];
1560 // init the frame buttons bitmaps
1561 m_bmpFrameButtons
[FrameButton_Close
] = wxBitmap(frame_button_close_xpm
);
1562 m_bmpFrameButtons
[FrameButton_Minimize
] = wxBitmap(frame_button_minimize_xpm
);
1563 m_bmpFrameButtons
[FrameButton_Maximize
] = wxBitmap(frame_button_maximize_xpm
);
1564 m_bmpFrameButtons
[FrameButton_Restore
] = wxBitmap(frame_button_restore_xpm
);
1565 m_bmpFrameButtons
[FrameButton_Help
] = wxBitmap(frame_button_help_xpm
);
1568 bool wxWin32Renderer::AreScrollbarsInsideBorder() const
1573 // ----------------------------------------------------------------------------
1575 // ----------------------------------------------------------------------------
1577 void wxWin32Renderer::DrawLabel(wxDC
& dc
,
1578 const wxString
& label
,
1585 // the underscores are not drawn for focused controls in wxMSW
1586 if ( flags
& wxCONTROL_FOCUSED
)
1591 if ( flags
& wxCONTROL_DISABLED
)
1593 // the combination of wxCONTROL_SELECTED and wxCONTROL_DISABLED
1594 // currently only can happen for a menu item and it seems that Windows
1595 // doesn't draw the shadow in this case, so we don't do it neither
1596 if ( flags
& wxCONTROL_SELECTED
)
1598 // just make the label text greyed out
1599 dc
.SetTextForeground(m_penDarkGrey
.GetColour());
1601 flags
&= ~wxCONTROL_DISABLED
;
1605 wxStdRenderer::DrawLabel(dc
, label
, rect
, flags
, alignment
,
1606 indexAccel
, rectBounds
);
1609 void wxWin32Renderer::DrawFrameWithLabel(wxDC
& dc
,
1610 const wxString
& label
,
1611 const wxRect
& rectFrame
,
1612 const wxRect
& rectText
,
1618 label2
<< _T(' ') << label
<< _T(' ');
1619 if ( indexAccel
!= -1 )
1621 // adjust it as we prepended a space
1625 wxStdRenderer::DrawFrameWithLabel(dc
, label2
, rectFrame
, rectText
,
1626 flags
, alignment
, indexAccel
);
1629 void wxWin32Renderer::DrawButtonLabel(wxDC
& dc
,
1630 const wxString
& label
,
1631 const wxBitmap
& image
,
1638 // the underscores are not drawn for focused controls in wxMSW
1639 if ( flags
& wxCONTROL_PRESSED
)
1644 wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
, alignment
,
1645 indexAccel
, rectBounds
);
1648 void wxWin32Renderer::DrawButtonBorder(wxDC
& dc
,
1649 const wxRect
& rectTotal
,
1653 wxRect rect
= rectTotal
;
1655 wxPen
penOut(*wxBLACK
);
1656 if ( flags
& wxCONTROL_PRESSED
)
1658 // button pressed: draw a double border around it
1659 DrawRect(dc
, &rect
, penOut
);
1660 DrawRect(dc
, &rect
, m_penDarkGrey
);
1662 else // button not pressed
1664 if ( flags
& (wxCONTROL_FOCUSED
| wxCONTROL_ISDEFAULT
) )
1666 // button either default or focused (or both): add an extra border
1668 DrawRect(dc
, &rect
, penOut
);
1671 // now draw a normal button border
1672 DrawRaisedBorder(dc
, &rect
);
1679 // ----------------------------------------------------------------------------
1680 // (check)listbox items
1681 // ----------------------------------------------------------------------------
1683 void wxWin32Renderer::DrawCheckItemBitmap(wxDC
& dc
,
1684 const wxBitmap
& bitmap
,
1693 else // use default bitmap
1695 IndicatorStatus i
= flags
& wxCONTROL_CHECKED
1696 ? IndicatorStatus_Checked
1697 : IndicatorStatus_Unchecked
;
1699 if ( !m_bmpCheckBitmaps
[i
].Ok() )
1701 m_bmpCheckBitmaps
[i
] = wxBitmap(ms_xpmChecked
[i
]);
1704 bmp
= m_bmpCheckBitmaps
[i
];
1707 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2 - 1,
1708 true /* use mask */);
1711 // ----------------------------------------------------------------------------
1712 // check/radio buttons
1713 // ----------------------------------------------------------------------------
1715 wxBitmap
wxWin32Renderer::GetIndicator(IndicatorType indType
, int flags
)
1717 IndicatorState indState
;
1718 IndicatorStatus indStatus
;
1719 GetIndicatorsFromFlags(flags
, indState
, indStatus
);
1721 wxBitmap
& bmp
= m_bmpIndicators
[indType
][indState
][indStatus
];
1724 const char **xpm
= ms_xpmIndicators
[indType
][indState
][indStatus
];
1727 // create and cache it
1728 bmp
= wxBitmap(xpm
);
1735 // ----------------------------------------------------------------------------
1737 // ----------------------------------------------------------------------------
1740 void wxWin32Renderer::DrawToolBarButton(wxDC
& dc
,
1741 const wxString
& label
,
1742 const wxBitmap
& bitmap
,
1743 const wxRect
& rectOrig
,
1748 if (style
== wxTOOL_STYLE_BUTTON
)
1750 wxRect rect
= rectOrig
;
1751 rect
.Deflate(BORDER_THICKNESS
);
1753 if ( flags
& wxCONTROL_PRESSED
)
1755 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
);
1757 else if ( flags
& wxCONTROL_CURRENT
)
1759 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
);
1762 if(tbarStyle
& wxTB_TEXT
)
1764 if(tbarStyle
& wxTB_HORIZONTAL
)
1766 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1770 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1775 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1776 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1777 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1780 else if (style
== wxTOOL_STYLE_SEPARATOR
)
1782 // leave a small gap aroudn the line, also account for the toolbar
1784 if(rectOrig
.height
> rectOrig
.width
)
1787 DrawVerticalLine(dc
, rectOrig
.x
+ rectOrig
.width
/2,
1788 rectOrig
.y
+ 2*BORDER_THICKNESS
,
1789 rectOrig
.GetBottom() - BORDER_THICKNESS
);
1794 DrawHorizontalLine(dc
, rectOrig
.y
+ rectOrig
.height
/2,
1795 rectOrig
.x
+ 2*BORDER_THICKNESS
,
1796 rectOrig
.GetRight() - BORDER_THICKNESS
);
1799 // don't draw wxTOOL_STYLE_CONTROL
1801 #endif // wxUSE_TOOLBAR
1803 // ----------------------------------------------------------------------------
1805 // ----------------------------------------------------------------------------
1809 void wxWin32Renderer::DrawTab(wxDC
& dc
,
1810 const wxRect
& rectOrig
,
1812 const wxString
& label
,
1813 const wxBitmap
& bitmap
,
1817 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1818 #define REVERSE_FOR_VERTICAL(X,Y) \
1819 SELECT_FOR_VERTICAL(X,Y) \
1821 SELECT_FOR_VERTICAL(Y,X)
1823 wxRect rect
= rectOrig
;
1825 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1827 // the current tab is drawn indented (to the top for default case) and
1828 // bigger than the other ones
1829 const wxSize indent
= GetTabIndent();
1830 if ( flags
& wxCONTROL_SELECTED
)
1832 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1833 SELECT_FOR_VERTICAL( 0, indent
.y
));
1837 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1844 rect
.height
+= indent
.y
;
1851 rect
.width
+= indent
.x
;
1856 // draw the text, image and the focus around them (if necessary)
1857 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1858 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1860 rectLabel
.Deflate(1, 1);
1863 // draw it horizontally into memory and rotate for screen
1865 wxBitmap bitmapRotated
,
1866 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1867 rectLabel
.y
+ rectLabel
.height
);
1868 dcMem
.SelectObject(bitmapMem
);
1869 dcMem
.SetBackground(dc
.GetBackground());
1870 dcMem
.SetFont(dc
.GetFont());
1871 dcMem
.SetTextForeground(dc
.GetTextForeground());
1875 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1878 #endif // wxUSE_IMAGE
1880 DrawButtonLabel(dcMem
, label
, bitmapRotated
, rectLabel
,
1881 flags
, wxALIGN_CENTRE
, indexAccel
);
1882 dcMem
.SelectObject(wxNullBitmap
);
1883 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1885 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
));
1886 #endif // wxUSE_IMAGE
1887 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1891 DrawButtonLabel(dc
, label
, bitmap
, rectLabel
,
1892 flags
, wxALIGN_CENTRE
, indexAccel
);
1895 // now draw the tab border itself (maybe use DrawRoundedRectangle()?)
1896 static const wxCoord CUTOFF
= 2; // radius of the rounded corner
1897 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1898 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1899 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1900 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1902 // FIXME: all this code will break if the tab indent or the border width,
1903 // it is tied to the fact that both of them are equal to 2
1909 // left orientation looks like top but IsVertical makes x and y reversed
1911 // top is not vertical so use coordinates in written order
1912 dc
.SetPen(m_penHighlight
);
1913 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1914 REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
));
1915 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
+ CUTOFF
),
1916 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
));
1917 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y
),
1918 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y
));
1920 dc
.SetPen(m_penBlack
);
1921 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1922 REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
));
1923 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
+ CUTOFF
),
1924 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y
));
1926 dc
.SetPen(m_penDarkGrey
);
1927 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1928 REVERSE_FOR_VERTICAL(x2
- 1, y
+ CUTOFF
- 1));
1930 if ( flags
& wxCONTROL_SELECTED
)
1932 dc
.SetPen(m_penLightGrey
);
1934 // overwrite the part of the border below this tab
1935 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1936 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1938 // and the shadow of the tab to the left of us
1939 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ CUTOFF
+ 1),
1940 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1945 // right orientation looks like bottom but IsVertical makes x and y reversed
1947 // bottom is not vertical so use coordinates in written order
1948 dc
.SetPen(m_penHighlight
);
1949 // we need to continue one pixel further to overwrite the corner of
1950 // the border for the selected tab
1951 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1952 REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
));
1953 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
- CUTOFF
),
1954 REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
));
1956 dc
.SetPen(m_penBlack
);
1957 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
),
1958 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
));
1959 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1960 REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
));
1961 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
- CUTOFF
),
1962 REVERSE_FOR_VERTICAL(x2
- CUTOFF
, y2
));
1964 dc
.SetPen(m_penDarkGrey
);
1965 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ CUTOFF
, y2
- 1),
1966 REVERSE_FOR_VERTICAL(x2
- CUTOFF
+ 1, y2
- 1));
1967 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1968 REVERSE_FOR_VERTICAL(x2
- 1, y2
- CUTOFF
+ 1));
1970 if ( flags
& wxCONTROL_SELECTED
)
1972 dc
.SetPen(m_penLightGrey
);
1974 // overwrite the part of the (double!) border above this tab
1975 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1976 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1977 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1978 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1980 // and the shadow of the tab to the left of us
1981 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- CUTOFF
),
1982 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1987 #undef SELECT_FOR_VERTICAL
1988 #undef REVERSE_FOR_VERTICAL
1991 #endif // wxUSE_NOTEBOOK
1995 // ----------------------------------------------------------------------------
1997 // ----------------------------------------------------------------------------
2000 wxWin32Renderer::GetSliderThumbSize(const wxRect
& WXUNUSED(rect
),
2002 wxOrientation orient
) const
2005 wxCoord width
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
) / 2;
2006 wxCoord height
= wxMax (lenThumb
, SLIDER_THUMB_LENGTH
);
2008 if (orient
== wxHORIZONTAL
)
2022 wxRect
wxWin32Renderer::GetSliderShaftRect(const wxRect
& rectOrig
,
2024 wxOrientation orient
,
2027 bool transpose
= (orient
== wxVERTICAL
);
2028 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2029 (((style
& wxSL_TOP
) != 0) & !transpose
|
2030 ((style
& wxSL_LEFT
) != 0) & transpose
|
2031 ((style
& wxSL_BOTH
) != 0));
2032 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2033 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2034 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2035 ((style
& wxSL_BOTH
) != 0));
2037 wxRect rect
= rectOrig
;
2039 wxSize sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2041 if (orient
== wxHORIZONTAL
) {
2042 rect
.x
+= SLIDER_MARGIN
;
2045 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.y
/2);
2049 rect
.y
+= wxMax ((rect
.height
- 2*BORDER_THICKNESS
- sizeThumb
.y
/2), sizeThumb
.y
/2);
2053 rect
.y
+= sizeThumb
.y
/2;
2055 rect
.width
-= 2*SLIDER_MARGIN
;
2056 rect
.height
= 2*BORDER_THICKNESS
;
2060 rect
.y
+= SLIDER_MARGIN
;
2063 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
) / 2, sizeThumb
.x
/2);
2067 rect
.x
+= wxMax ((rect
.width
- 2*BORDER_THICKNESS
- sizeThumb
.x
/2), sizeThumb
.x
/2);
2071 rect
.x
+= sizeThumb
.x
/2;
2073 rect
.width
= 2*BORDER_THICKNESS
;
2074 rect
.height
-= 2*SLIDER_MARGIN
;
2080 void wxWin32Renderer::DrawSliderShaft(wxDC
& dc
,
2081 const wxRect
& rectOrig
,
2083 wxOrientation orient
,
2088 /* show shaft geometry
2106 if (flags
& wxCONTROL_FOCUSED
) {
2107 DrawFocusRect(dc
, rectOrig
);
2110 wxRect rect
= GetSliderShaftRect(rectOrig
, lenThumb
, orient
, style
);
2112 if (rectShaft
) *rectShaft
= rect
;
2114 DrawSunkenBorder(dc
, &rect
);
2117 void wxWin32Renderer::DrawSliderThumb(wxDC
& dc
,
2119 wxOrientation orient
,
2123 /* show thumb geometry
2132 H D B where H is highlight colour
2146 The interior of this shape is filled with the hatched brush if the thumb
2150 DrawBackground(dc
, wxNullColour
, rect
, flags
);
2152 bool transpose
= (orient
== wxVERTICAL
);
2153 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2154 (((style
& wxSL_TOP
) != 0) & !transpose
|
2155 ((style
& wxSL_LEFT
) != 0) & transpose
) &
2156 ((style
& wxSL_BOTH
) == 0);
2157 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2158 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2159 ((style
& wxSL_RIGHT
) != 0) & transpose
) &
2160 ((style
& wxSL_BOTH
) == 0);
2162 wxCoord sizeArrow
= (transpose
? rect
.height
: rect
.width
) / 2;
2163 wxCoord c
= ((transpose
? rect
.height
: rect
.width
) - 2*sizeArrow
);
2165 wxCoord x1
, x2
, x3
, y1
, y2
, y3
, y4
;
2166 x1
= (transpose
? rect
.y
: rect
.x
);
2167 x2
= (transpose
? rect
.GetBottom() : rect
.GetRight());
2168 x3
= (x1
-1+c
) + sizeArrow
;
2169 y1
= (transpose
? rect
.x
: rect
.y
);
2170 y2
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2171 y3
= (left
? (y1
-1+c
) + sizeArrow
: y1
);
2172 y4
= (right
? (y2
+1-c
) - sizeArrow
: y2
);
2174 dc
.SetPen(m_penBlack
);
2176 DrawLine(dc
, x3
+1-c
, y1
, x2
, y3
, transpose
);
2178 DrawLine(dc
, x2
, y3
, x2
, y4
, transpose
);
2181 DrawLine(dc
, x3
+1-c
, y2
, x2
, y4
, transpose
);
2185 DrawLine(dc
, x1
, y2
, x2
, y2
, transpose
);
2188 dc
.SetPen(m_penDarkGrey
);
2189 DrawLine(dc
, x2
-1, y3
+1, x2
-1, y4
-1, transpose
);
2191 DrawLine(dc
, x3
+1-c
, y2
-1, x2
-1, y4
, transpose
);
2195 DrawLine(dc
, x1
+1, y2
-1, x2
-1, y2
-1, transpose
);
2198 dc
.SetPen(m_penHighlight
);
2201 DrawLine(dc
, x1
, y3
, x3
, y1
, transpose
);
2202 DrawLine(dc
, x3
+1-c
, y1
+1, x2
-1, y3
, transpose
);
2206 DrawLine(dc
, x1
, y1
, x2
, y1
, transpose
);
2208 DrawLine(dc
, x1
, y3
, x1
, y4
, transpose
);
2211 DrawLine(dc
, x1
, y4
, x3
+c
, y2
+c
, transpose
);
2214 if (flags
& wxCONTROL_PRESSED
) {
2215 // TODO: MSW fills the entire area inside, not just the rect
2216 wxRect rectInt
= rect
;
2219 rectInt
.SetLeft(y3
);
2220 rectInt
.SetRight(y4
);
2225 rectInt
.SetBottom(y4
);
2229 #if !defined(__WXMGL__)
2230 static const char *stipple_xpm
[] = {
2231 /* columns rows colors chars-per-pixel */
2240 // VS: MGL can only do 8x8 stipple brushes
2241 static const char *stipple_xpm
[] = {
2242 /* columns rows colors chars-per-pixel */
2257 dc
.SetBrush(wxBrush(stipple_xpm
));
2259 dc
.SetTextForeground(wxSCHEME_COLOUR(m_scheme
, SHADOW_HIGHLIGHT
));
2260 dc
.SetTextBackground(wxSCHEME_COLOUR(m_scheme
, CONTROL
));
2261 dc
.SetPen(*wxTRANSPARENT_PEN
);
2262 dc
.DrawRectangle(rectInt
);
2266 void wxWin32Renderer::DrawSliderTicks(wxDC
& dc
,
2269 wxOrientation orient
,
2273 int WXUNUSED(flags
),
2276 /* show ticks geometry
2291 if (end
== start
) return;
2293 bool transpose
= (orient
== wxVERTICAL
);
2294 bool left
= ((style
& wxSL_AUTOTICKS
) != 0) &
2295 (((style
& wxSL_TOP
) != 0) & !transpose
|
2296 ((style
& wxSL_LEFT
) != 0) & transpose
|
2297 ((style
& wxSL_BOTH
) != 0));
2298 bool right
= ((style
& wxSL_AUTOTICKS
) != 0) &
2299 (((style
& wxSL_BOTTOM
) != 0) & !transpose
|
2300 ((style
& wxSL_RIGHT
) != 0) & transpose
|
2301 ((style
& wxSL_BOTH
) != 0));
2303 // default thumb size
2304 wxSize sizeThumb
= GetSliderThumbSize (rect
, 0, orient
);
2305 wxCoord defaultLen
= (transpose
? sizeThumb
.x
: sizeThumb
.y
);
2307 // normal thumb size
2308 sizeThumb
= GetSliderThumbSize (rect
, lenThumb
, orient
);
2309 wxCoord widthThumb
= (transpose
? sizeThumb
.y
: sizeThumb
.x
);
2311 wxRect rectShaft
= GetSliderShaftRect (rect
, lenThumb
, orient
, style
);
2313 wxCoord x1
, x2
, y1
, y2
, y3
, y4
, len
;
2314 x1
= (transpose
? rectShaft
.y
: rectShaft
.x
) + widthThumb
/2;
2315 x2
= (transpose
? rectShaft
.GetBottom() : rectShaft
.GetRight()) - widthThumb
/2;
2316 y1
= (transpose
? rectShaft
.x
: rectShaft
.y
) - defaultLen
/2;
2317 y2
= (transpose
? rectShaft
.GetRight() : rectShaft
.GetBottom()) + defaultLen
/2;
2318 y3
= (transpose
? rect
.x
: rect
.y
);
2319 y4
= (transpose
? rect
.GetRight() : rect
.GetBottom());
2322 dc
.SetPen(m_penBlack
);
2324 int range
= end
- start
;
2325 for ( int n
= 0; n
< range
; n
+= step
) {
2326 wxCoord x
= x1
+ (len
*n
) / range
;
2328 if (left
& (y1
> y3
)) {
2329 DrawLine(dc
, x
, y1
, x
, y3
, orient
== wxVERTICAL
);
2331 if (right
& (y4
> y2
)) {
2332 DrawLine(dc
, x
, y2
, x
, y4
, orient
== wxVERTICAL
);
2335 // always draw the line at the end position
2336 if (left
& (y1
> y3
)) {
2337 DrawLine(dc
, x2
, y1
, x2
, y3
, orient
== wxVERTICAL
);
2339 if (right
& (y4
> y2
)) {
2340 DrawLine(dc
, x2
, y2
, x2
, y4
, orient
== wxVERTICAL
);
2344 #endif // wxUSE_SLIDER
2348 // ----------------------------------------------------------------------------
2350 // ----------------------------------------------------------------------------
2352 // wxWin32MenuGeometryInfo: the wxMenuGeometryInfo used by wxWin32Renderer
2353 class WXDLLEXPORT wxWin32MenuGeometryInfo
: public wxMenuGeometryInfo
2356 virtual wxSize
GetSize() const { return m_size
; }
2358 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
2359 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
2361 wxCoord
GetItemHeight() const { return m_heightItem
; }
2364 // the total size of the menu
2367 // the offset of the start of the menu item label
2370 // the offset of the start of the accel label
2373 // the height of a normal (not separator) item
2374 wxCoord m_heightItem
;
2376 friend wxMenuGeometryInfo
*
2377 wxWin32Renderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
2380 // FIXME: all constants are hardcoded but shouldn't be
2381 static const wxCoord MENU_LEFT_MARGIN
= 9;
2382 static const wxCoord MENU_RIGHT_MARGIN
= 18;
2383 static const wxCoord MENU_VERT_MARGIN
= 3;
2385 // the margin around bitmap/check marks (on each side)
2386 static const wxCoord MENU_BMP_MARGIN
= 2;
2388 // the margin between the labels and accel strings
2389 static const wxCoord MENU_ACCEL_MARGIN
= 8;
2391 // the separator height in pixels: in fact, strangely enough, the real height
2392 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
2394 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
2396 // the size of the standard checkmark bitmap
2397 static const wxCoord MENU_CHECK_SIZE
= 9;
2399 void wxWin32Renderer::DrawMenuBarItem(wxDC
& dc
,
2400 const wxRect
& rectOrig
,
2401 const wxString
& label
,
2405 wxRect rect
= rectOrig
;
2408 wxDCTextColourChanger
colChanger(dc
);
2410 if ( flags
& wxCONTROL_SELECTED
)
2412 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2414 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2417 dc
.DrawRectangle(rect
);
2420 // don't draw the focus rect around menu bar items
2421 DrawLabel(dc
, label
, rect
, flags
& ~wxCONTROL_FOCUSED
,
2422 wxALIGN_CENTRE
, indexAccel
);
2425 void wxWin32Renderer::DrawMenuItem(wxDC
& dc
,
2427 const wxMenuGeometryInfo
& gi
,
2428 const wxString
& label
,
2429 const wxString
& accel
,
2430 const wxBitmap
& bitmap
,
2434 const wxWin32MenuGeometryInfo
& geometryInfo
=
2435 (const wxWin32MenuGeometryInfo
&)gi
;
2440 rect
.width
= geometryInfo
.GetSize().x
;
2441 rect
.height
= geometryInfo
.GetItemHeight();
2443 // draw the selected item specially
2444 wxDCTextColourChanger
colChanger(dc
);
2445 if ( flags
& wxCONTROL_SELECTED
)
2447 colChanger
.Set(wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT_TEXT
));
2449 const wxColour colBg
= wxSCHEME_COLOUR(m_scheme
, HIGHLIGHT
);
2452 dc
.DrawRectangle(rect
);
2455 // draw the bitmap: use the bitmap provided or the standard checkmark for
2456 // the checkable items
2457 wxBitmap bmp
= bitmap
;
2458 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKED
) )
2460 bmp
= GetIndicator(IndicatorType_Menu
, flags
);
2465 rect
.SetRight(geometryInfo
.GetLabelOffset());
2466 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
2470 rect
.x
= geometryInfo
.GetLabelOffset();
2471 rect
.SetRight(geometryInfo
.GetAccelOffset());
2473 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
2475 // draw the accel string
2476 rect
.x
= geometryInfo
.GetAccelOffset();
2477 rect
.SetRight(geometryInfo
.GetSize().x
);
2479 // NB: no accel index here
2480 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
2482 // draw the submenu indicator
2483 if ( flags
& wxCONTROL_ISSUBMENU
)
2485 rect
.x
= geometryInfo
.GetSize().x
- MENU_RIGHT_MARGIN
;
2486 rect
.width
= MENU_RIGHT_MARGIN
;
2488 ArrowStyle arrowStyle
;
2489 if ( flags
& wxCONTROL_DISABLED
)
2490 arrowStyle
= flags
& wxCONTROL_SELECTED
? Arrow_InvertedDisabled
2492 else if ( flags
& wxCONTROL_SELECTED
)
2493 arrowStyle
= Arrow_Inverted
;
2495 arrowStyle
= Arrow_Normal
;
2497 DrawArrow(dc
, rect
, Arrow_Right
, arrowStyle
);
2501 void wxWin32Renderer::DrawMenuSeparator(wxDC
& dc
,
2503 const wxMenuGeometryInfo
& geomInfo
)
2505 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
2508 wxSize
wxWin32Renderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
2510 wxSize size
= sizeText
;
2512 // FIXME: menubar height is configurable under Windows
2519 wxMenuGeometryInfo
*wxWin32Renderer::GetMenuGeometry(wxWindow
*win
,
2520 const wxMenu
& menu
) const
2522 // prepare the dc: for now we draw all the items with the system font
2524 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
2526 // the height of a normal item
2527 wxCoord heightText
= dc
.GetCharHeight();
2532 // the max length of label and accel strings: the menu width is the sum of
2533 // them, even if they're for different items (as the accels should be
2536 // the max length of the bitmap is never 0 as Windows always leaves enough
2537 // space for a check mark indicator
2538 wxCoord widthLabelMax
= 0,
2540 widthBmpMax
= MENU_LEFT_MARGIN
;
2542 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
2544 node
= node
->GetNext() )
2546 // height of this item
2549 wxMenuItem
*item
= node
->GetData();
2550 if ( item
->IsSeparator() )
2552 h
= MENU_SEPARATOR_HEIGHT
;
2554 else // not separator
2559 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
2560 if ( widthLabel
> widthLabelMax
)
2562 widthLabelMax
= widthLabel
;
2566 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
2567 if ( widthAccel
> widthAccelMax
)
2569 widthAccelMax
= widthAccel
;
2572 const wxBitmap
& bmp
= item
->GetBitmap();
2575 wxCoord widthBmp
= bmp
.GetWidth();
2576 if ( widthBmp
> widthBmpMax
)
2577 widthBmpMax
= widthBmp
;
2579 //else if ( item->IsCheckable() ): no need to check for this as
2580 // MENU_LEFT_MARGIN is big enough to show the check mark
2583 h
+= 2*MENU_VERT_MARGIN
;
2585 // remember the item position and height
2586 item
->SetGeometry(height
, h
);
2591 // bundle the metrics into a struct and return it
2592 wxWin32MenuGeometryInfo
*gi
= new wxWin32MenuGeometryInfo
;
2594 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
2595 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
2596 if ( widthAccelMax
> 0 )
2598 // if we actually have any accesl, add a margin
2599 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
2602 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
2604 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
2605 gi
->m_size
.y
= height
;
2610 #endif // wxUSE_MENUS
2614 // ----------------------------------------------------------------------------
2616 // ----------------------------------------------------------------------------
2618 static const wxCoord STATBAR_BORDER_X
= 2;
2619 static const wxCoord STATBAR_BORDER_Y
= 2;
2621 wxSize
wxWin32Renderer::GetStatusBarBorders(wxCoord
*borderBetweenFields
) const
2623 if ( borderBetweenFields
)
2624 *borderBetweenFields
= 2;
2626 return wxSize(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2629 void wxWin32Renderer::DrawStatusField(wxDC
& dc
,
2631 const wxString
& label
,
2632 int flags
, int style
/*=0*/)
2636 if ( flags
& wxCONTROL_ISDEFAULT
)
2638 // draw the size grip: it is a normal rect except that in the lower
2639 // right corner we have several bands which may be used for dragging
2640 // the status bar corner
2642 // each band consists of 4 stripes: m_penHighlight, double
2643 // m_penDarkGrey and transparent one
2644 wxCoord x2
= rect
.GetRight(),
2645 y2
= rect
.GetBottom();
2647 // draw the upper left part of the rect normally
2648 if (style
!= wxSB_FLAT
)
2650 if (style
== wxSB_RAISED
)
2651 dc
.SetPen(m_penHighlight
);
2653 dc
.SetPen(m_penDarkGrey
);
2654 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(), rect
.GetLeft(), y2
);
2655 dc
.DrawLine(rect
.GetLeft() + 1, rect
.GetTop(), x2
, rect
.GetTop());
2658 // draw the grey stripes of the grip
2660 wxCoord ofs
= WIDTH_STATUSBAR_GRIP_BAND
- 1;
2661 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2663 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2664 dc
.DrawLine(x2
- ofs
, y2
- 1, x2
, y2
- ofs
- 1);
2667 // draw the white stripes
2668 dc
.SetPen(m_penHighlight
);
2669 ofs
= WIDTH_STATUSBAR_GRIP_BAND
+ 1;
2670 for ( n
= 0; n
< NUM_STATUSBAR_GRIP_BANDS
; n
++, ofs
+= WIDTH_STATUSBAR_GRIP_BAND
)
2672 dc
.DrawLine(x2
- ofs
+ 1, y2
- 1, x2
, y2
- ofs
);
2675 // draw the remaining rect boundaries
2676 if (style
!= wxSB_FLAT
)
2678 if (style
== wxSB_RAISED
)
2679 dc
.SetPen(m_penDarkGrey
);
2681 dc
.SetPen(m_penHighlight
);
2682 ofs
-= WIDTH_STATUSBAR_GRIP_BAND
;
2683 dc
.DrawLine(x2
, rect
.GetTop(), x2
, y2
- ofs
+ 1);
2684 dc
.DrawLine(rect
.GetLeft(), y2
, x2
- ofs
+ 1, y2
);
2690 rectIn
.width
-= STATUSBAR_GRIP_SIZE
;
2694 if (style
== wxSB_RAISED
)
2695 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
2696 else if (style
!= wxSB_FLAT
)
2697 DrawBorder(dc
, wxBORDER_STATIC
, rect
, flags
, &rectIn
);
2700 rectIn
.Deflate(STATBAR_BORDER_X
, STATBAR_BORDER_Y
);
2702 wxDCClipper
clipper(dc
, rectIn
);
2703 DrawLabel(dc
, label
, rectIn
, flags
, wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
2706 #endif // wxUSE_STATUSBAR
2708 // ----------------------------------------------------------------------------
2710 // ----------------------------------------------------------------------------
2712 void wxWin32Renderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2713 wxBitmap
* WXUNUSED(bmpFocus
),
2714 wxBitmap
*bmpPressed
,
2715 wxBitmap
*bmpDisabled
)
2717 static const wxCoord widthCombo
= 16;
2718 static const wxCoord heightCombo
= 17;
2724 bmpNormal
->Create(widthCombo
, heightCombo
);
2725 dcMem
.SelectObject(*bmpNormal
);
2726 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2727 Arrow_Down
, Arrow_Normal
);
2732 bmpPressed
->Create(widthCombo
, heightCombo
);
2733 dcMem
.SelectObject(*bmpPressed
);
2734 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2735 Arrow_Down
, Arrow_Pressed
);
2740 bmpDisabled
->Create(widthCombo
, heightCombo
);
2741 dcMem
.SelectObject(*bmpDisabled
);
2742 DrawArrowButton(dcMem
, wxRect(0, 0, widthCombo
, heightCombo
),
2743 Arrow_Down
, Arrow_Disabled
);
2747 // ----------------------------------------------------------------------------
2749 // ----------------------------------------------------------------------------
2751 void wxWin32Renderer::DrawArrowBorder(wxDC
& dc
, wxRect
*rect
, bool isPressed
)
2755 DrawRect(dc
, rect
, m_penDarkGrey
);
2757 // the arrow is usually drawn inside border of width 2 and is offset by
2758 // another pixel in both directions when it's pressed - as the border
2759 // in this case is more narrow as well, we have to adjust rect like
2767 DrawAntiSunkenBorder(dc
, rect
);
2771 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
2776 ArrowStyle arrowStyle
;
2777 if ( flags
& wxCONTROL_PRESSED
)
2779 // can't be pressed and disabled
2780 arrowStyle
= Arrow_Pressed
;
2784 arrowStyle
= flags
& wxCONTROL_DISABLED
? Arrow_Disabled
: Arrow_Normal
;
2787 DrawArrowButton(dc
, rect
, GetArrowDirection(dir
), arrowStyle
);
2790 void wxWin32Renderer::DrawArrow(wxDC
& dc
,
2792 ArrowDirection arrowDir
,
2793 ArrowStyle arrowStyle
)
2795 const wxBitmap
& bmp
= m_bmpArrows
[arrowStyle
][arrowDir
];
2797 // under Windows the arrows always have the same size so just centre it in
2798 // the provided rectangle
2799 wxCoord x
= rect
.x
+ (rect
.width
- bmp
.GetWidth()) / 2,
2800 y
= rect
.y
+ (rect
.height
- bmp
.GetHeight()) / 2;
2802 // Windows does it like this...
2803 if ( arrowDir
== Arrow_Left
)
2807 dc
.DrawBitmap(bmp
, x
, y
, true /* use mask */);
2810 void wxWin32Renderer::DrawArrowButton(wxDC
& dc
,
2811 const wxRect
& rectAll
,
2812 ArrowDirection arrowDir
,
2813 ArrowStyle arrowStyle
)
2815 wxRect rect
= rectAll
;
2816 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2817 DrawArrowBorder(dc
, &rect
, arrowStyle
== Arrow_Pressed
);
2818 DrawArrow(dc
, rect
, arrowDir
, arrowStyle
);
2821 void wxWin32Renderer::DrawScrollbarThumb(wxDC
& dc
,
2822 wxOrientation
WXUNUSED(orient
),
2824 int WXUNUSED(flags
))
2826 // we don't use the flags, the thumb never changes appearance
2827 wxRect rectThumb
= rect
;
2828 DrawArrowBorder(dc
, &rectThumb
);
2829 DrawBackground(dc
, wxNullColour
, rectThumb
);
2832 void wxWin32Renderer::DrawScrollbarShaft(wxDC
& dc
,
2833 wxOrientation
WXUNUSED(orient
),
2834 const wxRect
& rectBar
,
2837 wxColourScheme::StdColour col
= flags
& wxCONTROL_PRESSED
2838 ? wxColourScheme::SCROLLBAR_PRESSED
2839 : wxColourScheme::SCROLLBAR
;
2840 DrawBackground(dc
, m_scheme
->Get(col
), rectBar
);
2843 // ----------------------------------------------------------------------------
2844 // top level windows
2845 // ----------------------------------------------------------------------------
2847 int wxWin32Renderer::HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const
2849 wxRect client
= GetFrameClientArea(rect
, flags
);
2851 if ( client
.Contains(pt
) )
2852 return wxHT_TOPLEVEL_CLIENT_AREA
;
2854 if ( flags
& wxTOPLEVEL_TITLEBAR
)
2856 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
2858 if ( flags
& wxTOPLEVEL_ICON
)
2860 if ( wxRect(client
.GetPosition(), GetFrameIconSize()).Contains(pt
) )
2861 return wxHT_TOPLEVEL_ICON
;
2864 wxRect
btnRect(client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
,
2865 client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2,
2866 FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
2868 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
2870 if ( btnRect
.Contains(pt
) )
2871 return wxHT_TOPLEVEL_BUTTON_CLOSE
;
2872 btnRect
.x
-= FRAME_BUTTON_WIDTH
+ 2;
2874 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
2876 if ( btnRect
.Contains(pt
) )
2877 return wxHT_TOPLEVEL_BUTTON_MAXIMIZE
;
2878 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2880 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
2882 if ( btnRect
.Contains(pt
) )
2883 return wxHT_TOPLEVEL_BUTTON_RESTORE
;
2884 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2886 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
2888 if ( btnRect
.Contains(pt
) )
2889 return wxHT_TOPLEVEL_BUTTON_ICONIZE
;
2890 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2892 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
2894 if ( btnRect
.Contains(pt
) )
2895 return wxHT_TOPLEVEL_BUTTON_HELP
;
2896 btnRect
.x
-= FRAME_BUTTON_WIDTH
;
2899 if ( pt
.y
>= client
.y
&& pt
.y
< client
.y
+ FRAME_TITLEBAR_HEIGHT
)
2900 return wxHT_TOPLEVEL_TITLEBAR
;
2903 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
2905 // we are certainly at one of borders, lets decide which one:
2908 // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
2909 if ( pt
.x
< client
.x
)
2910 border
|= wxHT_TOPLEVEL_BORDER_W
;
2911 else if ( pt
.x
>= client
.width
+ client
.x
)
2912 border
|= wxHT_TOPLEVEL_BORDER_E
;
2913 if ( pt
.y
< client
.y
)
2914 border
|= wxHT_TOPLEVEL_BORDER_N
;
2915 else if ( pt
.y
>= client
.height
+ client
.y
)
2916 border
|= wxHT_TOPLEVEL_BORDER_S
;
2920 return wxHT_NOWHERE
;
2923 void wxWin32Renderer::DrawFrameTitleBar(wxDC
& dc
,
2925 const wxString
& title
,
2929 int specialButtonFlags
)
2931 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
2933 DrawFrameBorder(dc
, rect
, flags
);
2935 if ( flags
& wxTOPLEVEL_TITLEBAR
)
2937 DrawFrameBackground(dc
, rect
, flags
);
2938 if ( flags
& wxTOPLEVEL_ICON
)
2939 DrawFrameIcon(dc
, rect
, icon
, flags
);
2940 DrawFrameTitle(dc
, rect
, title
, flags
);
2942 wxRect client
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
2944 x
= client
.GetRight() - 2 - FRAME_BUTTON_WIDTH
;
2945 y
= client
.GetTop() + (FRAME_TITLEBAR_HEIGHT
-FRAME_BUTTON_HEIGHT
)/2;
2947 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
2949 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_CLOSE
,
2950 (specialButton
== wxTOPLEVEL_BUTTON_CLOSE
) ?
2951 specialButtonFlags
: 0);
2952 x
-= FRAME_BUTTON_WIDTH
+ 2;
2954 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
2956 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_MAXIMIZE
,
2957 (specialButton
== wxTOPLEVEL_BUTTON_MAXIMIZE
) ?
2958 specialButtonFlags
: 0);
2959 x
-= FRAME_BUTTON_WIDTH
;
2961 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
2963 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_RESTORE
,
2964 (specialButton
== wxTOPLEVEL_BUTTON_RESTORE
) ?
2965 specialButtonFlags
: 0);
2966 x
-= FRAME_BUTTON_WIDTH
;
2968 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
2970 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_ICONIZE
,
2971 (specialButton
== wxTOPLEVEL_BUTTON_ICONIZE
) ?
2972 specialButtonFlags
: 0);
2973 x
-= FRAME_BUTTON_WIDTH
;
2975 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
2977 DrawFrameButton(dc
, x
, y
, wxTOPLEVEL_BUTTON_HELP
,
2978 (specialButton
== wxTOPLEVEL_BUTTON_HELP
) ?
2979 specialButtonFlags
: 0);
2984 void wxWin32Renderer::DrawFrameBorder(wxDC
& dc
,
2988 if ( !(flags
& wxTOPLEVEL_BORDER
) ) return;
2992 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penBlack
);
2993 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penDarkGrey
);
2994 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
2995 if ( flags
& wxTOPLEVEL_RESIZEABLE
)
2996 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penLightGrey
);
2999 void wxWin32Renderer::DrawFrameBackground(wxDC
& dc
,
3003 if ( !(flags
& wxTOPLEVEL_TITLEBAR
) ) return;
3005 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3006 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE
) :
3007 wxSCHEME_COLOUR(m_scheme
, TITLEBAR
);
3009 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3010 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3012 DrawBackground(dc
, col
, r
);
3015 void wxWin32Renderer::DrawFrameTitle(wxDC
& dc
,
3017 const wxString
& title
,
3020 wxColour col
= (flags
& wxTOPLEVEL_ACTIVE
) ?
3021 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_ACTIVE_TEXT
) :
3022 wxSCHEME_COLOUR(m_scheme
, TITLEBAR_TEXT
);
3024 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3025 r
.height
= FRAME_TITLEBAR_HEIGHT
;
3026 if ( flags
& wxTOPLEVEL_ICON
)
3028 r
.x
+= FRAME_TITLEBAR_HEIGHT
;
3029 r
.width
-= FRAME_TITLEBAR_HEIGHT
+ 2;
3037 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3038 r
.width
-= FRAME_BUTTON_WIDTH
+ 2;
3039 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3040 r
.width
-= FRAME_BUTTON_WIDTH
;
3041 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3042 r
.width
-= FRAME_BUTTON_WIDTH
;
3043 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3044 r
.width
-= FRAME_BUTTON_WIDTH
;
3045 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3046 r
.width
-= FRAME_BUTTON_WIDTH
;
3048 dc
.SetFont(m_titlebarFont
);
3049 dc
.SetTextForeground(col
);
3052 dc
.GetTextExtent(title
, &textW
, NULL
);
3053 if ( textW
> r
.width
)
3055 // text is too big, let's shorten it and add "..." after it:
3056 size_t len
= title
.length();
3057 wxCoord WSoFar
, letterW
;
3059 dc
.GetTextExtent(wxT("..."), &WSoFar
, NULL
);
3060 if ( WSoFar
> r
.width
)
3062 // not enough space to draw anything
3068 for (size_t i
= 0; i
< len
; i
++)
3070 dc
.GetTextExtent(title
[i
], &letterW
, NULL
);
3071 if ( letterW
+ WSoFar
> r
.width
)
3077 dc
.DrawLabel(s
, wxNullBitmap
, r
,
3078 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3081 dc
.DrawLabel(title
, wxNullBitmap
, r
,
3082 wxALIGN_LEFT
| wxALIGN_CENTRE_VERTICAL
);
3085 void wxWin32Renderer::DrawFrameIcon(wxDC
& dc
,
3092 wxRect r
= GetFrameClientArea(rect
, flags
& ~wxTOPLEVEL_TITLEBAR
);
3093 dc
.DrawIcon(icon
, r
.x
, r
.y
);
3097 void wxWin32Renderer::DrawFrameButton(wxDC
& dc
,
3098 wxCoord x
, wxCoord y
,
3102 wxRect
r(x
, y
, FRAME_BUTTON_WIDTH
, FRAME_BUTTON_HEIGHT
);
3107 case wxTOPLEVEL_BUTTON_CLOSE
: idx
= FrameButton_Close
; break;
3108 case wxTOPLEVEL_BUTTON_MAXIMIZE
: idx
= FrameButton_Maximize
; break;
3109 case wxTOPLEVEL_BUTTON_ICONIZE
: idx
= FrameButton_Minimize
; break;
3110 case wxTOPLEVEL_BUTTON_RESTORE
: idx
= FrameButton_Restore
; break;
3111 case wxTOPLEVEL_BUTTON_HELP
: idx
= FrameButton_Help
; break;
3113 wxFAIL_MSG(wxT("incorrect button specification"));
3116 if ( flags
& wxCONTROL_PRESSED
)
3118 DrawShadedRect(dc
, &r
, m_penBlack
, m_penHighlight
);
3119 DrawShadedRect(dc
, &r
, m_penDarkGrey
, m_penLightGrey
);
3120 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3121 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
+1, r
.y
+1, true);
3125 DrawShadedRect(dc
, &r
, m_penHighlight
, m_penBlack
);
3126 DrawShadedRect(dc
, &r
, m_penLightGrey
, m_penDarkGrey
);
3127 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), r
);
3128 dc
.DrawBitmap(m_bmpFrameButtons
[idx
], r
.x
, r
.y
, true);
3133 wxRect
wxWin32Renderer::GetFrameClientArea(const wxRect
& rect
,
3138 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3140 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3141 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3142 FRAME_BORDER_THICKNESS
;
3145 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3147 r
.y
+= FRAME_TITLEBAR_HEIGHT
;
3148 r
.height
-= FRAME_TITLEBAR_HEIGHT
;
3154 wxSize
wxWin32Renderer::GetFrameTotalSize(const wxSize
& clientSize
,
3157 wxSize
s(clientSize
);
3159 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3161 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3162 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3163 FRAME_BORDER_THICKNESS
;
3167 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3168 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3173 wxSize
wxWin32Renderer::GetFrameMinSize(int flags
) const
3177 if ( (flags
& wxTOPLEVEL_BORDER
) && !(flags
& wxTOPLEVEL_MAXIMIZED
) )
3179 int border
= (flags
& wxTOPLEVEL_RESIZEABLE
) ?
3180 RESIZEABLE_FRAME_BORDER_THICKNESS
:
3181 FRAME_BORDER_THICKNESS
;
3186 if ( flags
& wxTOPLEVEL_TITLEBAR
)
3188 s
.y
+= FRAME_TITLEBAR_HEIGHT
;
3190 if ( flags
& wxTOPLEVEL_ICON
)
3191 s
.x
+= FRAME_TITLEBAR_HEIGHT
+ 2;
3192 if ( flags
& wxTOPLEVEL_BUTTON_CLOSE
)
3193 s
.x
+= FRAME_BUTTON_WIDTH
+ 2;
3194 if ( flags
& wxTOPLEVEL_BUTTON_MAXIMIZE
)
3195 s
.x
+= FRAME_BUTTON_WIDTH
;
3196 if ( flags
& wxTOPLEVEL_BUTTON_RESTORE
)
3197 s
.x
+= FRAME_BUTTON_WIDTH
;
3198 if ( flags
& wxTOPLEVEL_BUTTON_ICONIZE
)
3199 s
.x
+= FRAME_BUTTON_WIDTH
;
3200 if ( flags
& wxTOPLEVEL_BUTTON_HELP
)
3201 s
.x
+= FRAME_BUTTON_WIDTH
;
3207 wxSize
wxWin32Renderer::GetFrameIconSize() const
3209 return wxSize(16, 16);
3213 // ----------------------------------------------------------------------------
3215 // ----------------------------------------------------------------------------
3217 /* Copyright (c) Julian Smart */
3218 static char *error_xpm
[]={
3219 /* columns rows colors chars-per-pixel */
3296 " $oooooooooooo%& ",
3297 " *=-ooooooooooooo;: ",
3298 " *oooooooooooooooooo> ",
3299 " =ooooooooooooooooooo, ",
3300 " $-ooooooooooooooooooo<1 ",
3301 " .oooooo2334ooo533oooooo6 ",
3302 " +ooooooo789oo2883oooooo0q ",
3303 " oooooooo2w83o78eoooooooor ",
3304 " toooooooooy88u884oooooooori ",
3305 " Xooooooooooe888poooooooooas ",
3306 " ooooooooooo4889doooooooooof ",
3307 " ooooooooooo588w2oooooooooofi ",
3308 " oooooooooodw8887oooooooooofi ",
3309 " goooooooooh8w588jooooooookli ",
3310 " tooooooooz885op8wdooooooorix ",
3311 " oooooood98cood98cooooooori ",
3312 " @oooooop8w2ooo5885ooooovbi ",
3313 " n%ooooooooooooooooooooomiM ",
3314 " &;oooooooooooooooooooNBiV ",
3315 " :ooooooooooooooooooCZiA ",
3316 " nSooooooooooooooooCDiF ",
3317 " nG<oooooooooooooNZiiH ",
3318 " 160ooooooooovmBiFH ",
3319 " nqrraoookrrbiiA ",
3326 /* Copyright (c) Julian Smart */
3327 static char *info_xpm
[]={
3328 /* columns rows colors chars-per-pixel */
3350 " ..XXXXXXXXXXXXX.. ",
3351 " .XXXXXXXXXXXXXXXXX. ",
3352 " .XXXXXXXXoO+XXXXXXXX. ",
3353 " .XXXXXXXXX@#OXXXXXXXXX. ",
3354 " .XXXXXXXXXX$@oXXXXXXXXXX. ",
3355 " .XXXXXXXXXXXXXXXXXXXXXXX.% ",
3356 " .XXXXXXXXX&*=-XXXXXXXXXX.%% ",
3357 ".XXXXXXXXXX;:#>XXXXXXXXXXX.% ",
3358 ".XXXXXXXXXXX;#+XXXXXXXXXXX.% ",
3359 ".XXXXXXXXXXX;#+XXXXXXXXXXX.%% ",
3360 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
3361 " .XXXXXXXXXX;#+XXXXXXXXXX.%%% ",
3362 " .XXXXXXXXXX;#+XXXXXXXXXX.%% ",
3363 " .XXXXXXXX*-##+XXXXXXXX.%%% ",
3364 " .XXXXXXXXXXXXXXXXXXX.%%%% ",
3365 " .XXXXXXXXXXXXXXXXX.%%%% ",
3366 " ..XXXXXXXXXXXXX..%%%% ",
3367 " %...XXXXXXXX..%%%%% ",
3368 " %%%..XXXXXX.%%%%% ",
3382 /* Copyright (c) Julian Smart */
3383 static char *question_xpm
[]={
3384 /* columns rows colors chars-per-pixel */
3405 " ..XXXXXXXXXXXXX.. ",
3406 " .XXXXXXoO++@XXXXXX. ",
3407 " .XXXXXXO#$$$$#%XXXXX. ",
3408 " .XXXXXX@$$#&&#$#oXXXXX. ",
3409 " .XXXXXXX*$$%XX%$$=XXXXXX. ",
3410 " .XXXXXXX+-;XXXX$$-XXXXXX.: ",
3411 " .XXXXXXXXXXXXX+$$&XXXXXX.:: ",
3412 ".XXXXXXXXXXXXo;$$*oXXXXXXX.: ",
3413 ".XXXXXXXXXXXo*$$*oXXXXXXXX.: ",
3414 ".XXXXXXXXXXX+$$*oXXXXXXXXX.:: ",
3415 " .XXXXXXXXXX-$$oXXXXXXXXX.::: ",
3416 " .XXXXXXXXXXX--XXXXXXXXXX.::: ",
3417 " .XXXXXXXXXXXXXXXXXXXXXXX.:: ",
3418 " .XXXXXXXXX-$$XXXXXXXXX.::: ",
3419 " .XXXXXXXX-$$XXXXXXXX.:::: ",
3420 " .XXXXXXXO++XXXXXXX.:::: ",
3421 " ..XXXXXXXXXXXXX..:::: ",
3422 " :...XXXXXXXX..::::: ",
3423 " :::..XXXXXX.::::: ",
3437 /* Copyright (c) Julian Smart */
3438 static char *warning_xpm
[]={
3439 /* columns rows colors chars-per-pixel */
3465 " ..XXXXO@#XXX... ",
3466 " ...XXXXO@#XXXX.. ",
3467 " ..XXXXXO@#XXXX... ",
3468 " ...XXXXXo@OXXXXX.. ",
3469 " ...XXXXXXo@OXXXXXX.. ",
3470 " ..XXXXXXX$@OXXXXXX... ",
3471 " ...XXXXXXXX@XXXXXXXX.. ",
3472 " ...XXXXXXXXXXXXXXXXXX... ",
3473 " ..XXXXXXXXXXOXXXXXXXXX.. ",
3474 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
3475 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
3476 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
3477 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
3478 " .............................. ",
3479 " .............................. ",
3486 wxBitmap
wxWin32ArtProvider::CreateBitmap(const wxArtID
& id
,
3487 const wxArtClient
& WXUNUSED(client
),
3488 const wxSize
& WXUNUSED(size
))
3490 if ( id
== wxART_INFORMATION
)
3491 return wxBitmap(info_xpm
);
3492 if ( id
== wxART_ERROR
)
3493 return wxBitmap(error_xpm
);
3494 if ( id
== wxART_WARNING
)
3495 return wxBitmap(warning_xpm
);
3496 if ( id
== wxART_QUESTION
)
3497 return wxBitmap(question_xpm
);
3498 return wxNullBitmap
;
3504 // ----------------------------------------------------------------------------
3505 // text control geometry
3506 // ----------------------------------------------------------------------------
3509 wxWin32Renderer::GetTextTotalArea(const wxTextCtrl
*text
,
3510 const wxRect
& rect
) const
3512 wxRect rectTotal
= wxStdRenderer::GetTextTotalArea(text
, rect
);
3514 // this is strange but it's what Windows does
3521 wxWin32Renderer::GetTextClientArea(const wxTextCtrl
*text
,
3523 wxCoord
*extraSpaceBeyond
) const
3525 wxRect rectText
= rect
;
3527 // undo GetTextTotalArea()
3528 if ( rectText
.height
> 0 )
3531 return wxStdRenderer::GetTextClientArea(text
, rect
, extraSpaceBeyond
);
3534 #endif // wxUSE_TEXTCTRL
3536 // ----------------------------------------------------------------------------
3538 // ----------------------------------------------------------------------------
3540 void wxWin32Renderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
3543 if ( wxDynamicCast(window
, wxScrollBar
) )
3545 // we only set the width of vert scrollbars and height of the
3547 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
3548 size
->y
= m_sizeScrollbarArrow
.y
;
3550 size
->x
= m_sizeScrollbarArrow
.x
;
3552 // skip border width adjustments, they don't make sense for us
3555 #endif // wxUSE_SCROLLBAR
3558 if ( wxDynamicCast(window
, wxBitmapButton
) )
3562 #endif // wxUSE_BMPBUTTON
3563 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
3566 || wxDynamicCast(window
, wxButton
)
3567 # endif // wxUSE_BUTTON
3568 # if wxUSE_TOGGLEBTN
3569 || wxDynamicCast(window
, wxToggleButton
)
3570 # endif // wxUSE_TOGGLEBTN
3573 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3575 // TODO: don't harcode all this
3576 size
->x
+= 3*window
->GetCharWidth();
3578 wxCoord heightBtn
= (11*(window
->GetCharHeight() + 8))/10;
3579 if ( size
->y
< heightBtn
- 8 )
3580 size
->y
= heightBtn
;
3585 // for compatibility with other ports, the buttons default size is never
3586 // less than the standard one, but not when display not PDAs.
3587 if (wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA
)
3589 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
3591 wxSize szDef
= wxButton::GetDefaultSize();
3592 if ( size
->x
< szDef
.x
)
3597 // no border width adjustments for buttons
3600 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
3602 // take into account the border width
3603 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
3604 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
3605 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
3608 // ============================================================================
3610 // ============================================================================
3612 // ----------------------------------------------------------------------------
3613 // wxWin32InputHandler
3614 // ----------------------------------------------------------------------------
3616 bool wxWin32InputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
3617 const wxKeyEvent
& WXUNUSED(event
),
3618 bool WXUNUSED(pressed
))
3623 bool wxWin32InputHandler::HandleMouse(wxInputConsumer
*control
,
3624 const wxMouseEvent
& event
)
3626 // clicking on the control gives it focus
3627 if ( event
.ButtonDown() )
3629 wxWindow
*win
= control
->GetInputWindow();
3631 if ( (wxWindow::FindFocus() != control
->GetInputWindow()) &&
3632 win
->AcceptsFocus() )
3645 // ----------------------------------------------------------------------------
3646 // wxWin32ScrollBarInputHandler
3647 // ----------------------------------------------------------------------------
3649 wxWin32ScrollBarInputHandler::
3650 wxWin32ScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
3651 : wxStdScrollBarInputHandler(renderer
, handler
)
3653 m_scrollPaused
= false;
3657 bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar
*scrollbar
,
3658 const wxControlAction
& action
)
3660 // stop if went beyond the position of the original click (this can only
3661 // happen when we scroll by pages)
3663 if ( action
== wxACTION_SCROLL_PAGE_DOWN
)
3665 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3666 != wxHT_SCROLLBAR_BAR_2
;
3668 else if ( action
== wxACTION_SCROLL_PAGE_UP
)
3670 stop
= m_renderer
->HitTestScrollbar(scrollbar
, m_ptStartScrolling
)
3671 != wxHT_SCROLLBAR_BAR_1
;
3676 StopScrolling(scrollbar
);
3678 scrollbar
->Refresh();
3683 return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar
, action
);
3686 bool wxWin32ScrollBarInputHandler::HandleMouse(wxInputConsumer
*control
,
3687 const wxMouseEvent
& event
)
3689 // remember the current state
3690 bool wasDraggingThumb
= m_htLast
== wxHT_SCROLLBAR_THUMB
;
3692 // do process the message
3693 bool rc
= wxStdScrollBarInputHandler::HandleMouse(control
, event
);
3695 // analyse the changes
3696 if ( !wasDraggingThumb
&& (m_htLast
== wxHT_SCROLLBAR_THUMB
) )
3698 // we just started dragging the thumb, remember its initial position to
3699 // be able to restore it if the drag is cancelled later
3700 m_eventStartDrag
= event
;
3706 bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxInputConsumer
*control
,
3707 const wxMouseEvent
& event
)
3709 // we don't highlight scrollbar elements, so there is no need to process
3710 // mouse move events normally - only do it while mouse is captured (i.e.
3711 // when we're dragging the thumb or pressing on something)
3712 if ( !m_winCapture
)
3715 if ( event
.Entering() )
3717 // we're not interested in this at all
3721 wxScrollBar
*scrollbar
= wxStaticCast(control
->GetInputWindow(), wxScrollBar
);
3723 if ( m_scrollPaused
)
3725 // check if the mouse returned to its original location
3727 if ( event
.Leaving() )
3733 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3734 if ( ht
== m_htLast
)
3736 // yes it did, resume scrolling
3737 m_scrollPaused
= false;
3738 if ( m_timerScroll
)
3740 // we were scrolling by line/page, restart timer
3741 m_timerScroll
->Start(m_interval
);
3743 Press(scrollbar
, true);
3745 else // we were dragging the thumb
3747 // restore its last location
3748 HandleThumbMove(scrollbar
, m_eventLastDrag
);
3754 else // normal case, scrolling hasn't been paused
3756 // if we're scrolling the scrollbar because the arrow or the shaft was
3757 // pressed, check that the mouse stays on the same scrollbar element
3760 // Always let thumb jump back if we leave the scrollbar
3761 if ( event
.Moving() )
3763 ht
= m_renderer
->HitTestScrollbar(scrollbar
, event
.GetPosition());
3765 else // event.Leaving()
3770 // Jump back only if we get far away from it
3771 wxPoint pos
= event
.GetPosition();
3772 if (scrollbar
->HasFlag( wxVERTICAL
))
3774 if (pos
.x
> -40 && pos
.x
< scrollbar
->GetSize().x
+40)
3779 if (pos
.y
> -40 && pos
.y
< scrollbar
->GetSize().y
+40)
3782 ht
= m_renderer
->HitTestScrollbar(scrollbar
, pos
);
3785 // if we're dragging the thumb and the mouse stays in the scrollbar, it
3786 // is still ok - we only want to catch the case when the mouse leaves
3787 // the scrollbar here
3788 if ( m_htLast
== wxHT_SCROLLBAR_THUMB
&& ht
!= wxHT_NOWHERE
)
3790 ht
= wxHT_SCROLLBAR_THUMB
;
3793 if ( ht
!= m_htLast
)
3795 // what were we doing? 2 possibilities: either an arrow/shaft was
3796 // pressed in which case we have a timer and so we just stop it or
3797 // we were dragging the thumb
3798 if ( m_timerScroll
)
3801 m_interval
= m_timerScroll
->GetInterval();
3802 m_timerScroll
->Stop();
3803 m_scrollPaused
= true;
3805 // unpress the arrow
3806 Press(scrollbar
, false);
3808 else // we were dragging the thumb
3810 // remember the current thumb position to be able to restore it
3811 // if the mouse returns to it later
3812 m_eventLastDrag
= event
;
3814 // and restore the original position (before dragging) of the
3816 HandleThumbMove(scrollbar
, m_eventStartDrag
);
3823 return wxStdInputHandler::HandleMouseMove(control
, event
);
3826 #endif // wxUSE_SCROLLBAR
3830 // ----------------------------------------------------------------------------
3831 // wxWin32CheckboxInputHandler
3832 // ----------------------------------------------------------------------------
3834 bool wxWin32CheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
3835 const wxKeyEvent
& event
,
3840 wxControlAction action
;
3841 int keycode
= event
.GetKeyCode();
3845 action
= wxACTION_CHECKBOX_TOGGLE
;
3849 case WXK_NUMPAD_SUBTRACT
:
3850 action
= wxACTION_CHECKBOX_CHECK
;
3854 case WXK_NUMPAD_ADD
:
3855 case WXK_NUMPAD_EQUAL
:
3856 action
= wxACTION_CHECKBOX_CLEAR
;
3860 if ( !action
.IsEmpty() )
3862 control
->PerformAction(action
);
3871 #endif // wxUSE_CHECKBOX
3875 // ----------------------------------------------------------------------------
3876 // wxWin32TextCtrlInputHandler
3877 // ----------------------------------------------------------------------------
3879 bool wxWin32TextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
3880 const wxKeyEvent
& event
,
3883 // handle only MSW-specific text bindings here, the others are handled in
3887 int keycode
= event
.GetKeyCode();
3889 wxControlAction action
;
3890 if ( keycode
== WXK_DELETE
&& event
.ShiftDown() )
3892 action
= wxACTION_TEXT_CUT
;
3894 else if ( keycode
== WXK_INSERT
)
3896 if ( event
.ControlDown() )
3897 action
= wxACTION_TEXT_COPY
;
3898 else if ( event
.ShiftDown() )
3899 action
= wxACTION_TEXT_PASTE
;
3902 if ( action
!= wxACTION_NONE
)
3904 control
->PerformAction(action
);
3910 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
3913 #endif // wxUSE_TEXTCTRL
3917 // ----------------------------------------------------------------------------
3918 // wxWin32StatusBarInputHandler
3919 // ----------------------------------------------------------------------------
3921 wxWin32StatusBarInputHandler::
3922 wxWin32StatusBarInputHandler(wxInputHandler
*handler
)
3923 : wxStdInputHandler(handler
)
3928 bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow
*statbar
,
3929 const wxPoint
& pt
) const
3931 if ( statbar
->HasFlag(wxST_SIZEGRIP
) &&
3932 statbar
->GetParent()->HasFlag(wxRESIZE_BORDER
) )
3935 parentTLW
= wxDynamicCast(statbar
->GetParent(), wxTopLevelWindow
);
3937 wxCHECK_MSG( parentTLW
, false,
3938 _T("the status bar should be a child of a TLW") );
3940 // a maximized window can't be resized anyhow
3941 if ( !parentTLW
->IsMaximized() )
3943 // VZ: I think that the standard Windows behaviour is to only
3944 // show the resizing cursor when the mouse is on top of the
3945 // grip itself but apparently different Windows versions behave
3946 // differently (?) and it seems a better UI to allow resizing
3947 // the status bar even when the mouse is above the grip
3948 wxSize sizeSbar
= statbar
->GetSize();
3950 int diff
= sizeSbar
.x
- pt
.x
;
3951 return diff
>= 0 && diff
< (wxCoord
)STATUSBAR_GRIP_SIZE
;
3958 bool wxWin32StatusBarInputHandler::HandleMouse(wxInputConsumer
*consumer
,
3959 const wxMouseEvent
& event
)
3961 if ( event
.Button(1) )
3963 if ( event
.ButtonDown(1) )
3965 wxWindow
*statbar
= consumer
->GetInputWindow();
3967 if ( IsOnGrip(statbar
, event
.GetPosition()) )
3969 wxTopLevelWindow
*tlw
= wxDynamicCast(statbar
->GetParent(),
3973 tlw
->PerformAction(wxACTION_TOPLEVEL_RESIZE
,
3974 wxHT_TOPLEVEL_BORDER_SE
);
3976 statbar
->SetCursor(m_cursorOld
);
3984 return wxStdInputHandler::HandleMouse(consumer
, event
);
3987 bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
3988 const wxMouseEvent
& event
)
3990 wxWindow
*statbar
= consumer
->GetInputWindow();
3992 bool isOnGrip
= IsOnGrip(statbar
, event
.GetPosition());
3993 if ( isOnGrip
!= m_isOnGrip
)
3995 m_isOnGrip
= isOnGrip
;
3998 m_cursorOld
= statbar
->GetCursor();
3999 statbar
->SetCursor(wxCURSOR_SIZENWSE
);
4003 statbar
->SetCursor(m_cursorOld
);
4007 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
4010 #endif // wxUSE_STATUSBAR
4012 // ----------------------------------------------------------------------------
4013 // wxWin32FrameInputHandler
4014 // ----------------------------------------------------------------------------
4016 class wxWin32SystemMenuEvtHandler
: public wxEvtHandler
4019 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
);
4021 void Attach(wxInputConsumer
*consumer
);
4025 DECLARE_EVENT_TABLE()
4026 void OnSystemMenu(wxCommandEvent
&event
);
4027 void OnCloseFrame(wxCommandEvent
&event
);
4028 void OnClose(wxCloseEvent
&event
);
4030 wxWin32FrameInputHandler
*m_inputHnd
;
4031 wxTopLevelWindow
*m_wnd
;
4033 wxAcceleratorTable m_oldAccelTable
;
4037 wxWin32SystemMenuEvtHandler::
4038 wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler
*handler
)
4040 m_inputHnd
= handler
;
4044 void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer
*consumer
)
4046 wxASSERT_MSG( m_wnd
== NULL
, _T("can't attach the handler twice!") );
4048 m_wnd
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4049 m_wnd
->PushEventHandler(this);
4052 // VS: This code relies on using generic implementation of
4053 // wxAcceleratorTable in wxUniv!
4054 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4055 m_oldAccelTable
= table
;
4056 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_SPACE
, wxID_SYSTEM_MENU
));
4057 table
.Add(wxAcceleratorEntry(wxACCEL_ALT
, WXK_F4
, wxID_CLOSE_FRAME
));
4058 m_wnd
->SetAcceleratorTable(table
);
4062 void wxWin32SystemMenuEvtHandler::Detach()
4067 m_wnd
->SetAcceleratorTable(m_oldAccelTable
);
4069 m_wnd
->RemoveEventHandler(this);
4074 BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler
, wxEvtHandler
)
4075 EVT_MENU(wxID_SYSTEM_MENU
, wxWin32SystemMenuEvtHandler::OnSystemMenu
)
4076 EVT_MENU(wxID_CLOSE_FRAME
, wxWin32SystemMenuEvtHandler::OnCloseFrame
)
4077 EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose
)
4080 void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent
&WXUNUSED(event
))
4082 int border
= ((m_wnd
->GetWindowStyle() & wxRESIZE_BORDER
) &&
4083 !m_wnd
->IsMaximized()) ?
4084 RESIZEABLE_FRAME_BORDER_THICKNESS
:
4085 FRAME_BORDER_THICKNESS
;
4086 wxPoint pt
= m_wnd
->GetClientAreaOrigin();
4087 pt
.x
= -pt
.x
+ border
;
4088 pt
.y
= -pt
.y
+ border
+ FRAME_TITLEBAR_HEIGHT
;
4091 wxAcceleratorTable table
= *m_wnd
->GetAcceleratorTable();
4092 m_wnd
->SetAcceleratorTable(wxNullAcceleratorTable
);
4096 m_inputHnd
->PopupSystemMenu(m_wnd
, pt
);
4097 #endif // wxUSE_MENUS
4100 m_wnd
->SetAcceleratorTable(table
);
4104 void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent
&WXUNUSED(event
))
4106 m_wnd
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4107 wxTOPLEVEL_BUTTON_CLOSE
);
4110 void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent
&event
)
4117 wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler
*handler
)
4118 : wxStdInputHandler(handler
)
4120 m_menuHandler
= new wxWin32SystemMenuEvtHandler(this);
4123 wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
4125 if ( m_menuHandler
)
4127 m_menuHandler
->Detach();
4128 delete m_menuHandler
;
4132 bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
4133 const wxMouseEvent
& event
)
4135 if ( event
.LeftDClick() || event
.LeftDown() || event
.RightDown() )
4137 wxTopLevelWindow
*tlw
=
4138 wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
4140 long hit
= tlw
->HitTest(event
.GetPosition());
4142 if ( event
.LeftDClick() && hit
== wxHT_TOPLEVEL_TITLEBAR
)
4144 tlw
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
4145 tlw
->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
4146 : wxTOPLEVEL_BUTTON_MAXIMIZE
);
4149 else if ( tlw
->GetWindowStyle() & wxSYSTEM_MENU
)
4151 if ( (event
.LeftDown() && hit
== wxHT_TOPLEVEL_ICON
) ||
4152 (event
.RightDown() &&
4153 (hit
== wxHT_TOPLEVEL_TITLEBAR
||
4154 hit
== wxHT_TOPLEVEL_ICON
)) )
4157 PopupSystemMenu(tlw
, event
.GetPosition());
4158 #endif // wxUSE_MENUS
4164 return wxStdInputHandler::HandleMouse(consumer
, event
);
4169 void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow
*window
,
4170 const wxPoint
& pos
) const
4172 wxMenu
*menu
= new wxMenu
;
4174 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4175 menu
->Append(wxID_RESTORE_FRAME
, _("&Restore"));
4176 menu
->Append(wxID_MOVE_FRAME
, _("&Move"));
4177 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4178 menu
->Append(wxID_RESIZE_FRAME
, _("&Size"));
4179 if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
) )
4180 menu
->Append(wxID_ICONIZE_FRAME
, _("Mi&nimize"));
4181 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4182 menu
->Append(wxID_MAXIMIZE_FRAME
, _("Ma&ximize"));
4183 menu
->AppendSeparator();
4184 menu
->Append(wxID_CLOSE_FRAME
, _("Close\tAlt-F4"));
4186 if ( window
->GetWindowStyle() & wxMAXIMIZE_BOX
)
4188 if ( window
->IsMaximized() )
4190 menu
->Enable(wxID_MAXIMIZE_FRAME
, false);
4191 menu
->Enable(wxID_MOVE_FRAME
, false);
4192 if ( window
->GetWindowStyle() & wxRESIZE_BORDER
)
4193 menu
->Enable(wxID_RESIZE_FRAME
, false);
4196 menu
->Enable(wxID_RESTORE_FRAME
, false);
4199 window
->PopupMenu(menu
, pos
);
4203 #endif // wxUSE_MENUS
4205 bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
4208 if ( consumer
->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU
)
4210 // always detach if active frame changed:
4211 m_menuHandler
->Detach();
4215 m_menuHandler
->Attach(consumer
);
4219 return wxStdInputHandler::HandleActivation(consumer
, activated
);