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 #ifdef __WXGTK3__
00039 // wxINVERT is currently also not supported on GTK+3
00040 // see ticket http://trac.wxwidgets.org/ticket/16890
00041 #undef SUPPORTS_WXINVERT
00042 #else
00043 #define SUPPORTS_WXINVERT 1
00044 #endif
00045 #endif
00046 
00047 class MaskEditorPanel;
00048 
00053 class MaskImageCtrl : public wxScrolledWindow
00054 {
00055 public:
00058     MaskImageCtrl()
00059         : m_maskEditState(NO_IMAGE), m_scaleFactor(1), m_fitToWindow(false)
00060         { }
00061 
00062     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"));
00063 
00064     void Init(MaskEditorPanel * parent);
00065 
00070     enum ImageRotation { ROT0=0, ROT90, ROT180, ROT270 };
00071 
00073     void setPreviewOnly() { m_previewOnly=true; };
00075     void setImage (const std::string & filename, HuginBase::MaskPolygonVector newMask, HuginBase::MaskPolygonVector masksToDraw, ImageRotation rot);
00077     void setNewMasks(HuginBase::MaskPolygonVector newMasks, HuginBase::MaskPolygonVector masksToDraw);
00079     void setCrop(HuginBase::SrcPanoImage::CropMode newCropMode,vigra::Rect2D newCropRect, bool isCentered, hugin_utils::FDiff2D center, bool isCircleCrop);
00081     vigra::Rect2D getCrop() { return m_cropRect; };
00083     void setActiveMask(unsigned int newMask, bool doUpdate=true);
00085     HuginBase::MaskPolygonVector getNewMask() const { return m_imageMask; };
00087     void selectAllMarkers();
00088 
00090     void OnMouseMove(wxMouseEvent& mouse);
00092     void OnLeftMouseDown(wxMouseEvent& mouse);
00094     void OnLeftMouseUp(wxMouseEvent& mouse);
00096     void OnLeftMouseDblClick(wxMouseEvent& mouse);
00098     void OnRightMouseDown(wxMouseEvent& mouse);
00100     void OnRightMouseUp(wxMouseEvent& mouse);
00102     void OnKeyUp(wxKeyEvent &e);
00105     void OnCaptureLost(wxMouseCaptureLostEvent &e);
00107     void OnKillFocus(wxFocusEvent &e);
00109     void OnScroll(wxScrollWinEvent &e);
00110 
00112     void startNewPolygon();
00114     wxSize DoGetBestSize() const;
00115 
00117     void SetMaskMode(bool newMaskMode);
00118 
00123     void setScale(double factor);
00124 
00126     double getScale()
00127         { return m_fitToWindow ? 0 : m_scaleFactor; }
00128 
00130     ImageRotation getCurrentRotation() { return m_imgRotation; };
00131 
00133     void setDrawingActiveMasks(bool newDrawActiveMasks);
00135     void update();
00136 
00138     void SetUserColourPolygonNegative(wxColour newColour) { m_colour_polygon_negative=newColour; };
00139     void SetUserColourPolygonPositive(wxColour newColour) { m_colour_polygon_positive=newColour; };
00140     void SetUserColourPointSelected(wxColour newColour) { m_colour_point_selected=newColour; };
00141     void SetUserColourPointUnselected(wxColour newColour) { m_colour_point_unselected=newColour; };
00142 
00143 protected:
00145     void OnDraw(wxDC& dc);
00147     void OnSize(wxSizeEvent & e);
00148 
00150     double getScaleFactor() const;
00152     double calcAutoScaleFactor(wxSize size);
00154     void rescaleImage();
00155 
00156  private:
00157 
00158     //scaled bitmap
00159     wxBitmap m_bitmap;
00160     wxBitmap m_disabledBitmap;
00161     //filename of current editing file
00162     std::string m_imageFilename;
00163     // stores rotation of image
00164     ImageRotation m_imgRotation;
00165     // size of displayed (probably scaled) image
00166     wxSize m_imageSize;
00167     // size of real image
00168     wxSize m_realSize;
00169     // variables for crop
00170     HuginBase::SrcPanoImage::CropMode m_cropMode;
00171     vigra::Rect2D m_cropRect;
00172     bool m_cropCentered;
00173     bool m_cropCircle;
00174     hugin_utils::FDiff2D m_cropCenter;
00175     // draw active masks 
00176     bool m_showActiveMasks;
00177     // mask or crop mode
00178     bool m_maskMode;
00179 
00181     int scale(int x) const
00182         {  return (int) (x * getScaleFactor() + 0.5); }
00183 
00184     double scale(double x) const
00185         {  return x * getScaleFactor(); }
00186 
00188     int transform(int x) const
00189         {  return (int) ((x+HuginBase::maskOffset) * getScaleFactor() + 0.5); }
00190 
00191     double transform(double x) const
00192         {  return (x+HuginBase::maskOffset) * getScaleFactor(); }
00193 
00194     wxPoint transform(const hugin_utils::FDiff2D & p) const
00195         {
00196             wxPoint r;
00197             r.x = transform(p.x);
00198             r.y = transform(p.y);
00199             return r;
00200         };
00201 
00203     int invtransform(int x) const
00204         {  return (int) (x/getScaleFactor()-HuginBase::maskOffset + 0.5); };
00205 
00206     double invtransform(double x) const
00207         {  return (x/getScaleFactor()-HuginBase::maskOffset); };
00208 
00209     hugin_utils::FDiff2D invtransform(const wxPoint & p) const
00210         {
00211             hugin_utils::FDiff2D r;
00212             r.x = invtransform(p.x);
00213             r.y = invtransform(p.y);
00214             return r;
00215         };
00216     
00217     // rotate coordinate to fit possibly rotated image display
00218     // useful for drawing something on the rotated display
00219     template <class T>
00220     T applyRot(const T & p) const
00221     {
00222         switch (m_imgRotation) {
00223             case ROT0:
00224                 return p;
00225                 break;
00226             case ROT90:
00227                 return T(m_realSize.GetHeight()-1 - p.y, p.x);
00228                 break;
00229             case ROT180:
00230                 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00231                 break;
00232             case ROT270:
00233                 return T(p.y, m_realSize.GetWidth()-1 - p.x);
00234                 break;
00235             default:
00236                 return p;
00237                 break;
00238         }
00239     }
00240 
00241     // rotate coordinate to fit possibly rotated image display
00242     // useful for converting rotated display coordinates to image coordinates
00243     template <class T>
00244     T applyRotInv(const T & p) const
00245     {
00246         switch (m_imgRotation) {
00247             case ROT90:
00248                 return T(p.y, m_realSize.GetHeight()-1 - p.x);
00249                 break;
00250             case ROT180:
00251                 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00252                 break;
00253             case ROT270:
00254                 return T(m_realSize.GetWidth()-1 - p.y, p.x);
00255                 break;
00256             case ROT0:
00257             default:
00258                 return p;
00259                 break;
00260         }
00261     }
00262 
00263     //draw the given polygon
00264     void DrawPolygon(wxDC &dc, HuginBase::MaskPolygon poly, bool isSelected, bool drawMarker);
00265     //draw a selection rectange, when called the second time the rectangle is deleted
00266     void DrawSelectionRectangle();
00267     // draws the crop rectangle and/or circle
00268     void DrawCrop(wxDC & dc);
00269     void DrawCrop();
00270     // find the polygon for which the point p is inside the polygon
00271     void FindPolygon(hugin_utils::FDiff2D p);
00272     // returns a set of points which are in the selection rectangle 
00273     bool SelectPointsInsideMouseRect(HuginBase::UIntSet &points,const bool considerSelectedOnly);
00274     // updates the crop
00275     void UpdateCrop(hugin_utils::FDiff2D delta);
00276 
00277     // where the cursor is 
00278     enum ClickPos
00279     {
00280         CLICK_OUTSIDE, CLICK_INSIDE, CLICK_LEFT, CLICK_RIGHT, CLICK_TOP, CLICK_BOTTOM, CLICK_CIRCLE
00281     };
00282     // test, where the curos is
00283     ClickPos GetClickPos(vigra::Point2D pos);
00284 
00286     enum MaskEditorState
00287     {
00288         NO_IMAGE=0, // no image selected
00289         NO_MASK, // image loaded, but none active mask
00290         NO_SELECTION, // active polygon, but no point selected
00291         POINTS_SELECTED, // points selected
00292         POINTS_MOVING, // dragging points
00293         POINTS_DELETING,  // remove points inside rect
00294         POINTS_ADDING,  // adding new points add mouse position
00295         POLYGON_SELECTING, // selecting an region to select an other polygon
00296         REGION_SELECTING, // currently selecting an region
00297         NEW_POLYGON_STARTED, // modus is new polygon, but no point setted yet
00298         NEW_POLYGON_CREATING,  // currently creating new polygon
00299         CROP_SHOWING,  // only showing the crop
00300         CROP_MOVING,  // dragging crop
00301         CROP_CIRCLE_SCALING, // circular crop changing
00302         CROP_LEFT_MOVING, // dragging left border of crop
00303         CROP_RIGHT_MOVING, // dragging right border of crop
00304         CROP_TOP_MOVING,  // dragging top border of crop
00305         CROP_BOTTOM_MOVING // dragging bottom border of crop
00306     };
00307     MaskEditorState m_maskEditState;
00308 
00309     double m_scaleFactor;
00310     bool m_fitToWindow;
00311     bool m_previewOnly;
00312 
00313     MaskEditorPanel * m_editPanel;
00314     HuginBase::MaskPolygonVector m_imageMask;
00315     HuginBase::MaskPolygonVector m_masksToDraw;
00316     unsigned int m_activeMask;
00317     // the active masks, the one which is currently editing
00318     HuginBase::MaskPolygon m_editingMask;
00319     // all selected points
00320     HuginBase::UIntSet m_selectedPoints;
00321 
00322     ImageCache::EntryPtr m_img;
00323 
00324     // positions of mouse drag
00325     wxPoint m_dragStartPos;
00326     wxPoint m_currentPos;
00327 
00328     // colours for different parts
00329     wxColor m_colour_polygon_negative;
00330     wxColor m_colour_polygon_positive;
00331     wxColor m_colour_point_selected;
00332     wxColor m_colour_point_unselected;
00333 #ifndef SUPPORTS_WXINVERT
00334     wxColour m_color_selection;
00335 #endif
00336     int m_oldScrollPosX, m_oldScrollPosY;
00337 
00338     DECLARE_EVENT_TABLE();
00339     DECLARE_DYNAMIC_CLASS(MaskImageCtrl)
00340 };
00341 
00343 class MaskImageCtrlXmlHandler : public wxXmlResourceHandler
00344 {
00345     DECLARE_DYNAMIC_CLASS(MaskImageCtrlXmlHandler)
00346 
00347 public:
00348     MaskImageCtrlXmlHandler();
00349     virtual wxObject *DoCreateResource();
00350     virtual bool CanHandle(wxXmlNode *node);
00351 };
00352 
00353 
00354 #endif // _MaskImageCtrl_H

Generated on 27 Aug 2016 for Hugintrunk by  doxygen 1.4.7