Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PreviewFrame.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
27 #include "hugin_config.h"
28 
29 #include "panoinc_WX.h"
30 
31 #include "panoinc.h"
32 
33 #include "base_wx/platform.h"
34 #include "hugin/config_defaults.h"
35 #include "hugin/PreviewFrame.h"
36 #include "hugin/huginApp.h"
37 #include "hugin/PreviewPanel.h"
38 #include "hugin/ImagesPanel.h"
39 #include "base_wx/CommandHistory.h"
40 #include "base_wx/PanoCommand.h"
44 #include "base_wx/wxPlatform.h"
45 
47 
48 extern "C" {
49 #include <pano13/queryfeature.h>
50 }
51 
52 // a random id, hope this doesn't break something..
53 enum {
54  ID_PROJECTION_CHOICE = wxID_HIGHEST +1,
63  ID_TOGGLE_BUT = wxID_HIGHEST+100,
64  PROJ_PARAM_NAMES_ID = wxID_HIGHEST+1000,
65  PROJ_PARAM_VAL_ID = wxID_HIGHEST+1100,
66  PROJ_PARAM_SLIDER_ID = wxID_HIGHEST+1200,
67  PROJ_PARAM_RESET_ID = wxID_HIGHEST+1250,
68  ID_FULL_SCREEN = wxID_HIGHEST+1700,
69  ID_UNDO = wxID_HIGHEST+1701,
70  ID_REDO = wxID_HIGHEST+1702
71 };
72 
73 BEGIN_EVENT_TABLE(PreviewFrame, wxFrame)
74  EVT_CLOSE(PreviewFrame::OnClose)
75 // EVT_CHECKBOX(-1, PreviewFrame::OnAutoPreviewToggle)
76  EVT_TOOL(XRCID("preview_center_tool"), PreviewFrame::OnCenterHorizontally)
77  EVT_TOOL(XRCID("preview_fit_pano_tool"), PreviewFrame::OnFitPano)
78  EVT_TOOL(XRCID("preview_straighten_pano_tool"), PreviewFrame::OnStraighten)
79  EVT_TOOL(XRCID("preview_auto_update_tool"), PreviewFrame::OnAutoPreviewToggle)
80  EVT_TOOL(XRCID("preview_update_tool"), PreviewFrame::OnUpdate)
81  EVT_TOOL(XRCID("preview_show_all_tool"), PreviewFrame::OnShowAll)
82  EVT_TOOL(XRCID("preview_show_none_tool"), PreviewFrame::OnShowNone)
83  EVT_TOOL(XRCID("preview_num_transform"), PreviewFrame::OnNumTransform)
84  EVT_TEXT_ENTER( -1 , PreviewFrame::OnTextCtrlChanged)
85 
86  EVT_BUTTON(ID_EXPOSURE_DEFAULT, PreviewFrame::OnDefaultExposure)
87  EVT_SPIN_DOWN(ID_EXPOSURE_SPIN, PreviewFrame::OnDecreaseExposure)
88  EVT_SPIN_UP(ID_EXPOSURE_SPIN, PreviewFrame::OnIncreaseExposure)
89  EVT_SPIN_DOWN(ID_RANGE_COMPRESSION_SPIN, PreviewFrame::OnRangeCompressionDecrease)
90  EVT_SPIN_UP(ID_RANGE_COMPRESSION_SPIN, PreviewFrame::OnRangeCompressionIncrease)
91  EVT_CHOICE(ID_BLEND_CHOICE, PreviewFrame::OnBlendChoice)
92  EVT_CHOICE(ID_PROJECTION_CHOICE, PreviewFrame::OnProjectionChoice)
93  EVT_CHOICE(ID_OUTPUTMODE_CHOICE, PreviewFrame::OnOutputChoice)
94  EVT_TOGGLEBUTTON(-1, PreviewFrame::OnChangeDisplayedImgs)
95  EVT_SCROLL_CHANGED(PreviewFrame::OnChangeFOV)
96  EVT_TOOL(ID_FULL_SCREEN, PreviewFrame::OnFullScreen)
97  EVT_TOOL(ID_UNDO, PreviewFrame::OnUndo)
98  EVT_TOOL(ID_REDO, PreviewFrame::OnRedo)
99  EVT_BUTTON(PROJ_PARAM_RESET_ID, PreviewFrame::OnProjParameterReset)
101 
102 #define PF_STYLE (wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
103 
105  : wxFrame(frame,-1, _("Panorama preview"), wxDefaultPosition, wxDefaultSize,
106  PF_STYLE),
107  m_pano(pano)
108 {
109  DEBUG_TRACE("");
110 
111  m_oldProjFormat = -1;
112  m_ToolBar = wxXmlResource::Get()->LoadToolBar(this, wxT("preview_toolbar"));
114  // create tool bar
115  SetToolBar(m_ToolBar);
116 
117  m_topsizer = new wxBoxSizer( wxVERTICAL );
118 
119  m_ToggleButtonSizer = new wxStaticBoxSizer(
120  new wxStaticBox(this, -1, _("displayed images")),
121  wxHORIZONTAL );
122 
123  m_ButtonPanel = new wxScrolledWindow(this, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
124  // Set min height big enough to display scrollbars as well
125  m_ButtonPanel->SetSizeHints(20, 42);
126  //Horizontal scroll bars only
127  m_ButtonPanel->SetScrollRate(10, 0);
128  m_ButtonSizer = new wxBoxSizer(wxHORIZONTAL);
129  m_ButtonPanel->SetAutoLayout(true);
130  m_ButtonPanel->SetSizer(m_ButtonSizer);
131 
132  m_ToggleButtonSizer->Add(m_ButtonPanel, 1, wxEXPAND, 0);
133 
134  m_topsizer->Add(m_ToggleButtonSizer, 0, wxEXPAND | wxALL, 5);
135 
136  wxFlexGridSizer * flexSizer = new wxFlexGridSizer(2,0,5,5);
137  flexSizer->AddGrowableCol(0);
138  flexSizer->AddGrowableRow(0);
139 
140  // create our preview panel
142  m_PreviewPanel->Create(this);
143  m_PreviewPanel->Init(this, &pano);
144 
145  flexSizer->Add(m_PreviewPanel,
146  1, // not vertically stretchable
147  wxEXPAND | // horizontally stretchable
148  wxALL, // draw border all around
149  5); // border width
150 
151 
152  m_VFOVSlider = new wxSlider(this, -1, 1,
153  1, 180,
154  wxDefaultPosition, wxDefaultSize,
155  wxSL_VERTICAL | wxSL_AUTOTICKS,
156  wxDefaultValidator,
157  _("VFOV"));
158  m_VFOVSlider->SetLineSize(2);
159  m_VFOVSlider->SetPageSize(10);
160  m_VFOVSlider->SetTickFreq(5);
161  m_VFOVSlider->SetToolTip(_("drag to change the vertical field of view"));
162 
163  flexSizer->Add(m_VFOVSlider, 0, wxEXPAND);
164 
165  m_HFOVSlider = new wxSlider(this, -1, 1,
166  1, 360,
167  wxDefaultPosition, wxDefaultSize,
168  wxSL_HORIZONTAL | wxSL_AUTOTICKS,
169  wxDefaultValidator,
170  _("HFOV"));
171  m_HFOVSlider->SetPageSize(10);
172  m_HFOVSlider->SetLineSize(2);
173  m_HFOVSlider->SetTickFreq(5);
174 
175  m_HFOVSlider->SetToolTip(_("drag to change the horizontal field of view"));
176 
177  flexSizer->Add(m_HFOVSlider, 0, wxEXPAND);
178 
179  m_topsizer->Add(flexSizer,
180  1, // vertically stretchable
181  wxEXPAND | // horizontally stretchable
182  wxALL, // draw border all around
183  5); // border width
184 
185  wxStaticBoxSizer * blendModeSizer = new wxStaticBoxSizer(
186  new wxStaticBox(this, -1, _("Preview Options")),
187  wxHORIZONTAL);
188 
189  blendModeSizer->Add(new wxStaticText(this, -1, _("projection (f):")),
190  0, // not vertically strechable
191  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
192  5); // border width
193  m_ProjectionChoice = new wxChoice(this, ID_PROJECTION_CHOICE,
194  wxDefaultPosition, wxDefaultSize);
195 
196  /* populate with all available projection types */
197  int nP = panoProjectionFormatCount();
198  for(int n=0; n < nP; n++) {
199  pano_projection_features proj;
200  if (panoProjectionFeaturesQuery(n, &proj)) {
201  wxString str2(proj.name, wxConvLocal);
202  m_ProjectionChoice->Append(wxGetTranslation(str2));
203  }
204  }
205  m_ProjectionChoice->SetSelection(2);
206 
207  blendModeSizer->Add(m_ProjectionChoice,
208  0,
209  wxALL | wxALIGN_CENTER_VERTICAL,
210  5);
211 
213  // Blend mode
214  blendModeSizer->Add(new wxStaticText(this, -1, _("Blend mode:")),
215  0, // not vertically strechable
216  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
217  5); // border width
218 
219  m_choices[0] = _("normal");
220  m_choices[1] = _("difference");
221 
222  int oldMode = wxConfigBase::Get()->Read(wxT("/PreviewFrame/blendMode"), 0l);
223  if (oldMode > 1) oldMode = 0;
224  m_BlendModeChoice = new wxChoice(this, ID_BLEND_CHOICE,
225  wxDefaultPosition, wxDefaultSize,
226  2, m_choices);
227  m_BlendModeChoice->SetSelection((PreviewPanel::BlendMode) oldMode);
228 
229  blendModeSizer->Add(m_BlendModeChoice,
230  0,
231  wxALL | wxALIGN_CENTER_VERTICAL,
232  5);
233 
235  // LDR, HDR
236  blendModeSizer->Add(new wxStaticText(this, -1, _("Output:")),
237  0, // not vertically strechable
238  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
239  5); // border width
240 
241  m_choices[0] = _("LDR");
242  m_choices[1] = _("HDR");
243  m_outputModeChoice = new wxChoice(this, ID_OUTPUTMODE_CHOICE,
244  wxDefaultPosition, wxDefaultSize,
245  2, m_choices);
246  m_outputModeChoice->SetSelection(0);
247  blendModeSizer->Add(m_outputModeChoice,
248  0,
249  wxALL | wxALIGN_CENTER_VERTICAL,
250  5);
251 
253  // exposure
254  blendModeSizer->Add(new wxStaticText(this, -1, _("EV:")),
255  0, // not vertically strechable
256  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
257  5); // border width
258 
259  m_defaultExposureBut = new wxBitmapButton(this, ID_EXPOSURE_DEFAULT,
260  wxArtProvider::GetBitmap(wxART_REDO));
261  blendModeSizer->Add(m_defaultExposureBut, 0, wxLEFT | wxRIGHT, 5);
262 
263 // m_decExposureBut = new wxBitmapButton(this, ID_EXPOSURE_DECREASE,
264 // wxArtProvider::GetBitmap(wxART_GO_BACK));
265 // blendModeSizer->Add(m_decExposureBut);
266 
267  m_exposureTextCtrl = new wxTextCtrl(this, ID_EXPOSURE_TEXT, wxT("0"),
268  wxDefaultPosition,wxSize(50,-1), wxTE_PROCESS_ENTER);
269  blendModeSizer->Add(m_exposureTextCtrl,
270  0, // not vertically strechable
271  wxLEFT | wxTOP | wxBOTTOM | wxALIGN_CENTER_VERTICAL, // draw border all around
272  5); // border width
273 // m_incExposureBut = new wxBitmapButton(this, ID_EXPOSURE_INCREASE,
274 // wxArtProvider::GetBitmap(wxART_GO_FORWARD));
275  m_exposureSpinBut = new wxSpinButton(this, ID_EXPOSURE_SPIN, wxDefaultPosition,
276  wxDefaultSize, wxSP_VERTICAL);
277  m_exposureSpinBut->SetRange(-0x8000, 0x7fff);
278  m_exposureSpinBut->SetValue(0);
279  m_exposureSpinBut->SetMaxSize(wxSize(-1, m_exposureTextCtrl->GetSize().GetHeight()));
280  blendModeSizer->Add(m_exposureSpinBut, 0, wxALIGN_CENTER_VERTICAL);
281  blendModeSizer->Add(new wxStaticText(this, wxID_ANY, _("Range compression:")), 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5);
282  m_rangeCompressionTextCtrl = new wxTextCtrl(this, ID_RANGE_COMPRESSION_TEXT, wxT("0"),
283  wxDefaultPosition, wxSize(30, -1), wxTE_PROCESS_ENTER);
284  blendModeSizer->Add(m_rangeCompressionTextCtrl, 0, wxLEFT | wxTOP | wxBOTTOM | wxALIGN_CENTER_VERTICAL, 5);
285  m_rangeCompressionSpinBut = new wxSpinButton(this, ID_RANGE_COMPRESSION_SPIN, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL);
286  m_rangeCompressionSpinBut->SetRange(-0x8000, 0x7fff);
287  m_rangeCompressionSpinBut->SetValue(0);
288  m_rangeCompressionSpinBut->SetMaxSize(wxSize(-1, m_rangeCompressionTextCtrl->GetSize().GetHeight()));
289  blendModeSizer->Add(m_rangeCompressionSpinBut, 0, wxALIGN_CENTER_VERTICAL);
290  m_topsizer->Add(blendModeSizer, 0, wxEXPAND | wxALL, 5);
291 
292  m_projParamSizer = new wxStaticBoxSizer(
293  new wxStaticBox(this, -1, _("Projection Parameters")),
294  wxHORIZONTAL);
295 
296  wxBitmapButton * resetProjButton=new wxBitmapButton(this, PROJ_PARAM_RESET_ID,
297  wxArtProvider::GetBitmap(wxART_REDO));
298  resetProjButton->SetToolTip(_("Resets the projection's parameters to their default values."));
299  m_projParamSizer->Add(resetProjButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
300 
301  m_projParamNamesLabel.resize(PANO_PROJECTION_MAX_PARMS);
302  m_projParamTextCtrl.resize(PANO_PROJECTION_MAX_PARMS);
303  m_projParamSlider.resize(PANO_PROJECTION_MAX_PARMS);
304 
305  for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++) {
306 
307  m_projParamNamesLabel[i] = new wxStaticText(this, PROJ_PARAM_NAMES_ID+i, _("param:"));
309  0, // not vertically strechable
310  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
311  5); // border width
312  m_projParamTextCtrl[i] = new wxTextCtrl(this, PROJ_PARAM_VAL_ID+i, wxT("0"),
313  wxDefaultPosition, wxSize(35,-1), wxTE_PROCESS_ENTER);
314  m_projParamTextCtrl[i]->PushEventHandler(new TextKillFocusHandler(this));
316  0, // not vertically strechable
317  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
318  5); // border width
319 
320  m_projParamSlider[i] = new wxSlider(this, PROJ_PARAM_SLIDER_ID+i, 0, -90, 90);
322  1, // not vertically strechable
323  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
324  5); // border width
325  }
326 
327  m_topsizer->Add(m_projParamSizer, 0, wxEXPAND | wxALL, 5);
328 
329  // do not show projection param sizer
330  m_topsizer->Show(m_projParamSizer, false, true);
331 
332  wxConfigBase * config = wxConfigBase::Get();
333 
334  // add a status bar
335  CreateStatusBar(3);
336  int widths[3] = {-3, 150, 150};
337  SetStatusWidths(3, widths);
338  SetStatusText(_("Left click to define new center point, right click to move point to horizon."),0);
339  SetStatusText(wxT(""),1);
340  SetStatusText(wxT(""),2);
341 
342  // the initial size as calculated by the sizers
343  this->SetSizer( m_topsizer );
344  m_topsizer->SetSizeHints( this );
345 
346  // set the minimize icon
347 #ifdef __WXMSW__
348  wxIconBundle myIcons(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
349  SetIcons(myIcons);
350 #else
351  wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
352  SetIcon(myIcon);
353 #endif
354 
355  m_pano.addObserver(this);
356 
357  RestoreFramePosition(this, wxT("PreviewFrame"));
358 
360 
361  long aup = config->Read(wxT("/PreviewFrame/autoUpdate"),0l);
362  m_PreviewPanel->SetAutoUpdate(aup != 0);
363 
364  m_ToolBar->ToggleTool(XRCID("preview_auto_update_tool"), aup !=0);
365 
366 #ifdef __WXMSW__
367  // wxFrame does have a strange background color on Windows..
368  this->SetBackgroundColour(m_PreviewPanel->GetBackgroundColour());
369 #endif
370 
371  if (config->Read(wxT("/PreviewFrame/isShown"), 0l) != 0) {
372  Show();
373  }
374  SetStatusText(_("Center panorama with left mouse button, set horizon with right button"),0);
375  wxAcceleratorEntry entries[3];
376 #ifdef __WXMAC
377  entries[0].Set(wxACCEL_CMD,(int)'F',ID_FULL_SCREEN);
378 #else
379  entries[0].Set(wxACCEL_NORMAL,WXK_F11,ID_FULL_SCREEN);
380 #endif
381  entries[1].Set(wxACCEL_CMD,(int)'Z',ID_UNDO);
382  entries[2].Set(wxACCEL_CMD,(int)'R',ID_REDO);
383  wxAcceleratorTable accel(3, entries);
384  SetAcceleratorTable(accel);
385 #ifdef __WXGTK__
386  // set explicit focus to button panel, otherwise the hotkey F11 is not right processed
387  m_ButtonPanel->SetFocus();
388 #endif
389 }
390 
392 {
393  DEBUG_TRACE("dtor writing config");
394  wxConfigBase * config = wxConfigBase::Get();
395 
396  StoreFramePosition(this, wxT("PreviewFrame"));
397 
398  if ( (!this->IsIconized()) && (! this->IsMaximized()) && this->IsShown()) {
399  config->Write(wxT("/PreviewFrame/isShown"), 1l);
400  } else {
401  config->Write(wxT("/PreviewFrame/isShown"), 0l);
402  }
403 
404  bool checked = m_ToolBar->GetToolState(XRCID("preview_auto_update_tool"));
405  config->Write(wxT("/PreviewFrame/autoUpdate"), checked ? 1l: 0l);
406  config->Write(wxT("/PreviewFrame/blendMode"), m_BlendModeChoice->GetSelection());
407  for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++)
408  {
409  m_projParamTextCtrl[i]->PopEventHandler(true);
410  };
411  m_pano.removeObserver(this);
412  DEBUG_TRACE("dtor end");
413 }
414 
415 void PreviewFrame::OnChangeDisplayedImgs(wxCommandEvent & e)
416 {
417  int id = e.GetId() - ID_TOGGLE_BUT;
418  int nImg = m_pano.getNrOfImages();
419  HuginBase::UIntSet activeImages = m_pano.getActiveImages();
420  DEBUG_DEBUG("toggle_button_id: " << id << " nImg:" << nImg << " m_ToggleButtons.size(): " << m_ToggleButtons.size());
421  if (id >= 0 && id < nImg) {
422  if (e.IsChecked()) {
423  activeImages.insert(id);
424  } else {
425  activeImages.erase(id);
426  }
427 // m_PreviewPanel->SetDisplayedImages(m_displayedImgs);
429  new PanoCommand::SetActiveImagesCmd(m_pano, activeImages)
430  );
431  } else {
432  DEBUG_ERROR("invalid Togglebutton ID");
433  }
434 }
435 
437 {
438  const HuginBase::PanoramaOptions & opts = pano.getOptions();
439 
440  wxString projection;
441  m_ProjectionChoice->SetSelection(opts.getProjection());
442  m_VFOVSlider->Enable( opts.fovCalcSupported(opts.getProjection()) );
443 
444  m_outputModeChoice->SetSelection(opts.outputMode);
446  /*
447  m_exposureTextCtrl->Hide();
448  m_defaultExposureBut->Hide();
449  m_decExposureBut->Hide();
450  m_incExposureBut->Hide();
451  */
452  } else {
453  /*
454  m_exposureTextCtrl->Show();
455  m_defaultExposureBut->Show();
456  m_decExposureBut->Show();
457  m_incExposureBut->Show();
458  */
459  }
460  m_exposureTextCtrl->SetValue(wxString(hugin_utils::doubleToString(opts.outputExposureValue,2).c_str(), wxConvLocal));
461  m_rangeCompressionTextCtrl->SetValue(wxString(hugin_utils::doubleToString(opts.outputRangeCompression,1).c_str(), wxConvLocal));
462 
463  const bool activeImgs = !pano.getActiveImages().empty();
464  m_ToolBar->EnableTool(XRCID("preview_center_tool"), activeImgs);
465  m_ToolBar->EnableTool(XRCID("preview_fit_pano_tool"), activeImgs);
466  m_ToolBar->EnableTool(XRCID("preview_update_tool"), activeImgs);
467  m_ToolBar->EnableTool(XRCID("preview_num_transform"), activeImgs);
468  m_ToolBar->EnableTool(XRCID("preview_straighten_pano_tool"), pano.getNrOfImages() > 0);
469 
470  // TODO: enable display of parameters and set their limits, if projection has some.
471  int nParam = opts.m_projFeatures.numberOfParameters;
472  bool relayout = false;
473  // if the projection format has changed
474  if (opts.getProjection() != m_oldProjFormat) {
475  DEBUG_DEBUG("Projection format changed");
476  if (nParam) {
477  // show parameters and update labels.
478  m_topsizer->Show(m_projParamSizer, true, true);
479  int i;
480  for (i=0; i < nParam; i++) {
481  const pano_projection_parameter * pp = & (opts.m_projFeatures.parm[i]);
482  wxString str2(pp->name, wxConvLocal);
483  str2 = wxGetTranslation(str2);
484  m_projParamNamesLabel[i]->SetLabel(str2);
485  m_projParamSlider[i]->SetRange(hugin_utils::roundi(pp->minValue), hugin_utils::roundi(pp->maxValue));
486  }
487  for(;i < PANO_PROJECTION_MAX_PARMS; i++) {
488  m_projParamNamesLabel[i]->Hide();
489  m_projParamSlider[i]->Hide();
490  m_projParamTextCtrl[i]->Hide();
491  }
492  relayout = true;
493  } else {
494  m_topsizer->Show(m_projParamSizer, false, true);
495  relayout = true;
496  }
497  }
498  if (nParam) {
499  // display new values
500  std::vector<double> params = opts.getProjectionParameters();
501  assert((int) params.size() == nParam);
502  for (int i=0; i < nParam; i++) {
503  wxString val = wxString(hugin_utils::doubleToString(params[i],1).c_str(), wxConvLocal);
504  m_projParamTextCtrl[i]->SetValue(wxString(val.wc_str(), wxConvLocal));
505  m_projParamSlider[i]->SetValue(hugin_utils::roundi(params[i]));
506  }
507  }
508  if (relayout) {
509  m_topsizer->Layout();
510  Refresh();
511  }
512  SetStatusText(_("Center panorama with left mouse button, set horizon with right button"),0);
513  SetStatusText(wxString::Format(wxT("%.1f x %.1f"), opts.getHFOV(), opts.getVFOV()),2);
514  m_HFOVSlider->SetValue(hugin_utils::roundi(opts.getHFOV()));
515  m_VFOVSlider->SetValue(hugin_utils::roundi(opts.getVFOV()));
516 
518  updatePano();
519 }
520 
522 {
523  DEBUG_TRACE("");
524 
525  bool dirty = false;
526 
527  unsigned int nrImages = pano.getNrOfImages();
528  unsigned int nrButtons = m_ToggleButtons.size();
529 
530 // m_displayedImgs.clear();
531 
532  // remove items for nonexisting images
533  for (int i=nrButtons-1; i>=(int)nrImages; i--)
534  {
535  m_ButtonSizer->Detach(m_ToggleButtons[i]);
536  delete m_ToggleButtons[i];
537  m_ToggleButtons.pop_back();
538  dirty = true;
539  }
540 
541  // add buttons
542  if ( nrImages >= nrButtons ) {
543  for(HuginBase::UIntSet::const_iterator it = changed.begin(); it != changed.end(); ++it){
544  if (*it >= nrButtons) {
545  // create new item.
546 // wxImage * bmp = new wxImage(sz.GetWidth(), sz.GetHeight());
547  wxToggleButton * but = new wxToggleButton(m_ButtonPanel,
548  ID_TOGGLE_BUT + *it,
549  wxString::Format(wxT(" %d "),*it),
550  wxDefaultPosition, wxDefaultSize,
551  wxBU_EXACTFIT);
552  but->SetValue(true);
553  m_ButtonSizer->Add(but,
554  0,
555  wxLEFT | wxTOP,
556  5);
557  m_ToggleButtons.push_back(but);
558  dirty = true;
559  }
560  }
561  }
562 
563  // update existing items
564  HuginBase::UIntSet displayedImages = m_pano.getActiveImages();
565  for (unsigned i=0; i < nrImages; i++) {
566  m_ToggleButtons[i]->SetValue(set_contains(displayedImages, i));
567  wxFileName tFilename(wxString (pano.getImage(i).getFilename().c_str(), HUGIN_CONV_FILENAME));
568  m_ToggleButtons[i]->SetToolTip(tFilename.GetFullName());
569  }
570 
571  if (dirty) {
572  m_ButtonSizer->FitInside(m_ButtonPanel);
573  // Layout();
574  DEBUG_INFO("New m_ButtonPanel width: " << (m_ButtonPanel->GetSize()).GetWidth());
575  DEBUG_INFO("New m_ButtonPanel Height: " << (m_ButtonPanel->GetSize()).GetHeight());
576  }
577  updatePano();
578 }
579 
580 
581 void PreviewFrame::OnClose(wxCloseEvent& event)
582 {
583  DEBUG_TRACE("OnClose")
584  // do not close, just hide if we're not forced
585  if (event.CanVeto()) {
586  event.Veto();
587  Hide();
588  DEBUG_DEBUG("hiding");
589  } else {
590  DEBUG_DEBUG("closing");
591  this->Destroy();
592  }
593 }
594 
595 void PreviewFrame::OnAutoPreviewToggle(wxCommandEvent & e)
596 {
597  m_PreviewPanel->SetAutoUpdate(e.IsChecked());
598  if (e.IsChecked()) {
600  }
601 }
602 
603 #if 0
604 // need to add the wxChoice somewhere
605 void PreviewFrame::OnProjectionChanged()
606 {
607  PanoramaOptions opt = m_pano.getOptions();
608  int lt = m_ProjectionChoice->GetSelection();
609  wxString Ip;
610  switch ( lt ) {
611  case PanoramaOptions::RECTILINEAR: Ip = _("Rectilinear"); break;
612  case PanoramaOptions::CYLINDRICAL: Ip = _("Cylindrical"); break;
613  case PanoramaOptions::EQUIRECTANGULAR: Ip = _("Equirectangular"); break;
614  }
615  opt.projectionFormat = (PanoramaOptions::ProjectionFormat) lt;
617  new PanoCommand::SetPanoOptionsCmd( pano, opt )
618  );
619  DEBUG_DEBUG ("Projection changed: " << lt << ":" << Ip )
620 
621 
622 }
623 #endif
624 
625 void PreviewFrame::OnCenterHorizontally(wxCommandEvent & e)
626 {
627  if (m_pano.getActiveImages().empty()) return;
628 
631  );
632 }
633 
634 void PreviewFrame::OnStraighten(wxCommandEvent & e)
635 {
636  if (m_pano.getNrOfImages() == 0) return;
637 
640  );
641 }
642 
643 void PreviewFrame::OnUpdate(wxCommandEvent& event)
644 {
646 }
647 
649 {
650  if (m_ToolBar->GetToolState(XRCID("preview_auto_update_tool"))) {
652  }
653 }
654 
655 void PreviewFrame::OnFitPano(wxCommandEvent & e)
656 {
657  if (m_pano.getActiveImages().empty()) return;
658 
659  DEBUG_TRACE("");
662  fitPano.run();
663  opt.setHFOV(fitPano.getResultHorizontalFOV());
665 
668  );
669 
670  DEBUG_INFO ( "new fov: [" << opt.getHFOV() << " "<< opt.getVFOV() << "] => height: " << opt.getHeight() );
671  updatePano();
672 }
673 
674 void PreviewFrame::OnShowAll(wxCommandEvent & e)
675 {
676  if (m_pano.getNrOfImages() == 0) return;
677 
679  HuginBase::UIntSet displayedImgs;
680  for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
681  displayedImgs.insert(i);
682  }
684  new PanoCommand::SetActiveImagesCmd(m_pano, displayedImgs)
685  );
686  updatePano();
687 }
688 
689 void PreviewFrame::OnShowNone(wxCommandEvent & e)
690 {
691  if (m_pano.getNrOfImages() == 0) return;
692 
694  for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
695  m_ToggleButtons[i]->SetValue(false);
696  }
697  HuginBase::UIntSet displayedImgs;
699  new PanoCommand::SetActiveImagesCmd(m_pano, displayedImgs)
700  );
701  updatePano();
702 }
703 
704 void PreviewFrame::OnNumTransform(wxCommandEvent & e)
705 {
706  if (m_pano.getNrOfImages() == 0) return;
707 
708  wxDialog dlg;
709  wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("dlg_numtrans"));
710  dlg.CentreOnParent();
711  if (dlg.ShowModal() == wxID_OK ) {
712  wxString text = XRCCTRL(dlg, "numtrans_yaw", wxTextCtrl)->GetValue();
713  double y;
714  if (!hugin_utils::str2double(text, y)) {
715  wxLogError(_("Yaw value must be numeric."));
716  return;
717  }
718  text = XRCCTRL(dlg, "numtrans_pitch", wxTextCtrl)->GetValue();
719  double p;
720  if (!hugin_utils::str2double(text, p)) {
721  wxLogError(_("Pitch value must be numeric."));
722  return;
723  }
724  text = XRCCTRL(dlg, "numtrans_roll", wxTextCtrl)->GetValue();
725  double r;
726  if (!hugin_utils::str2double(text, r)) {
727  wxLogError(_("Roll value must be numeric."));
728  return;
729  }
731  new PanoCommand::RotatePanoCmd(m_pano, y, p, r)
732  );
733  // update preview panel
734  updatePano();
735  } else {
736  DEBUG_DEBUG("Numerical transform canceled");
737  }
738 }
739 
740 void PreviewFrame::OnTextCtrlChanged(wxCommandEvent & e)
741 {
743  if (e.GetEventObject() == m_exposureTextCtrl) {
744  // exposure
745  wxString text = m_exposureTextCtrl->GetValue();
746  DEBUG_INFO ("target exposure = " << text.mb_str(wxConvLocal) );
747  double p = 0;
748  if (text != wxT("")) {
749  if (!hugin_utils::str2double(text, p)) {
750  wxLogError(_("Value must be numeric."));
751  return;
752  }
753  }
754  opts.outputExposureValue = p;
755  }
756  else
757  {
758  if (e.GetEventObject() == m_rangeCompressionTextCtrl)
759  {
760  //range compression
761  const wxString text = m_rangeCompressionTextCtrl->GetValue();
762  if (text.IsEmpty())
763  {
764  return;
765  };
766  double p = 0;
767  if (!hugin_utils::str2double(text, p))
768  {
769  wxLogError(_("Value must be numeric."));
770  return;
771  };
772  if (p < 0 || p>20)
773  {
774  wxLogError(_("Value for range compression is outside of valid range."));
775  return;
776  };
777  if (p == opts.outputRangeCompression)
778  {
779  return;
780  };
781  opts.outputRangeCompression = p;
782  }
783  else
784  {
785  int nParam = opts.m_projFeatures.numberOfParameters;
786  std::vector<double> para = opts.getProjectionParameters();
787  for (int i = 0; i < nParam; i++)
788  {
789  if (e.GetEventObject() == m_projParamTextCtrl[i])
790  {
791  wxString text = m_projParamTextCtrl[i]->GetValue();
792  DEBUG_INFO("param " << i << ": = " << text.mb_str(wxConvLocal));
793  double p = 0;
794  if (text != wxT(""))
795  {
796  if (!hugin_utils::str2double(text, p))
797  {
798  wxLogError(_("Value must be numeric."));
799  return;
800  }
801  }
802  para[i] = p;
803  }
804  }
805  opts.setProjectionParameters(para);
806  };
807  };
810  );
811  // update preview panel
812  updatePano();
813 
814 }
815 
816 void PreviewFrame::OnProjParameterReset(wxCommandEvent &e)
817 {
822  );
823 };
824 
825 void PreviewFrame::OnChangeFOV(wxScrollEvent & e)
826 {
827  DEBUG_TRACE("");
828 
830 
831  if (e.GetEventObject() == m_HFOVSlider) {
832  DEBUG_DEBUG("HFOV changed (slider): " << e.GetInt() << " == " << m_HFOVSlider->GetValue());
833  opt.setHFOV(e.GetInt());
834  } else if (e.GetEventObject() == m_VFOVSlider) {
835  DEBUG_DEBUG("VFOV changed (slider): " << e.GetInt());
836  opt.setVFOV(e.GetInt());
837  } else {
838  int nParam = opt.m_projFeatures.numberOfParameters;
839  std::vector<double> para = opt.getProjectionParameters();
840  for (int i = 0; i < nParam; i++) {
841  if (e.GetEventObject() == m_projParamSlider[i]) {
842  // update
843  para[i] = e.GetInt();
844  }
845  }
846  opt.setProjectionParameters(para);
847  opt.setHFOV(m_HFOVSlider->GetValue());
848  opt.setVFOV(m_VFOVSlider->GetValue());
849  }
850 
853  );
854 }
855 
856 void PreviewFrame::OnBlendChoice(wxCommandEvent & e)
857 {
858  if (e.GetEventObject() == m_BlendModeChoice) {
859  int sel = e.GetSelection();
860  switch (sel) {
861  case 0:
863  break;
864  case 1:
866  break;
867  default:
868  DEBUG_WARN("Unknown blend mode selected");
869  }
870  } else {
871  DEBUG_WARN("wxChoice event from unknown object received");
872  }
873 }
874 
875 
876 void PreviewFrame::OnDefaultExposure( wxCommandEvent & e )
877 {
878  if (m_pano.getActiveImages().size() > 0) {
883  );
884  updatePano();
885  }
886 }
887 
888 void PreviewFrame::OnIncreaseExposure( wxSpinEvent & e )
889 {
891  opt.outputExposureValue = opt.outputExposureValue + 1.0/3;
894  );
895  updatePano();
896 }
897 
898 void PreviewFrame::OnDecreaseExposure( wxSpinEvent & e )
899 {
901  opt.outputExposureValue = opt.outputExposureValue - 1.0/3;
904  );
905  updatePano();
906 }
907 
909 {
914  );
915  updatePano();
916 }
917 
919 {
924  );
925  updatePano();
926 }
927 
928 void PreviewFrame::OnProjectionChoice( wxCommandEvent & e )
929 {
930  if (e.GetEventObject() == m_ProjectionChoice) {
932  int lt = m_ProjectionChoice->GetSelection();
933  wxString Ip;
937  );
938  DEBUG_DEBUG ("Projection changed: " << lt);
939  updatePano();
940 
941  } else {
942  DEBUG_WARN("wxChoice event from unknown object received");
943  }
944 }
945 
946 void PreviewFrame::OnOutputChoice( wxCommandEvent & e)
947 {
948  if (e.GetEventObject() == m_outputModeChoice) {
950  int lt = m_outputModeChoice->GetSelection();
951  wxString Ip;
955  );
956  updatePano();
957 
958  } else {
959  DEBUG_WARN("wxChoice event from unknown object received");
960  }
961 }
962 
965 {
966  wxString msg;
967  if (!m_message.empty())
968  {
969  msg = wxGetTranslation(wxString(m_message.c_str(), wxConvLocal));
970  if (!m_filename.empty())
971  {
972  msg.Append(wxT(" "));
973  msg.Append(wxString(ProgressDisplay::m_filename.c_str(), HUGIN_CONV_FILENAME));
974  };
975  };
976  GetStatusBar()->SetStatusText(msg, 0);
977 
978 #ifdef __WXMSW__
979  UpdateWindow(NULL);
980 #endif
981 }
982 
983 void PreviewFrame::OnFullScreen(wxCommandEvent & e)
984 {
985  ShowFullScreen(!IsFullScreen(), wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION);
986 #ifdef __WXGTK__
987  //workaround a wxGTK bug that also the toolbar is hidden, but not requested to hide
988  GetToolBar()->Show(true);
989 #endif
991 };
992 
993 void PreviewFrame::OnUndo(wxCommandEvent &e)
994 {
996  {
997  wxCommandEvent dummy(wxEVT_COMMAND_MENU_SELECTED, XRCID("ID_EDITUNDO"));
998  m_parent->GetEventHandler()->AddPendingEvent(dummy);
999  }
1000  else
1001  {
1002  wxBell();
1003  };
1004 };
1005 
1006 void PreviewFrame::OnRedo(wxCommandEvent &e)
1007 {
1009  {
1010  wxCommandEvent dummy(wxEVT_COMMAND_MENU_SELECTED, XRCID("ID_EDITREDO"));
1011  m_parent->GetEventHandler()->AddPendingEvent(dummy);
1012  }
1013  else
1014  {
1015  wxBell();
1016  };
1017 };
1018 
#define DEBUG_INFO(msg)
Definition: utils.h:69
void OnShowAll(wxCommandEvent &e)
HuginBase::Panorama & m_pano
Definition: PreviewFrame.h:93
PanoramaOptions::ProjectionFormat getProjection() const
void OnUpdate(wxCommandEvent &event)
implementation of huginApp Class
wxBoxSizer * m_topsizer
Definition: PreviewFrame.h:118
wxString m_choices[3]
Definition: PreviewFrame.h:108
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"))
#define PF_STYLE
void setHeight(unsigned int h)
set panorama height
pano_projection_features m_projFeatures
int roundi(T x)
Definition: hugin_math.h:73
static double calcMeanExposure(const PanoramaData &pano)
bool str2double(const wxString &s, double &d)
Definition: wxPlatform.cpp:37
void OnBlendChoice(wxCommandEvent &e)
wxSlider * m_VFOVSlider
Definition: PreviewFrame.h:98
center panorama horizontically
Definition: PanoCommand.h:250
void OnNumTransform(wxCommandEvent &e)
void OnTextCtrlChanged(wxCommandEvent &e)
std::vector< wxStaticText * > m_projParamNamesLabel
Definition: PreviewFrame.h:120
bool fovCalcSupported(ProjectionFormat f) const
true, if FOV calcuations are supported for projection f
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
Definition: Panorama.cpp:1551
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
virtual ~PreviewFrame()
dtor.
wxSpinButton * m_exposureSpinBut
Definition: PreviewFrame.h:104
#define DEBUG_TRACE(msg)
Definition: utils.h:67
unsigned int getHeight() const
get panorama height
std::vector< wxSlider * > m_projParamSlider
Definition: PreviewFrame.h:122
wxChoice * m_ProjectionChoice
Definition: PreviewFrame.h:100
bool set_contains(const _Container &c, const typename _Container::key_type &key)
Definition: stl_utils.h:74
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
void setProjectionParameters(const std::vector< double > &params)
set the optional parameters (they need to be of the correct size)
END_EVENT_TABLE()
include file for the hugin project
virtual void run()
runs the algorithm.
wxToolBar * m_ToolBar
Definition: PreviewFrame.h:96
void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &changed)
notifies about changes to images
std::string doubleToString(double d, int digits)
convert a double to a string, suitable for display within a GUI.
Definition: utils.cpp:228
static huginApp * Get()
hack.. kind of a pseudo singleton...
Definition: huginApp.cpp:641
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
void OnCenterHorizontally(wxCommandEvent &e)
set the panorama options
Definition: PanoCommand.h:418
#define DEBUG_WARN(msg)
Definition: utils.h:74
void OnIncreaseExposure(wxSpinEvent &e)
void Init(PreviewFrame *parent, HuginBase::Panorama *pano)
Model for a panorama.
Definition: Panorama.h:152
void OnUndo(wxCommandEvent &e)
event handler for undo
void resetProjectionParameters()
sets the optional parameters to their default values
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
void SetAutoUpdate(bool enabled)
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Store window size and position in configfile/registry.
Definition: LensCalApp.cpp:212
wxSlider * m_HFOVSlider
Definition: PreviewFrame.h:97
void OnRedo(wxCommandEvent &e)
event handler for redo
virtual double getResultHeight()
Definition: FitPanorama.h:75
void OnProjectionChoice(wxCommandEvent &e)
void SetBlendMode(BlendMode b)
void OnShowNone(wxCommandEvent &e)
wxBitmapButton * m_defaultExposureBut
Definition: PreviewFrame.h:103
void RestoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Restore window size and position from configfile/registry.
Definition: LensCalApp.cpp:158
std::vector< wxToggleButton * > m_ToggleButtons
Definition: PreviewFrame.h:123
static GlobalCmdHist & getInstance()
std::vector< wxTextCtrl * > m_projParamTextCtrl
Definition: PreviewFrame.h:121
void OnChangeFOV(wxScrollEvent &e)
wxBoxSizer * m_ButtonSizer
Definition: PreviewFrame.h:115
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
Contains functions to transform whole images.
#define DEBUG_ERROR(msg)
Definition: utils.h:76
wxScrolledWindow * m_ButtonPanel
Definition: PreviewFrame.h:114
The image preview frame.
Definition: PreviewFrame.h:40
void panoramaChanged(HuginBase::Panorama &pano)
Notification about a Panorama change.
straighten panorama horizontically
Definition: PanoCommand.h:259
UIntSet getActiveImages() const
get active images
Definition: Panorama.cpp:1585
void OnStraighten(wxCommandEvent &e)
void setHFOV(double h, bool keepView=true)
set the horizontal field of view.
void addObserver(PanoramaObserver *o)
add a panorama observer.
Definition: Panorama.cpp:1546
include file for the hugin project
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
Handle EVT_KILL_FOCUS and convert it to a EVT_TEXT_ENTER event.
virtual double getResultHorizontalFOV()
Definition: FitPanorama.h:68
void OnClose(wxCloseEvent &e)
PreviewFrame(wxFrame *frame, HuginBase::Panorama &pano)
ctor.
void OnChangeDisplayedImgs(wxCommandEvent &e)
const std::vector< double > & getProjectionParameters() const
Get the optional projection parameters.
static T max(T x, T y)
Definition: svm.cpp:65
wxSpinButton * m_rangeCompressionSpinBut
Definition: PreviewFrame.h:106
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
void OnFitPano(wxCommandEvent &e)
void OnProjParameterReset(wxCommandEvent &e)
event handler for reset projection parameters
platform/compiler specific stuff.
void OnOutputChoice(wxCommandEvent &e)
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
wxStaticBoxSizer * m_projParamSizer
Definition: PreviewFrame.h:119
void OnRangeCompressionIncrease(wxSpinEvent &e)
void OnRangeCompressionDecrease(wxSpinEvent &e)
A preview panel that renders the pictures using the panotools library.
Definition: PreviewPanel.h:40
void ForceUpdate()
void OnDefaultExposure(wxCommandEvent &e)
PreviewPanel * m_PreviewPanel
Definition: PreviewFrame.h:95
ProjectionFormat
Projection of final panorama.
wxTextCtrl * m_exposureTextCtrl
Definition: PreviewFrame.h:102
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
Panorama image options.
wxStaticBoxSizer * m_ToggleButtonSizer
Definition: PreviewFrame.h:116
void OnAutoPreviewToggle(wxCommandEvent &e)
Rotate the panorama.
Definition: PanoCommand.h:448
wxTextCtrl * m_rangeCompressionTextCtrl
Definition: PreviewFrame.h:105
static T min(T x, T y)
Definition: svm.cpp:62
void updateProgressDisplay()
update the display
void OnDecreaseExposure(wxSpinEvent &e)
wxChoice * m_BlendModeChoice
Definition: PreviewFrame.h:99
void OnFullScreen(wxCommandEvent &e)
event handler for full screen
wxChoice * m_outputModeChoice
Definition: PreviewFrame.h:101