+// ----------------------------------------------------------------------------
+// data class for images that need to be rendered
+// ----------------------------------------------------------------------------
+
+#include "wx/arrimpl.cpp"
+WX_DEFINE_OBJARRAY(ArrayOfImages);
+
+// ----------------------------------------------------------------------------
+// custom canvas control that we can draw on
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
+ EVT_LEFT_UP (MyCanvas::OnMouseLeftUp)
+ EVT_RIGHT_UP (MyCanvas::OnMouseRightUp)
+ EVT_PAINT (MyCanvas::OnPaint)
+END_EVENT_TABLE()
+
+MyCanvas::MyCanvas(wxWindow* parent):
+ wxScrolledWindow(parent, wxID_ANY)
+{
+ SetBackgroundColour (wxColour (0,80,60));
+ ClearBackground();
+}
+
+void MyCanvas::ClearImages ()
+{
+ m_images.Clear();
+ Refresh(true);
+}
+
+// Rotate with interpolation and with offset correction
+void MyCanvas::OnMouseLeftUp (wxMouseEvent & event)
+{
+ MyFrame* frame = (MyFrame*) GetParent();
+
+ wxPoint offset;
+ const wxImage& img = wxGetApp().GetImage();
+ wxImage img2 = img.Rotate(frame->m_angle,
+ wxPoint(img.GetWidth() / 2, img.GetHeight() / 2), true, &offset);
+
+ // Add the images to an array to be drawn later in OnPaint()
+ m_images.Add(new MyRenderedImage(wxBitmap(img2),
+ event.m_x + offset.x, event.m_y + offset.y));
+ Refresh(false);
+}
+
+// without interpolation, and without offset correction
+void MyCanvas::OnMouseRightUp (wxMouseEvent & event)
+{
+ MyFrame* frame = (MyFrame*) GetParent();
+
+ const wxImage& img = wxGetApp().GetImage();
+ wxImage img2 = img.Rotate(frame->m_angle,
+ wxPoint(img.GetWidth() / 2, img.GetHeight() / 2), false);
+
+ // Add the images to an array to be drawn later in OnPaint()
+ m_images.Add(new MyRenderedImage(wxBitmap(img2), event.m_x, event.m_y));
+ Refresh(false);
+}
+
+void MyCanvas::OnPaint (wxPaintEvent &)
+{
+ size_t numImages = m_images.GetCount();
+
+ wxPaintDC dc(this);
+ dc.BeginDrawing();
+
+ dc.SetTextForeground(wxColour(255, 255, 255));
+ dc.DrawText(wxT("Click on the canvas to draw a duck."), 10, 10);
+
+ for (size_t i = 0; i < numImages; i++) {
+ MyRenderedImage & image = m_images.Item(i);
+ dc.DrawBitmap(image.m_bmp, image.m_x, image.m_y, true);
+ }
+
+ dc.EndDrawing();
+}
+
+// ----------------------------------------------------------------------------
+// main frame
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+ EVT_MENU (ID_Quit, MyFrame::OnQuit)
+ EVT_MENU (ID_Angle, MyFrame::OnAngle)
+ EVT_MENU (ID_Clear, MyFrame::OnClear)
+END_EVENT_TABLE()
+