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 <panotools/PanoToolsInterface.h>
00031 #include <base_wx/wxImageCache.h>
00032 
00033 class CPEditorPanel;
00034 class CPImageCtrl;
00035 
00039 class CPEvent : public wxCommandEvent
00040 {
00041     DECLARE_DYNAMIC_CLASS(CPEvent)
00042 
00043     enum CPEventMode { NONE, NEW_POINT_CHANGED, NEW_LINE_ADDED, POINT_SELECTED, POINT_CHANGED, RIGHT_CLICK, SCROLLED, DELETE_REGION_SELECTED };
00044 
00045 public:
00046     CPEvent( );
00048     CPEvent(wxWindow* win, CPEventMode mode);
00050     CPEvent(wxWindow* win, hugin_utils::FDiff2D & p);
00052     CPEvent(wxWindow *win, unsigned int cpNr);
00054     CPEvent(wxWindow* win, unsigned int cpNr, const hugin_utils::FDiff2D & p);
00056     CPEvent(wxWindow* win, const hugin_utils::FDiff2D & p1, const hugin_utils::FDiff2D & p2);
00058     CPEvent(wxWindow* win, CPEventMode mode, const hugin_utils::FDiff2D & p);
00060     CPEvent(wxWindow* win, CPEventMode mode, const HuginBase::ControlPoint cp);
00062     CPEvent(wxWindow* win, CPEventMode mode, size_t cpNr, const HuginBase::ControlPoint cp);
00063 
00064     virtual wxEvent* Clone() const;
00065 
00068     CPEventMode getMode()
00069         { return mode; };
00070 
00071     const wxRect & getRect()
00072         { return region; }
00073 
00074     const hugin_utils::FDiff2D & getPoint()
00075         { return point; }
00076 
00077     unsigned int getPointNr()
00078         { return pointNr; }
00079 
00080     const HuginBase::ControlPoint& getControlPoint() 
00081         { return m_cp; };
00082 private:
00083     CPEventMode mode;
00084     wxRect region;
00085     hugin_utils::FDiff2D point;
00086     HuginBase::ControlPoint m_cp;
00087     int pointNr;
00088 };
00089 
00090 typedef void (wxEvtHandler::*CPEventFunction)(CPEvent&);
00091 
00092 BEGIN_DECLARE_EVENT_TYPES()
00093 #if _WINDOWS && defined Hugin_shared
00094     DECLARE_LOCAL_EVENT_TYPE(EVT_CPEVENT,1)
00095 #else
00096     DECLARE_EVENT_TYPE(EVT_CPEVENT,1)
00097 #endif
00098 END_DECLARE_EVENT_TYPES()
00099 
00100 #define EVT_CPEVENT(func) \
00101     DECLARE_EVENT_TABLE_ENTRY( EVT_CPEVENT, \
00102                             -1,                       \
00103                             -1,                       \
00104                             (wxObjectEventFunction)   \
00105                             (CPEventFunction) & func, \
00106                             (wxObject *) NULL ),
00107 
00108 
00110 class DisplayedControlPoint
00111 {
00112 public:
00114     DisplayedControlPoint() { m_mirrored=false; m_control=NULL; m_line=false; };
00116     DisplayedControlPoint(const HuginBase::ControlPoint& cp, CPImageCtrl* control, bool mirrored);
00118     void SetColour(wxColour pointColour, wxColour textColour);
00120     void SetLabel(wxString newLabel);
00122     void SetControl(CPImageCtrl* control);
00124     void Draw(wxDC& dc, bool selected, bool newPoint=false);
00126     const bool isOccupiedLabel(const wxPoint mousePos) const;
00128     const bool isOccupiedPos(const hugin_utils::FDiff2D &p) const;
00132     void CheckSelection(const wxPoint mousePos, const hugin_utils::FDiff2D& p);
00134     const bool IsMirrored() const { return m_mirrored; };
00136     const wxString GetLabel() const { return m_label; };
00138     void UpdateControlPointX(double x);
00140     void UpdateControlPointY(double y);
00142     void UpdateControlPoint(hugin_utils::FDiff2D newPoint);
00144     void ShiftControlPoint(hugin_utils::FDiff2D shift);
00146     void StartLineControlPoint(hugin_utils::FDiff2D newPoint);
00148     hugin_utils::FDiff2D GetPos() const;
00150     const HuginBase::ControlPoint GetControlPoint() const { return m_cp; };
00152     bool operator==(const DisplayedControlPoint other);
00153 private:
00155     wxRect DrawTextMag(wxDC& dc, wxPoint p, hugin_utils::FDiff2D pointInput, bool drawMag, wxColour pointColour, wxColour textColour);
00157     void DrawLine(wxDC& dc);
00159     void DrawLineSegment(wxDC& dc);
00161     HuginBase::ControlPoint m_cp;
00163     bool m_mirrored;
00165     CPImageCtrl* m_control;
00167     wxColour m_pointColour;
00169     wxColour m_textColour;
00171     wxString m_label;
00173     wxRect m_labelPos;
00174     wxRect m_labelPos2;
00176     bool m_line;
00177 };
00178 
00183 class CPImageCtrl : public wxScrolledWindow
00184 {
00185 public:
00234     enum EditorState {NO_IMAGE=0, NO_SELECTION, KNOWN_POINT_SELECTED, NEW_POINT_SELECTED, NEW_LINE_CREATING, SELECT_DELETE_REGION};
00235     
00238     CPImageCtrl()
00239         : scaleFactor(1),fitToWindow(false)
00240         { }
00241 
00242     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"));
00243 
00244     void Init(CPEditorPanel * parent);
00245 
00246 
00249     ~CPImageCtrl();
00250 
00255     enum ImageRotation { ROT0=0, ROT90, ROT180, ROT270 };
00256 
00259     void setImage (const std::string & filename, ImageRotation rot);
00260     void setSameImage(bool sameImage);
00261     void setTransforms(HuginBase::PTools::Transform* firstTrans, HuginBase::PTools::Transform* firstInvTrans, HuginBase::PTools::Transform* secondInvTrans);
00262     HuginBase::PTools::Transform* getFirstTrans() const { return m_firstTrans; };
00263     HuginBase::PTools::Transform* getFirstInvTrans() const { return m_firstInvTrans; };
00264     HuginBase::PTools::Transform* getSecondInvTrans() const { return m_secondInvTrans; };
00265 
00267     void setCtrlPoint(const HuginBase::ControlPoint& cp, const bool mirrored);
00269     void clearCtrlPointList();
00270 
00272     void clearNewPoint();
00273 
00275     void setNewPoint(const hugin_utils::FDiff2D & p);
00276 
00278     void selectPoint(unsigned int);
00279 
00281     void deselect();
00282 
00283     void mousePressLMBEvent(wxMouseEvent& mouse);
00284     void mouseReleaseLMBEvent(wxMouseEvent& mouse);
00285     void mousePressRMBEvent(wxMouseEvent& mouse);
00286     void mouseReleaseRMBEvent(wxMouseEvent& mouse);
00287     void mouseMoveEvent(wxMouseEvent& mouse);
00288     void mousePressMMBEvent(wxMouseEvent& mouse);
00289     void mouseReleaseMMBEvent(wxMouseEvent& mouse);
00290 
00291     wxSize DoGetBestSize() const;
00292 //    virtual wxSize GetBestSize() const
00293 //        { return DoGetBestSize(); }
00294 
00299     void setScale(double factor);
00300 
00302     double getScale()
00303         { return fitToWindow ? 0 : scaleFactor; }
00304 
00311     void showPosition(hugin_utils::FDiff2D point, bool warpPointer=false);
00312 
00316     void showSearchArea(bool show=true);
00317 
00318     void showTemplateArea(bool show=true);
00319 
00321     hugin_utils::FDiff2D getNewPoint();
00322 
00324     void update();
00325 
00327     void ScrollDelta(const wxPoint & delta);
00328 
00330     wxPoint MaxScrollDelta(wxPoint delta);
00331 
00332     int scale(int x) const
00333         {  return (int) (x * getScaleFactor() + 0.5); }
00334 
00335     double scale(double x) const
00336         {  return x * getScaleFactor(); }
00337 
00338     hugin_utils::FDiff2D scale(const hugin_utils::FDiff2D & p) const
00339         {
00340             hugin_utils::FDiff2D r;
00341             r.x = scale(p.x);
00342             r.y = scale(p.y);
00343             return r;
00344         }
00345 
00346     wxPoint scale(const wxPoint & p) const
00347         {
00348             wxPoint r;
00349             r.x = scale(p.x);
00350             r.y = scale(p.y);
00351             return r;
00352         }
00353 
00354     int invScale(int x) const
00355         {  return (int) (x / getScaleFactor() + 0.5); }
00356 
00357     double invScale(double x) const
00358         {  return x / getScaleFactor(); }
00359 
00360     hugin_utils::FDiff2D invScale(const hugin_utils::FDiff2D & p) const
00361         {
00362             hugin_utils::FDiff2D r;
00363             r.x = invScale(p.x);
00364             r.y = invScale(p.y);
00365             return r;
00366         }
00367 
00368     wxPoint invScale(const wxPoint & p) const
00369         {
00370             wxPoint r;
00371             r.x = invScale(p.x);
00372             r.y = invScale(p.y);
00373             return r;
00374         }
00375 
00376     wxPoint roundP(const hugin_utils::FDiff2D & p) const
00377         {
00378             return wxPoint(hugin_utils::roundi(p.x), hugin_utils::roundi(p.y));
00379         }
00380 
00381     // rotate coordinate to fit possibly rotated image display
00382     // useful for drawing something on the rotated display
00383     template <class T>
00384     T applyRot(const T & p) const
00385     {
00386         switch (m_imgRotation) {
00387             case ROT0:
00388                 return p;
00389                 break;
00390             case ROT90:
00391                 return T(m_realSize.GetHeight()-1 - p.y, p.x);
00392                 break;
00393             case ROT180:
00394                 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00395                 break;
00396             case ROT270:
00397                 return T(p.y, m_realSize.GetWidth()-1 - p.x);
00398                 break;
00399             default:
00400                 return p;
00401                 break;
00402         }
00403     }
00404 
00405     // rotate coordinate to fit possibly rotated image display
00406     // useful for converting rotated display coordinates to image coordinates
00407     template <class T>
00408     T applyRotInv(const T & p) const
00409     {
00410         switch (m_imgRotation) {
00411             case ROT90:
00412                 return T(p.y, m_realSize.GetHeight()-1 - p.x);
00413                 break;
00414             case ROT180:
00415                 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00416                 break;
00417             case ROT270:
00418                 return T(m_realSize.GetWidth()-1 - p.y, p.x);
00419                 break;
00420             case ROT0:
00421             default:
00422                 return p;
00423                 break;
00424         }
00425     }
00426     // some helper function for DisplayedControlPoint 
00427     const bool GetMouseInWindow() const { return m_mouseInWindow; };
00428     const bool GetForceMagnifier() const { return m_forceMagnifier; };
00430     const HuginBase::ImageCache::ImageCacheRGB8Ptr GetImg() const { return m_img->image8; };
00432     wxBitmap generateMagBitmap(hugin_utils::FDiff2D point, wxPoint canvasPos) const;
00434     const wxSize GetRealImageSize() const { return m_realSize; };
00436     const wxSize GetBitmapSize() const;
00437 
00438 protected:
00439     // display the image when loading finishes
00440     void OnImageLoaded(ImageCache::EntryPtr entry, std::string filename, bool load_small);
00441     void OnDraw(wxDC& dc);
00442     void OnSize(wxSizeEvent & e);
00443     void OnKey(wxKeyEvent & e);
00444     void OnKeyDown(wxKeyEvent & e);
00445     void OnMouseLeave(wxMouseEvent & e);
00446     void OnMouseEnter(wxMouseEvent & e);
00447     void OnTimer(wxTimerEvent & e);
00448 
00450     bool emit(CPEvent & ev);
00451 
00453     double getScaleFactor() const;
00454 
00456     double calcAutoScaleFactor(wxSize size);
00457 
00458     // rescale image
00459     void rescaleImage();
00460 
00461 private:
00462     wxBitmap bitmap;
00463     std::string imageFilename;
00464     // size of displayed (probably scaled) image
00465     wxSize imageSize;
00466     // size of real image
00467     wxSize m_realSize;
00468 
00469     std::vector<DisplayedControlPoint> m_points;
00470 
00471     wxCursor * m_CPSelectCursor;
00472     wxCursor * m_ScrollCursor;
00473 
00474     // this is only valid during MOVE_POINT
00475     unsigned int selectedPointNr;
00476     // valid during MOVE_POINT and CREATE_POINT
00477     DisplayedControlPoint m_selectedPoint;
00478     hugin_utils::FDiff2D newPoint;
00482     bool m_sameImage;
00483 
00484     // only valid during SELECT_DELETE_REGION
00485     hugin_utils::FDiff2D rectStartPos;
00486     // draw a selection rectangle from pos1 to pos2
00487     void DrawSelectionRectangle(hugin_utils::FDiff2D pos1,hugin_utils::FDiff2D pos2);
00488 
00489     EditorState editState;
00490     // store pointer to transformation object to draw line control points
00491     HuginBase::PTools::Transform* m_firstTrans;
00492     HuginBase::PTools::Transform* m_firstInvTrans;
00493     HuginBase::PTools::Transform* m_secondInvTrans;
00494 
00495     // colors for the different points
00496     std::vector<wxColour> pointColors;
00497     std::vector<wxColour> textColours;
00498     double scaleFactor;
00499     bool fitToWindow;
00500 
00501     bool m_showSearchArea;
00502     int m_searchRectWidth;
00503 
00504     hugin_utils::FDiff2D m_mousePos;
00505     wxPoint m_mouseScrollPos;
00506 
00507     bool m_showTemplateArea;
00508     int m_templateRectWidth;
00509 
00512     EditorState isOccupied(wxPoint mousePos, const hugin_utils::FDiff2D & point, unsigned int & pointNr) const;
00513 
00514     CPEditorPanel * m_editPanel;
00515 
00516     ImageRotation m_imgRotation;
00517 
00518     ImageCache::EntryPtr m_img;
00519     ImageCache::RequestPtr m_imgRequest;
00520 
00521     bool m_mouseInWindow;
00522     bool m_forceMagnifier;
00523     wxTimer m_timer;
00524 
00525     DECLARE_EVENT_TABLE();
00526     DECLARE_DYNAMIC_CLASS(CPImageCtrl)
00527 };
00528 
00530 class CPImageCtrlXmlHandler : public wxXmlResourceHandler
00531 {
00532     DECLARE_DYNAMIC_CLASS(CPImageCtrlXmlHandler)
00533 
00534 public:
00535     CPImageCtrlXmlHandler();
00536     virtual wxObject *DoCreateResource();
00537     virtual bool CanHandle(wxXmlNode *node);
00538 };
00539 
00540 
00541 #endif // _CPIMAGECTRL_H

Generated on 30 Jul 2015 for Hugintrunk by  doxygen 1.4.7