132 lines
3.6 KiB
C++
132 lines
3.6 KiB
C++
#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();
|
|
}
|
|
}
|