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, write to the Free Software
00022  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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);
00102 
00104     void startNewPolygon();
00106     wxSize DoGetBestSize() const;
00107 
00109     void SetMaskMode(bool newMaskMode);
00110 
00115     void setScale(double factor);
00116 
00118     double getScale()
00119         { return m_fitToWindow ? 0 : m_scaleFactor; }
00120 
00122     ImageRotation getCurrentRotation() { return m_imgRotation; };
00123 
00125     void setDrawingActiveMasks(bool newDrawActiveMasks);
00127     void update();
00128 
00130     void SetUserColourPolygonNegative(wxColour newColour) { m_colour_polygon_negative=newColour; };
00131     void SetUserColourPolygonPositive(wxColour newColour) { m_colour_polygon_positive=newColour; };
00132     void SetUserColourPointSelected(wxColour newColour) { m_colour_point_selected=newColour; };
00133     void SetUserColourPointUnselected(wxColour newColour) { m_colour_point_unselected=newColour; };
00134 
00135 protected:
00137     void OnDraw(wxDC& dc);
00139     void OnSize(wxSizeEvent & e);
00140 
00142     double getScaleFactor() const;
00144     double calcAutoScaleFactor(wxSize size);
00146     void rescaleImage();
00147 
00148  private:
00149 
00150     //scaled bitmap
00151     wxBitmap m_bitmap;
00152     wxBitmap m_disabledBitmap;
00153     //filename of current editing file
00154     std::string m_imageFilename;
00155     // stores rotation of image
00156     ImageRotation m_imgRotation;
00157     // size of displayed (probably scaled) image
00158     wxSize m_imageSize;
00159     // size of real image
00160     wxSize m_realSize;
00161     // variables for crop
00162     HuginBase::SrcPanoImage::CropMode m_cropMode;
00163     vigra::Rect2D m_cropRect;
00164     bool m_cropCentered;
00165     bool m_cropCircle;
00166     hugin_utils::FDiff2D m_cropCenter;
00167     // draw active masks 
00168     bool m_showActiveMasks;
00169     // mask or crop mode
00170     bool m_maskMode;
00171 
00173     int scale(int x) const
00174         {  return (int) (x * getScaleFactor() + 0.5); }
00175 
00176     double scale(double x) const
00177         {  return x * getScaleFactor(); }
00178 
00180     int transform(int x) const
00181         {  return (int) ((x+HuginBase::maskOffset) * getScaleFactor() + 0.5); }
00182 
00183     double transform(double x) const
00184         {  return (x+HuginBase::maskOffset) * getScaleFactor(); }
00185 
00186     wxPoint transform(const hugin_utils::FDiff2D & p) const
00187         {
00188             wxPoint r;
00189             r.x = transform(p.x);
00190             r.y = transform(p.y);
00191             return r;
00192         };
00193 
00195     int invtransform(int x) const
00196         {  return (int) (x/getScaleFactor()-HuginBase::maskOffset + 0.5); };
00197 
00198     double invtransform(double x) const
00199         {  return (x/getScaleFactor()-HuginBase::maskOffset); };
00200 
00201     hugin_utils::FDiff2D invtransform(const wxPoint & p) const
00202         {
00203             hugin_utils::FDiff2D r;
00204             r.x = invtransform(p.x);
00205             r.y = invtransform(p.y);
00206             return r;
00207         };
00208     
00209     // rotate coordinate to fit possibly rotated image display
00210     // useful for drawing something on the rotated display
00211     template <class T>
00212     T applyRot(const T & p) const
00213     {
00214         switch (m_imgRotation) {
00215             case ROT0:
00216                 return p;
00217                 break;
00218             case ROT90:
00219                 return T(m_realSize.GetHeight()-1 - p.y, p.x);
00220                 break;
00221             case ROT180:
00222                 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00223                 break;
00224             case ROT270:
00225                 return T(p.y, m_realSize.GetWidth()-1 - p.x);
00226                 break;
00227             default:
00228                 return p;
00229                 break;
00230         }
00231     }
00232 
00233     // rotate coordinate to fit possibly rotated image display
00234     // useful for converting rotated display coordinates to image coordinates
00235     template <class T>
00236     T applyRotInv(const T & p) const
00237     {
00238         switch (m_imgRotation) {
00239             case ROT90:
00240                 return T(p.y, m_realSize.GetHeight()-1 - p.x);
00241                 break;
00242             case ROT180:
00243                 return T(m_realSize.GetWidth()-1 - p.x, m_realSize.GetHeight()-1 - p.y);
00244                 break;
00245             case ROT270:
00246                 return T(m_realSize.GetWidth()-1 - p.y, p.x);
00247                 break;
00248             case ROT0:
00249             default:
00250                 return p;
00251                 break;
00252         }
00253     }
00254 
00255     //draw the given polygon
00256     void DrawPolygon(wxDC &dc, HuginBase::MaskPolygon poly, bool isSelected, bool drawMarker);
00257     //draw a selection rectange, when called the second time the rectangle is deleted
00258     void DrawSelectionRectangle();
00259     // draws the crop rectangle and/or circle
00260     void DrawCrop(wxDC & dc);
00261     void DrawCrop();
00262     // find the polygon for which the point p is inside the polygon
00263     void FindPolygon(hugin_utils::FDiff2D p);
00264     // returns a set of points which are in the selection rectangle 
00265     bool SelectPointsInsideMouseRect(HuginBase::UIntSet &points,const bool considerSelectedOnly);
00266     // updates the crop
00267     void UpdateCrop(hugin_utils::FDiff2D delta);
00268 
00269     // where the cursor is 
00270     enum ClickPos
00271     {
00272         CLICK_OUTSIDE, CLICK_INSIDE, CLICK_LEFT, CLICK_RIGHT, CLICK_TOP, CLICK_BOTTOM, CLICK_CIRCLE
00273     };
00274     // test, where the curos is
00275     ClickPos GetClickPos(vigra::Point2D pos);
00276 
00278     enum MaskEditorState
00279     {
00280         NO_IMAGE=0, // no image selected
00281         NO_MASK, // image loaded, but none active mask
00282         NO_SELECTION, // active polygon, but no point selected
00283         POINTS_SELECTED, // points selected
00284         POINTS_MOVING, // dragging points
00285         POINTS_DELETING,  // remove points inside rect
00286         POINTS_ADDING,  // adding new points add mouse position
00287         POLYGON_SELECTING, // selecting an region to select an other polygon
00288         REGION_SELECTING, // currently selecting an region
00289         NEW_POLYGON_STARTED, // modus is new polygon, but no point setted yet
00290         NEW_POLYGON_CREATING,  // currently creating new polygon
00291         CROP_SHOWING,  // only showing the crop
00292         CROP_MOVING,  // dragging crop
00293         CROP_CIRCLE_SCALING, // circular crop changing
00294         CROP_LEFT_MOVING, // dragging left border of crop
00295         CROP_RIGHT_MOVING, // dragging right border of crop
00296         CROP_TOP_MOVING,  // dragging top border of crop
00297         CROP_BOTTOM_MOVING // dragging bottom border of crop
00298     };
00299     MaskEditorState m_maskEditState;
00300 
00301     double m_scaleFactor;
00302     bool m_fitToWindow;
00303     bool m_previewOnly;
00304 
00305     MaskEditorPanel * m_editPanel;
00306     HuginBase::MaskPolygonVector m_imageMask;
00307     HuginBase::MaskPolygonVector m_masksToDraw;
00308     unsigned int m_activeMask;
00309     // the active masks, the one which is currently editing
00310     HuginBase::MaskPolygon m_editingMask;
00311     // all selected points
00312     HuginBase::UIntSet m_selectedPoints;
00313 
00314     ImageCache::EntryPtr m_img;
00315 
00316     // positions of mouse drag
00317     wxPoint m_dragStartPos;
00318     wxPoint m_currentPos;
00319 
00320     // colours for different parts
00321     wxColor m_colour_polygon_negative;
00322     wxColor m_colour_polygon_positive;
00323     wxColor m_colour_point_selected;
00324     wxColor m_colour_point_unselected;
00325 #ifndef SUPPORTS_WXINVERT
00326     wxColour m_color_selection;
00327 #endif
00328 
00329     DECLARE_EVENT_TABLE();
00330     DECLARE_DYNAMIC_CLASS(MaskImageCtrl)
00331 };
00332 
00334 class MaskImageCtrlXmlHandler : public wxXmlResourceHandler
00335 {
00336     DECLARE_DYNAMIC_CLASS(MaskImageCtrlXmlHandler)
00337 
00338 public:
00339     MaskImageCtrlXmlHandler();
00340     virtual wxObject *DoCreateResource();
00341     virtual bool CanHandle(wxXmlNode *node);
00342 };
00343 
00344 
00345 #endif // _MaskImageCtrl_H

Generated on Mon Apr 21 01:25:32 2014 for Hugintrunk by  doxygen 1.3.9.1