erase.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: samples/erase/erase.cpp
  3. // Purpose: Erase wxWidgets sample
  4. // Author: Robert Roebling, Vadim Zeitlin
  5. // Created: 04/01/98
  6. // Copyright: (c) 1998 Robert Roebling
  7. // (c) 2009 Vadim Zeitlin
  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. // for all others, include the necessary headers (this file is usually all you
  22. // need because it includes almost all "standard" wxWidgets headers)
  23. #ifndef WX_PRECOMP
  24. #include "wx/wx.h"
  25. #endif
  26. #include "wx/custombgwin.h"
  27. #include "wx/dcbuffer.h"
  28. #include "wx/artprov.h"
  29. // ----------------------------------------------------------------------------
  30. // resources
  31. // ----------------------------------------------------------------------------
  32. // the application icon
  33. #ifndef wxHAS_IMAGES_IN_RESOURCES
  34. #include "../sample.xpm"
  35. #endif
  36. // ----------------------------------------------------------------------------
  37. // private classes
  38. // ----------------------------------------------------------------------------
  39. class MyApp : public wxApp
  40. {
  41. public:
  42. virtual bool OnInit();
  43. };
  44. class MyCanvas : public wxCustomBackgroundWindow<wxScrolledWindow>
  45. {
  46. public:
  47. MyCanvas(wxFrame *parent);
  48. void UseBuffer(bool useBuffer) { m_useBuffer = useBuffer; Refresh(); }
  49. bool UsesBuffer() const { return m_useBuffer; }
  50. void UseBgBitmap(bool useBgBmp)
  51. {
  52. m_useBgBmp = useBgBmp;
  53. SetBackgroundBitmap(m_useBgBmp ? GetBgBitmap() : wxBitmap());
  54. Refresh();
  55. }
  56. void EraseBgInPaint(bool erase) { m_eraseBgInPaint = erase; Refresh(); }
  57. private:
  58. void OnPaint( wxPaintEvent &event );
  59. void OnEraseBackground( wxEraseEvent &event );
  60. void DoPaint(wxDC& dc);
  61. // Create an easily recognizable background bitmap.
  62. static wxBitmap GetBgBitmap()
  63. {
  64. static const int BMP_SIZE = 40;
  65. wxBitmap bmp(BMP_SIZE, BMP_SIZE);
  66. wxMemoryDC dc(bmp);
  67. dc.SetBackground(*wxCYAN);
  68. dc.Clear();
  69. dc.SetPen(*wxBLUE_PEN);
  70. dc.DrawLine(0, BMP_SIZE/2, BMP_SIZE/2, 0);
  71. dc.DrawLine(BMP_SIZE/2, 0, BMP_SIZE, BMP_SIZE/2);
  72. dc.DrawLine(BMP_SIZE, BMP_SIZE/2, BMP_SIZE/2, BMP_SIZE);
  73. dc.DrawLine(BMP_SIZE/2, BMP_SIZE, 0, BMP_SIZE/2);
  74. return bmp;
  75. }
  76. wxBitmap m_bitmap;
  77. // use wxMemoryDC in OnPaint()?
  78. bool m_useBuffer;
  79. // use background bitmap?
  80. bool m_useBgBmp;
  81. // erase background in OnPaint()?
  82. bool m_eraseBgInPaint;
  83. wxDECLARE_EVENT_TABLE();
  84. };
  85. class MyFrame : public wxFrame
  86. {
  87. public:
  88. MyFrame();
  89. private:
  90. void OnUseBuffer(wxCommandEvent& event);
  91. void OnUseBgBitmap(wxCommandEvent& event);
  92. void OnEraseBgInPaint(wxCommandEvent& event);
  93. void OnChangeBgStyle(wxCommandEvent& event);
  94. void OnQuit(wxCommandEvent& event);
  95. void OnAbout(wxCommandEvent& event);
  96. // we can only use double-buffering with wxBG_STYLE_PAINT
  97. void OnUpdateUIUseBuffer(wxUpdateUIEvent& event)
  98. {
  99. event.Enable( m_canvas->GetBackgroundStyle() == wxBG_STYLE_PAINT );
  100. }
  101. void OnUpdateUIChangeBgStyle(wxUpdateUIEvent& event)
  102. {
  103. event.Enable( !m_canvas->UsesBuffer() );
  104. }
  105. MyCanvas *m_canvas;
  106. wxDECLARE_EVENT_TABLE();
  107. };
  108. class ControlWithTransparency : public wxWindow
  109. {
  110. public:
  111. ControlWithTransparency(wxWindow *parent,
  112. const wxPoint& pos,
  113. const wxSize& size)
  114. {
  115. wxString reason;
  116. if ( parent->IsTransparentBackgroundSupported(&reason) )
  117. {
  118. SetBackgroundStyle (wxBG_STYLE_TRANSPARENT);
  119. m_message = "This is custom control with transparency";
  120. }
  121. else
  122. {
  123. m_message = "Transparency not supported, check tooltip.";
  124. }
  125. Create (parent, wxID_ANY, pos, size, wxBORDER_NONE);
  126. Connect(wxEVT_PAINT,
  127. wxPaintEventHandler(ControlWithTransparency::OnPaint));
  128. if ( !reason.empty() )
  129. {
  130. // This can be only done now, after creating the window.
  131. SetToolTip(reason);
  132. }
  133. }
  134. private:
  135. void OnPaint( wxPaintEvent& WXUNUSED(event) )
  136. {
  137. wxPaintDC dc(this);
  138. dc.SetPen(*wxRED_PEN);
  139. dc.SetBrush(*wxTRANSPARENT_BRUSH);
  140. dc.DrawRectangle(GetClientSize());
  141. dc.SetTextForeground(*wxBLUE);
  142. dc.SetBackgroundMode(wxTRANSPARENT);
  143. dc.DrawText(m_message, 0, 2);
  144. // Draw some bitmap/icon to ensure transparent bitmaps are indeed
  145. // transparent on transparent windows
  146. wxBitmap bmp(wxArtProvider::GetBitmap(wxART_WARNING, wxART_MENU));
  147. wxIcon icon(wxArtProvider::GetIcon(wxART_GOTO_LAST, wxART_MENU));
  148. dc.DrawBitmap (bmp, GetSize().x - 1 - bmp.GetWidth(), 2);
  149. dc.DrawIcon(icon, GetSize().x - 1 - bmp.GetWidth()-icon.GetWidth(), 2);
  150. }
  151. wxString m_message;
  152. };
  153. // ----------------------------------------------------------------------------
  154. // constants
  155. // ----------------------------------------------------------------------------
  156. enum
  157. {
  158. // menu items
  159. Erase_Menu_UseBuffer = 100,
  160. Erase_Menu_UseBgBitmap,
  161. Erase_Menu_EraseBgInPaint,
  162. Erase_Menu_BgStyleErase,
  163. Erase_Menu_BgStyleSystem,
  164. Erase_Menu_BgStylePaint,
  165. Erase_Menu_Exit = wxID_EXIT,
  166. Erase_Menu_About = wxID_ABOUT
  167. };
  168. // ----------------------------------------------------------------------------
  169. // the application class
  170. // ----------------------------------------------------------------------------
  171. IMPLEMENT_APP(MyApp)
  172. bool MyApp::OnInit()
  173. {
  174. if ( !wxApp::OnInit() )
  175. return false;
  176. MyFrame *frame = new MyFrame;
  177. frame->Show(true);
  178. return true;
  179. }
  180. // ----------------------------------------------------------------------------
  181. // main frame
  182. // ----------------------------------------------------------------------------
  183. wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
  184. EVT_MENU(Erase_Menu_UseBuffer, MyFrame::OnUseBuffer)
  185. EVT_MENU(Erase_Menu_UseBgBitmap, MyFrame::OnUseBgBitmap)
  186. EVT_MENU(Erase_Menu_EraseBgInPaint, MyFrame::OnEraseBgInPaint)
  187. EVT_MENU_RANGE(Erase_Menu_BgStyleErase, Erase_Menu_BgStylePaint,
  188. MyFrame::OnChangeBgStyle)
  189. EVT_MENU(Erase_Menu_Exit, MyFrame::OnQuit)
  190. EVT_MENU(Erase_Menu_About, MyFrame::OnAbout)
  191. EVT_UPDATE_UI(Erase_Menu_UseBuffer, MyFrame::OnUpdateUIUseBuffer)
  192. EVT_UPDATE_UI_RANGE(Erase_Menu_BgStyleErase, Erase_Menu_BgStylePaint,
  193. MyFrame::OnUpdateUIChangeBgStyle)
  194. wxEND_EVENT_TABLE()
  195. // frame constructor
  196. MyFrame::MyFrame()
  197. : wxFrame(NULL, wxID_ANY, "Erase sample",
  198. wxPoint(50, 50), wxSize(450, 340))
  199. {
  200. SetIcon(wxICON(sample));
  201. wxMenu *menuFile = new wxMenu("", wxMENU_TEAROFF);
  202. menuFile->AppendCheckItem(Erase_Menu_UseBuffer, "&Use memory DC\tCtrl-M");
  203. menuFile->AppendCheckItem(Erase_Menu_UseBgBitmap,
  204. "Use background &bitmap\tCtrl-B");
  205. menuFile->AppendCheckItem(Erase_Menu_EraseBgInPaint,
  206. "&Erase background in EVT_PAINT\tCtrl-R");
  207. menuFile->AppendSeparator();
  208. menuFile->AppendRadioItem(Erase_Menu_BgStyleErase,
  209. "Use wxBG_STYLE_&ERASE\tCtrl-E");
  210. menuFile->AppendRadioItem(Erase_Menu_BgStyleSystem,
  211. "Use wxBG_STYLE_&SYSTEM\tCtrl-S");
  212. menuFile->AppendRadioItem(Erase_Menu_BgStylePaint,
  213. "Use wxBG_STYLE_&PAINT\tCtrl-P");
  214. menuFile->AppendSeparator();
  215. menuFile->Append(Erase_Menu_Exit, "E&xit\tAlt-X", "Quit this program");
  216. wxMenu *helpMenu = new wxMenu;
  217. helpMenu->Append(Erase_Menu_About, "&About\tCtrl-A", "Show about dialog");
  218. wxMenuBar *menuBar = new wxMenuBar();
  219. menuBar->Append(menuFile, "&File");
  220. menuBar->Append(helpMenu, "&Help");
  221. SetMenuBar(menuBar);
  222. m_canvas = new MyCanvas( this );
  223. }
  224. void MyFrame::OnUseBuffer(wxCommandEvent& event)
  225. {
  226. m_canvas->UseBuffer(event.IsChecked());
  227. }
  228. void MyFrame::OnUseBgBitmap(wxCommandEvent& event)
  229. {
  230. m_canvas->UseBgBitmap(event.IsChecked());
  231. }
  232. void MyFrame::OnEraseBgInPaint(wxCommandEvent& event)
  233. {
  234. m_canvas->EraseBgInPaint(event.IsChecked());
  235. }
  236. void MyFrame::OnChangeBgStyle(wxCommandEvent& event)
  237. {
  238. int style = wxBG_STYLE_ERASE + event.GetId() - Erase_Menu_BgStyleErase;
  239. m_canvas->SetBackgroundStyle(static_cast<wxBackgroundStyle>(style));
  240. m_canvas->Refresh();
  241. }
  242. void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
  243. {
  244. Close(true);
  245. }
  246. void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
  247. {
  248. wxMessageBox
  249. (
  250. "This sample shows differences between different background styles "
  251. "and how you may draw custom background.\n"
  252. "\n"
  253. "(c) 1998 Robert Roebling\n"
  254. "(c) 2009 Vadim Zeitlin\n",
  255. "About Erase Sample",
  256. wxOK | wxICON_INFORMATION,
  257. this
  258. );
  259. }
  260. wxBEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
  261. EVT_PAINT(MyCanvas::OnPaint)
  262. EVT_ERASE_BACKGROUND(MyCanvas::OnEraseBackground)
  263. wxEND_EVENT_TABLE()
  264. MyCanvas::MyCanvas(wxFrame *parent)
  265. {
  266. Create(parent, wxID_ANY);
  267. m_useBuffer = false;
  268. m_useBgBmp = false;
  269. m_eraseBgInPaint = false;
  270. SetScrollbars( 10, 10, 40, 100, 0, 0 );
  271. m_bitmap = wxBitmap( wxICON(sample) );
  272. new wxStaticBitmap( this, wxID_ANY, m_bitmap, wxPoint(80,20) );
  273. new wxStaticText(this, wxID_ANY,
  274. "Left bitmap is a wxStaticBitmap,\n"
  275. "right one drawn directly",
  276. wxPoint(150, 20));
  277. new ControlWithTransparency(this, wxPoint(65, 125), wxSize(350, 22));
  278. SetFocusIgnoringChildren();
  279. SetBackgroundColour(*wxCYAN);
  280. }
  281. void MyCanvas::DoPaint(wxDC& dc)
  282. {
  283. PrepareDC(dc);
  284. if ( m_eraseBgInPaint )
  285. {
  286. dc.SetBackground(*wxLIGHT_GREY);
  287. // Erase the entire virtual area, not just the client area.
  288. dc.SetPen(*wxTRANSPARENT_PEN);
  289. dc.SetBrush(GetBackgroundColour());
  290. dc.DrawRectangle(GetVirtualSize());
  291. dc.DrawText("Background erased in OnPaint", 65, 110);
  292. }
  293. else if ( GetBackgroundStyle() == wxBG_STYLE_PAINT )
  294. {
  295. dc.SetTextForeground(*wxRED);
  296. dc.DrawText("You must enable erasing background in OnPaint to avoid "
  297. "display corruption", 65, 110);
  298. }
  299. dc.DrawBitmap( m_bitmap, 20, 20, true );
  300. dc.SetTextForeground(*wxRED);
  301. dc.DrawText("This text is drawn from OnPaint", 65, 65);
  302. }
  303. void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
  304. {
  305. if ( m_useBuffer )
  306. {
  307. wxAutoBufferedPaintDC dc(this);
  308. DoPaint(dc);
  309. }
  310. else
  311. {
  312. wxPaintDC dc(this);
  313. DoPaint(dc);
  314. }
  315. }
  316. void MyCanvas::OnEraseBackground( wxEraseEvent& event )
  317. {
  318. // We must not erase the background ourselves if we asked wxPanel to erase
  319. // it using a background bitmap.
  320. if ( m_useBgBmp )
  321. {
  322. event.Skip();
  323. return;
  324. }
  325. wxASSERT_MSG
  326. (
  327. GetBackgroundStyle() == wxBG_STYLE_ERASE,
  328. "shouldn't be called unless background style is \"erase\""
  329. );
  330. wxDC& dc = *event.GetDC();
  331. dc.SetPen(*wxGREEN_PEN);
  332. // clear any junk currently displayed
  333. dc.Clear();
  334. PrepareDC( dc );
  335. const wxSize size = GetVirtualSize();
  336. for ( int x = 0; x < size.x; x += 15 )
  337. {
  338. dc.DrawLine(x, 0, x, size.y);
  339. }
  340. for ( int y = 0; y < size.y; y += 15 )
  341. {
  342. dc.DrawLine(0, y, size.x, y);
  343. }
  344. dc.SetTextForeground(*wxRED);
  345. dc.SetBackgroundMode(wxSOLID);
  346. dc.DrawText("This text is drawn from OnEraseBackground", 60, 160);
  347. }