00001
00024 #ifndef _CPIMAGECTRL_H
00025 #define _CPIMAGECTRL_H
00026
00027 #include <string>
00028 #include <vector>
00029
00030 #include <base_wx/wxImageCache.h>
00031
00032 class CPEditorPanel;
00033 class CPImageCtrl;
00034
00038 class CPEvent : public wxCommandEvent
00039 {
00040 DECLARE_DYNAMIC_CLASS(CPEvent)
00041
00042 enum CPEventMode { NONE, NEW_POINT_CHANGED, NEW_LINE_ADDED, POINT_SELECTED, POINT_CHANGED, RIGHT_CLICK, SCROLLED, DELETE_REGION_SELECTED };
00043
00044 public:
00045 CPEvent( );
00047 CPEvent(wxWindow* win, CPEventMode mode);
00049 CPEvent(wxWindow* win, hugin_utils::FDiff2D & p);
00051 CPEvent(wxWindow *win, unsigned int cpNr);
00053 CPEvent(wxWindow* win, unsigned int cpNr, const hugin_utils::FDiff2D & p);
00055 CPEvent(wxWindow* win, const hugin_utils::FDiff2D & p1, const hugin_utils::FDiff2D & p2);
00057 CPEvent(wxWindow* win, CPEventMode mode, const hugin_utils::FDiff2D & p);
00059 CPEvent(wxWindow* win, CPEventMode mode, const HuginBase::ControlPoint cp);
00061 CPEvent(wxWindow* win, CPEventMode mode, size_t cpNr, const HuginBase::ControlPoint cp);
00062
00063 virtual wxEvent* Clone() const;
00064
00067 CPEventMode getMode()
00068 { return mode; };
00069
00070 const wxRect & getRect()
00071 { return region; }
00072
00073 const hugin_utils::FDiff2D & getPoint()
00074 { return point; }
00075
00076 unsigned int getPointNr()
00077 { return pointNr; }
00078
00079 const HuginBase::ControlPoint& getControlPoint()
00080 { return m_cp; };
00081 private:
00082 CPEventMode mode;
00083 wxRect region;
00084 hugin_utils::FDiff2D point;
00085 HuginBase::ControlPoint m_cp;
00086 int pointNr;
00087 };
00088
00089 typedef void (wxEvtHandler::*CPEventFunction)(CPEvent&);
00090
00091 BEGIN_DECLARE_EVENT_TYPES()
00092 #if _WINDOWS && defined Hugin_shared
00093 DECLARE_LOCAL_EVENT_TYPE(EVT_CPEVENT,1)
00094 #else
00095 DECLARE_EVENT_TYPE(EVT_CPEVENT,1)
00096 #endif
00097 END_DECLARE_EVENT_TYPES()
00098
00099 #define EVT_CPEVENT(func) \
00100 DECLARE_EVENT_TABLE_ENTRY( EVT_CPEVENT, \
00101 -1, \
00102 -1, \
00103 (wxObjectEventFunction) \
00104 (CPEventFunction) & func, \
00105 (wxObject *) NULL ),
00106
00107
00109 class DisplayedControlPoint
00110 {
00111 public:
00113 DisplayedControlPoint() { m_mirrored=false; m_control=NULL; m_line=false; };
00115 DisplayedControlPoint(const HuginBase::ControlPoint& cp, CPImageCtrl* control, bool mirrored);
00117 void SetColour(wxColour pointColour, wxColour textColour);
00119 void SetLabel(wxString newLabel);
00121 void SetControl(CPImageCtrl* control);
00123 void Draw(wxDC& dc, bool selected, bool newPoint=false);
00125 const bool isOccupiedLabel(const wxPoint mousePos) const;
00127 const bool isOccupiedPos(const hugin_utils::FDiff2D &p) const;
00131 void CheckSelection(const wxPoint mousePos, const hugin_utils::FDiff2D& p);
00133 const bool IsMirrored() const { return m_mirrored; };
00135 const wxString GetLabel() const { return m_label; };
00137 void UpdateControlPointX(double x);
00139 void UpdateControlPointY(double y);
00141 void UpdateControlPoint(hugin_utils::FDiff2D newPoint);
00143 void ShiftControlPoint(hugin_utils::FDiff2D shift);
00145 void StartLineControlPoint(hugin_utils::FDiff2D newPoint);
00147 hugin_utils::FDiff2D GetPos() const;
00149 const HuginBase::ControlPoint GetControlPoint() const { return m_cp; };
00151 bool operator==(const DisplayedControlPoint other);
00152 private:
00154 wxRect DrawTextMag(wxDC& dc, wxPoint p, hugin_utils::FDiff2D pointInput, bool drawMag, wxColour pointColour, wxColour textColour);
00156 void DrawLine(wxDC& dc);
00158 void DrawLineSegment(wxDC& dc);
00160 HuginBase::ControlPoint m_cp;
00162 bool m_mirrored;
00164 CPImageCtrl* m_control;
00166 wxColour m_pointColour;
00168 wxColour m_textColour;
00170 wxString m_label;
00172 wxRect m_labelPos;
00173 wxRect m_labelPos2;
00175 bool m_line;
00176 };
00177
00182 class CPImageCtrl : public wxScrolledWindow
00183 {
00184 public:
00233 enum EditorState {NO_IMAGE=0, NO_SELECTION, KNOWN_POINT_SELECTED, NEW_POINT_SELECTED, NEW_LINE_CREATING, SELECT_DELETE_REGION};
00234
00237 CPImageCtrl()
00238 : scaleFactor(1),fitToWindow(false)
00239 { }
00240
00241 bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = wxT("panel"));
00242
00243 void Init(CPEditorPanel * parent);
00244
00245
00248 ~CPImageCtrl();
00249
00254 enum ImageRotation { ROT0=0, ROT90, ROT180, ROT270 };
00255
00258 void setImage (const std::string & filename, ImageRotation rot);
00259 void setSameImage(bool sameImage);
00260 void setTransforms(PTools::Transform* firstTrans, PTools::Transform* firstInvTrans, PTools::Transform* secondInvTrans);
00261 PTools::Transform* getFirstTrans() const { return m_firstTrans; };
00262 PTools::Transform* getFirstInvTrans() const { return m_firstInvTrans; };
00263 PTools::Transform* getSecondInvTrans() const { return m_secondInvTrans; };
00264
00266 void setCtrlPoint(const HuginBase::ControlPoint& cp, const bool mirrored);
00268 void clearCtrlPointList();
00269
00271 void clearNewPoint();
00272
00274 void setNewPoint(const hugin_utils::FDiff2D & p);
00275
00277 void selectPoint(unsigned int);
00278
00280 void deselect();
00281
00282 void mousePressLMBEvent(wxMouseEvent& mouse);
00283 void mouseReleaseLMBEvent(wxMouseEvent& mouse);
00284 void mousePressRMBEvent(wxMouseEvent& mouse);
00285 void mouseReleaseRMBEvent(wxMouseEvent& mouse);
00286 void mouseMoveEvent(wxMouseEvent& mouse);
00287 void mousePressMMBEvent(wxMouseEvent& mouse);
00288 void mouseReleaseMMBEvent(wxMouseEvent& mouse);
00289
00290 wxSize DoGetBestSize() const;
00291
00292
00293
00298 void setScale(double factor);
00299
00301 double getScale()
00302 { return fitToWindow ? 0 : scaleFactor; }
00303
00310 void showPosition(hugin_utils::FDiff2D point, bool warpPointer=false);
00311
00315 void showSearchArea(bool show=true);
00316
00317 void showTemplateArea(bool show=true);
00318
00320 hugin_utils::FDiff2D getNewPoint();
00321
00323 void update();
00324
00326 void ScrollDelta(const wxPoint & delta);
00327
00329 wxPoint MaxScrollDelta(wxPoint delta);
00330
00331 int scale(int x) const
00332 { return (int) (x * getScaleFactor() + 0.5); }
00333
00334 double scale(double x) const
00335 { return x * getScaleFactor(); }
00336
00337 hugin_utils::FDiff2D scale(const hugin_utils::FDiff2D & p) const
00338 {
00339 hugin_utils::FDiff2D r;
00340 r.x = scale(p.x);
00341 r.y = scale(p.y);
00342 return r;
00343 }
00344
00345 wxPoint scale(const wxPoint & p) const
00346 {
00347 wxPoint r;
00348 r.x = scale(p.x);
00349 r.y = scale(p.y);
00350 return r;
00351 }
00352
00353 int invScale(int x) const
00354 { return (int) (x / getScaleFactor() + 0.5); }
00355
00356 double invScale(double x) const
00357 { return x / getScaleFactor(); }
00358
00359 hugin_utils::FDiff2D invScale(const hugin_utils::FDiff2D & p) const
00360 {
00361 hugin_utils::FDiff2D r;
00362 r.x = invScale(p.x);
00363 r.y = invScale(p.y);
00364 return r;
00365 }
00366
00367 wxPoint invScale(const wxPoint & p) const
00368 {
00369 wxPoint r;
00370 r.x = invScale(p.x);
00371 r.y = invScale(p.y);
00372 return r;
00373 }
00374
00375 wxPoint roundP(const hugin_utils::FDiff2D & p) const
00376 {
00377 return wxPoint(hugin_utils::roundi(p.x), hugin_utils::roundi(p.y));
00378 }
00379
00380
00381
00382 template <class T>
00383 T applyRot(const T & p) const
00384 {
00385 switch (m_imgRotation) {
00386 case ROT0:
00387 return p;
00388 break;
00389 case ROT90:
00390 return T(m_realSize.GetHeight()-1 - p.y, p.x);
00391 break;
00392 case ROT180:
00393 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00394 break;
00395 case ROT270:
00396 return T(p.y, m_realSize.GetWidth()-1 - p.x);
00397 break;
00398 default:
00399 return p;
00400 break;
00401 }
00402 }
00403
00404
00405
00406 template <class T>
00407 T applyRotInv(const T & p) const
00408 {
00409 switch (m_imgRotation) {
00410 case ROT90:
00411 return T(p.y, m_realSize.GetHeight()-1 - p.x);
00412 break;
00413 case ROT180:
00414 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00415 break;
00416 case ROT270:
00417 return T(m_realSize.GetWidth()-1 - p.y, p.x);
00418 break;
00419 case ROT0:
00420 default:
00421 return p;
00422 break;
00423 }
00424 }
00425
00426 const bool GetMouseInWindow() const { return m_mouseInWindow; };
00427 const bool GetForceMagnifier() const { return m_forceMagnifier; };
00429 const HuginBase::ImageCache::ImageCacheRGB8Ptr GetImg() const { return m_img->image8; };
00431 wxBitmap generateMagBitmap(hugin_utils::FDiff2D point, wxPoint canvasPos) const;
00433 const wxSize GetRealImageSize() const { return m_realSize; };
00435 const wxSize GetBitmapSize() const;
00436
00437 protected:
00438
00439 void OnImageLoaded(ImageCache::EntryPtr entry, std::string filename, bool load_small);
00440 void OnDraw(wxDC& dc);
00441 void OnSize(wxSizeEvent & e);
00442 void OnKey(wxKeyEvent & e);
00443 void OnKeyDown(wxKeyEvent & e);
00444 void OnMouseLeave(wxMouseEvent & e);
00445 void OnMouseEnter(wxMouseEvent & e);
00446 void OnTimer(wxTimerEvent & e);
00447
00449 bool emit(CPEvent & ev);
00450
00452 double getScaleFactor() const;
00453
00455 double calcAutoScaleFactor(wxSize size);
00456
00457
00458 void rescaleImage();
00459
00460 private:
00461 wxBitmap bitmap;
00462 std::string imageFilename;
00463
00464 wxSize imageSize;
00465
00466 wxSize m_realSize;
00467
00468 std::vector<DisplayedControlPoint> m_points;
00469
00470 wxCursor * m_CPSelectCursor;
00471 wxCursor * m_ScrollCursor;
00472
00473
00474 unsigned int selectedPointNr;
00475
00476 DisplayedControlPoint m_selectedPoint;
00477 hugin_utils::FDiff2D newPoint;
00481 bool m_sameImage;
00482
00483
00484 hugin_utils::FDiff2D rectStartPos;
00485
00486 void DrawSelectionRectangle(hugin_utils::FDiff2D pos1,hugin_utils::FDiff2D pos2);
00487
00488 EditorState editState;
00489
00490 PTools::Transform* m_firstTrans;
00491 PTools::Transform* m_firstInvTrans;
00492 PTools::Transform* m_secondInvTrans;
00493
00494
00495 std::vector<wxColour> pointColors;
00496 std::vector<wxColour> textColours;
00497 double scaleFactor;
00498 bool fitToWindow;
00499
00500 bool m_showSearchArea;
00501 int m_searchRectWidth;
00502
00503 hugin_utils::FDiff2D m_mousePos;
00504 wxPoint m_mouseScrollPos;
00505
00506 bool m_showTemplateArea;
00507 int m_templateRectWidth;
00508
00511 EditorState isOccupied(wxPoint mousePos, const hugin_utils::FDiff2D & point, unsigned int & pointNr) const;
00512
00513 CPEditorPanel * m_editPanel;
00514
00515 ImageRotation m_imgRotation;
00516
00517 ImageCache::EntryPtr m_img;
00518 ImageCache::RequestPtr m_imgRequest;
00519
00520 bool m_mouseInWindow;
00521 bool m_forceMagnifier;
00522 wxTimer m_timer;
00523
00524 DECLARE_EVENT_TABLE();
00525 DECLARE_DYNAMIC_CLASS(CPImageCtrl)
00526 };
00527
00529 class CPImageCtrlXmlHandler : public wxXmlResourceHandler
00530 {
00531 DECLARE_DYNAMIC_CLASS(CPImageCtrlXmlHandler)
00532
00533 public:
00534 CPImageCtrlXmlHandler();
00535 virtual wxObject *DoCreateResource();
00536 virtual bool CanHandle(wxXmlNode *node);
00537 };
00538
00539
00540 #endif // _CPIMAGECTRL_H