1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Render wxWidgets sample
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
30 #include "wx/dcclient.h"
33 #include "wx/textdlg.h"
35 #include "wx/msgdlg.h"
40 #include "wx/apptrait.h"
41 #include "wx/artprov.h"
42 #include "wx/renderer.h"
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 // the application icon (under Windows and OS/2 it is in resources)
49 #ifndef wxHAS_IMAGES_IN_RESOURCES
50 #include "../sample.xpm"
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 // A renderer class draws the header buttons in a "special" way
58 class MyRenderer
: public wxDelegateRendererNative
61 MyRenderer() : wxDelegateRendererNative(wxRendererNative::GetDefault()) { }
63 virtual int DrawHeaderButton(wxWindow
*WXUNUSED(win
),
66 int WXUNUSED(flags
) = 0,
67 wxHeaderSortIconType
WXUNUSED(sortArrow
)
68 = wxHDR_SORT_ICON_NONE
,
69 wxHeaderButtonParams
* params
= NULL
)
71 wxDCBrushChanger
setBrush(dc
, *wxBLUE_BRUSH
);
72 wxDCTextColourChanger
setFgCol(dc
, *wxWHITE
);
73 dc
.DrawRoundedRectangle(rect
, 5);
77 label
= params
->m_labelText
;
78 dc
.DrawLabel(label
, wxNullBitmap
, rect
, wxALIGN_CENTER
);
83 // To use a different renderer from the very beginning we must override
84 // wxAppTraits method creating the renderer (another, simpler, alternative is
85 // to call wxRendererNative::Set() a.s.a.p. which should work in 99% of the
86 // cases, but we show this here just for completeness)
87 class MyTraits
: public wxGUIAppTraits
89 virtual wxRendererNative
*CreateRenderer()
91 // it will be deleted on program shutdown by wxWidgets itself
92 return new MyRenderer
;
96 // Define a new application type, each program should derive a class from wxApp
97 class MyApp
: public wxApp
100 virtual bool OnInit();
102 // if we want MyTraits to be used we must override CreateTraits()
103 virtual wxAppTraits
*CreateTraits() { return new MyTraits
; }
106 // Define a new frame type: this is going to be our main frame
107 class MyFrame
: public wxFrame
115 // event handlers (these functions should _not_ be virtual)
116 void OnDrawDisabled(wxCommandEvent
& event
)
117 { OnToggleDrawFlag(event
, wxCONTROL_DISABLED
); }
118 void OnDrawFocused(wxCommandEvent
& event
)
119 { OnToggleDrawFlag(event
, wxCONTROL_FOCUSED
); }
120 void OnDrawPressed(wxCommandEvent
& event
)
121 { OnToggleDrawFlag(event
, wxCONTROL_PRESSED
); }
122 void OnDrawChecked(wxCommandEvent
& event
)
123 { OnToggleDrawFlag(event
, wxCONTROL_CHECKED
); }
124 void OnDrawHot(wxCommandEvent
& event
)
125 { OnToggleDrawFlag(event
, wxCONTROL_CURRENT
); }
126 void OnDrawUndetermined(wxCommandEvent
&event
)
127 { OnToggleDrawFlag(event
, wxCONTROL_UNDETERMINED
); }
129 void OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
130 { OnChangeAlign(wxALIGN_LEFT
); }
131 void OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
132 { OnChangeAlign(wxALIGN_CENTRE
); }
133 void OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
134 { OnChangeAlign(wxALIGN_RIGHT
); }
136 void OnUseIcon(wxCommandEvent
& event
);
137 void OnUseBitmap(wxCommandEvent
& event
);
139 #if wxUSE_DYNLIB_CLASS
140 void OnLoad(wxCommandEvent
& event
);
141 void OnUnload(wxCommandEvent
& event
);
142 #endif // wxUSE_DYNLIB_CLASS
143 void OnQuit(wxCommandEvent
& event
);
144 void OnAbout(wxCommandEvent
& event
);
146 void OnToggleDrawFlag(wxCommandEvent
& event
, int flag
);
147 void OnChangeAlign(int align
);
149 class MyPanel
*m_panel
;
151 // any class wishing to process wxWidgets events must use this macro
152 DECLARE_EVENT_TABLE()
155 // a very simple class just to have something to draw on
156 class MyPanel
: public wxPanel
159 MyPanel(wxWindow
*parent
) : wxPanel(parent
)
162 m_align
= wxALIGN_LEFT
;
167 int GetFlags() const { return m_flags
; }
168 void SetFlags(int flags
) { m_flags
= flags
; }
170 void SetAlignment(int align
) { m_align
= align
; }
171 void SetUseIcon(bool useIcon
) { m_useIcon
= useIcon
; }
172 void SetUseBitmap(bool useBitmap
) { m_useBitmap
= useBitmap
; }
175 void OnPaint(wxPaintEvent
&)
179 wxRendererNative
& renderer
= wxRendererNative::Get();
181 int x1
= 10, // text offset
182 x2
= 300, // drawing offset
185 const int lineHeight
= dc
.GetCharHeight();
186 dc
.DrawText("Demonstration of various wxRenderer functions:", x1
, y
);
188 wxString flagsString
;
189 if ( m_flags
& wxCONTROL_DISABLED
)
190 flagsString
+= "wxCONTROL_DISABLED ";
191 if ( m_flags
& wxCONTROL_FOCUSED
)
192 flagsString
+= "wxCONTROL_FOCUSED ";
193 if ( m_flags
& wxCONTROL_PRESSED
)
194 flagsString
+= "wxCONTROL_PRESSED ";
195 if ( m_flags
& wxCONTROL_CURRENT
)
196 flagsString
+= "wxCONTROL_CURRENT ";
197 if ( m_flags
& wxCONTROL_CHECKED
)
198 flagsString
+= "wxCONTROL_CHECKED ";
199 if ( m_flags
& wxCONTROL_UNDETERMINED
)
200 flagsString
+= "wxCONTROL_UNDETERMINED ";
201 if ( flagsString
.empty() )
202 flagsString
= "(none)";
203 dc
.DrawText("Using flags: " + flagsString
, x1
, y
);
206 const wxCoord heightHdr
= renderer
.GetHeaderButtonHeight(this);
207 const wxCoord widthHdr
= 120;
209 const wxHeaderSortIconType
210 hdrSortIcon
= m_useIcon
? wxHDR_SORT_ICON_UP
211 : wxHDR_SORT_ICON_NONE
;
213 wxHeaderButtonParams hdrParams
;
214 hdrParams
.m_labelText
= "Header";
215 hdrParams
.m_labelAlignment
= m_align
;
218 hdrParams
.m_labelBitmap
= wxArtProvider::GetBitmap(wxART_WARNING
,
222 dc
.DrawText("DrawHeaderButton() (default)", x1
, y
);
223 wxRendererNative::GetDefault().DrawHeaderButton(this, dc
,
224 wxRect(x2
, y
, widthHdr
, heightHdr
), m_flags
,
225 hdrSortIcon
, &hdrParams
);
226 y
+= lineHeight
+ heightHdr
;
228 dc
.DrawText("DrawHeaderButton() (overridden)", x1
, y
);
229 renderer
.DrawHeaderButton(this, dc
,
230 wxRect(x2
, y
, widthHdr
, heightHdr
), m_flags
,
231 hdrSortIcon
, &hdrParams
);
232 y
+= lineHeight
+ heightHdr
;
234 dc
.DrawText("DrawCheckBox()", x1
, y
);
235 const wxSize sizeCheck
= renderer
.GetCheckBoxSize(this);
236 renderer
.DrawCheckBox(this, dc
,
237 wxRect(wxPoint(x2
, y
), sizeCheck
), m_flags
);
238 y
+= lineHeight
+ sizeCheck
.y
;
240 dc
.DrawText("DrawRadioBitmap()", x1
, y
);
241 renderer
.DrawRadioBitmap(this, dc
,
242 wxRect(wxPoint(x2
, y
), sizeCheck
), m_flags
);
243 y
+= lineHeight
+ sizeCheck
.y
;
245 dc
.DrawText("DrawTreeItemButton()", x1
, y
);
246 renderer
.DrawTreeItemButton(this, dc
,
247 wxRect(x2
, y
, 20, 20), m_flags
);
248 y
+= lineHeight
+ 20;
250 #ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
251 dc
.DrawText("DrawTitleBarBitmap()", x1
, y
);
252 wxRect
rBtn(x2
, y
, 21, 21);
253 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
254 wxTITLEBAR_BUTTON_HELP
, m_flags
);
255 rBtn
.x
+= 2*rBtn
.width
;
256 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
257 wxTITLEBAR_BUTTON_ICONIZE
, m_flags
);
258 rBtn
.x
+= 2*rBtn
.width
;
259 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
260 wxTITLEBAR_BUTTON_RESTORE
, m_flags
);
261 rBtn
.x
+= 2*rBtn
.width
;
262 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
263 wxTITLEBAR_BUTTON_MAXIMIZE
, m_flags
);
264 rBtn
.x
+= 2*rBtn
.width
;
265 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
266 wxTITLEBAR_BUTTON_CLOSE
, m_flags
);
268 y
+= lineHeight
+ rBtn
.height
;
269 #endif // wxHAS_DRAW_TITLE_BAR_BITMAP
277 DECLARE_EVENT_TABLE()
280 BEGIN_EVENT_TABLE(MyPanel
, wxPanel
)
281 EVT_PAINT(MyPanel::OnPaint
)
284 // ----------------------------------------------------------------------------
286 // ----------------------------------------------------------------------------
288 // IDs for the controls and the menu commands
292 Render_DrawDisabled
= 100,
297 Render_DrawUndetermined
,
306 #if wxUSE_DYNLIB_CLASS
309 #endif // wxUSE_DYNLIB_CLASS
311 // standard menu items
312 Render_Quit
= wxID_EXIT
,
314 // it is important for the id corresponding to the "About" command to have
315 // this standard value as otherwise it won't be handled properly under Mac
316 // (where it is special and put into the "Apple" menu)
317 Render_About
= wxID_ABOUT
320 // ----------------------------------------------------------------------------
321 // event tables and other macros for wxWidgets
322 // ----------------------------------------------------------------------------
324 // the event tables connect the wxWidgets events with the functions (event
325 // handlers) which process them. It can be also done at run-time, but for the
326 // simple menu events like this the static method is much simpler.
327 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
328 EVT_MENU(Render_DrawDisabled
, MyFrame::OnDrawDisabled
)
329 EVT_MENU(Render_DrawFocused
, MyFrame::OnDrawFocused
)
330 EVT_MENU(Render_DrawPressed
, MyFrame::OnDrawPressed
)
331 EVT_MENU(Render_DrawChecked
, MyFrame::OnDrawChecked
)
332 EVT_MENU(Render_DrawHot
, MyFrame::OnDrawHot
)
333 EVT_MENU(Render_DrawUndetermined
, MyFrame::OnDrawUndetermined
)
334 EVT_MENU(Render_AlignLeft
, MyFrame::OnAlignLeft
)
335 EVT_MENU(Render_AlignCentre
, MyFrame::OnAlignCentre
)
336 EVT_MENU(Render_AlignRight
, MyFrame::OnAlignRight
)
338 EVT_MENU(Render_UseIcon
, MyFrame::OnUseIcon
)
339 EVT_MENU(Render_UseBitmap
, MyFrame::OnUseBitmap
)
341 #if wxUSE_DYNLIB_CLASS
342 EVT_MENU(Render_Load
, MyFrame::OnLoad
)
343 EVT_MENU(Render_Unload
,MyFrame::OnUnload
)
344 #endif // wxUSE_DYNLIB_CLASS
345 EVT_MENU(Render_Quit
, MyFrame::OnQuit
)
347 EVT_MENU(Render_About
, MyFrame::OnAbout
)
350 // Create a new application object: this macro will allow wxWidgets to create
351 // the application object during program execution (it's better than using a
352 // static object for many reasons) and also implements the accessor function
353 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
357 // ============================================================================
359 // ============================================================================
361 // ----------------------------------------------------------------------------
362 // the application class
363 // ----------------------------------------------------------------------------
365 // 'Main program' equivalent: the program execution "starts" here
368 if ( !wxApp::OnInit() )
372 // currently the images used by DrawTitleBarBitmap() are hard coded as PNG
373 // images inside the library itself so we need to enable PNG support to use
375 wxImage::AddHandler(new wxPNGHandler
);
378 // create the main application window
384 // ----------------------------------------------------------------------------
386 // ----------------------------------------------------------------------------
392 wxT("Render wxWidgets Sample"),
396 // set the frame icon
397 SetIcon(wxICON(sample
));
401 wxMenu
*menuFile
= new wxMenu
;
402 menuFile
->AppendCheckItem(Render_DrawDisabled
,
403 "Draw in &disabled state\tCtrl-D");
404 menuFile
->AppendCheckItem(Render_DrawFocused
,
405 "Draw in &focused state\tCtrl-F");
406 menuFile
->AppendCheckItem(Render_DrawPressed
,
407 "Draw in &pressed state\tCtrl-P");
408 menuFile
->AppendCheckItem(Render_DrawChecked
,
409 "Draw in &checked state\tCtrl-C");
410 menuFile
->AppendCheckItem(Render_DrawHot
,
411 "Draw in &hot state\tCtrl-H");
412 menuFile
->AppendCheckItem(Render_DrawUndetermined
,
413 "Draw in unde&termined state\tCtrl-T");
414 menuFile
->AppendSeparator();
416 menuFile
->AppendRadioItem(Render_AlignLeft
, "&Left align\tCtrl-1");
417 menuFile
->AppendRadioItem(Render_AlignCentre
, "C&entre align\tCtrl-2");
418 menuFile
->AppendRadioItem(Render_AlignRight
, "&Right align\tCtrl-3");
419 menuFile
->AppendSeparator();
421 menuFile
->AppendCheckItem(Render_UseIcon
, "Draw &icon\tCtrl-I");
422 menuFile
->AppendCheckItem(Render_UseBitmap
, "Draw &bitmap\tCtrl-B");
423 menuFile
->AppendSeparator();
425 #if wxUSE_DYNLIB_CLASS
426 menuFile
->Append(Render_Load
, wxT("&Load renderer...\tCtrl-L"));
427 menuFile
->Append(Render_Unload
, wxT("&Unload renderer\tCtrl-U"));
428 menuFile
->AppendSeparator();
429 #endif // wxUSE_DYNLIB_CLASS
430 menuFile
->Append(Render_Quit
);
432 // the "About" item should be in the help menu
433 wxMenu
*helpMenu
= new wxMenu
;
434 helpMenu
->Append(Render_About
);
436 // now append the freshly created menu to the menu bar...
437 wxMenuBar
*menuBar
= new wxMenuBar();
438 menuBar
->Append(menuFile
, wxT("&File"));
439 menuBar
->Append(helpMenu
, wxT("&Help"));
441 // ... and attach this menu bar to the frame
443 #endif // wxUSE_MENUS
445 m_panel
= new MyPanel(this);
448 // create a status bar just for fun (by default with 1 pane only)
450 SetStatusText(wxT("Welcome to wxWidgets!"));
451 #endif // wxUSE_STATUSBAR
458 delete wxRendererNative::Set(NULL
);
464 void MyFrame::OnToggleDrawFlag(wxCommandEvent
& event
, int flag
)
466 int flags
= m_panel
->GetFlags();
467 if ( event
.IsChecked() )
472 m_panel
->SetFlags(flags
);
476 void MyFrame::OnChangeAlign(int align
)
478 m_panel
->SetAlignment(align
);
482 void MyFrame::OnUseIcon(wxCommandEvent
& event
)
484 m_panel
->SetUseIcon(event
.IsChecked());
488 void MyFrame::OnUseBitmap(wxCommandEvent
& event
)
490 m_panel
->SetUseBitmap(event
.IsChecked());
494 #if wxUSE_DYNLIB_CLASS
496 void MyFrame::OnLoad(wxCommandEvent
& WXUNUSED(event
))
498 static wxString s_name
= wxT("renddll");
500 wxString name
= wxGetTextFromUser
502 wxT("Name of the renderer to load:"),
503 wxT("Render wxWidgets Sample"),
515 wxRendererNative
*renderer
= wxRendererNative::Load(name
);
518 wxLogError(wxT("Failed to load renderer \"%s\"."), name
.c_str());
522 delete wxRendererNative::Set(renderer
);
526 wxLogStatus(this, wxT("Successfully loaded the renderer \"%s\"."),
531 void MyFrame::OnUnload(wxCommandEvent
& WXUNUSED(event
))
533 wxRendererNative
*renderer
= wxRendererNative::Set(NULL
);
540 wxLogStatus(this, wxT("Unloaded the previously loaded renderer."));
544 wxLogWarning(wxT("No renderer to unload."));
548 #endif // wxUSE_DYNLIB_CLASS
550 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
552 // true is to force the frame to close
556 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
558 wxMessageBox(wxT("Render sample shows how to use custom renderers.\n")
560 wxT("(c) 2003 Vadim Zeitlin"),
561 wxT("About Render wxWidgets Sample"),
562 wxOK
| wxICON_INFORMATION
, this);