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"
40 #include "wx/apptrait.h"
41 #include "wx/renderer.h"
43 // ----------------------------------------------------------------------------
45 // ----------------------------------------------------------------------------
47 // the application icon (under Windows and OS/2 it is in resources)
48 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__)
49 #include "../sample.xpm"
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 // A renderer class draws the header buttons in a "special" way
57 class MyRenderer
: public wxDelegateRendererNative
60 MyRenderer() : wxDelegateRendererNative(wxRendererNative::GetDefault()) { }
62 virtual int DrawHeaderButton(wxWindow
*WXUNUSED(win
),
65 int WXUNUSED(flags
) = 0,
66 wxHeaderSortIconType
WXUNUSED(sortArrow
) = wxHDR_SORT_ICON_NONE
,
67 wxHeaderButtonParams
* WXUNUSED(params
) = NULL
)
69 wxDCBrushChanger
setBrush(dc
, *wxBLUE_BRUSH
);
70 wxDCTextColourChanger
setFgCol(dc
, *wxWHITE
);
71 dc
.DrawRoundedRectangle(rect
, 5);
72 dc
.DrawLabel(wxT("MyRenderer"), wxNullBitmap
, rect
, wxALIGN_CENTER
);
77 // To use a different renderer from the very beginning we must override
78 // wxAppTraits method creating the renderer (another, simpler, alternative is
79 // to call wxRendererNative::Set() a.s.a.p. which should work in 99% of the
80 // cases, but we show this here just for completeness)
81 class MyTraits
: public wxGUIAppTraits
83 virtual wxRendererNative
*CreateRenderer()
85 // it will be deleted on program shutdown by wxWidgets itself
86 return new MyRenderer
;
90 // Define a new application type, each program should derive a class from wxApp
91 class MyApp
: public wxApp
94 virtual bool OnInit();
96 // if we want MyTraits to be used we must override CreateTraits()
97 virtual wxAppTraits
*CreateTraits() { return new MyTraits
; }
100 // Define a new frame type: this is going to be our main frame
101 class MyFrame
: public wxFrame
109 // event handlers (these functions should _not_ be virtual)
110 void OnDrawDisabled(wxCommandEvent
& event
)
111 { OnToggleDrawFlag(event
, wxCONTROL_DISABLED
); }
112 void OnDrawFocused(wxCommandEvent
& event
)
113 { OnToggleDrawFlag(event
, wxCONTROL_FOCUSED
); }
114 void OnDrawPressed(wxCommandEvent
& event
)
115 { OnToggleDrawFlag(event
, wxCONTROL_PRESSED
); }
116 void OnDrawChecked(wxCommandEvent
& event
)
117 { OnToggleDrawFlag(event
, wxCONTROL_CHECKED
); }
118 void OnDrawHot(wxCommandEvent
& event
)
119 { OnToggleDrawFlag(event
, wxCONTROL_CURRENT
); }
121 #if wxUSE_DYNLIB_CLASS
122 void OnLoad(wxCommandEvent
& event
);
123 void OnUnload(wxCommandEvent
& event
);
124 #endif // wxUSE_DYNLIB_CLASS
125 void OnQuit(wxCommandEvent
& event
);
126 void OnAbout(wxCommandEvent
& event
);
128 void OnToggleDrawFlag(wxCommandEvent
& event
, int flag
);
130 class MyPanel
*m_panel
;
132 // any class wishing to process wxWidgets events must use this macro
133 DECLARE_EVENT_TABLE()
136 // a very simple class just to have something to draw on
137 class MyPanel
: public wxPanel
140 MyPanel(wxWindow
*parent
) : wxPanel(parent
) { m_flags
= 0; }
142 int GetFlags() const { return m_flags
; }
143 void SetFlags(int flags
) { m_flags
= flags
; }
146 void OnPaint(wxPaintEvent
&)
150 wxRendererNative
& renderer
= wxRendererNative::Get();
152 int x1
= 10, // text offset
153 x2
= 200, // drawing offset
156 const int lineHeight
= dc
.GetCharHeight();
157 dc
.DrawText("Demonstration of various wxRenderer functions:", x1
, y
);
159 wxString flagsString
;
160 if ( m_flags
& wxCONTROL_DISABLED
)
161 flagsString
+= "wxCONTROL_DISABLED ";
162 if ( m_flags
& wxCONTROL_FOCUSED
)
163 flagsString
+= "wxCONTROL_FOCUSED ";
164 if ( m_flags
& wxCONTROL_PRESSED
)
165 flagsString
+= "wxCONTROL_PRESSED ";
166 if ( m_flags
& wxCONTROL_CURRENT
)
167 flagsString
+= "wxCONTROL_CURRENT ";
168 if ( m_flags
& wxCONTROL_CHECKED
)
169 flagsString
+= "wxCONTROL_CHECKED ";
170 if ( flagsString
.empty() )
171 flagsString
= "(none)";
172 dc
.DrawText("Using flags: " + flagsString
, x1
, y
);
175 dc
.DrawText("DrawHeaderButton() (overridden)", x1
, y
);
176 const wxCoord heightHdr
= renderer
.GetHeaderButtonHeight(this);
177 renderer
.DrawHeaderButton(this, dc
,
178 wxRect(x2
, y
, 100, heightHdr
), m_flags
);
179 y
+= lineHeight
+ heightHdr
;
181 dc
.DrawText("DrawCheckBox()", x1
, y
);
182 const wxSize sizeCheck
= renderer
.GetCheckBoxSize(this);
183 renderer
.DrawCheckBox(this, dc
,
184 wxRect(wxPoint(x2
, y
), sizeCheck
), m_flags
);
185 y
+= lineHeight
+ sizeCheck
.y
;
187 dc
.DrawText("DrawRadioBitmap()", x1
, y
);
188 renderer
.DrawRadioBitmap(this, dc
,
189 wxRect(wxPoint(x2
, y
), sizeCheck
), m_flags
);
190 y
+= lineHeight
+ sizeCheck
.y
;
192 dc
.DrawText("DrawTreeItemButton()", x1
, y
);
193 renderer
.DrawTreeItemButton(this, dc
,
194 wxRect(x2
, y
, 20, 20), m_flags
);
195 y
+= lineHeight
+ 20;
197 #ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
198 dc
.DrawText("DrawTitleBarBitmap()", x1
, y
);
199 wxRect
rBtn(x2
, y
, 21, 21);
200 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
201 wxTITLEBAR_BUTTON_HELP
, m_flags
);
202 rBtn
.x
+= 2*rBtn
.width
;
203 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
204 wxTITLEBAR_BUTTON_ICONIZE
, m_flags
);
205 rBtn
.x
+= 2*rBtn
.width
;
206 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
207 wxTITLEBAR_BUTTON_RESTORE
, m_flags
);
208 rBtn
.x
+= 2*rBtn
.width
;
209 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
210 wxTITLEBAR_BUTTON_MAXIMIZE
, m_flags
);
211 rBtn
.x
+= 2*rBtn
.width
;
212 renderer
.DrawTitleBarBitmap(this, dc
, rBtn
,
213 wxTITLEBAR_BUTTON_CLOSE
, m_flags
);
215 y
+= lineHeight
+ rBtn
.height
;
216 #endif // wxHAS_DRAW_TITLE_BAR_BITMAP
221 DECLARE_EVENT_TABLE()
224 BEGIN_EVENT_TABLE(MyPanel
, wxPanel
)
225 EVT_PAINT(MyPanel::OnPaint
)
228 // ----------------------------------------------------------------------------
230 // ----------------------------------------------------------------------------
232 // IDs for the controls and the menu commands
236 Render_DrawDisabled
= 100,
242 #if wxUSE_DYNLIB_CLASS
245 #endif // wxUSE_DYNLIB_CLASS
247 // standard menu items
248 Render_Quit
= wxID_EXIT
,
250 // it is important for the id corresponding to the "About" command to have
251 // this standard value as otherwise it won't be handled properly under Mac
252 // (where it is special and put into the "Apple" menu)
253 Render_About
= wxID_ABOUT
256 // ----------------------------------------------------------------------------
257 // event tables and other macros for wxWidgets
258 // ----------------------------------------------------------------------------
260 // the event tables connect the wxWidgets events with the functions (event
261 // handlers) which process them. It can be also done at run-time, but for the
262 // simple menu events like this the static method is much simpler.
263 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
264 EVT_MENU(Render_DrawDisabled
, MyFrame::OnDrawDisabled
)
265 EVT_MENU(Render_DrawFocused
, MyFrame::OnDrawFocused
)
266 EVT_MENU(Render_DrawPressed
, MyFrame::OnDrawPressed
)
267 EVT_MENU(Render_DrawChecked
, MyFrame::OnDrawChecked
)
268 EVT_MENU(Render_DrawHot
, MyFrame::OnDrawHot
)
270 #if wxUSE_DYNLIB_CLASS
271 EVT_MENU(Render_Load
, MyFrame::OnLoad
)
272 EVT_MENU(Render_Unload
,MyFrame::OnUnload
)
273 #endif // wxUSE_DYNLIB_CLASS
274 EVT_MENU(Render_Quit
, MyFrame::OnQuit
)
276 EVT_MENU(Render_About
, MyFrame::OnAbout
)
279 // Create a new application object: this macro will allow wxWidgets to create
280 // the application object during program execution (it's better than using a
281 // static object for many reasons) and also implements the accessor function
282 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
286 // ============================================================================
288 // ============================================================================
290 // ----------------------------------------------------------------------------
291 // the application class
292 // ----------------------------------------------------------------------------
294 // 'Main program' equivalent: the program execution "starts" here
297 if ( !wxApp::OnInit() )
300 // create the main application window
306 // ----------------------------------------------------------------------------
308 // ----------------------------------------------------------------------------
314 wxT("Render wxWidgets Sample"),
318 // set the frame icon
319 SetIcon(wxICON(sample
));
323 wxMenu
*menuFile
= new wxMenu
;
324 menuFile
->AppendCheckItem(Render_DrawDisabled
,
325 "Draw in &disabled state\tCtrl-D");
326 menuFile
->AppendCheckItem(Render_DrawFocused
,
327 "Draw in &focused state\tCtrl-F");
328 menuFile
->AppendCheckItem(Render_DrawPressed
,
329 "Draw in &pressed state\tCtrl-P");
330 menuFile
->AppendCheckItem(Render_DrawChecked
,
331 "Draw in &checked state\tCtrl-C");
332 menuFile
->AppendCheckItem(Render_DrawHot
,
333 "Draw in &hot state\tCtrl-H");
334 menuFile
->AppendSeparator();
335 #if wxUSE_DYNLIB_CLASS
336 menuFile
->Append(Render_Load
, wxT("&Load renderer...\tCtrl-L"));
337 menuFile
->Append(Render_Unload
, wxT("&Unload renderer\tCtrl-U"));
338 menuFile
->AppendSeparator();
339 #endif // wxUSE_DYNLIB_CLASS
340 menuFile
->Append(Render_Quit
);
342 // the "About" item should be in the help menu
343 wxMenu
*helpMenu
= new wxMenu
;
344 helpMenu
->Append(Render_About
);
346 // now append the freshly created menu to the menu bar...
347 wxMenuBar
*menuBar
= new wxMenuBar();
348 menuBar
->Append(menuFile
, wxT("&File"));
349 menuBar
->Append(helpMenu
, wxT("&Help"));
351 // ... and attach this menu bar to the frame
353 #endif // wxUSE_MENUS
355 m_panel
= new MyPanel(this);
358 // create a status bar just for fun (by default with 1 pane only)
360 SetStatusText(wxT("Welcome to wxWidgets!"));
361 #endif // wxUSE_STATUSBAR
368 delete wxRendererNative::Set(NULL
);
374 void MyFrame::OnToggleDrawFlag(wxCommandEvent
& event
, int flag
)
376 int flags
= m_panel
->GetFlags();
377 if ( event
.IsChecked() )
382 m_panel
->SetFlags(flags
);
386 #if wxUSE_DYNLIB_CLASS
388 void MyFrame::OnLoad(wxCommandEvent
& WXUNUSED(event
))
390 static wxString s_name
= wxT("renddll");
392 wxString name
= wxGetTextFromUser
394 wxT("Name of the renderer to load:"),
395 wxT("Render wxWidgets Sample"),
407 wxRendererNative
*renderer
= wxRendererNative::Load(name
);
410 wxLogError(wxT("Failed to load renderer \"%s\"."), name
.c_str());
414 delete wxRendererNative::Set(renderer
);
418 wxLogStatus(this, wxT("Successfully loaded the renderer \"%s\"."),
423 void MyFrame::OnUnload(wxCommandEvent
& WXUNUSED(event
))
425 wxRendererNative
*renderer
= wxRendererNative::Set(NULL
);
432 wxLogStatus(this, wxT("Unloaded the previously loaded renderer."));
436 wxLogWarning(wxT("No renderer to unload."));
440 #endif // wxUSE_DYNLIB_CLASS
442 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
444 // true is to force the frame to close
448 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
450 wxMessageBox(wxT("Render sample shows how to use custom renderers.\n")
452 wxT("(c) 2003 Vadim Zeitlin"),
453 wxT("About Render wxWidgets Sample"),
454 wxOK
| wxICON_INFORMATION
, this);