MaskImageCtrl.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00010 /*  This is free software; you can redistribute it and/or
00011  *  modify it under the terms of the GNU General Public
00012  *  License as published by the Free Software Foundation; either
00013  *  version 2 of the License, or (at your option) any later version.
00014  *
00015  *  This software is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  *  Lesser General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public
00021  *  License along with this software. If not, see
00022  *  <http://www.gnu.org/licenses/>.
00023  *
00024  */
00025 
00026 #ifndef _MaskImageCtrl_H
00027 #define _MaskImageCtrl_H
00028 
00029 #include <base_wx/wxImageCache.h>
00030 
00031 #if defined __WXOSX_CARBON__ || defined __WXOSX_COCOA__
00032 // on wxMac wxInvert does not work for drawing rubberband, so we are the following workaround
00033 // instead of using wxInvert we are drawing the background image before the selection rectangle
00034 // or the crop rectangle, the color of the selection is defined by the overall colour of the image
00035 // this approach is already used for the polygon editor also on wxMSW and wxGTK
00036 #undef SUPPORTS_WXINVERT
00037 #else
00038 #define SUPPORTS_WXINVERT 1
00039 #endif
00040 
00041 class MaskEditorPanel;
00042 
00047 class MaskImageCtrl : public wxScrolledWindow
00048 {
00049 public:
00052     MaskImageCtrl()
00053         : m_scaleFactor(1),m_fitToWindow(false),m_maskEditState(NO_IMAGE)
00054         { }
00055 
00056     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"));
00057 
00058     void Init(MaskEditorPanel * parent);
00059 
00064     enum ImageRotation { ROT0=0, ROT90, ROT180, ROT270 };
00065 
00067     void setPreviewOnly() { m_previewOnly=true; };
00069     void setImage (const std::string & filename, HuginBase::MaskPolygonVector newMask, HuginBase::MaskPolygonVector masksToDraw, ImageRotation rot);
00071     void setNewMasks(HuginBase::MaskPolygonVector newMasks, HuginBase::MaskPolygonVector masksToDraw);
00073     void setCrop(HuginBase::SrcPanoImage::CropMode newCropMode,vigra::Rect2D newCropRect, bool isCentered, hugin_utils::FDiff2D center, bool isCircleCrop);
00075     vigra::Rect2D getCrop() { return m_cropRect; };
00077     void setActiveMask(unsigned int newMask, bool doUpdate=true);
00079     HuginBase::MaskPolygonVector getNewMask() const { return m_imageMask; };
00081     void selectAllMarkers();
00082 
00084     void OnMouseMove(wxMouseEvent& mouse);
00086     void OnLeftMouseDown(wxMouseEvent& mouse);
00088     void OnLeftMouseUp(wxMouseEvent& mouse);
00090     void OnLeftMouseDblClick(wxMouseEvent& mouse);
00092     void OnRightMouseDown(wxMouseEvent& mouse);
00094     void OnRightMouseUp(wxMouseEvent& mouse);
00096     void OnKeyUp(wxKeyEvent &e);
00099     void OnCaptureLost(wxMouseCaptureLostEvent &e);
00101     void OnKillFocus(wxFocusEvent &e);
00103     void OnScroll(wxScrollWinEvent &e);
00104 
00106     void startNewPolygon();
00108     wxSize DoGetBestSize() const;
00109 
00111     void SetMaskMode(bool newMaskMode);
00112 
00117     void setScale(double factor);
00118 
00120     double getScale()
00121         { return m_fitToWindow ? 0 : m_scaleFactor; }
00122 
00124     ImageRotation getCurrentRotation() { return m_imgRotation; };
00125 
00127     void setDrawingActiveMasks(bool newDrawActiveMasks);
00129     void update();
00130 
00132     void SetUserColourPolygonNegative(wxColour newColour) { m_colour_polygon_negative=newColour; };
00133     void SetUserColourPolygonPositive(wxColour newColour) { m_colour_polygon_positive=newColour; };
00134     void SetUserColourPointSelected(wxColour newColour) { m_colour_point_selected=newColour; };
00135     void SetUserColourPointUnselected(wxColour newColour) { m_colour_point_unselected=newColour; };
00136 
00137 protected:
00139     void OnDraw(wxDC& dc);
00141     void OnSize(wxSizeEvent & e);
00142 
00144     double getScaleFactor() const;
00146     double calcAutoScaleFactor(wxSize size);
00148     void rescaleImage();
00149 
00150  private:
00151 
00152     //scaled bitmap
00153     wxBitmap m_bitmap;
00154     wxBitmap m_disabledBitmap;
00155     //filename of current editing file
00156     std::string m_imageFilename;
00157     // stores rotation of image
00158     ImageRotation m_imgRotation;
00159     // size of displayed (probably scaled) image
00160     wxSize m_imageSize;
00161     // size of real image
00162     wxSize m_realSize;
00163     // variables for crop
00164     HuginBase::SrcPanoImage::CropMode m_cropMode;
00165     vigra::Rect2D m_cropRect;
00166     bool m_cropCentered;
00167     bool m_cropCircle;
00168     hugin_utils::FDiff2D m_cropCenter;
00169     // draw active masks 
00170     bool m_showActiveMasks;
00171     // mask or crop mode
00172     bool m_maskMode;
00173 
00175     int scale(int x) const
00176         {  return (int) (x * getScaleFactor() + 0.5); }
00177 
00178     double scale(double x) const
00179         {  return x * getScaleFactor(); }
00180 
00182     int transform(int x) const
00183         {  return (int) ((x+HuginBase::maskOffset) * getScaleFactor() + 0.5); }
00184 
00185     double transform(double x) const
00186         {  return (x+HuginBase::maskOffset) * getScaleFactor(); }
00187 
00188     wxPoint transform(const hugin_utils::FDiff2D & p) const
00189         {
00190             wxPoint r;
00191             r.x = transform(p.x);
00192             r.y = transform(p.y);
00193             return r;
00194         };
00195 
00197     int invtransform(int x) const
00198         {  return (int) (x/getScaleFactor()-HuginBase::maskOffset + 0.5); };
00199 
00200     double invtransform(double x) const
00201         {  return (x/getScaleFactor()-HuginBase::maskOffset); };
00202 
00203     hugin_utils::FDiff2D invtransform(const wxPoint & p) const
00204         {
00205             hugin_utils::FDiff2D r;
00206             r.x = invtransform(p.x);
00207             r.y = invtransform(p.y);
00208             return r;
00209         };
00210     
00211     // rotate coordinate to fit possibly rotated image display
00212     // useful for drawing something on the rotated display
00213     template <class T>
00214     T applyRot(const T & p) const
00215     {
00216         switch (m_imgRotation) {
00217             case ROT0:
00218                 return p;
00219                 break;
00220             case ROT90:
00221                 return T(m_realSize.GetHeight()-1 - p.y, p.x);
00222                 break;
00223             case ROT180:
00224                 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00225                 break;
00226             case ROT270:
00227                 return T(p.y, m_realSize.GetWidth()-1 - p.x);
00228                 break;
00229             default:
00230                 return p;
00231                 break;
00232         }
00233     }
00234 
00235     // rotate coordinate to fit possibly rotated image display
00236     // useful for converting rotated display coordinates to image coordinates
00237     template <class T>
00238     T applyRotInv(const T & p) const
00239     {
00240         switch (m_imgRotation) {
00241             case ROT90:
00242                 return T(p.y, m_realSize.GetHeight()-1 - p.x);
00243                 break;
00244             case ROT180:
00245                 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00246                 break;
00247             case ROT270:
00248                 return T(m_realSize.GetWidth()-1 - p.y, p.x);
00249                 break;
00250             case ROT0:
00251             default:
00252                 return p;
00253                 break;
00254         }
00255     }
00256 
00257     //draw the given polygon
00258     void DrawPolygon(wxDC &dc, HuginBase::MaskPolygon poly, bool isSelected, bool drawMarker);
00259     //draw a selection rectange, when called the second time the rectangle is deleted
00260     void DrawSelectionRectangle();
00261     // draws the crop rectangle and/or circle
00262     void DrawCrop(wxDC & dc);
00263     void DrawCrop();
00264     // find the polygon for which the point p is inside the polygon
00265     void FindPolygon(hugin_utils::FDiff2D p);
00266     // returns a set of points which are in the selection rectangle 
00267     bool SelectPointsInsideMouseRect(HuginBase::UIntSet &points,const bool considerSelectedOnly);
00268     // updates the crop
00269     void UpdateCrop(hugin_utils::FDiff2D delta);
00270 
00271     // where the cursor is 
00272     enum ClickPos
00273     {
00274         CLICK_OUTSIDE, CLICK_INSIDE, CLICK_LEFT, CLICK_RIGHT, CLICK_TOP, CLICK_BOTTOM, CLICK_CIRCLE
00275     };
00276     // test, where the curos is
00277     ClickPos GetClickPos(vigra::Point2D pos);
00278 
00280     enum MaskEditorState
00281     {
00282         NO_IMAGE=0, // no image selected
00283         NO_MASK, // image loaded, but none active mask
00284         NO_SELECTION, // active polygon, but no point selected
00285         POINTS_SELECTED, // points selected
00286         POINTS_MOVING, // dragging points
00287         POINTS_DELETING,  // remove points inside rect
00288         POINTS_ADDING,  // adding new points add mouse position
00289         POLYGON_SELECTING, // selecting an region to select an other polygon
00290         REGION_SELECTING, // currently selecting an region
00291         NEW_POLYGON_STARTED, // modus is new polygon, but no point setted yet
00292         NEW_POLYGON_CREATING,  // currently creating new polygon
00293         CROP_SHOWING,  // only showing the crop
00294         CROP_MOVING,  // dragging crop
00295         CROP_CIRCLE_SCALING, // circular crop changing
00296         CROP_LEFT_MOVING, // dragging left border of crop
00297         CROP_RIGHT_MOVING, // dragging right border of crop
00298         CROP_TOP_MOVING,  // dragging top border of crop
00299         CROP_BOTTOM_MOVING // dragging bottom border of crop
00300     };
00301     MaskEditorState m_maskEditState;
00302 
00303     double m_scaleFactor;
00304     bool m_fitToWindow;
00305     bool m_previewOnly;
00306 
00307     MaskEditorPanel * m_editPanel;
00308     HuginBase::MaskPolygonVector m_imageMask;
00309     HuginBase::MaskPolygonVector m_masksToDraw;
00310     unsigned int m_activeMask;
00311     // the active masks, the one which is currently editing
00312     HuginBase::MaskPolygon m_editingMask;
00313     // all selected points
00314     HuginBase::UIntSet m_selectedPoints;
00315 
00316     ImageCache::EntryPtr m_img;
00317 
00318     // positions of mouse drag
00319     wxPoint m_dragStartPos;
00320     wxPoint m_currentPos;
00321 
00322     // colours for different parts
00323     wxColor m_colour_polygon_negative;
00324     wxColor m_colour_polygon_positive;
00325     wxColor m_colour_point_selected;
00326     wxColor m_colour_point_unselected;
00327 #ifndef SUPPORTS_WXINVERT
00328     wxColour m_color_selection;
00329 #endif
00330     int m_oldScrollPosX, m_oldScrollPosY;
00331 
00332     DECLARE_EVENT_TABLE();
00333     DECLARE_DYNAMIC_CLASS(MaskImageCtrl)
00334 };
00335 
00337 class MaskImageCtrlXmlHandler : public wxXmlResourceHandler
00338 {
00339     DECLARE_DYNAMIC_CLASS(MaskImageCtrlXmlHandler)
00340 
00341 public:
00342     MaskImageCtrlXmlHandler();
00343     virtual wxObject *DoCreateResource();
00344     virtual bool CanHandle(wxXmlNode *node);
00345 };
00346 
00347 
00348 #endif // _MaskImageCtrl_H

Generated on 1 Aug 2015 for Hugintrunk by  doxygen 1.4.7