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(__WXMGL__) || 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
); }
128 void OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
129 { OnChangeAlign(wxALIGN_LEFT
); }
130 void OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
131 { OnChangeAlign(wxALIGN_CENTRE
); }
132 void OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
133 { OnChangeAlign(wxALIGN_RIGHT
); }
135 void OnUseIcon(wxCommandEvent
& event
);
136 void OnUseBitmap(wxCommandEvent
& event
);
138 #if wxUSE_DYNLIB_CLASS
139 void OnLoad(wxCommandEvent
& event
);
140 void OnUnload(wxCommandEvent
& event
);
141 #endif // wxUSE_DYNLIB_CLASS
142 void OnQuit(wxCommandEvent
& event
);
143 void OnAbout(wxCommandEvent
& event
);
145 void OnToggleDrawFlag(wxCommandEvent
& event
, int flag
);
146 void OnChangeAlign(int align
);
148 class MyPanel
*m_panel
;
150 // any class wishing to process wxWidgets events must use this macro
151 DECLARE_EVENT_TABLE()
154 // a very simple class just to have something to draw on
155 class MyPanel
: public wxPanel
158 MyPanel(wxWindow
*parent
) : wxPanel(parent
)
161 m_align
= wxALIGN_LEFT
;
166 int GetFlags() const { return m_flags
; }
167 void SetFlags(int flags
) { m_flags
= flags
; }
169 void SetAlignment(int align
) { m_align
= align
; }
170 void SetUseIcon(bool useIcon
) { m_useIcon
= useIcon
; }
171 void SetUseBitmap(bool useBitmap
) { m_useBitmap
= useBitmap
; }
174 void OnPaint(wxPaintEvent
&)
178 wxRendererNative
& renderer
= wxRendererNative::Get();
180 int x1
= 10, // text offset
181 x2
= 300, // drawing offset
184 const int lineHeight
= dc
.GetCharHeight();
185 dc
.DrawText("Demonstration of various wxRenderer functions:", x1
, y
);
187 wxString flagsString
;
188 if ( m_flags
& wxCONTROL_DISABLED
)
189 flagsString
+= "wxCONTROL_DISABLED ";
190 if ( m_flags
& wxCONTROL_FOCUSED
)
191 flagsString
+= "wxCONTROL_FOCUSED ";
192 if ( m_flags
& wxCONTROL_PRESSED
)
193 flagsString
+= "wxCONTROL_PRESSED ";
194 if ( m_flags
& wxCONTROL_CURRENT
)
195 flagsString
+= "wxCONTROL_CURRENT ";
196 if ( m_flags
& wxCONTROL_CHECKED
)
197 flagsString
+= "wxCONTROL_CHECKED ";
198 if ( flagsString
.empty() )
199 flagsString
= "(none)";
200 dc
.DrawText("Using flags: " + flagsString
, x1
, y
);
203 const wxCoord heightHdr
= renderer
.GetHeaderButtonHeight(this);
204 const wxCoord widthHdr
= 120;
206 const wxHeaderSortIconType
207 hdrSortIcon
= m_useIcon
? wxHDR_SORT_ICON_UP
208 : wxHDR_SORT_ICON_NONE
;
210 wxHeaderButtonParams hdrParams
;
211 hdrParams
.m_labelText
= "Header";
212 hdrParams
.m_labelAlignment
= m_align
;
215 hdrParams
.m_labelBitmap
= wxArtProvider::GetBitmap(wxART_WARNING
,
219 dc
.DrawText("DrawHeaderButton() (default)", x1
, y
);
220 wxRendererNative::GetDefault().DrawHeaderButton(this, dc
,
221 wxRect(x2
, y
, widthHdr
, heightHdr
), m_flags
,
222 hdrSortIcon
, &hdrParams
);
223 y
+= lineHeight
+ heightHdr
;
225 dc
.DrawText("DrawHeaderButton() (overridden)", x1
, y
);
226 renderer
.DrawHeaderButton(this, dc
,
227 wxRect(x2
, y
, widthHdr
, heightHdr
), m_flags
,
228 hdrSortIcon
, &hdrParams
);
229 y
+= lineHeight
+ heightHdr
;
231 dc
.DrawText("DrawCheckBox()", x1
, y
);
232 const wxSize sizeCheck
= renderer
.GetCheckBoxSize(this);
233 renderer
.DrawCheckBox(this, dc
,
234 wxRect(wxPoint(x2
, y
), sizeCheck
), m_flags
);
235 y
+= lineHeight
+ sizeCheck
.y
;
237 dc
.DrawText("DrawRadioBitmap()", x1
, y
);
238 renderer
.DrawRadioBitmap(this, dc
,
239 wxRect(wxPoint(x2
, y
), sizeCheck
), m_flags
);
240 y
+= lineHeight
+ sizeCheck
.y
;
242 dc
.DrawText("DrawTreeItemButton()", x1
, y
);
243 renderer
.DrawTreeItemButton(this, dc
,
244 wxRect(x2
, y
, 20, 20), m_flags
);
245 y
+= lineHeight
+ 20;
247 #ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
248 dc
.DrawText("DrawTitleBarBitmap()", x1
, y
);
249 wxRect
rBtn(x2
, y
, 21, 21);
250 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
251 wxTITLEBAR_BUTTON_HELP
, m_flags
);
252 rBtn
.x
+= 2*rBtn
.width
;
253 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
254 wxTITLEBAR_BUTTON_ICONIZE
, m_flags
);
255 rBtn
.x
+= 2*rBtn
.width
;
256 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
257 wxTITLEBAR_BUTTON_RESTORE
, m_flags
);
258 rBtn
.x
+= 2*rBtn
.width
;
259 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
260 wxTITLEBAR_BUTTON_MAXIMIZE
, m_flags
);
261 rBtn
.x
+= 2*rBtn
.width
;
262 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
263 wxTITLEBAR_BUTTON_CLOSE
, m_flags
);
265 y
+= lineHeight
+ rBtn
.height
;
266 #endif // wxHAS_DRAW_TITLE_BAR_BITMAP
274 DECLARE_EVENT_TABLE()
277 BEGIN_EVENT_TABLE(MyPanel
, wxPanel
)
278 EVT_PAINT(MyPanel::OnPaint
)
281 // ----------------------------------------------------------------------------
283 // ----------------------------------------------------------------------------
285 // IDs for the controls and the menu commands
289 Render_DrawDisabled
= 100,
302 #if wxUSE_DYNLIB_CLASS
305 #endif // wxUSE_DYNLIB_CLASS
307 // standard menu items
308 Render_Quit
= wxID_EXIT
,
310 // it is important for the id corresponding to the "About" command to have
311 // this standard value as otherwise it won't be handled properly under Mac
312 // (where it is special and put into the "Apple" menu)
313 Render_About
= wxID_ABOUT
316 // ----------------------------------------------------------------------------
317 // event tables and other macros for wxWidgets
318 // ----------------------------------------------------------------------------
320 // the event tables connect the wxWidgets events with the functions (event
321 // handlers) which process them. It can be also done at run-time, but for the
322 // simple menu events like this the static method is much simpler.
323 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
324 EVT_MENU(Render_DrawDisabled
, MyFrame::OnDrawDisabled
)
325 EVT_MENU(Render_DrawFocused
, MyFrame::OnDrawFocused
)
326 EVT_MENU(Render_DrawPressed
, MyFrame::OnDrawPressed
)
327 EVT_MENU(Render_DrawChecked
, MyFrame::OnDrawChecked
)
328 EVT_MENU(Render_DrawHot
, MyFrame::OnDrawHot
)
330 EVT_MENU(Render_AlignLeft
, MyFrame::OnAlignLeft
)
331 EVT_MENU(Render_AlignCentre
, MyFrame::OnAlignCentre
)
332 EVT_MENU(Render_AlignRight
, MyFrame::OnAlignRight
)
334 EVT_MENU(Render_UseIcon
, MyFrame::OnUseIcon
)
335 EVT_MENU(Render_UseBitmap
, MyFrame::OnUseBitmap
)
337 #if wxUSE_DYNLIB_CLASS
338 EVT_MENU(Render_Load
, MyFrame::OnLoad
)
339 EVT_MENU(Render_Unload
,MyFrame::OnUnload
)
340 #endif // wxUSE_DYNLIB_CLASS
341 EVT_MENU(Render_Quit
, MyFrame::OnQuit
)
343 EVT_MENU(Render_About
, MyFrame::OnAbout
)
346 // Create a new application object: this macro will allow wxWidgets to create
347 // the application object during program execution (it's better than using a
348 // static object for many reasons) and also implements the accessor function
349 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
353 // ============================================================================
355 // ============================================================================
357 // ----------------------------------------------------------------------------
358 // the application class
359 // ----------------------------------------------------------------------------
361 // 'Main program' equivalent: the program execution "starts" here
364 if ( !wxApp::OnInit() )
368 // currently the images used by DrawTitleBarBitmap() are hard coded as PNG
369 // images inside the library itself so we need to enable PNG support to use
371 wxImage::AddHandler(new wxPNGHandler
);
374 // create the main application window
380 // ----------------------------------------------------------------------------
382 // ----------------------------------------------------------------------------
388 wxT("Render wxWidgets Sample"),
392 // set the frame icon
393 SetIcon(wxICON(sample
));
397 wxMenu
*menuFile
= new wxMenu
;
398 menuFile
->AppendCheckItem(Render_DrawDisabled
,
399 "Draw in &disabled state\tCtrl-D");
400 menuFile
->AppendCheckItem(Render_DrawFocused
,
401 "Draw in &focused state\tCtrl-F");
402 menuFile
->AppendCheckItem(Render_DrawPressed
,
403 "Draw in &pressed state\tCtrl-P");
404 menuFile
->AppendCheckItem(Render_DrawChecked
,
405 "Draw in &checked state\tCtrl-C");
406 menuFile
->AppendCheckItem(Render_DrawHot
,
407 "Draw in &hot state\tCtrl-H");
408 menuFile
->AppendSeparator();
410 menuFile
->AppendRadioItem(Render_AlignLeft
, "&Left align\tCtrl-1");
411 menuFile
->AppendRadioItem(Render_AlignCentre
, "C&entre align\tCtrl-2");
412 menuFile
->AppendRadioItem(Render_AlignRight
, "&Right align\tCtrl-3");
413 menuFile
->AppendSeparator();
415 menuFile
->AppendCheckItem(Render_UseIcon
, "Draw &icon\tCtrl-I");
416 menuFile
->AppendCheckItem(Render_UseBitmap
, "Draw &bitmap\tCtrl-B");
417 menuFile
->AppendSeparator();
419 #if wxUSE_DYNLIB_CLASS
420 menuFile
->Append(Render_Load
, wxT("&Load renderer...\tCtrl-L"));
421 menuFile
->Append(Render_Unload
, wxT("&Unload renderer\tCtrl-U"));
422 menuFile
->AppendSeparator();
423 #endif // wxUSE_DYNLIB_CLASS
424 menuFile
->Append(Render_Quit
);
426 // the "About" item should be in the help menu
427 wxMenu
*helpMenu
= new wxMenu
;
428 helpMenu
->Append(Render_About
);
430 // now append the freshly created menu to the menu bar...
431 wxMenuBar
*menuBar
= new wxMenuBar();
432 menuBar
->Append(menuFile
, wxT("&File"));
433 menuBar
->Append(helpMenu
, wxT("&Help"));
435 // ... and attach this menu bar to the frame
437 #endif // wxUSE_MENUS
439 m_panel
= new MyPanel(this);
442 // create a status bar just for fun (by default with 1 pane only)
444 SetStatusText(wxT("Welcome to wxWidgets!"));
445 #endif // wxUSE_STATUSBAR
452 delete wxRendererNative::Set(NULL
);
458 void MyFrame::OnToggleDrawFlag(wxCommandEvent
& event
, int flag
)
460 int flags
= m_panel
->GetFlags();
461 if ( event
.IsChecked() )
466 m_panel
->SetFlags(flags
);
470 void MyFrame::OnChangeAlign(int align
)
472 m_panel
->SetAlignment(align
);
476 void MyFrame::OnUseIcon(wxCommandEvent
& event
)
478 m_panel
->SetUseIcon(event
.IsChecked());
482 void MyFrame::OnUseBitmap(wxCommandEvent
& event
)
484 m_panel
->SetUseBitmap(event
.IsChecked());
488 #if wxUSE_DYNLIB_CLASS
490 void MyFrame::OnLoad(wxCommandEvent
& WXUNUSED(event
))
492 static wxString s_name
= wxT("renddll");
494 wxString name
= wxGetTextFromUser
496 wxT("Name of the renderer to load:"),
497 wxT("Render wxWidgets Sample"),
509 wxRendererNative
*renderer
= wxRendererNative::Load(name
);
512 wxLogError(wxT("Failed to load renderer \"%s\"."), name
.c_str());
516 delete wxRendererNative::Set(renderer
);
520 wxLogStatus(this, wxT("Successfully loaded the renderer \"%s\"."),
525 void MyFrame::OnUnload(wxCommandEvent
& WXUNUSED(event
))
527 wxRendererNative
*renderer
= wxRendererNative::Set(NULL
);
534 wxLogStatus(this, wxT("Unloaded the previously loaded renderer."));
538 wxLogWarning(wxT("No renderer to unload."));
542 #endif // wxUSE_DYNLIB_CLASS
544 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
546 // true is to force the frame to close
550 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
552 wxMessageBox(wxT("Render sample shows how to use custom renderers.\n")
554 wxT("(c) 2003 Vadim Zeitlin"),
555 wxT("About Render wxWidgets Sample"),
556 wxOK
| wxICON_INFORMATION
, this);