CPImageCtrl.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
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 //    virtual wxSize GetBestSize() const
00292 //        { return DoGetBestSize(); }
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     // rotate coordinate to fit possibly rotated image display
00381     // useful for drawing something on the rotated display
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     // rotate coordinate to fit possibly rotated image display
00405     // useful for converting rotated display coordinates to image coordinates
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     // some helper function for DisplayedControlPoint 
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     // display the image when loading finishes
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     // rescale image
00458     void rescaleImage();
00459 
00460 private:
00461     wxBitmap bitmap;
00462     std::string imageFilename;
00463     // size of displayed (probably scaled) image
00464     wxSize imageSize;
00465     // size of real image
00466     wxSize m_realSize;
00467 
00468     std::vector<DisplayedControlPoint> m_points;
00469 
00470     wxCursor * m_CPSelectCursor;
00471     wxCursor * m_ScrollCursor;
00472 
00473     // this is only valid during MOVE_POINT
00474     unsigned int selectedPointNr;
00475     // valid during MOVE_POINT and CREATE_POINT
00476     DisplayedControlPoint m_selectedPoint;
00477     hugin_utils::FDiff2D newPoint;
00481     bool m_sameImage;
00482 
00483     // only valid during SELECT_DELETE_REGION
00484     hugin_utils::FDiff2D rectStartPos;
00485     // draw a selection rectangle from pos1 to pos2
00486     void DrawSelectionRectangle(hugin_utils::FDiff2D pos1,hugin_utils::FDiff2D pos2);
00487 
00488     EditorState editState;
00489     // store pointer to transformation object to draw line control points
00490     PTools::Transform* m_firstTrans;
00491     PTools::Transform* m_firstInvTrans;
00492     PTools::Transform* m_secondInvTrans;
00493 
00494     // colors for the different points
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

Generated on 1 Nov 2014 for Hugintrunk by  doxygen 1.4.7