#include "image_position_picker.h" BEGIN_EVENT_TABLE(ImagePositionPicker, wxPanel) // some useful events /* EVT_MOTION(ImagePositionPicker::mouseMoved) EVT_LEFT_DOWN(ImagePositionPicker::mouseDown) EVT_LEFT_UP(ImagePositionPicker::mouseReleased) EVT_RIGHT_DOWN(ImagePositionPicker::rightClick) EVT_LEAVE_WINDOW(ImagePositionPicker::mouseLeftWindow) EVT_KEY_DOWN(ImagePositionPicker::keyPressed) EVT_KEY_UP(ImagePositionPicker::keyReleased) EVT_MOUSEWHEEL(ImagePositionPicker::mouseWheelMoved) */ // catch paint events EVT_PAINT(ImagePositionPicker::paintEvent) //Size event EVT_SIZE(ImagePositionPicker::OnSize) EVT_MOUSE_EVENTS(ImagePositionPicker::OnMouseEvent) END_EVENT_TABLE() // some useful events /* void ImagePositionPicker::mouseMoved(wxMouseEvent& event) {} void ImagePositionPicker::mouseDown(wxMouseEvent& event) {} void ImagePositionPicker::mouseWheelMoved(wxMouseEvent& event) {} void ImagePositionPicker::mouseReleased(wxMouseEvent& event) {} void ImagePositionPicker::rightClick(wxMouseEvent& event) {} void ImagePositionPicker::mouseLeftWindow(wxMouseEvent& event) {} void ImagePositionPicker::keyPressed(wxKeyEvent& event) {} void ImagePositionPicker::keyReleased(wxKeyEvent& event) {} */ ImagePositionPicker::ImagePositionPicker(wxWindow* parent, wxImage i, updator upd) : wxPanel(parent) { image = i; prevW = -1; prevH = -1; w = image.GetWidth(); h = image.GetHeight(); update = upd; } /* * Called by the system of by wxWidgets when the panel needs * to be redrawn. You can also trigger this call by * calling Refresh()/Update(). */ void ImagePositionPicker::paintEvent(wxPaintEvent& evt) { // depending on your system you may need to look at double-buffered dcs wxPaintDC dc(this); render(dc); } /* * Alternatively, you can use a clientDC to paint on the panel * at any time. Using this generally does not free you from * catching paint events, since it is possible that e.g. the window * manager throws away your drawing when the window comes to the * background, and expects you will redraw it when the window comes * back (by sending a paint event). */ void ImagePositionPicker::paintNow() { // depending on your system you may need to look at double-buffered dcs wxClientDC dc(this); render(dc); } /* * Here we do the actual rendering. I put it in a separate * method so that it can work no matter what type of DC * (e.g. wxPaintDC or wxClientDC) is used. */ void ImagePositionPicker::render(wxDC& dc) { int neww, newh; dc.GetSize(&neww, &newh); if (neww != prevW || newh != prevH) { // keep the image proportionate int ww, hh; if (double(neww) / w >= double(newh) / h) // too long { ww = newh * w / h; hh = newh; } else { ww = neww; hh = neww * h / w; } resized = wxBitmap(image.Scale(ww, hh /*, wxIMAGE_QUALITY_HIGH*/)); prevW = ww; prevH = hh; dc.DrawBitmap(resized, 0, 0, false); } else { dc.DrawBitmap(resized, 0, 0, false); } } /* * Here we call refresh to tell the panel to draw itself again. * So when the user resizes the image panel the image should be resized too. */ void ImagePositionPicker::OnSize(wxSizeEvent& event) { Refresh(); //skip the event. event.Skip(); } void ImagePositionPicker::OnMouseEvent(wxMouseEvent& evt) { wxPoint pos = evt.GetPosition(); if (evt.Dragging() || evt.LeftDown() || evt.LeftUp()) { int x = pos.x * w / prevW; int y = pos.y * h / prevH; if (x >= 0 && x < w && y >= 0 && y < h) update(x, y, image.GetRed(x, y), image.GetGreen(x, y), image.GetBlue(x, y)); } else if (evt.LeftDClick()) { // Propagate the double click event to submit evt.ResumePropagation(wxEVENT_PROPAGATE_MAX); evt.Skip(); } }