1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Render wxWidgets sample
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
31 #include "wx/dcclient.h"
34 #include "wx/textdlg.h"
36 #include "wx/msgdlg.h"
41 #include "wx/apptrait.h"
42 #include "wx/artprov.h"
43 #include "wx/renderer.h"
45 // ----------------------------------------------------------------------------
47 // ----------------------------------------------------------------------------
49 // the application icon (under Windows and OS/2 it is in resources)
50 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXX11__)
51 #include "../sample.xpm"
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 // A renderer class draws the header buttons in a "special" way
59 class MyRenderer
: public wxDelegateRendererNative
62 MyRenderer() : wxDelegateRendererNative(wxRendererNative::GetDefault()) { }
64 virtual int DrawHeaderButton(wxWindow
*WXUNUSED(win
),
67 int WXUNUSED(flags
) = 0,
68 wxHeaderSortIconType
WXUNUSED(sortArrow
)
69 = wxHDR_SORT_ICON_NONE
,
70 wxHeaderButtonParams
* params
= NULL
)
72 wxDCBrushChanger
setBrush(dc
, *wxBLUE_BRUSH
);
73 wxDCTextColourChanger
setFgCol(dc
, *wxWHITE
);
74 dc
.DrawRoundedRectangle(rect
, 5);
78 label
= params
->m_labelText
;
79 dc
.DrawLabel(label
, wxNullBitmap
, rect
, wxALIGN_CENTER
);
84 // To use a different renderer from the very beginning we must override
85 // wxAppTraits method creating the renderer (another, simpler, alternative is
86 // to call wxRendererNative::Set() a.s.a.p. which should work in 99% of the
87 // cases, but we show this here just for completeness)
88 class MyTraits
: public wxGUIAppTraits
90 virtual wxRendererNative
*CreateRenderer()
92 // it will be deleted on program shutdown by wxWidgets itself
93 return new MyRenderer
;
97 // Define a new application type, each program should derive a class from wxApp
98 class MyApp
: public wxApp
101 virtual bool OnInit();
103 // if we want MyTraits to be used we must override CreateTraits()
104 virtual wxAppTraits
*CreateTraits() { return new MyTraits
; }
107 // Define a new frame type: this is going to be our main frame
108 class MyFrame
: public wxFrame
116 // event handlers (these functions should _not_ be virtual)
117 void OnDrawDisabled(wxCommandEvent
& event
)
118 { OnToggleDrawFlag(event
, wxCONTROL_DISABLED
); }
119 void OnDrawFocused(wxCommandEvent
& event
)
120 { OnToggleDrawFlag(event
, wxCONTROL_FOCUSED
); }
121 void OnDrawPressed(wxCommandEvent
& event
)
122 { OnToggleDrawFlag(event
, wxCONTROL_PRESSED
); }
123 void OnDrawChecked(wxCommandEvent
& event
)
124 { OnToggleDrawFlag(event
, wxCONTROL_CHECKED
); }
125 void OnDrawHot(wxCommandEvent
& event
)
126 { OnToggleDrawFlag(event
, wxCONTROL_CURRENT
); }
127 void OnDrawUndetermined(wxCommandEvent
&event
)
128 { OnToggleDrawFlag(event
, wxCONTROL_UNDETERMINED
); }
130 void OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
131 { OnChangeAlign(wxALIGN_LEFT
); }
132 void OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
133 { OnChangeAlign(wxALIGN_CENTRE
); }
134 void OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
135 { OnChangeAlign(wxALIGN_RIGHT
); }
137 void OnUseIcon(wxCommandEvent
& event
);
138 void OnUseBitmap(wxCommandEvent
& event
);
140 #if wxUSE_DYNLIB_CLASS
141 void OnLoad(wxCommandEvent
& event
);
142 void OnUnload(wxCommandEvent
& event
);
143 #endif // wxUSE_DYNLIB_CLASS
144 void OnQuit(wxCommandEvent
& event
);
145 void OnAbout(wxCommandEvent
& event
);
147 void OnToggleDrawFlag(wxCommandEvent
& event
, int flag
);
148 void OnChangeAlign(int align
);
150 class MyPanel
*m_panel
;
152 // any class wishing to process wxWidgets events must use this macro
153 DECLARE_EVENT_TABLE()
156 // a very simple class just to have something to draw on
157 class MyPanel
: public wxPanel
160 MyPanel(wxWindow
*parent
) : wxPanel(parent
)
163 m_align
= wxALIGN_LEFT
;
168 int GetFlags() const { return m_flags
; }
169 void SetFlags(int flags
) { m_flags
= flags
; }
171 void SetAlignment(int align
) { m_align
= align
; }
172 void SetUseIcon(bool useIcon
) { m_useIcon
= useIcon
; }
173 void SetUseBitmap(bool useBitmap
) { m_useBitmap
= useBitmap
; }
176 void OnPaint(wxPaintEvent
&)
180 wxRendererNative
& renderer
= wxRendererNative::Get();
182 int x1
= 10, // text offset
183 x2
= 300, // drawing offset
186 const int lineHeight
= dc
.GetCharHeight();
187 dc
.DrawText("Demonstration of various wxRenderer functions:", x1
, y
);
189 wxString flagsString
;
190 if ( m_flags
& wxCONTROL_DISABLED
)
191 flagsString
+= "wxCONTROL_DISABLED ";
192 if ( m_flags
& wxCONTROL_FOCUSED
)
193 flagsString
+= "wxCONTROL_FOCUSED ";
194 if ( m_flags
& wxCONTROL_PRESSED
)
195 flagsString
+= "wxCONTROL_PRESSED ";
196 if ( m_flags
& wxCONTROL_CURRENT
)
197 flagsString
+= "wxCONTROL_CURRENT ";
198 if ( m_flags
& wxCONTROL_CHECKED
)
199 flagsString
+= "wxCONTROL_CHECKED ";
200 if ( m_flags
& wxCONTROL_UNDETERMINED
)
201 flagsString
+= "wxCONTROL_UNDETERMINED ";
202 if ( flagsString
.empty() )
203 flagsString
= "(none)";
204 dc
.DrawText("Using flags: " + flagsString
, x1
, y
);
207 const wxCoord heightHdr
= renderer
.GetHeaderButtonHeight(this);
208 const wxCoord widthHdr
= 120;
210 const wxHeaderSortIconType
211 hdrSortIcon
= m_useIcon
? wxHDR_SORT_ICON_UP
212 : wxHDR_SORT_ICON_NONE
;
214 wxHeaderButtonParams hdrParams
;
215 hdrParams
.m_labelText
= "Header";
216 hdrParams
.m_labelAlignment
= m_align
;
219 hdrParams
.m_labelBitmap
= wxArtProvider::GetBitmap(wxART_WARNING
,
223 dc
.DrawText("DrawHeaderButton() (default)", x1
, y
);
224 wxRendererNative::GetDefault().DrawHeaderButton(this, dc
,
225 wxRect(x2
, y
, widthHdr
, heightHdr
), m_flags
,
226 hdrSortIcon
, &hdrParams
);
227 y
+= lineHeight
+ heightHdr
;
229 dc
.DrawText("DrawHeaderButton() (overridden)", x1
, y
);
230 renderer
.DrawHeaderButton(this, dc
,
231 wxRect(x2
, y
, widthHdr
, heightHdr
), m_flags
,
232 hdrSortIcon
, &hdrParams
);
233 y
+= lineHeight
+ heightHdr
;
235 dc
.DrawText("DrawCheckBox()", x1
, y
);
236 const wxSize sizeCheck
= renderer
.GetCheckBoxSize(this);
237 renderer
.DrawCheckBox(this, dc
,
238 wxRect(wxPoint(x2
, y
), sizeCheck
), m_flags
);
239 y
+= lineHeight
+ sizeCheck
.y
;
241 dc
.DrawText("DrawRadioBitmap()", x1
, y
);
242 renderer
.DrawRadioBitmap(this, dc
,
243 wxRect(wxPoint(x2
, y
), sizeCheck
), m_flags
);
244 y
+= lineHeight
+ sizeCheck
.y
;
246 dc
.DrawText("DrawTreeItemButton()", x1
, y
);
247 renderer
.DrawTreeItemButton(this, dc
,
248 wxRect(x2
, y
, 20, 20), m_flags
);
249 y
+= lineHeight
+ 20;
251 #ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
252 dc
.DrawText("DrawTitleBarBitmap()", x1
, y
);
253 wxRect
rBtn(x2
, y
, 21, 21);
254 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
255 wxTITLEBAR_BUTTON_HELP
, m_flags
);
256 rBtn
.x
+= 2*rBtn
.width
;
257 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
258 wxTITLEBAR_BUTTON_ICONIZE
, m_flags
);
259 rBtn
.x
+= 2*rBtn
.width
;
260 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
261 wxTITLEBAR_BUTTON_RESTORE
, m_flags
);
262 rBtn
.x
+= 2*rBtn
.width
;
263 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
264 wxTITLEBAR_BUTTON_MAXIMIZE
, m_flags
);
265 rBtn
.x
+= 2*rBtn
.width
;
266 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
267 wxTITLEBAR_BUTTON_CLOSE
, m_flags
);
269 y
+= lineHeight
+ rBtn
.height
;
270 #endif // wxHAS_DRAW_TITLE_BAR_BITMAP
278 DECLARE_EVENT_TABLE()
281 BEGIN_EVENT_TABLE(MyPanel
, wxPanel
)
282 EVT_PAINT(MyPanel::OnPaint
)
285 // ----------------------------------------------------------------------------
287 // ----------------------------------------------------------------------------
289 // IDs for the controls and the menu commands
293 Render_DrawDisabled
= 100,
298 Render_DrawUndetermined
,
307 #if wxUSE_DYNLIB_CLASS
310 #endif // wxUSE_DYNLIB_CLASS
312 // standard menu items
313 Render_Quit
= wxID_EXIT
,
315 // it is important for the id corresponding to the "About" command to have
316 // this standard value as otherwise it won't be handled properly under Mac
317 // (where it is special and put into the "Apple" menu)
318 Render_About
= wxID_ABOUT
321 // ----------------------------------------------------------------------------
322 // event tables and other macros for wxWidgets
323 // ----------------------------------------------------------------------------
325 // the event tables connect the wxWidgets events with the functions (event
326 // handlers) which process them. It can be also done at run-time, but for the
327 // simple menu events like this the static method is much simpler.
328 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
329 EVT_MENU(Render_DrawDisabled
, MyFrame::OnDrawDisabled
)
330 EVT_MENU(Render_DrawFocused
, MyFrame::OnDrawFocused
)
331 EVT_MENU(Render_DrawPressed
, MyFrame::OnDrawPressed
)
332 EVT_MENU(Render_DrawChecked
, MyFrame::OnDrawChecked
)
333 EVT_MENU(Render_DrawHot
, MyFrame::OnDrawHot
)
334 EVT_MENU(Render_DrawUndetermined
, MyFrame::OnDrawUndetermined
)
335 EVT_MENU(Render_AlignLeft
, MyFrame::OnAlignLeft
)
336 EVT_MENU(Render_AlignCentre
, MyFrame::OnAlignCentre
)
337 EVT_MENU(Render_AlignRight
, MyFrame::OnAlignRight
)
339 EVT_MENU(Render_UseIcon
, MyFrame::OnUseIcon
)
340 EVT_MENU(Render_UseBitmap
, MyFrame::OnUseBitmap
)
342 #if wxUSE_DYNLIB_CLASS
343 EVT_MENU(Render_Load
, MyFrame::OnLoad
)
344 EVT_MENU(Render_Unload
,MyFrame::OnUnload
)
345 #endif // wxUSE_DYNLIB_CLASS
346 EVT_MENU(Render_Quit
, MyFrame::OnQuit
)
348 EVT_MENU(Render_About
, MyFrame::OnAbout
)
351 // Create a new application object: this macro will allow wxWidgets to create
352 // the application object during program execution (it's better than using a
353 // static object for many reasons) and also implements the accessor function
354 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
358 // ============================================================================
360 // ============================================================================
362 // ----------------------------------------------------------------------------
363 // the application class
364 // ----------------------------------------------------------------------------
366 // 'Main program' equivalent: the program execution "starts" here
369 if ( !wxApp::OnInit() )
373 // currently the images used by DrawTitleBarBitmap() are hard coded as PNG
374 // images inside the library itself so we need to enable PNG support to use
376 wxImage::AddHandler(new wxPNGHandler
);
379 // create the main application window
385 // ----------------------------------------------------------------------------
387 // ----------------------------------------------------------------------------
393 wxT("Render wxWidgets Sample"),
397 // set the frame icon
398 SetIcon(wxICON(sample
));
402 wxMenu
*menuFile
= new wxMenu
;
403 menuFile
->AppendCheckItem(Render_DrawDisabled
,
404 "Draw in &disabled state\tCtrl-D");
405 menuFile
->AppendCheckItem(Render_DrawFocused
,
406 "Draw in &focused state\tCtrl-F");
407 menuFile
->AppendCheckItem(Render_DrawPressed
,
408 "Draw in &pressed state\tCtrl-P");
409 menuFile
->AppendCheckItem(Render_DrawChecked
,
410 "Draw in &checked state\tCtrl-C");
411 menuFile
->AppendCheckItem(Render_DrawHot
,
412 "Draw in &hot state\tCtrl-H");
413 menuFile
->AppendCheckItem(Render_DrawUndetermined
,
414 "Draw in unde&termined state\tCtrl-T");
415 menuFile
->AppendSeparator();
417 menuFile
->AppendRadioItem(Render_AlignLeft
, "&Left align\tCtrl-1");
418 menuFile
->AppendRadioItem(Render_AlignCentre
, "C&entre align\tCtrl-2");
419 menuFile
->AppendRadioItem(Render_AlignRight
, "&Right align\tCtrl-3");
420 menuFile
->AppendSeparator();
422 menuFile
->AppendCheckItem(Render_UseIcon
, "Draw &icon\tCtrl-I");
423 menuFile
->AppendCheckItem(Render_UseBitmap
, "Draw &bitmap\tCtrl-B");
424 menuFile
->AppendSeparator();
426 #if wxUSE_DYNLIB_CLASS
427 menuFile
->Append(Render_Load
, wxT("&Load renderer...\tCtrl-L"));
428 menuFile
->Append(Render_Unload
, wxT("&Unload renderer\tCtrl-U"));
429 menuFile
->AppendSeparator();
430 #endif // wxUSE_DYNLIB_CLASS
431 menuFile
->Append(Render_Quit
);
433 // the "About" item should be in the help menu
434 wxMenu
*helpMenu
= new wxMenu
;
435 helpMenu
->Append(Render_About
);
437 // now append the freshly created menu to the menu bar...
438 wxMenuBar
*menuBar
= new wxMenuBar();
439 menuBar
->Append(menuFile
, wxT("&File"));
440 menuBar
->Append(helpMenu
, wxT("&Help"));
442 // ... and attach this menu bar to the frame
444 #endif // wxUSE_MENUS
446 m_panel
= new MyPanel(this);
449 // create a status bar just for fun (by default with 1 pane only)
451 SetStatusText(wxT("Welcome to wxWidgets!"));
452 #endif // wxUSE_STATUSBAR
459 delete wxRendererNative::Set(NULL
);
465 void MyFrame::OnToggleDrawFlag(wxCommandEvent
& event
, int flag
)
467 int flags
= m_panel
->GetFlags();
468 if ( event
.IsChecked() )
473 m_panel
->SetFlags(flags
);
477 void MyFrame::OnChangeAlign(int align
)
479 m_panel
->SetAlignment(align
);
483 void MyFrame::OnUseIcon(wxCommandEvent
& event
)
485 m_panel
->SetUseIcon(event
.IsChecked());
489 void MyFrame::OnUseBitmap(wxCommandEvent
& event
)
491 m_panel
->SetUseBitmap(event
.IsChecked());
495 #if wxUSE_DYNLIB_CLASS
497 void MyFrame::OnLoad(wxCommandEvent
& WXUNUSED(event
))
499 static wxString s_name
= wxT("renddll");
501 wxString name
= wxGetTextFromUser
503 wxT("Name of the renderer to load:"),
504 wxT("Render wxWidgets Sample"),
516 wxRendererNative
*renderer
= wxRendererNative::Load(name
);
519 wxLogError(wxT("Failed to load renderer \"%s\"."), name
.c_str());
523 delete wxRendererNative::Set(renderer
);
527 wxLogStatus(this, wxT("Successfully loaded the renderer \"%s\"."),
532 void MyFrame::OnUnload(wxCommandEvent
& WXUNUSED(event
))
534 wxRendererNative
*renderer
= wxRendererNative::Set(NULL
);
541 wxLogStatus(this, wxT("Unloaded the previously loaded renderer."));
545 wxLogWarning(wxT("No renderer to unload."));
549 #endif // wxUSE_DYNLIB_CLASS
551 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
553 // true is to force the frame to close
557 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
559 wxMessageBox(wxT("Render sample shows how to use custom renderers.\n")
561 wxT("(c) 2003 Vadim Zeitlin"),
562 wxT("About Render wxWidgets Sample"),
563 wxOK
| wxICON_INFORMATION
, this);