]> git.saurik.com Git - wxWidgets.git/blob - samples/rotate/rotate.cpp
don't bubble up the events upwards the window hierarchy in non-last event handler...
[wxWidgets.git] / samples / rotate / rotate.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: rotate.cpp
3 // Purpose: Image rotation test
4 // Author: Carlos Moreno
5 // Modified by:
6 // Created: 6/2/2000
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #include "wx/wx.h"
29 #endif
30
31 #include "wx/image.h"
32 #include "wx/numdlg.h"
33 #include "wx/dynarray.h"
34
35 // ----------------------------------------------------------------------------
36 // application class
37 // ----------------------------------------------------------------------------
38
39 class MyApp: public wxApp
40 {
41 public:
42 virtual bool OnInit();
43 const wxImage& GetImage() const { return m_image; }
44
45 private:
46 wxImage m_image;
47 };
48
49 // ----------------------------------------------------------------------------
50 // data class for images that need to be rendered
51 // ----------------------------------------------------------------------------
52
53 class MyRenderedImage
54 {
55 public:
56 MyRenderedImage(const wxBitmap& bmp, int x, int y)
57 : m_bmp(bmp), m_x(x), m_y(y) { }
58 wxBitmap m_bmp;
59 int m_x, m_y;
60 };
61
62 // Declare a wxArray type to hold MyRenderedImages.
63 WX_DECLARE_OBJARRAY(MyRenderedImage, ArrayOfImages);
64
65 // ----------------------------------------------------------------------------
66 // custom canvas control that we can draw on
67 // ----------------------------------------------------------------------------
68
69 class MyCanvas: public wxScrolledWindow
70 {
71 public:
72 MyCanvas(wxWindow* parent);
73
74 void ClearImages();
75
76 void OnMouseLeftUp (wxMouseEvent & event);
77 void OnMouseRightUp (wxMouseEvent & event);
78 void OnPaint (wxPaintEvent & event);
79
80 private:
81 ArrayOfImages m_images;
82
83 DECLARE_EVENT_TABLE()
84 };
85
86 // ----------------------------------------------------------------------------
87 // main frame
88 // ----------------------------------------------------------------------------
89
90 class MyFrame: public wxFrame
91 {
92 public:
93 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
94
95 void OnQuit (wxCommandEvent &);
96 void OnAngle(wxCommandEvent &);
97 void OnClear(wxCommandEvent &);
98
99 double m_angle;
100
101 DECLARE_EVENT_TABLE()
102
103 private:
104 MyCanvas *m_canvas;
105 };
106
107 // ----------------------------------------------------------------------------
108 // menu item identifiers
109 // ----------------------------------------------------------------------------
110
111 enum
112 {
113 ID_Quit = 1,
114 ID_Angle,
115 ID_Clear
116 };
117
118 // ============================================================================
119 // implementation
120 // ============================================================================
121
122 // ----------------------------------------------------------------------------
123 // application class
124 // ----------------------------------------------------------------------------
125
126 IMPLEMENT_APP(MyApp)
127
128 bool MyApp::OnInit()
129 {
130 if ( !wxApp::OnInit() )
131 return false;
132
133 #if wxUSE_LIBPNG
134 wxImage::AddHandler( new wxPNGHandler );
135 #endif
136
137 m_image = wxImage(_T("duck.png"), wxBITMAP_TYPE_PNG);
138
139 if ( !m_image.Ok() )
140 {
141 wxLogError(wxT("Can't load the test image, please copy it to the ")
142 wxT("program directory"));
143 return false;
144 }
145
146 MyFrame *frame = new MyFrame (_T("wxWidgets rotate sample"),
147 wxPoint(20, 20), wxSize(600, 450));
148
149 frame->Show (true);
150 SetTopWindow (frame);
151 return true;
152 }
153
154 // ----------------------------------------------------------------------------
155 // data class for images that need to be rendered
156 // ----------------------------------------------------------------------------
157
158 #include "wx/arrimpl.cpp"
159 WX_DEFINE_OBJARRAY(ArrayOfImages)
160
161 // ----------------------------------------------------------------------------
162 // custom canvas control that we can draw on
163 // ----------------------------------------------------------------------------
164
165 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
166 EVT_LEFT_UP (MyCanvas::OnMouseLeftUp)
167 EVT_RIGHT_UP (MyCanvas::OnMouseRightUp)
168 EVT_PAINT (MyCanvas::OnPaint)
169 END_EVENT_TABLE()
170
171 MyCanvas::MyCanvas(wxWindow* parent):
172 wxScrolledWindow(parent, wxID_ANY)
173 {
174 SetBackgroundColour (wxColour (0,80,60));
175 ClearBackground();
176 }
177
178 void MyCanvas::ClearImages ()
179 {
180 m_images.Clear();
181 Refresh(true);
182 }
183
184 // Rotate with interpolation and with offset correction
185 void MyCanvas::OnMouseLeftUp (wxMouseEvent & event)
186 {
187 MyFrame* frame = (MyFrame*) GetParent();
188
189 wxPoint offset;
190 const wxImage& img = wxGetApp().GetImage();
191 wxImage img2 = img.Rotate(frame->m_angle,
192 wxPoint(img.GetWidth() / 2, img.GetHeight() / 2), true, &offset);
193
194 // Add the images to an array to be drawn later in OnPaint()
195 m_images.Add(new MyRenderedImage(wxBitmap(img2),
196 event.m_x + offset.x, event.m_y + offset.y));
197 Refresh(false);
198 }
199
200 // without interpolation, and without offset correction
201 void MyCanvas::OnMouseRightUp (wxMouseEvent & event)
202 {
203 MyFrame* frame = (MyFrame*) GetParent();
204
205 const wxImage& img = wxGetApp().GetImage();
206 wxImage img2 = img.Rotate(frame->m_angle,
207 wxPoint(img.GetWidth() / 2, img.GetHeight() / 2), false);
208
209 // Add the images to an array to be drawn later in OnPaint()
210 m_images.Add(new MyRenderedImage(wxBitmap(img2), event.m_x, event.m_y));
211 Refresh(false);
212 }
213
214 void MyCanvas::OnPaint (wxPaintEvent &)
215 {
216 size_t numImages = m_images.GetCount();
217
218 wxPaintDC dc(this);
219
220 dc.SetTextForeground(wxColour(255, 255, 255));
221 dc.DrawText(wxT("Click on the canvas to draw a duck."), 10, 10);
222
223 for (size_t i = 0; i < numImages; i++) {
224 MyRenderedImage & image = m_images.Item(i);
225 dc.DrawBitmap(image.m_bmp, image.m_x, image.m_y, true);
226 }
227 }
228
229 // ----------------------------------------------------------------------------
230 // main frame
231 // ----------------------------------------------------------------------------
232
233 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
234 EVT_MENU (ID_Quit, MyFrame::OnQuit)
235 EVT_MENU (ID_Angle, MyFrame::OnAngle)
236 EVT_MENU (ID_Clear, MyFrame::OnClear)
237 END_EVENT_TABLE()
238
239 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
240 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
241 {
242 m_angle = 0.1;
243
244 m_canvas = new MyCanvas(this);
245
246 wxMenu *menuFile = new wxMenu;
247 menuFile->Append (ID_Angle, _T("Set &angle...\tCtrl-A"));
248 menuFile->Append (ID_Clear, _T("&Clear all ducks\tCtrl-C"));
249 menuFile->AppendSeparator();
250 menuFile->Append (ID_Quit, _T("E&xit\tAlt-X"));
251
252 wxMenuBar *menuBar = new wxMenuBar;
253 menuBar->Append (menuFile, _T("&File"));
254
255 SetMenuBar (menuBar);
256 }
257
258 void MyFrame::OnAngle (wxCommandEvent &)
259 {
260 long degrees = (long)((180*m_angle)/M_PI);
261 degrees = wxGetNumberFromUser(_T("Change the image rotation angle"),
262 _T("Angle in degrees:"),
263 _T("wxWidgets rotate sample"),
264 degrees,
265 -180, +180,
266 this);
267 if ( degrees != -1 )
268 m_angle = (degrees * M_PI) / 180.0;
269 }
270
271 void MyFrame::OnQuit (wxCommandEvent &)
272 {
273 Close (true);
274 }
275
276 void MyFrame::OnClear (wxCommandEvent &)
277 {
278 m_canvas->ClearImages ();
279 }
280