Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PreviewCropTool.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
23 #include "panoinc_WX.h"
24 #include "panoinc.h"
25 #include "PreviewCropTool.h"
26 #include "hugin_config.h"
27 #include "base_wx/platform.h"
28 #include "hugin/config_defaults.h"
29 #include "base_wx/CommandHistory.h"
30 #include "base_wx/wxPanoCommand.h"
31 
32 #include <wx/platform.h>
33 #ifdef __WXMAC__
34 #include <OpenGL/gl.h>
35 #else
36 #include <GL/gl.h>
37 #endif
38 #include "GLPreviewFrame.h"
39 #include "GLViewer.h"
40 
42  : PreviewTool(helper)
43 {
44 
45 }
46 
48 {
52  mouse_down = false;
53  moving_left = false;
54  moving_right = false;
55  moving_top = false;
56  moving_bottom = false;
57  helper->SetStatusMessage(_("Drag the inside of the cropping rectangle to adjust the crop."));
58 }
59 
61 {
62  // draw lines for the border to crop:
63  // We use 1/4 of the smallest dimension as the size of an internal margin
64  // inside the cropping region.
65  // dragging a point in that margin moves the edges for the side we are on
66  // (so the corners move both edges)
67  // dragging a point in the middle moves the whole frame.
68 
69  // find the cropped region
71  vigra::Rect2D roi = opts->getROI();
72  double width = (double) roi.width(),
73  height = (double) roi.height(),
74  margin = (width > height ? height : width) / 4.0;
75  top = (double) roi.top() + margin;
76  bottom = (double) roi.bottom() - margin;
77  left = (double) roi.left() + margin;
78  right = (double) roi.right() - margin;
79 
80  // now draw boxes to indicate what dragging would do.
81  if (!mouse_down)
82  {
83  glEnable(GL_BLEND);
85  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
86  glColor4f(1.0f, 1.0f, 1.0f, 0.38197f);
87  glBegin(GL_QUADS);
88  if (moving_left)
89  {
90  glVertex2d(roi.left(), top); glVertex2d(left, top);
91  glVertex2d(left, bottom); glVertex2d(roi.left(), bottom);
92  }
93  if (moving_right)
94  {
95  glVertex2d(right, top); glVertex2d(roi.right(), top);
96  glVertex2d(roi.right(), bottom); glVertex2d(right, bottom);
97  }
98  if (moving_top)
99  {
100  glVertex2d(right, top); glVertex2d(right, roi.top());
101  glVertex2d(left, roi.top()); glVertex2d(left, top);
102  }
103  if (moving_bottom)
104  {
105  glVertex2d(right, bottom); glVertex2d(right, roi.bottom());
106  glVertex2d(left, roi.bottom()); glVertex2d(left, bottom);
107  }
108  glEnd();
109  glEnable(GL_TEXTURE_2D);
110  glDisable(GL_BLEND);
111  } else {
112  // while dragging, reset the displayed ROI to ours incase something else
113  // tries to redraw the preview with the panorama's real ROI.
114  opts->setROI(new_roi);
116  }
117 }
118 
119 void PreviewCropTool::MouseMoveEvent(double x, double y, wxMouseEvent & e)
120 {
121 
122 // std::cout << "outlines tool " << x << " " << y << std::endl;
123 // double xp, yp;
124 // HuginBase::PTools::Transform transform;
125 // HuginBase::SrcPanoImage image;
126 // image.setSize(vigra::Size2D(360,180));
127 // image.setHFOV(360);
128 // image.setProjection(HuginBase::BaseSrcPanoImage::EQUIRECTANGULAR);
129 // if (helper->GetPanoramaPtr()->getNrOfImages() > 0) {
131 // transform.createTransform(image, *(helper->GetVisualizationStatePtr()->GetOptions()));
132 // transform.transformImgCoord(xp,yp,x,y);
133 // std::cout << "outlines tool " << xp << " " << yp << std::endl;
134 // }
135 
136  if (mouse_down)
137  {
138  vigra::Rect2D roi = start_drag_options.getROI();
139  int left_d = 0;
140  int top_d = 0;
141  int right_d = 0;
142  int bottom_d = 0;
143  if (moving_left)
144  {
145  left_d = (start_drag_x - x);
146  };
147  if (moving_top)
148  {
149  top_d = (start_drag_y - y);
150  };
151  if (moving_right)
152  {
153  right_d = (start_drag_x - x);
154  };
155  if (moving_bottom)
156  {
157  bottom_d = (start_drag_y - y);
158  };
159  const unsigned int movingCounter = moving_left + moving_right + moving_top + moving_bottom;
160  double ratio = 0.0;
161  if (movingCounter == 4 && wxGetKeyState(WXK_SHIFT))
162  {
163  // moving crop with pressed SHIFT button
164  // restrict to horizontal or vertical movement
165  if (std::abs(left_d) < std::abs(top_d))
166  {
167  left_d = 0;
168  right_d = 0;
169  }
170  else
171  {
172  top_d = 0;
173  bottom_d = 0;
174  };
175  }
176  else
177  {
178  if (movingCounter == 2 && wxGetKeyState(WXK_COMMAND))
179  {
180  // keep aspect ratio when move edges with control key
181  ratio = 1.0f * roi.width() / roi.height();
182  }
183  else
184  {
185  if ((movingCounter == 1 || movingCounter == 2) && wxGetKeyState(WXK_SHIFT))
186  {
187  // symmetric movement of crop with shift key
188  if (left_d == 0)
189  {
190  left_d = -right_d;
191  };
192  if (right_d == 0)
193  {
194  right_d = -left_d;
195  };
196  if (top_d == 0)
197  {
198  top_d = -bottom_d;
199  };
200  if (bottom_d == 0)
201  {
202  bottom_d = -top_d;
203  };
204  };
205  };
206  };
207  roi.setUpperLeft(vigra::Point2D(roi.left() - left_d, roi.top() - top_d));
208  roi.setLowerRight(vigra::Point2D(roi.right() - right_d, roi.bottom() - bottom_d));
209  if (ratio > 0.0)
210  {
211  const vigra::Size2D oldSize = roi.size();
212  if (ratio > 1)
213  {
214  roi.setSize(roi.width(), roi.width() / ratio);
215  }
216  else
217  {
218  roi.setSize(roi.height() * ratio, roi.height());
219  };
220  if (moving_top)
221  {
222  // moving the top one requires to update the offset position of the rect
223  roi.moveBy(oldSize.width() - roi.width(), oldSize.height() - roi.height());
224  };
225  };
226  // apply the movement only if it does not bring about a negative crop
227  if((roi.top()<roi.bottom())&&(roi.left()<roi.right()))
228  {
229  opts.setROI(roi);
230  new_roi = roi;
233  }
234  } else {
235  start_drag_x = x;
236  start_drag_y = y;
237  // check if the pointer moved to a region where dragging does something
238  // different. If so, update the display to reflect it.
239  // Note that since we normally only allow redraws to rerender the scene
240  // if the view of the panorama has changed, we have to force a redraw.
241  // (our moving boxes aren't known by the view_state!)
242  int changes = 0;
243  if ((x < left) != moving_left)
244  {
246  changes++;
247  }
248  if ((x > right) != moving_right)
249  {
251  changes++;
252  }
253  if ((y < top) != moving_top)
254  {
256  changes++;
257  }
258  if ((y > bottom) != moving_bottom)
259  {
261  changes++;
262  }
264  {
265  // in the middle moves the whole region
266  moving_left = true; moving_right = true;
267  moving_top = true; moving_bottom = true;
268  changes++;
269  }
270  // the middle section is an exception to the other 4 rules:
271  if (changes == 5) changes = 0;
272  // Draw if the boxes we show are different to what is already drawn.
273  if (changes)
274  {
275  // since we didn't change the panorama, view_state doesn't think we
276  // should redraw. Persuade it otherwise:
278  helper->GetVisualizationStatePtr()->Redraw(); // now redraw.
279  }
280  }
281 }
282 
283 
285 {
286  if (e.GetButton() == wxMOUSE_BTN_LEFT)
287  {
288  if (e.ButtonDown())
289  {
292  new_roi = opts.getROI();
293  mouse_down = true;
294  moving_left = false;
295  moving_right = false;
296  moving_top = false;
297  moving_bottom = false;
298  if (start_drag_x < left) moving_left = true;
299  if (start_drag_x > right) moving_right = true;
300  if (start_drag_y < top) moving_top = true;
301  if (start_drag_y > bottom) moving_bottom = true;
302  // in the middle, move everything.
304  {
305  moving_left = true;
306  moving_right = true;
307  moving_top = true;
308  moving_bottom = true;
309  }
310  if (!helper->GetPreviewFrame()->getPreview()->HasCapture())
311  {
312  helper->GetPreviewFrame()->getPreview()->CaptureMouse();
313  };
314  } else {
315  if (mouse_down)
316  {
317  if (helper->GetPreviewFrame()->getPreview()->HasCapture())
318  {
319  helper->GetPreviewFrame()->getPreview()->ReleaseMouse();
320  };
321  mouse_down = false;
322  moving_left = false;
323  moving_right = false;
324  moving_top = false;
325  moving_bottom = false;
326  // set the new cropping region permanently.
329  opts));
330  }
331  }
332  }
333 }
334 
implementation of huginApp Class
ViewState * GetViewStatePtr()
Definition: ToolHelper.cpp:305
HuginBase::PanoramaOptions opts
void MouseMoveEvent(double x, double y, wxMouseEvent &e)
Notify when the mouse pointer has moved over the panorama preview.
HuginBase::Panorama * GetPanoramaPtr()
Definition: ToolHelper.cpp:310
void DisableTexture(bool maskOnly=false)
include file for the hugin project
vigra::Rect2D new_roi
void ForceRequireRedraw()
Definition: ViewState.cpp:439
void NotifyMe(Event event, Tool *tool)
Definition: ToolHelper.cpp:315
void ReallyAfterDrawImagesEvent()
Draw (using OpenGL) the overlays, e.g. crop highlights, guides.
VisualizationState * GetVisualizationStatePtr()
Definition: ToolHelper.cpp:300
HuginBase::PanoramaOptions * GetOptions()
Definition: ViewState.cpp:273
set the panorama options
Definition: PanoCommand.h:418
ToolHelper * helper
The PreviewToolHelper that uses the same preview window and panorama as the tool should.
Definition: Tool.h:102
const vigra::Rect2D & getROI() const
HuginBase::PanoramaOptions start_drag_options
void Activate()
Switch on a tool.
TextureManager * GetTextureManager()
Definition: ViewState.h:104
wxwindows specific panorama commands
static GlobalCmdHist & getInstance()
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
void setROI(const vigra::Rect2D &val)
ViewState * getViewState()
Definition: ViewState.h:239
void MouseButtonEvent(wxMouseEvent &e)
Notify of a mouse button press on the panorama preview.
include file for the hugin project
void SetOptions(const HuginBase::PanoramaOptions *new_opts)
Definition: ViewState.cpp:120
void SetStatusMessage(wxString message)
Definition: ToolHelper.cpp:409
PreviewCropTool(PreviewToolHelper *helper)
GLPreview * getPreview()
Panorama image options.
GLPreviewFrame * GetPreviewFrame()
Definition: ToolHelper.h:139