render.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: render.cpp
  3. // Purpose: Render wxWidgets sample
  4. // Author: Vadim Zeitlin
  5. // Modified by:
  6. // Created: 04.08.03
  7. // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org>
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. // ============================================================================
  11. // declarations
  12. // ============================================================================
  13. // ----------------------------------------------------------------------------
  14. // headers
  15. // ----------------------------------------------------------------------------
  16. // For compilers that support precompilation, includes "wx/wx.h".
  17. #include "wx/wxprec.h"
  18. #ifdef __BORLANDC__
  19. #pragma hdrstop
  20. #endif
  21. #ifndef WX_PRECOMP
  22. #include "wx/app.h"
  23. #include "wx/frame.h"
  24. #include "wx/dc.h"
  25. #include "wx/dcclient.h"
  26. #include "wx/panel.h"
  27. #include "wx/menu.h"
  28. #include "wx/textdlg.h"
  29. #include "wx/log.h"
  30. #include "wx/msgdlg.h"
  31. #include "wx/icon.h"
  32. #include "wx/image.h"
  33. #endif
  34. #include "wx/apptrait.h"
  35. #include "wx/artprov.h"
  36. #include "wx/renderer.h"
  37. // ----------------------------------------------------------------------------
  38. // resources
  39. // ----------------------------------------------------------------------------
  40. // the application icon (under Windows and OS/2 it is in resources)
  41. #ifndef wxHAS_IMAGES_IN_RESOURCES
  42. #include "../sample.xpm"
  43. #endif
  44. // ----------------------------------------------------------------------------
  45. // private classes
  46. // ----------------------------------------------------------------------------
  47. // A renderer class draws the header buttons in a "special" way
  48. class MyRenderer : public wxDelegateRendererNative
  49. {
  50. public:
  51. MyRenderer() : wxDelegateRendererNative(wxRendererNative::GetDefault()) { }
  52. virtual int DrawHeaderButton(wxWindow *WXUNUSED(win),
  53. wxDC& dc,
  54. const wxRect& rect,
  55. int WXUNUSED(flags) = 0,
  56. wxHeaderSortIconType WXUNUSED(sortArrow)
  57. = wxHDR_SORT_ICON_NONE,
  58. wxHeaderButtonParams* params = NULL)
  59. {
  60. wxDCBrushChanger setBrush(dc, *wxBLUE_BRUSH);
  61. wxDCTextColourChanger setFgCol(dc, *wxWHITE);
  62. dc.DrawRoundedRectangle(rect, 5);
  63. wxString label;
  64. if ( params )
  65. label = params->m_labelText;
  66. dc.DrawLabel(label, wxNullBitmap, rect, wxALIGN_CENTER);
  67. return rect.width;
  68. }
  69. };
  70. // To use a different renderer from the very beginning we must override
  71. // wxAppTraits method creating the renderer (another, simpler, alternative is
  72. // to call wxRendererNative::Set() a.s.a.p. which should work in 99% of the
  73. // cases, but we show this here just for completeness)
  74. class MyTraits : public wxGUIAppTraits
  75. {
  76. virtual wxRendererNative *CreateRenderer()
  77. {
  78. // it will be deleted on program shutdown by wxWidgets itself
  79. return new MyRenderer;
  80. }
  81. };
  82. // Define a new application type, each program should derive a class from wxApp
  83. class MyApp : public wxApp
  84. {
  85. public:
  86. virtual bool OnInit();
  87. // if we want MyTraits to be used we must override CreateTraits()
  88. virtual wxAppTraits *CreateTraits() { return new MyTraits; }
  89. };
  90. // Define a new frame type: this is going to be our main frame
  91. class MyFrame : public wxFrame
  92. {
  93. public:
  94. // ctor(s)
  95. MyFrame();
  96. virtual ~MyFrame();
  97. private:
  98. // event handlers (these functions should _not_ be virtual)
  99. void OnDrawDisabled(wxCommandEvent& event)
  100. { OnToggleDrawFlag(event, wxCONTROL_DISABLED); }
  101. void OnDrawFocused(wxCommandEvent& event)
  102. { OnToggleDrawFlag(event, wxCONTROL_FOCUSED); }
  103. void OnDrawPressed(wxCommandEvent& event)
  104. { OnToggleDrawFlag(event, wxCONTROL_PRESSED); }
  105. void OnDrawChecked(wxCommandEvent& event)
  106. { OnToggleDrawFlag(event, wxCONTROL_CHECKED); }
  107. void OnDrawHot(wxCommandEvent& event)
  108. { OnToggleDrawFlag(event, wxCONTROL_CURRENT); }
  109. void OnDrawUndetermined(wxCommandEvent &event)
  110. { OnToggleDrawFlag(event, wxCONTROL_UNDETERMINED); }
  111. void OnAlignLeft(wxCommandEvent& WXUNUSED(event))
  112. { OnChangeAlign(wxALIGN_LEFT); }
  113. void OnAlignCentre(wxCommandEvent& WXUNUSED(event))
  114. { OnChangeAlign(wxALIGN_CENTRE); }
  115. void OnAlignRight(wxCommandEvent& WXUNUSED(event))
  116. { OnChangeAlign(wxALIGN_RIGHT); }
  117. void OnUseIcon(wxCommandEvent& event);
  118. void OnUseBitmap(wxCommandEvent& event);
  119. #if wxUSE_DYNLIB_CLASS
  120. void OnLoad(wxCommandEvent& event);
  121. void OnUnload(wxCommandEvent& event);
  122. #endif // wxUSE_DYNLIB_CLASS
  123. void OnQuit(wxCommandEvent& event);
  124. void OnAbout(wxCommandEvent& event);
  125. void OnToggleDrawFlag(wxCommandEvent& event, int flag);
  126. void OnChangeAlign(int align);
  127. class MyPanel *m_panel;
  128. // any class wishing to process wxWidgets events must use this macro
  129. wxDECLARE_EVENT_TABLE();
  130. };
  131. // a very simple class just to have something to draw on
  132. class MyPanel : public wxPanel
  133. {
  134. public:
  135. MyPanel(wxWindow *parent) : wxPanel(parent)
  136. {
  137. m_flags = 0;
  138. m_align = wxALIGN_LEFT;
  139. m_useIcon =
  140. m_useBitmap = false;
  141. }
  142. int GetFlags() const { return m_flags; }
  143. void SetFlags(int flags) { m_flags = flags; }
  144. void SetAlignment(int align) { m_align = align; }
  145. void SetUseIcon(bool useIcon) { m_useIcon = useIcon; }
  146. void SetUseBitmap(bool useBitmap) { m_useBitmap = useBitmap; }
  147. private:
  148. void OnPaint(wxPaintEvent&)
  149. {
  150. wxPaintDC dc(this);
  151. wxRendererNative& renderer = wxRendererNative::Get();
  152. int x1 = 10, // text offset
  153. x2 = 300, // drawing offset
  154. y = 10;
  155. const int lineHeight = dc.GetCharHeight();
  156. dc.DrawText("Demonstration of various wxRenderer functions:", x1, y);
  157. y += lineHeight;
  158. wxString flagsString;
  159. if ( m_flags & wxCONTROL_DISABLED )
  160. flagsString += "wxCONTROL_DISABLED ";
  161. if ( m_flags & wxCONTROL_FOCUSED )
  162. flagsString += "wxCONTROL_FOCUSED ";
  163. if ( m_flags & wxCONTROL_PRESSED )
  164. flagsString += "wxCONTROL_PRESSED ";
  165. if ( m_flags & wxCONTROL_CURRENT )
  166. flagsString += "wxCONTROL_CURRENT ";
  167. if ( m_flags & wxCONTROL_CHECKED )
  168. flagsString += "wxCONTROL_CHECKED ";
  169. if ( m_flags & wxCONTROL_UNDETERMINED )
  170. flagsString += "wxCONTROL_UNDETERMINED ";
  171. if ( flagsString.empty() )
  172. flagsString = "(none)";
  173. dc.DrawText("Using flags: " + flagsString, x1, y);
  174. y += lineHeight*3;
  175. const wxCoord heightHdr = renderer.GetHeaderButtonHeight(this);
  176. const wxCoord widthHdr = 120;
  177. const wxHeaderSortIconType
  178. hdrSortIcon = m_useIcon ? wxHDR_SORT_ICON_UP
  179. : wxHDR_SORT_ICON_NONE;
  180. wxHeaderButtonParams hdrParams;
  181. hdrParams.m_labelText = "Header";
  182. hdrParams.m_labelAlignment = m_align;
  183. if ( m_useBitmap )
  184. {
  185. hdrParams.m_labelBitmap = wxArtProvider::GetBitmap(wxART_WARNING,
  186. wxART_LIST);
  187. }
  188. dc.DrawText("DrawHeaderButton() (default)", x1, y);
  189. wxRendererNative::GetDefault().DrawHeaderButton(this, dc,
  190. wxRect(x2, y, widthHdr, heightHdr), m_flags,
  191. hdrSortIcon, &hdrParams);
  192. y += lineHeight + heightHdr;
  193. dc.DrawText("DrawHeaderButton() (overridden)", x1, y);
  194. renderer.DrawHeaderButton(this, dc,
  195. wxRect(x2, y, widthHdr, heightHdr), m_flags,
  196. hdrSortIcon, &hdrParams);
  197. y += lineHeight + heightHdr;
  198. dc.DrawText("DrawCheckBox()", x1, y);
  199. const wxSize sizeCheck = renderer.GetCheckBoxSize(this);
  200. renderer.DrawCheckBox(this, dc,
  201. wxRect(wxPoint(x2, y), sizeCheck), m_flags);
  202. y += lineHeight + sizeCheck.y;
  203. dc.DrawText("DrawRadioBitmap()", x1, y);
  204. renderer.DrawRadioBitmap(this, dc,
  205. wxRect(wxPoint(x2, y), sizeCheck), m_flags);
  206. y += lineHeight + sizeCheck.y;
  207. dc.DrawText("DrawTreeItemButton()", x1, y);
  208. renderer.DrawTreeItemButton(this, dc,
  209. wxRect(x2, y, 20, 20), m_flags);
  210. y += lineHeight + 20;
  211. #ifdef wxHAS_DRAW_TITLE_BAR_BITMAP
  212. dc.DrawText("DrawTitleBarBitmap()", x1, y);
  213. wxRect rBtn(x2, y, 21, 21);
  214. renderer.DrawTitleBarBitmap(this, dc, rBtn,
  215. wxTITLEBAR_BUTTON_HELP, m_flags);
  216. rBtn.x += 2*rBtn.width;
  217. renderer.DrawTitleBarBitmap(this, dc, rBtn,
  218. wxTITLEBAR_BUTTON_ICONIZE, m_flags);
  219. rBtn.x += 2*rBtn.width;
  220. renderer.DrawTitleBarBitmap(this, dc, rBtn,
  221. wxTITLEBAR_BUTTON_RESTORE, m_flags);
  222. rBtn.x += 2*rBtn.width;
  223. renderer.DrawTitleBarBitmap(this, dc, rBtn,
  224. wxTITLEBAR_BUTTON_MAXIMIZE, m_flags);
  225. rBtn.x += 2*rBtn.width;
  226. renderer.DrawTitleBarBitmap(this, dc, rBtn,
  227. wxTITLEBAR_BUTTON_CLOSE, m_flags);
  228. y += lineHeight + rBtn.height;
  229. #endif // wxHAS_DRAW_TITLE_BAR_BITMAP
  230. }
  231. int m_flags;
  232. int m_align;
  233. bool m_useIcon,
  234. m_useBitmap;
  235. wxDECLARE_EVENT_TABLE();
  236. };
  237. wxBEGIN_EVENT_TABLE(MyPanel, wxPanel)
  238. EVT_PAINT(MyPanel::OnPaint)
  239. wxEND_EVENT_TABLE()
  240. // ----------------------------------------------------------------------------
  241. // constants
  242. // ----------------------------------------------------------------------------
  243. // IDs for the controls and the menu commands
  244. enum
  245. {
  246. // our menu items
  247. Render_DrawDisabled = 100,
  248. Render_DrawFocused,
  249. Render_DrawPressed,
  250. Render_DrawChecked,
  251. Render_DrawHot,
  252. Render_DrawUndetermined,
  253. Render_AlignLeft,
  254. Render_AlignCentre,
  255. Render_AlignRight,
  256. Render_UseIcon,
  257. Render_UseBitmap,
  258. #if wxUSE_DYNLIB_CLASS
  259. Render_Load,
  260. Render_Unload,
  261. #endif // wxUSE_DYNLIB_CLASS
  262. // standard menu items
  263. Render_Quit = wxID_EXIT,
  264. // it is important for the id corresponding to the "About" command to have
  265. // this standard value as otherwise it won't be handled properly under Mac
  266. // (where it is special and put into the "Apple" menu)
  267. Render_About = wxID_ABOUT
  268. };
  269. // ----------------------------------------------------------------------------
  270. // event tables and other macros for wxWidgets
  271. // ----------------------------------------------------------------------------
  272. // the event tables connect the wxWidgets events with the functions (event
  273. // handlers) which process them. It can be also done at run-time, but for the
  274. // simple menu events like this the static method is much simpler.
  275. wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
  276. EVT_MENU(Render_DrawDisabled, MyFrame::OnDrawDisabled)
  277. EVT_MENU(Render_DrawFocused, MyFrame::OnDrawFocused)
  278. EVT_MENU(Render_DrawPressed, MyFrame::OnDrawPressed)
  279. EVT_MENU(Render_DrawChecked, MyFrame::OnDrawChecked)
  280. EVT_MENU(Render_DrawHot, MyFrame::OnDrawHot)
  281. EVT_MENU(Render_DrawUndetermined, MyFrame::OnDrawUndetermined)
  282. EVT_MENU(Render_AlignLeft, MyFrame::OnAlignLeft)
  283. EVT_MENU(Render_AlignCentre, MyFrame::OnAlignCentre)
  284. EVT_MENU(Render_AlignRight, MyFrame::OnAlignRight)
  285. EVT_MENU(Render_UseIcon, MyFrame::OnUseIcon)
  286. EVT_MENU(Render_UseBitmap, MyFrame::OnUseBitmap)
  287. #if wxUSE_DYNLIB_CLASS
  288. EVT_MENU(Render_Load, MyFrame::OnLoad)
  289. EVT_MENU(Render_Unload,MyFrame::OnUnload)
  290. #endif // wxUSE_DYNLIB_CLASS
  291. EVT_MENU(Render_Quit, MyFrame::OnQuit)
  292. EVT_MENU(Render_About, MyFrame::OnAbout)
  293. wxEND_EVENT_TABLE()
  294. // Create a new application object: this macro will allow wxWidgets to create
  295. // the application object during program execution (it's better than using a
  296. // static object for many reasons) and also implements the accessor function
  297. // wxGetApp() which will return the reference of the right type (i.e. MyApp and
  298. // not wxApp)
  299. IMPLEMENT_APP(MyApp)
  300. // ============================================================================
  301. // implementation
  302. // ============================================================================
  303. // ----------------------------------------------------------------------------
  304. // the application class
  305. // ----------------------------------------------------------------------------
  306. // 'Main program' equivalent: the program execution "starts" here
  307. bool MyApp::OnInit()
  308. {
  309. if ( !wxApp::OnInit() )
  310. return false;
  311. #ifdef __WXOSX__
  312. // currently the images used by DrawTitleBarBitmap() are hard coded as PNG
  313. // images inside the library itself so we need to enable PNG support to use
  314. // this function
  315. wxImage::AddHandler(new wxPNGHandler);
  316. #endif // OS X
  317. // create the main application window
  318. new MyFrame;
  319. return true;
  320. }
  321. // ----------------------------------------------------------------------------
  322. // main frame
  323. // ----------------------------------------------------------------------------
  324. // frame constructor
  325. MyFrame::MyFrame()
  326. : wxFrame(NULL,
  327. wxID_ANY,
  328. wxT("Render wxWidgets Sample"),
  329. wxPoint(50, 50),
  330. wxSize(450, 340))
  331. {
  332. // set the frame icon
  333. SetIcon(wxICON(sample));
  334. #if wxUSE_MENUS
  335. // create a menu bar
  336. wxMenu *menuFile = new wxMenu;
  337. menuFile->AppendCheckItem(Render_DrawDisabled,
  338. "Draw in &disabled state\tCtrl-D");
  339. menuFile->AppendCheckItem(Render_DrawFocused,
  340. "Draw in &focused state\tCtrl-F");
  341. menuFile->AppendCheckItem(Render_DrawPressed,
  342. "Draw in &pressed state\tCtrl-P");
  343. menuFile->AppendCheckItem(Render_DrawChecked,
  344. "Draw in &checked state\tCtrl-C");
  345. menuFile->AppendCheckItem(Render_DrawHot,
  346. "Draw in &hot state\tCtrl-H");
  347. menuFile->AppendCheckItem(Render_DrawUndetermined,
  348. "Draw in unde&termined state\tCtrl-T");
  349. menuFile->AppendSeparator();
  350. menuFile->AppendRadioItem(Render_AlignLeft, "&Left align\tCtrl-1");
  351. menuFile->AppendRadioItem(Render_AlignCentre, "C&entre align\tCtrl-2");
  352. menuFile->AppendRadioItem(Render_AlignRight, "&Right align\tCtrl-3");
  353. menuFile->AppendSeparator();
  354. menuFile->AppendCheckItem(Render_UseIcon, "Draw &icon\tCtrl-I");
  355. menuFile->AppendCheckItem(Render_UseBitmap, "Draw &bitmap\tCtrl-B");
  356. menuFile->AppendSeparator();
  357. #if wxUSE_DYNLIB_CLASS
  358. menuFile->Append(Render_Load, wxT("&Load renderer...\tCtrl-L"));
  359. menuFile->Append(Render_Unload, wxT("&Unload renderer\tCtrl-U"));
  360. menuFile->AppendSeparator();
  361. #endif // wxUSE_DYNLIB_CLASS
  362. menuFile->Append(Render_Quit);
  363. // the "About" item should be in the help menu
  364. wxMenu *helpMenu = new wxMenu;
  365. helpMenu->Append(Render_About);
  366. // now append the freshly created menu to the menu bar...
  367. wxMenuBar *menuBar = new wxMenuBar();
  368. menuBar->Append(menuFile, wxT("&File"));
  369. menuBar->Append(helpMenu, wxT("&Help"));
  370. // ... and attach this menu bar to the frame
  371. SetMenuBar(menuBar);
  372. #endif // wxUSE_MENUS
  373. m_panel = new MyPanel(this);
  374. #if wxUSE_STATUSBAR
  375. // create a status bar just for fun (by default with 1 pane only)
  376. CreateStatusBar(2);
  377. SetStatusText(wxT("Welcome to wxWidgets!"));
  378. #endif // wxUSE_STATUSBAR
  379. Show();
  380. }
  381. MyFrame::~MyFrame()
  382. {
  383. delete wxRendererNative::Set(NULL);
  384. }
  385. // event handlers
  386. void MyFrame::OnToggleDrawFlag(wxCommandEvent& event, int flag)
  387. {
  388. int flags = m_panel->GetFlags();
  389. if ( event.IsChecked() )
  390. flags |= flag;
  391. else
  392. flags &= ~flag;
  393. m_panel->SetFlags(flags);
  394. m_panel->Refresh();
  395. }
  396. void MyFrame::OnChangeAlign(int align)
  397. {
  398. m_panel->SetAlignment(align);
  399. m_panel->Refresh();
  400. }
  401. void MyFrame::OnUseIcon(wxCommandEvent& event)
  402. {
  403. m_panel->SetUseIcon(event.IsChecked());
  404. m_panel->Refresh();
  405. }
  406. void MyFrame::OnUseBitmap(wxCommandEvent& event)
  407. {
  408. m_panel->SetUseBitmap(event.IsChecked());
  409. m_panel->Refresh();
  410. }
  411. #if wxUSE_DYNLIB_CLASS
  412. void MyFrame::OnLoad(wxCommandEvent& WXUNUSED(event))
  413. {
  414. static wxString s_name = wxT("renddll");
  415. wxString name = wxGetTextFromUser
  416. (
  417. wxT("Name of the renderer to load:"),
  418. wxT("Render wxWidgets Sample"),
  419. s_name,
  420. this
  421. );
  422. if ( name.empty() )
  423. {
  424. // cancelled
  425. return;
  426. }
  427. s_name = name;
  428. wxRendererNative *renderer = wxRendererNative::Load(name);
  429. if ( !renderer )
  430. {
  431. wxLogError(wxT("Failed to load renderer \"%s\"."), name.c_str());
  432. }
  433. else // loaded ok
  434. {
  435. delete wxRendererNative::Set(renderer);
  436. m_panel->Refresh();
  437. wxLogStatus(this, wxT("Successfully loaded the renderer \"%s\"."),
  438. name.c_str());
  439. }
  440. }
  441. void MyFrame::OnUnload(wxCommandEvent& WXUNUSED(event))
  442. {
  443. wxRendererNative *renderer = wxRendererNative::Set(NULL);
  444. if ( renderer )
  445. {
  446. delete renderer;
  447. m_panel->Refresh();
  448. wxLogStatus(this, wxT("Unloaded the previously loaded renderer."));
  449. }
  450. else
  451. {
  452. wxLogWarning(wxT("No renderer to unload."));
  453. }
  454. }
  455. #endif // wxUSE_DYNLIB_CLASS
  456. void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
  457. {
  458. // true is to force the frame to close
  459. Close(true);
  460. }
  461. void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
  462. {
  463. wxMessageBox(wxT("Render sample shows how to use custom renderers.\n")
  464. wxT("\n")
  465. wxT("(c) 2003 Vadim Zeitlin"),
  466. wxT("About Render wxWidgets Sample"),
  467. wxOK | wxICON_INFORMATION, this);
  468. }