1///////////////////////////////////////////////////////////////////////////// 2// Name: erase.cpp 3// Purpose: Erase wxWidgets sample 4// Author: Robert Roebling 5// Modified by: 6// Created: 04/01/98 7// RCS-ID: $Id: erase.cpp 35650 2005-09-23 12:56:45Z MR $ 8// Copyright: (c) Robert Roebling 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// ============================================================================ 13// declarations 14// ============================================================================ 15 16// ---------------------------------------------------------------------------- 17// headers 18// ---------------------------------------------------------------------------- 19 20// For compilers that support precompilation, includes "wx/wx.h". 21#include "wx/wxprec.h" 22 23#ifdef __BORLANDC__ 24 #pragma hdrstop 25#endif 26 27// for all others, include the necessary headers (this file is usually all you 28// need because it includes almost all "standard" wxWidgets headers) 29#ifndef WX_PRECOMP 30 #include "wx/wx.h" 31#endif 32 33// ---------------------------------------------------------------------------- 34// resources 35// ---------------------------------------------------------------------------- 36// the application icon 37#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__) 38 #include "mondrian.xpm" 39#endif 40 41// ---------------------------------------------------------------------------- 42// private classes 43// ---------------------------------------------------------------------------- 44 45class MyApp : public wxApp 46{ 47public: 48 virtual bool OnInit(); 49}; 50 51 52class MyCanvas : public wxScrolledWindow 53{ 54public: 55 MyCanvas( wxFrame *parent ); 56 57 void UseBuffer(bool useBuffer) { m_useBuffer = useBuffer; Refresh(); } 58 void EraseBg(bool eraseBg) { m_eraseBg = eraseBg; Refresh(); } 59 60private: 61 void OnPaint( wxPaintEvent &event ); 62 void OnChar( wxKeyEvent &event ); 63 void OnEraseBackground( wxEraseEvent &event ); 64 65 void DoPaint(wxDC& dc); 66 67 68 wxBitmap m_bitmap; 69 wxString m_text; 70 71 // use wxMemoryDC in OnPaint()? 72 bool m_useBuffer; 73 74 // paint custom background in OnEraseBackground()? 75 bool m_eraseBg; 76 77 78 DECLARE_EVENT_TABLE() 79}; 80 81class MyFrame : public wxFrame 82{ 83public: 84 MyFrame(); 85 86 void OnUseBuffer(wxCommandEvent& event); 87 void OnEraseBg(wxCommandEvent& event); 88 void OnQuit(wxCommandEvent& event); 89 void OnAbout(wxCommandEvent& event); 90 91private: 92 MyCanvas *m_canvas; 93 94 DECLARE_EVENT_TABLE() 95}; 96 97 98// ---------------------------------------------------------------------------- 99// constants 100// ---------------------------------------------------------------------------- 101 102enum 103{ 104 // menu items 105 Erase_Menu_UseBuffer = 100, 106 Erase_Menu_EraseBg, 107 Erase_Menu_Exit = wxID_EXIT, 108 Erase_Menu_About = wxID_ABOUT 109}; 110 111 112// ---------------------------------------------------------------------------- 113// the application class 114// ---------------------------------------------------------------------------- 115 116IMPLEMENT_APP(MyApp) 117 118bool MyApp::OnInit() 119{ 120 MyFrame *frame = new MyFrame; 121 122 frame->Show(true); 123 124 return true; 125} 126 127// ---------------------------------------------------------------------------- 128// main frame 129// ---------------------------------------------------------------------------- 130 131BEGIN_EVENT_TABLE(MyFrame, wxFrame) 132 EVT_MENU(Erase_Menu_UseBuffer, MyFrame::OnUseBuffer) 133 EVT_MENU(Erase_Menu_EraseBg, MyFrame::OnEraseBg) 134 EVT_MENU(Erase_Menu_Exit, MyFrame::OnQuit) 135 EVT_MENU(Erase_Menu_About, MyFrame::OnAbout) 136END_EVENT_TABLE() 137 138// frame constructor 139MyFrame::MyFrame() 140 : wxFrame(NULL, wxID_ANY, _T("Erase sample"), 141 wxPoint(50, 50), wxSize(450, 340)) 142{ 143 SetIcon(wxICON(mondrian)); 144 145 wxMenu *menuFile = new wxMenu(_T(""), wxMENU_TEAROFF); 146 menuFile->AppendCheckItem(Erase_Menu_UseBuffer, _T("&Use memory DC\tCtrl-M")); 147 menuFile->AppendCheckItem(Erase_Menu_EraseBg, _T("Custom &background\tCtrl-B")); 148 menuFile->AppendSeparator(); 149 menuFile->Append(Erase_Menu_Exit, _T("E&xit\tAlt-X"), _T("Quit this program")); 150 151 152 wxMenu *helpMenu = new wxMenu; 153 helpMenu->Append(Erase_Menu_About, _T("&About...\tCtrl-A"), _T("Show about dialog")); 154 155 wxMenuBar *menuBar = new wxMenuBar(); 156 menuBar->Append(menuFile, _T("&File")); 157 menuBar->Append(helpMenu, _T("&Help")); 158 159 SetMenuBar(menuBar); 160 161#if wxUSE_STATUSBAR 162 // create a status bar just for fun (by default with 1 pane only) 163 CreateStatusBar(2); 164 SetStatusText(_T("Welcome to wxWidgets erase sample!")); 165#endif // wxUSE_STATUSBAR 166 167 m_canvas = new MyCanvas( this ); 168} 169 170 171void MyFrame::OnUseBuffer(wxCommandEvent& event) 172{ 173 m_canvas->UseBuffer(event.IsChecked()); 174} 175 176void MyFrame::OnEraseBg(wxCommandEvent& event) 177{ 178 m_canvas->EraseBg(event.IsChecked()); 179} 180 181void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) 182{ 183 Close(true); 184} 185 186void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) 187{ 188 wxMessageBox(_T("This sample shows how you can draw custom background."), 189 _T("About Erase Sample"), wxOK | wxICON_INFORMATION, this); 190} 191 192 193BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) 194 EVT_PAINT( MyCanvas::OnPaint) 195 EVT_CHAR( MyCanvas::OnChar) 196 EVT_ERASE_BACKGROUND( MyCanvas::OnEraseBackground) 197END_EVENT_TABLE() 198 199MyCanvas::MyCanvas( wxFrame *parent ) 200 : wxScrolledWindow( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 201 wxScrolledWindowStyle | wxSUNKEN_BORDER ) 202{ 203 m_eraseBg = 204 m_useBuffer = false; 205 206 SetScrollbars( 10, 10, 40, 100, 0, 0 ); 207 208 m_bitmap = wxBitmap( wxICON(mondrian) ); 209 210 new wxStaticBitmap( this, wxID_ANY, m_bitmap, wxPoint(80,20) ); 211 212 SetFocusIgnoringChildren(); 213} 214 215void MyCanvas::OnChar( wxKeyEvent &event ) 216{ 217#if wxUSE_UNICODE 218 if (event.m_uniChar) 219 { 220 m_text += event.m_uniChar; 221 Refresh(); 222 return; 223 } 224#endif 225 226 // some test cases 227 switch (event.m_keyCode) 228 { 229 case WXK_UP: m_text += wxT( "<UP>" ); break; 230 case WXK_LEFT: m_text += wxT( "<LEFT>" ); break; 231 case WXK_RIGHT: m_text += wxT( "<RIGHT>" ); break; 232 case WXK_DOWN: m_text += wxT( "<DOWN>" ); break; 233 case WXK_RETURN: m_text += wxT( "<ENTER>" ); break; 234 default: m_text += (wxChar)event.m_keyCode; break; 235 } 236} 237 238void MyCanvas::DoPaint(wxDC& dc) 239{ 240 dc.SetBrush( *wxBLACK_BRUSH ); 241 dc.DrawRectangle( 10,10,200,50 ); 242 243 dc.DrawBitmap( m_bitmap, 10, 20, true ); 244 245 dc.SetTextForeground(*wxBLUE); 246 dc.DrawText(_T("This text is drawn from OnPaint"), 65, 65); 247 248 wxString tmp; 249 tmp.Printf( _T("Hit any key to display more text: %s"), m_text.c_str() ); 250 int w,h; 251 dc.GetTextExtent( tmp, &w, &h ); 252 dc.SetBrush( *wxWHITE_BRUSH ); 253 dc.DrawRectangle( 65, 85, w, h ); 254 dc.DrawText( tmp, 65, 85 ); 255 256#if 0 257 wxRegionIterator upd( GetUpdateRegion() ); 258 while (upd) 259 { 260 wxLogDebug( _T("Paint: %d %d %d %d"), upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); 261 upd ++; 262 } 263#endif 264 265#if 0 266 wxSize size = GetSize(); 267 wxSize client_size = GetClientSize(); 268 wxLogDebug( _T("size %d %d client_size %d %d"), size.x, size.y, client_size.x, client_size.y ); 269#endif 270 271#if 0 272 int i; 273 dc.SetPen( *wxWHITE_PEN ); 274 for (i = 0; i < 20; i += 2) 275 dc.DrawLine( i,i, i+100,i ); 276 277 dc.SetPen( *wxWHITE_PEN ); 278 for (i = 200; i < 220; i += 2) 279 dc.DrawLine( i-200,i, i-100,i ); 280 281 wxRegion region( 110, 110, 80, 80 ); 282 wxRegion hole( 130, 130, 40, 1 ); 283 region.Intersect( hole ); 284 dc.SetClippingRegion( region ); 285 286 dc.SetBrush( *wxRED_BRUSH ); 287 dc.DrawRectangle( 100, 100, 200, 200 ); 288 289 dc.DestroyClippingRegion(); 290 291 dc.SetPen( *wxTRANSPARENT_PEN ); 292 293 wxRegion strip( 110, 200, 30, 1 ); 294 wxRegionIterator it( strip ); 295 while (it) 296 { 297 dc.DrawRectangle( it.GetX(), it.GetY(), it.GetWidth(), it.GetHeight() ); 298 it ++; 299 } 300#endif // 0 301} 302 303void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) 304{ 305 wxPaintDC dcWin(this); 306 PrepareDC( dcWin ); 307 308 if ( m_useBuffer ) 309 { 310 const wxSize size = GetClientSize(); 311 wxMemoryDC dc; 312 wxBitmap bmp(size.x, size.y); 313 dc.SelectObject(bmp); 314 dc.Blit(0, 0, size.x, size.y, &dcWin, 0, 0); 315 dc.DrawText(_T("(copy of background)"), 5, 120 ); 316 317 DoPaint(dc); 318 319 dcWin.Blit(0, 0, size.x, size.y, &dc, 0, 0); 320 } 321 else 322 { 323 DoPaint(dcWin); 324 } 325} 326 327void MyCanvas::OnEraseBackground( wxEraseEvent& event ) 328{ 329 if ( !m_eraseBg ) 330 { 331 event.Skip(); 332 return; 333 } 334 335 wxDC& dc = *event.GetDC(); 336 dc.SetPen(*wxGREEN_PEN); 337 338 PrepareDC( dc ); 339 340 // clear any junk currently displayed 341 dc.Clear(); 342 343 const wxSize size = GetClientSize(); 344 for ( int x = 0; x < size.x; x += 15 ) 345 { 346 dc.DrawLine(x, 0, x, size.y); 347 } 348 349 for ( int y = 0; y < size.y; y += 15 ) 350 { 351 dc.DrawLine(0, y, size.x, y); 352 } 353 354 dc.SetTextForeground(*wxRED); 355 dc.DrawText(_T("This text is drawn from OnEraseBackground"), 60, 160); 356} 357 358