00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00033
00034
00035
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
00151 wxBitmap m_bitmap;
00152 wxBitmap m_disabledBitmap;
00153
00154 std::string m_imageFilename;
00155
00156 ImageRotation m_imgRotation;
00157
00158 wxSize m_imageSize;
00159
00160 wxSize m_realSize;
00161
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
00168 bool m_showActiveMasks;
00169
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
00210
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
00234
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
00256 void DrawPolygon(wxDC &dc, HuginBase::MaskPolygon poly, bool isSelected, bool drawMarker);
00257
00258 void DrawSelectionRectangle();
00259
00260 void DrawCrop(wxDC & dc);
00261 void DrawCrop();
00262
00263 void FindPolygon(hugin_utils::FDiff2D p);
00264
00265 bool SelectPointsInsideMouseRect(HuginBase::UIntSet &points,const bool considerSelectedOnly);
00266
00267 void UpdateCrop(hugin_utils::FDiff2D delta);
00268
00269
00270 enum ClickPos
00271 {
00272 CLICK_OUTSIDE, CLICK_INSIDE, CLICK_LEFT, CLICK_RIGHT, CLICK_TOP, CLICK_BOTTOM, CLICK_CIRCLE
00273 };
00274
00275 ClickPos GetClickPos(vigra::Point2D pos);
00276
00278 enum MaskEditorState
00279 {
00280 NO_IMAGE=0,
00281 NO_MASK,
00282 NO_SELECTION,
00283 POINTS_SELECTED,
00284 POINTS_MOVING,
00285 POINTS_DELETING,
00286 POINTS_ADDING,
00287 POLYGON_SELECTING,
00288 REGION_SELECTING,
00289 NEW_POLYGON_STARTED,
00290 NEW_POLYGON_CREATING,
00291 CROP_SHOWING,
00292 CROP_MOVING,
00293 CROP_CIRCLE_SCALING,
00294 CROP_LEFT_MOVING,
00295 CROP_RIGHT_MOVING,
00296 CROP_TOP_MOVING,
00297 CROP_BOTTOM_MOVING
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
00310 HuginBase::MaskPolygon m_editingMask;
00311
00312 HuginBase::UIntSet m_selectedPoints;
00313
00314 ImageCache::EntryPtr m_img;
00315
00316
00317 wxPoint m_dragStartPos;
00318 wxPoint m_currentPos;
00319
00320
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