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 #define PF_STYLE (wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
74 
76  : wxFrame(frame,-1, _("Panorama preview"), wxDefaultPosition, wxDefaultSize,
77  PF_STYLE),
78  m_pano(pano)
79 {
80  DEBUG_TRACE("");
81 
82  m_oldProjFormat = -1;
83  m_ToolBar = wxXmlResource::Get()->LoadToolBar(this, wxT("preview_toolbar"));
85  // create tool bar
86  SetToolBar(m_ToolBar);
87 
88  m_topsizer = new wxBoxSizer( wxVERTICAL );
89 
90  m_ToggleButtonSizer = new wxStaticBoxSizer(
91  new wxStaticBox(this, -1, _("displayed images")),
92  wxHORIZONTAL );
93 
94  m_ButtonPanel = new wxScrolledWindow(this, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
95  // Set min height big enough to display scrollbars as well
96  m_ButtonPanel->SetSizeHints(20, 42);
97  //Horizontal scroll bars only
98  m_ButtonPanel->SetScrollRate(10, 0);
99  m_ButtonSizer = new wxBoxSizer(wxHORIZONTAL);
100  m_ButtonPanel->SetAutoLayout(true);
101  m_ButtonPanel->SetSizer(m_ButtonSizer);
102 
103  m_ToggleButtonSizer->Add(m_ButtonPanel, 1, wxEXPAND, 0);
104 
105  m_topsizer->Add(m_ToggleButtonSizer, 0, wxEXPAND | wxALL, 5);
106 
107  wxFlexGridSizer * flexSizer = new wxFlexGridSizer(2,0,5,5);
108  flexSizer->AddGrowableCol(0);
109  flexSizer->AddGrowableRow(0);
110 
111  // create our preview panel
113  m_PreviewPanel->Create(this);
114  m_PreviewPanel->Init(this, &pano);
115 
116  flexSizer->Add(m_PreviewPanel,
117  1, // not vertically stretchable
118  wxEXPAND | // horizontally stretchable
119  wxALL, // draw border all around
120  5); // border width
121 
122 
123  m_VFOVSlider = new wxSlider(this, -1, 1,
124  1, 180,
125  wxDefaultPosition, wxDefaultSize,
126  wxSL_VERTICAL | wxSL_AUTOTICKS,
127  wxDefaultValidator,
128  _("VFOV"));
129  m_VFOVSlider->SetLineSize(2);
130  m_VFOVSlider->SetPageSize(10);
131  m_VFOVSlider->SetTickFreq(5);
132  m_VFOVSlider->SetToolTip(_("drag to change the vertical field of view"));
133 
134  flexSizer->Add(m_VFOVSlider, 0, wxEXPAND);
135 
136  m_HFOVSlider = new wxSlider(this, -1, 1,
137  1, 360,
138  wxDefaultPosition, wxDefaultSize,
139  wxSL_HORIZONTAL | wxSL_AUTOTICKS,
140  wxDefaultValidator,
141  _("HFOV"));
142  m_HFOVSlider->SetPageSize(10);
143  m_HFOVSlider->SetLineSize(2);
144  m_HFOVSlider->SetTickFreq(5);
145 
146  m_HFOVSlider->SetToolTip(_("drag to change the horizontal field of view"));
147 
148  flexSizer->Add(m_HFOVSlider, 0, wxEXPAND);
149 
150  m_topsizer->Add(flexSizer,
151  1, // vertically stretchable
152  wxEXPAND | // horizontally stretchable
153  wxALL, // draw border all around
154  5); // border width
155 
156  wxStaticBoxSizer * blendModeSizer = new wxStaticBoxSizer(
157  new wxStaticBox(this, -1, _("Preview Options")),
158  wxHORIZONTAL);
159 
160  blendModeSizer->Add(new wxStaticText(this, -1, _("projection (f):")),
161  0, // not vertically strechable
162  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
163  5); // border width
164  m_ProjectionChoice = new wxChoice(this, ID_PROJECTION_CHOICE,
165  wxDefaultPosition, wxDefaultSize);
166  m_ProjectionChoice->Bind(wxEVT_CHOICE, &PreviewFrame::OnProjectionChoice, this);
167 
168  /* populate with all available projection types */
169  int nP = panoProjectionFormatCount();
170  for(int n=0; n < nP; n++) {
171  pano_projection_features proj;
172  if (panoProjectionFeaturesQuery(n, &proj)) {
173  wxString str2(proj.name, wxConvLocal);
174  m_ProjectionChoice->Append(wxGetTranslation(str2));
175  }
176  }
177  m_ProjectionChoice->SetSelection(2);
178 
179  blendModeSizer->Add(m_ProjectionChoice,
180  0,
181  wxALL | wxALIGN_CENTER_VERTICAL,
182  5);
183 
185  // Blend mode
186  blendModeSizer->Add(new wxStaticText(this, -1, _("Blend mode:")),
187  0, // not vertically strechable
188  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
189  5); // border width
190 
191  m_choices[0] = _("normal");
192  m_choices[1] = _("difference");
193 
194  int oldMode = wxConfigBase::Get()->Read(wxT("/PreviewFrame/blendMode"), 0l);
195  if (oldMode > 1) oldMode = 0;
196  m_BlendModeChoice = new wxChoice(this, ID_BLEND_CHOICE,
197  wxDefaultPosition, wxDefaultSize,
198  2, m_choices);
199  m_BlendModeChoice->SetSelection((PreviewPanel::BlendMode) oldMode);
200  m_BlendModeChoice->Bind(wxEVT_CHOICE, &PreviewFrame::OnBlendChoice, this);
201 
202  blendModeSizer->Add(m_BlendModeChoice,
203  0,
204  wxALL | wxALIGN_CENTER_VERTICAL,
205  5);
206 
208  // LDR, HDR
209  blendModeSizer->Add(new wxStaticText(this, -1, _("Output:")),
210  0, // not vertically strechable
211  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
212  5); // border width
213 
214  m_choices[0] = _("LDR");
215  m_choices[1] = _("HDR");
216  m_outputModeChoice = new wxChoice(this, ID_OUTPUTMODE_CHOICE,
217  wxDefaultPosition, wxDefaultSize,
218  2, m_choices);
219  m_outputModeChoice->SetSelection(0);
220  m_outputModeChoice->Bind(wxEVT_CHOICE, &PreviewFrame::OnOutputChoice, this);
221  blendModeSizer->Add(m_outputModeChoice,
222  0,
223  wxALL | wxALIGN_CENTER_VERTICAL,
224  5);
225 
227  // exposure
228  blendModeSizer->Add(new wxStaticText(this, -1, _("EV:")),
229  0, // not vertically strechable
230  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
231  5); // border width
232 
233  m_defaultExposureBut = new wxBitmapButton(this, ID_EXPOSURE_DEFAULT,
234  wxArtProvider::GetBitmap(wxART_REDO));
235  m_defaultExposureBut->Bind(wxEVT_BUTTON, &PreviewFrame::OnDefaultExposure, this);
236 
237  blendModeSizer->Add(m_defaultExposureBut, 0, wxLEFT | wxRIGHT, 5);
238 
239 // m_decExposureBut = new wxBitmapButton(this, ID_EXPOSURE_DECREASE,
240 // wxArtProvider::GetBitmap(wxART_GO_BACK));
241 // blendModeSizer->Add(m_decExposureBut);
242 
243  m_exposureTextCtrl = new wxTextCtrl(this, ID_EXPOSURE_TEXT, wxT("0"),
244  wxDefaultPosition,wxSize(50,-1), wxTE_PROCESS_ENTER);
245  m_exposureTextCtrl->Bind(wxEVT_TEXT_ENTER, &PreviewFrame::OnExposureTextChanged, this);
246  blendModeSizer->Add(m_exposureTextCtrl,
247  0, // not vertically strechable
248  wxLEFT | wxTOP | wxBOTTOM | wxALIGN_CENTER_VERTICAL, // draw border all around
249  5); // border width
250 // m_incExposureBut = new wxBitmapButton(this, ID_EXPOSURE_INCREASE,
251 // wxArtProvider::GetBitmap(wxART_GO_FORWARD));
252  m_exposureSpinBut = new wxSpinButton(this, ID_EXPOSURE_SPIN, wxDefaultPosition,
253  wxDefaultSize, wxSP_VERTICAL);
254  m_exposureSpinBut->SetRange(-0x8000, 0x7fff);
255  m_exposureSpinBut->SetValue(0);
256  m_exposureSpinBut->SetMaxSize(wxSize(-1, m_exposureTextCtrl->GetSize().GetHeight()));
257  m_exposureSpinBut->Bind(wxEVT_SPIN_DOWN, &PreviewFrame::OnDecreaseExposure, this);
258  m_exposureSpinBut->Bind(wxEVT_SPIN_UP, &PreviewFrame::OnIncreaseExposure, this);
259 
260  blendModeSizer->Add(m_exposureSpinBut, 0, wxALIGN_CENTER_VERTICAL);
261  blendModeSizer->Add(new wxStaticText(this, wxID_ANY, _("Range compression:")), 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5);
262  m_rangeCompressionTextCtrl = new wxTextCtrl(this, ID_RANGE_COMPRESSION_TEXT, wxT("0"),
263  wxDefaultPosition, wxSize(30, -1), wxTE_PROCESS_ENTER);
265  blendModeSizer->Add(m_rangeCompressionTextCtrl, 0, wxLEFT | wxTOP | wxBOTTOM | wxALIGN_CENTER_VERTICAL, 5);
266  m_rangeCompressionSpinBut = new wxSpinButton(this, ID_RANGE_COMPRESSION_SPIN, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL);
267  m_rangeCompressionSpinBut->SetRange(-0x8000, 0x7fff);
268  m_rangeCompressionSpinBut->SetValue(0);
269  m_rangeCompressionSpinBut->SetMaxSize(wxSize(-1, m_rangeCompressionTextCtrl->GetSize().GetHeight()));
272 
273  blendModeSizer->Add(m_rangeCompressionSpinBut, 0, wxALIGN_CENTER_VERTICAL);
274  m_topsizer->Add(blendModeSizer, 0, wxEXPAND | wxALL, 5);
275 
276  m_projParamSizer = new wxStaticBoxSizer(
277  new wxStaticBox(this, -1, _("Projection Parameters")),
278  wxHORIZONTAL);
279 
280  wxBitmapButton * resetProjButton=new wxBitmapButton(this, PROJ_PARAM_RESET_ID,
281  wxArtProvider::GetBitmap(wxART_REDO));
282  resetProjButton->SetToolTip(_("Resets the projection's parameters to their default values."));
283  resetProjButton->Bind(wxEVT_BUTTON, &PreviewFrame::OnProjParameterReset, this);
284  m_projParamSizer->Add(resetProjButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
285 
286  m_projParamNamesLabel.resize(PANO_PROJECTION_MAX_PARMS);
287  m_projParamTextCtrl.resize(PANO_PROJECTION_MAX_PARMS);
288  m_projParamSlider.resize(PANO_PROJECTION_MAX_PARMS);
289 
290  for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++) {
291 
292  m_projParamNamesLabel[i] = new wxStaticText(this, PROJ_PARAM_NAMES_ID+i, _("param:"));
294  0, // not vertically strechable
295  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
296  5); // border width
297  m_projParamTextCtrl[i] = new wxTextCtrl(this, PROJ_PARAM_VAL_ID+i, wxT("0"),
298  wxDefaultPosition, wxSize(35,-1), wxTE_PROCESS_ENTER);
299  m_projParamTextCtrl[i]->PushEventHandler(new TextKillFocusHandler(this));
300  m_projParamTextCtrl[i]->Bind(wxEVT_TEXT_ENTER, &PreviewFrame::OnTextCtrlChanged, this);
302  0, // not vertically strechable
303  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
304  5); // border width
305 
306  m_projParamSlider[i] = new wxSlider(this, PROJ_PARAM_SLIDER_ID+i, 0, -90, 90);
308  1, // not vertically strechable
309  wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
310  5); // border width
311  }
312 
313  m_topsizer->Add(m_projParamSizer, 0, wxEXPAND | wxALL, 5);
314 
315  // do not show projection param sizer
316  m_topsizer->Show(m_projParamSizer, false, true);
317 
318  wxConfigBase * config = wxConfigBase::Get();
319 
320  // add a status bar
321  CreateStatusBar(3);
322  int widths[3] = {-3, 150, 150};
323  SetStatusWidths(3, widths);
324  SetStatusText(_("Left click to define new center point, right click to move point to horizon."),0);
325  SetStatusText(wxT(""),1);
326  SetStatusText(wxT(""),2);
327 
328  // the initial size as calculated by the sizers
329  this->SetSizer( m_topsizer );
330  m_topsizer->SetSizeHints( this );
331 
332  // set the minimize icon
333 #ifdef __WXMSW__
334  wxIconBundle myIcons(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
335  SetIcons(myIcons);
336 #else
337  wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
338  SetIcon(myIcon);
339 #endif
340 
341  m_pano.addObserver(this);
342 
343  RestoreFramePosition(this, wxT("PreviewFrame"));
344 
346 
347  long aup = config->Read(wxT("/PreviewFrame/autoUpdate"),0l);
348  m_PreviewPanel->SetAutoUpdate(aup != 0);
349 
350  m_ToolBar->ToggleTool(XRCID("preview_auto_update_tool"), aup !=0);
351 
352 #ifdef __WXMSW__
353  // wxFrame does have a strange background color on Windows..
354  this->SetBackgroundColour(m_PreviewPanel->GetBackgroundColour());
355 #endif
356 
357  if (config->Read(wxT("/PreviewFrame/isShown"), 0l) != 0) {
358  Show();
359  }
360  SetStatusText(_("Center panorama with left mouse button, set horizon with right button"),0);
361  wxAcceleratorEntry entries[3];
362 #ifdef __WXMAC
363  entries[0].Set(wxACCEL_CMD,(int)'F',ID_FULL_SCREEN);
364 #else
365  entries[0].Set(wxACCEL_NORMAL,WXK_F11,ID_FULL_SCREEN);
366 #endif
367  entries[1].Set(wxACCEL_CMD,(int)'Z',ID_UNDO);
368  entries[2].Set(wxACCEL_CMD,(int)'R',ID_REDO);
369  wxAcceleratorTable accel(3, entries);
370  SetAcceleratorTable(accel);
371  Bind(wxEVT_MENU, &PreviewFrame::OnFullScreen, this, ID_FULL_SCREEN);
372  Bind(wxEVT_MENU, &PreviewFrame::OnUndo, this, ID_UNDO);
373  Bind(wxEVT_MENU, &PreviewFrame::OnRedo, this, ID_REDO);
374 #ifdef __WXGTK__
375  // set explicit focus to button panel, otherwise the hotkey F11 is not right processed
376  m_ButtonPanel->SetFocus();
377 #endif
378  //Bind event handler
379  Bind(wxEVT_CLOSE_WINDOW, &PreviewFrame::OnClose, this);
380  Bind(wxEVT_TOOL, &PreviewFrame::OnCenterHorizontally, this, XRCID("preview_center_tool"));
381  Bind(wxEVT_TOOL, &PreviewFrame::OnFitPano, this, XRCID("preview_fit_pano_tool"));
382  Bind(wxEVT_TOOL, &PreviewFrame::OnStraighten, this, XRCID("preview_straighten_pano_tool"));
383  Bind(wxEVT_TOOL, &PreviewFrame::OnAutoPreviewToggle, this, XRCID("preview_auto_update_tool"));
384  Bind(wxEVT_TOOL, &PreviewFrame::OnUpdate, this, XRCID("preview_update_tool"));
385  Bind(wxEVT_TOOL, &PreviewFrame::OnShowAll, this, XRCID("preview_show_all_tool"));
386  Bind(wxEVT_TOOL, &PreviewFrame::OnShowNone, this, XRCID("preview_show_none_tool"));
387  Bind(wxEVT_TOOL, &PreviewFrame::OnNumTransform, this, XRCID("preview_num_transform"));
388  Bind(wxEVT_SCROLL_CHANGED, &PreviewFrame::OnChangeFOV, this);
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  but->Bind(wxEVT_TOGGLEBUTTON, &PreviewFrame::OnChangeDisplayedImgs, this);
554  m_ButtonSizer->Add(but,
555  0,
556  wxLEFT | wxTOP,
557  5);
558  m_ToggleButtons.push_back(but);
559  dirty = true;
560  }
561  }
562  }
563 
564  // update existing items
565  HuginBase::UIntSet displayedImages = m_pano.getActiveImages();
566  for (unsigned i=0; i < nrImages; i++) {
567  m_ToggleButtons[i]->SetValue(set_contains(displayedImages, i));
568  wxFileName tFilename(wxString (pano.getImage(i).getFilename().c_str(), HUGIN_CONV_FILENAME));
569  m_ToggleButtons[i]->SetToolTip(tFilename.GetFullName());
570  }
571 
572  if (dirty) {
573  m_ButtonSizer->FitInside(m_ButtonPanel);
574  // Layout();
575  DEBUG_INFO("New m_ButtonPanel width: " << (m_ButtonPanel->GetSize()).GetWidth());
576  DEBUG_INFO("New m_ButtonPanel Height: " << (m_ButtonPanel->GetSize()).GetHeight());
577  }
578  updatePano();
579 }
580 
581 
582 void PreviewFrame::OnClose(wxCloseEvent& event)
583 {
584  DEBUG_TRACE("OnClose")
585  // do not close, just hide if we're not forced
586  if (event.CanVeto()) {
587  event.Veto();
588  Hide();
589  DEBUG_DEBUG("hiding");
590  } else {
591  DEBUG_DEBUG("closing");
592  this->Destroy();
593  }
594 }
595 
596 void PreviewFrame::OnAutoPreviewToggle(wxCommandEvent & e)
597 {
598  m_PreviewPanel->SetAutoUpdate(e.IsChecked());
599  if (e.IsChecked()) {
601  }
602 }
603 
604 #if 0
605 // need to add the wxChoice somewhere
606 void PreviewFrame::OnProjectionChanged()
607 {
608  PanoramaOptions opt = m_pano.getOptions();
609  int lt = m_ProjectionChoice->GetSelection();
610  wxString Ip;
611  switch ( lt ) {
612  case PanoramaOptions::RECTILINEAR: Ip = _("Rectilinear"); break;
613  case PanoramaOptions::CYLINDRICAL: Ip = _("Cylindrical"); break;
614  case PanoramaOptions::EQUIRECTANGULAR: Ip = _("Equirectangular"); break;
615  }
616  opt.projectionFormat = (PanoramaOptions::ProjectionFormat) lt;
618  new PanoCommand::SetPanoOptionsCmd( pano, opt )
619  );
620  DEBUG_DEBUG ("Projection changed: " << lt << ":" << Ip )
621 
622 
623 }
624 #endif
625 
626 void PreviewFrame::OnCenterHorizontally(wxCommandEvent & e)
627 {
628  if (m_pano.getActiveImages().empty()) return;
629 
632  );
633 }
634 
635 void PreviewFrame::OnStraighten(wxCommandEvent & e)
636 {
637  if (m_pano.getNrOfImages() == 0) return;
638 
641  );
642 }
643 
644 void PreviewFrame::OnUpdate(wxCommandEvent& event)
645 {
647 }
648 
650 {
651  if (m_ToolBar->GetToolState(XRCID("preview_auto_update_tool"))) {
653  }
654 }
655 
656 void PreviewFrame::OnFitPano(wxCommandEvent & e)
657 {
658  if (m_pano.getActiveImages().empty()) return;
659 
660  DEBUG_TRACE("");
663  fitPano.run();
664  opt.setHFOV(fitPano.getResultHorizontalFOV());
666 
669  );
670 
671  DEBUG_INFO ( "new fov: [" << opt.getHFOV() << " "<< opt.getVFOV() << "] => height: " << opt.getHeight() );
672  updatePano();
673 }
674 
675 void PreviewFrame::OnShowAll(wxCommandEvent & e)
676 {
677  if (m_pano.getNrOfImages() == 0) return;
678 
680  HuginBase::UIntSet displayedImgs;
681  for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
682  displayedImgs.insert(i);
683  }
685  new PanoCommand::SetActiveImagesCmd(m_pano, displayedImgs)
686  );
687  updatePano();
688 }
689 
690 void PreviewFrame::OnShowNone(wxCommandEvent & e)
691 {
692  if (m_pano.getNrOfImages() == 0) return;
693 
695  for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
696  m_ToggleButtons[i]->SetValue(false);
697  }
698  HuginBase::UIntSet displayedImgs;
700  new PanoCommand::SetActiveImagesCmd(m_pano, displayedImgs)
701  );
702  updatePano();
703 }
704 
705 void PreviewFrame::OnNumTransform(wxCommandEvent & e)
706 {
707  if (m_pano.getNrOfImages() == 0) return;
708 
709  wxDialog dlg;
710  wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("dlg_numtrans"));
711  dlg.CentreOnParent();
712  if (dlg.ShowModal() == wxID_OK ) {
713  wxString text = XRCCTRL(dlg, "numtrans_yaw", wxTextCtrl)->GetValue();
714  double y;
715  if (!hugin_utils::str2double(text, y)) {
716  wxLogError(_("Yaw value must be numeric."));
717  return;
718  }
719  text = XRCCTRL(dlg, "numtrans_pitch", wxTextCtrl)->GetValue();
720  double p;
721  if (!hugin_utils::str2double(text, p)) {
722  wxLogError(_("Pitch value must be numeric."));
723  return;
724  }
725  text = XRCCTRL(dlg, "numtrans_roll", wxTextCtrl)->GetValue();
726  double r;
727  if (!hugin_utils::str2double(text, r)) {
728  wxLogError(_("Roll value must be numeric."));
729  return;
730  }
732  new PanoCommand::RotatePanoCmd(m_pano, y, p, r)
733  );
734  // update preview panel
735  updatePano();
736  } else {
737  DEBUG_DEBUG("Numerical transform canceled");
738  }
739 }
740 
741 void PreviewFrame::OnExposureTextChanged(wxCommandEvent& e)
742 {
744  const wxString text = m_exposureTextCtrl->GetValue();
745  double p = 0;
746  if (!text.IsEmpty())
747  {
748  if (!hugin_utils::str2double(text, p))
749  {
750  wxLogError(_("Value must be numeric."));
751  return;
752  }
753  opts.outputExposureValue = p;
755  // update preview panel
756  updatePano();
757  }
758 }
759 
761 {
763  const wxString text = m_rangeCompressionTextCtrl->GetValue();
764  if (text.IsEmpty())
765  {
766  return;
767  }
768  double p = 0;
769  if (!hugin_utils::str2double(text, p))
770  {
771  wxLogError(_("Value must be numeric."));
772  return;
773  }
774  if (p < 0 || p>20)
775  {
776  wxLogError(_("Value for range compression is outside of valid range."));
777  return;
778  }
779  if (p == opts.outputRangeCompression)
780  {
781  return;
782  }
783  opts.outputRangeCompression = p;
785  // update preview panel
786  updatePano();
787 }
788 
789 void PreviewFrame::OnTextCtrlChanged(wxCommandEvent & e)
790 {
792  const int nParam = opts.m_projFeatures.numberOfParameters;
793  std::vector<double> para = opts.getProjectionParameters();
794  for (int i = 0; i < nParam; i++)
795  {
796  if (e.GetEventObject() == m_projParamTextCtrl[i])
797  {
798  wxString text = m_projParamTextCtrl[i]->GetValue();
799  DEBUG_INFO("param " << i << ": = " << text.mb_str(wxConvLocal));
800  double p = 0;
801  if (!text.IsEmpty())
802  {
803  if (!hugin_utils::str2double(text, p))
804  {
805  wxLogError(_("Value must be numeric."));
806  return;
807  }
808  para[i] = p;
809  }
810  }
811  }
812  opts.setProjectionParameters(para);
814  // update preview panel
815  updatePano();
816 }
817 
818 void PreviewFrame::OnProjParameterReset(wxCommandEvent &e)
819 {
824  );
825 };
826 
827 void PreviewFrame::OnChangeFOV(wxScrollEvent & e)
828 {
829  DEBUG_TRACE("");
830 
832 
833  if (e.GetEventObject() == m_HFOVSlider) {
834  DEBUG_DEBUG("HFOV changed (slider): " << e.GetInt() << " == " << m_HFOVSlider->GetValue());
835  opt.setHFOV(e.GetInt());
836  } else if (e.GetEventObject() == m_VFOVSlider) {
837  DEBUG_DEBUG("VFOV changed (slider): " << e.GetInt());
838  opt.setVFOV(e.GetInt());
839  } else {
840  int nParam = opt.m_projFeatures.numberOfParameters;
841  std::vector<double> para = opt.getProjectionParameters();
842  for (int i = 0; i < nParam; i++) {
843  if (e.GetEventObject() == m_projParamSlider[i]) {
844  // update
845  para[i] = e.GetInt();
846  }
847  }
848  opt.setProjectionParameters(para);
849  opt.setHFOV(m_HFOVSlider->GetValue());
850  opt.setVFOV(m_VFOVSlider->GetValue());
851  }
852 
855  );
856 }
857 
858 void PreviewFrame::OnBlendChoice(wxCommandEvent & e)
859 {
860  if (e.GetEventObject() == m_BlendModeChoice) {
861  int sel = e.GetSelection();
862  switch (sel) {
863  case 0:
865  break;
866  case 1:
868  break;
869  default:
870  DEBUG_WARN("Unknown blend mode selected");
871  }
872  } else {
873  DEBUG_WARN("wxChoice event from unknown object received");
874  }
875 }
876 
877 
878 void PreviewFrame::OnDefaultExposure( wxCommandEvent & e )
879 {
880  if (m_pano.getActiveImages().size() > 0) {
885  );
886  updatePano();
887  }
888 }
889 
890 void PreviewFrame::OnIncreaseExposure( wxSpinEvent & e )
891 {
893  opt.outputExposureValue = opt.outputExposureValue + 1.0/3;
896  );
897  updatePano();
898 }
899 
900 void PreviewFrame::OnDecreaseExposure( wxSpinEvent & e )
901 {
903  opt.outputExposureValue = opt.outputExposureValue - 1.0/3;
906  );
907  updatePano();
908 }
909 
911 {
916  );
917  updatePano();
918 }
919 
921 {
926  );
927  updatePano();
928 }
929 
930 void PreviewFrame::OnProjectionChoice( wxCommandEvent & e )
931 {
932  if (e.GetEventObject() == m_ProjectionChoice) {
934  int lt = m_ProjectionChoice->GetSelection();
935  wxString Ip;
939  );
940  DEBUG_DEBUG ("Projection changed: " << lt);
941  updatePano();
942 
943  } else {
944  DEBUG_WARN("wxChoice event from unknown object received");
945  }
946 }
947 
948 void PreviewFrame::OnOutputChoice( wxCommandEvent & e)
949 {
950  if (e.GetEventObject() == m_outputModeChoice) {
952  int lt = m_outputModeChoice->GetSelection();
953  wxString Ip;
957  );
958  updatePano();
959 
960  } else {
961  DEBUG_WARN("wxChoice event from unknown object received");
962  }
963 }
964 
967 {
968  wxString msg;
969  if (!m_message.empty())
970  {
971  msg = wxGetTranslation(wxString(m_message.c_str(), wxConvLocal));
972  if (!m_filename.empty())
973  {
974  msg.Append(wxT(" "));
975  msg.Append(wxString(ProgressDisplay::m_filename.c_str(), HUGIN_CONV_FILENAME));
976  };
977  };
978  GetStatusBar()->SetStatusText(msg, 0);
979 
980 #ifdef __WXMSW__
981  UpdateWindow(NULL);
982 #endif
983 }
984 
985 void PreviewFrame::OnFullScreen(wxCommandEvent & e)
986 {
987  ShowFullScreen(!IsFullScreen(), wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION);
988 #ifdef __WXGTK__
989  //workaround a wxGTK bug that also the toolbar is hidden, but not requested to hide
990  GetToolBar()->Show(true);
991 #endif
993 };
994 
995 void PreviewFrame::OnUndo(wxCommandEvent &e)
996 {
998  {
999  wxCommandEvent dummy(wxEVT_COMMAND_MENU_SELECTED, XRCID("ID_EDITUNDO"));
1000  m_parent->GetEventHandler()->AddPendingEvent(dummy);
1001  }
1002  else
1003  {
1004  wxBell();
1005  };
1006 };
1007 
1008 void PreviewFrame::OnRedo(wxCommandEvent &e)
1009 {
1011  {
1012  wxCommandEvent dummy(wxEVT_COMMAND_MENU_SELECTED, XRCID("ID_EDITREDO"));
1013  m_parent->GetEventHandler()->AddPendingEvent(dummy);
1014  }
1015  else
1016  {
1017  wxBell();
1018  };
1019 };
1020 
#define DEBUG_INFO(msg)
Definition: utils.h:69
void OnShowAll(wxCommandEvent &e)
HuginBase::Panorama & m_pano
Definition: PreviewFrame.h:95
PanoramaOptions::ProjectionFormat getProjection() const
void OnUpdate(wxCommandEvent &event)
implementation of huginApp Class
wxBoxSizer * m_topsizer
Definition: PreviewFrame.h:120
wxString m_choices[3]
Definition: PreviewFrame.h:110
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:100
center panorama horizontically
Definition: PanoCommand.h:250
void OnNumTransform(wxCommandEvent &e)
void OnTextCtrlChanged(wxCommandEvent &e)
std::vector< wxStaticText * > m_projParamNamesLabel
Definition: PreviewFrame.h:122
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:106
#define DEBUG_TRACE(msg)
Definition: utils.h:67
unsigned int getHeight() const
get panorama height
std::vector< wxSlider * > m_projParamSlider
Definition: PreviewFrame.h:124
wxChoice * m_ProjectionChoice
Definition: PreviewFrame.h:102
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)
include file for the hugin project
virtual void run()
runs the algorithm.
wxToolBar * m_ToolBar
Definition: PreviewFrame.h:98
void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &changed)
notifies about changes to images
void OnRangeCompressionTextChanged(wxCommandEvent &e)
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:645
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:210
wxSlider * m_HFOVSlider
Definition: PreviewFrame.h:99
void OnRedo(wxCommandEvent &e)
event handler for redo
virtual double getResultHeight()
Definition: FitPanorama.h:75
void OnExposureTextChanged(wxCommandEvent &e)
void OnProjectionChoice(wxCommandEvent &e)
void SetBlendMode(BlendMode b)
void OnShowNone(wxCommandEvent &e)
wxBitmapButton * m_defaultExposureBut
Definition: PreviewFrame.h:105
void RestoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Restore window size and position from configfile/registry.
Definition: LensCalApp.cpp:156
std::vector< wxToggleButton * > m_ToggleButtons
Definition: PreviewFrame.h:125
static GlobalCmdHist & getInstance()
std::vector< wxTextCtrl * > m_projParamTextCtrl
Definition: PreviewFrame.h:123
void OnChangeFOV(wxScrollEvent &e)
wxBoxSizer * m_ButtonSizer
Definition: PreviewFrame.h:117
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:116
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:108
#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:121
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:97
ProjectionFormat
Projection of final panorama.
wxTextCtrl * m_exposureTextCtrl
Definition: PreviewFrame.h:104
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
Panorama image options.
wxStaticBoxSizer * m_ToggleButtonSizer
Definition: PreviewFrame.h:118
void OnAutoPreviewToggle(wxCommandEvent &e)
Rotate the panorama.
Definition: PanoCommand.h:448
wxTextCtrl * m_rangeCompressionTextCtrl
Definition: PreviewFrame.h:107
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:101
void OnFullScreen(wxCommandEvent &e)
event handler for full screen
wxChoice * m_outputModeChoice
Definition: PreviewFrame.h:103