PreviewFrame.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00027 #include "hugin_config.h"
00028 
00029 #include "panoinc_WX.h"
00030 
00031 #include "panoinc.h"
00032 
00033 #include "base_wx/platform.h"
00034 #include "hugin/config_defaults.h"
00035 #include "hugin/PreviewFrame.h"
00036 #include "hugin/huginApp.h"
00037 #include "hugin/PreviewPanel.h"
00038 #include "hugin/ImagesPanel.h"
00039 #include "base_wx/CommandHistory.h"
00040 #include "base_wx/PanoCommand.h"
00041 #include "hugin/TextKillFocusHandler.h"
00042 #include "algorithms/nona/FitPanorama.h"
00043 #include "algorithms/basic/CalculateMeanExposure.h"
00044 #include "base_wx/wxPlatform.h"
00045 
00046 #include <vigra_ext/ImageTransforms.h>
00047 
00048 extern "C" {
00049 #include <pano13/queryfeature.h>
00050 }
00051 
00052 // a random id, hope this doesn't break something..
00053 enum {
00054     ID_PROJECTION_CHOICE = wxID_HIGHEST +1,
00055     ID_BLEND_CHOICE,
00056     ID_UPDATE_BUTTON,
00057     ID_OUTPUTMODE_CHOICE,
00058     ID_EXPOSURE_TEXT,
00059     ID_EXPOSURE_SPIN,
00060     ID_EXPOSURE_DEFAULT,
00061     ID_TOGGLE_BUT = wxID_HIGHEST+100,
00062     PROJ_PARAM_NAMES_ID = wxID_HIGHEST+1000,
00063     PROJ_PARAM_VAL_ID = wxID_HIGHEST+1100,
00064     PROJ_PARAM_SLIDER_ID = wxID_HIGHEST+1200,
00065     PROJ_PARAM_RESET_ID = wxID_HIGHEST+1250,
00066     ID_FULL_SCREEN = wxID_HIGHEST+1700,
00067     ID_UNDO = wxID_HIGHEST+1701,
00068     ID_REDO = wxID_HIGHEST+1702
00069 };
00070 
00071 BEGIN_EVENT_TABLE(PreviewFrame, wxFrame)
00072     EVT_CLOSE(PreviewFrame::OnClose)
00073 //    EVT_CHECKBOX(-1, PreviewFrame::OnAutoPreviewToggle)
00074     EVT_TOOL(XRCID("preview_center_tool"), PreviewFrame::OnCenterHorizontally)
00075     EVT_TOOL(XRCID("preview_fit_pano_tool"), PreviewFrame::OnFitPano)
00076     EVT_TOOL(XRCID("preview_straighten_pano_tool"), PreviewFrame::OnStraighten)
00077     EVT_TOOL(XRCID("preview_auto_update_tool"), PreviewFrame::OnAutoPreviewToggle)
00078     EVT_TOOL(XRCID("preview_update_tool"), PreviewFrame::OnUpdate)
00079     EVT_TOOL(XRCID("preview_show_all_tool"), PreviewFrame::OnShowAll)
00080     EVT_TOOL(XRCID("preview_show_none_tool"), PreviewFrame::OnShowNone)
00081     EVT_TOOL(XRCID("preview_num_transform"), PreviewFrame::OnNumTransform)
00082     EVT_TEXT_ENTER( -1 , PreviewFrame::OnTextCtrlChanged)
00083 
00084     EVT_BUTTON(ID_EXPOSURE_DEFAULT, PreviewFrame::OnDefaultExposure)
00085     EVT_SPIN_DOWN(ID_EXPOSURE_SPIN, PreviewFrame::OnDecreaseExposure)
00086     EVT_SPIN_UP(ID_EXPOSURE_SPIN, PreviewFrame::OnIncreaseExposure)
00087     EVT_CHOICE(ID_BLEND_CHOICE, PreviewFrame::OnBlendChoice)
00088     EVT_CHOICE(ID_PROJECTION_CHOICE, PreviewFrame::OnProjectionChoice)
00089     EVT_CHOICE(ID_OUTPUTMODE_CHOICE, PreviewFrame::OnOutputChoice)
00090     EVT_TOGGLEBUTTON(-1, PreviewFrame::OnChangeDisplayedImgs)
00091         EVT_SCROLL_CHANGED(PreviewFrame::OnChangeFOV)
00092         EVT_TOOL(ID_FULL_SCREEN, PreviewFrame::OnFullScreen)
00093     EVT_TOOL(ID_UNDO, PreviewFrame::OnUndo)
00094     EVT_TOOL(ID_REDO, PreviewFrame::OnRedo)
00095     EVT_BUTTON(PROJ_PARAM_RESET_ID, PreviewFrame::OnProjParameterReset)
00096 END_EVENT_TABLE()
00097 
00098 #define PF_STYLE (wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
00099 
00100 PreviewFrame::PreviewFrame(wxFrame * frame, HuginBase::Panorama &pano)
00101     : wxFrame(frame,-1, _("Panorama preview"), wxDefaultPosition, wxDefaultSize,
00102               PF_STYLE),
00103       m_pano(pano)
00104 {
00105         DEBUG_TRACE("");
00106 
00107     m_oldProjFormat = -1;
00108     m_ToolBar = wxXmlResource::Get()->LoadToolBar(this, wxT("preview_toolbar"));
00109     DEBUG_ASSERT(m_ToolBar);
00110     // create tool bar
00111     SetToolBar(m_ToolBar);
00112 
00113     m_topsizer = new wxBoxSizer( wxVERTICAL );
00114 
00115     m_ToggleButtonSizer = new wxStaticBoxSizer(
00116         new wxStaticBox(this, -1, _("displayed images")),
00117     wxHORIZONTAL );
00118 
00119         m_ButtonPanel = new wxScrolledWindow(this, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
00120         // Set min height big enough to display scrollbars as well
00121     m_ButtonPanel->SetSizeHints(20, 42);
00122         //Horizontal scroll bars only
00123         m_ButtonPanel->SetScrollRate(10, 0);
00124     m_ButtonSizer = new wxBoxSizer(wxHORIZONTAL);
00125     m_ButtonPanel->SetAutoLayout(true);
00126         m_ButtonPanel->SetSizer(m_ButtonSizer);
00127                                                 
00128         m_ToggleButtonSizer->Add(m_ButtonPanel, 1, wxEXPAND, 0);
00129 
00130     m_topsizer->Add(m_ToggleButtonSizer, 0, wxEXPAND | wxALL, 5);
00131 
00132     wxFlexGridSizer * flexSizer = new wxFlexGridSizer(2,0,5,5);
00133     flexSizer->AddGrowableCol(0);
00134     flexSizer->AddGrowableRow(0);
00135 
00136     // create our preview panel
00137     m_PreviewPanel = new PreviewPanel();
00138     m_PreviewPanel->Create(this);
00139     m_PreviewPanel->Init(this, &pano);
00140 
00141     flexSizer->Add(m_PreviewPanel,
00142                   1,        // not vertically stretchable
00143                   wxEXPAND | // horizontally stretchable
00144                   wxALL,    // draw border all around
00145                   5);       // border width
00146 
00147 
00148     m_VFOVSlider = new wxSlider(this, -1, 1,
00149                                 1, 180,
00150                                 wxDefaultPosition, wxDefaultSize,
00151                                 wxSL_VERTICAL | wxSL_AUTOTICKS,
00152                                 wxDefaultValidator,
00153                                 _("VFOV"));
00154     m_VFOVSlider->SetLineSize(2);
00155     m_VFOVSlider->SetPageSize(10);
00156     m_VFOVSlider->SetTickFreq(5);
00157     m_VFOVSlider->SetToolTip(_("drag to change the vertical field of view"));
00158 
00159     flexSizer->Add(m_VFOVSlider, 0, wxEXPAND);
00160 
00161     m_HFOVSlider = new wxSlider(this, -1, 1,
00162                                 1, 360,
00163                                 wxDefaultPosition, wxDefaultSize,
00164                                 wxSL_HORIZONTAL | wxSL_AUTOTICKS,
00165                                 wxDefaultValidator,
00166                                 _("HFOV"));
00167     m_HFOVSlider->SetPageSize(10);
00168     m_HFOVSlider->SetLineSize(2);
00169     m_HFOVSlider->SetTickFreq(5);
00170 
00171     m_HFOVSlider->SetToolTip(_("drag to change the horizontal field of view"));
00172 
00173     flexSizer->Add(m_HFOVSlider, 0, wxEXPAND);
00174 
00175     m_topsizer->Add(flexSizer,
00176                   1,        // vertically stretchable
00177                   wxEXPAND | // horizontally stretchable
00178                   wxALL,    // draw border all around
00179                   5);       // border width
00180 
00181     wxStaticBoxSizer * blendModeSizer = new wxStaticBoxSizer(
00182         new wxStaticBox(this, -1, _("Preview Options")),
00183         wxHORIZONTAL);
00184 
00185     blendModeSizer->Add(new wxStaticText(this, -1, _("projection (f):")),
00186                         0,        // not vertically strechable
00187                         wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00188                         5);       // border width
00189     m_ProjectionChoice = new wxChoice(this, ID_PROJECTION_CHOICE,
00190                                       wxDefaultPosition, wxDefaultSize);
00191 
00192     /* populate with all available projection types */
00193     int nP = panoProjectionFormatCount();
00194     for(int n=0; n < nP; n++) {
00195         pano_projection_features proj;
00196         if (panoProjectionFeaturesQuery(n, &proj)) {
00197             wxString str2(proj.name, wxConvLocal);
00198             m_ProjectionChoice->Append(wxGetTranslation(str2));
00199         }
00200     }
00201     m_ProjectionChoice->SetSelection(2);
00202 
00203     blendModeSizer->Add(m_ProjectionChoice,
00204                         0,
00205                         wxALL | wxALIGN_CENTER_VERTICAL,
00206                         5);
00207 
00209     // Blend mode
00210     blendModeSizer->Add(new wxStaticText(this, -1, _("Blend mode:")),
00211                         0,        // not vertically strechable
00212                         wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00213                         5);       // border width
00214 
00215     m_choices[0] = _("normal");
00216     m_choices[1] = _("difference");
00217 
00218     int oldMode = wxConfigBase::Get()->Read(wxT("/PreviewFrame/blendMode"), 0l);
00219     if (oldMode > 1) oldMode = 0;
00220     m_BlendModeChoice = new wxChoice(this, ID_BLEND_CHOICE,
00221                                      wxDefaultPosition, wxDefaultSize,
00222                                      2, m_choices);
00223     m_BlendModeChoice->SetSelection((PreviewPanel::BlendMode) oldMode);
00224 
00225     blendModeSizer->Add(m_BlendModeChoice,
00226                         0,
00227                         wxALL | wxALIGN_CENTER_VERTICAL,
00228                         5);
00229 
00231     // LDR, HDR
00232     blendModeSizer->Add(new wxStaticText(this, -1, _("Output:")),
00233                         0,        // not vertically strechable
00234                         wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00235                         5);       // border width
00236 
00237     m_choices[0] = _("LDR");
00238     m_choices[1] = _("HDR");
00239     m_outputModeChoice = new wxChoice(this, ID_OUTPUTMODE_CHOICE,
00240                                       wxDefaultPosition, wxDefaultSize,
00241                                       2, m_choices);
00242     m_outputModeChoice->SetSelection(0);
00243     blendModeSizer->Add(m_outputModeChoice,
00244                         0,
00245                         wxALL | wxALIGN_CENTER_VERTICAL,
00246                         5);
00247 
00249     // exposure
00250     blendModeSizer->Add(new wxStaticText(this, -1, _("EV:")),
00251                           0,        // not vertically strechable
00252                           wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00253                           5);       // border width
00254     
00255     m_defaultExposureBut = new wxBitmapButton(this, ID_EXPOSURE_DEFAULT,
00256                                               wxArtProvider::GetBitmap(wxART_REDO));
00257     blendModeSizer->Add(m_defaultExposureBut, 0, wxLEFT | wxRIGHT, 5);
00258 
00259 //    m_decExposureBut = new wxBitmapButton(this, ID_EXPOSURE_DECREASE,
00260 //                                          wxArtProvider::GetBitmap(wxART_GO_BACK));
00261 //    blendModeSizer->Add(m_decExposureBut);
00262 
00263     m_exposureTextCtrl = new wxTextCtrl(this, ID_EXPOSURE_TEXT, wxT("0"),
00264                                         wxDefaultPosition,wxSize(50,-1), wxTE_PROCESS_ENTER);
00265     blendModeSizer->Add(m_exposureTextCtrl,
00266                           0,        // not vertically strechable
00267                           wxLEFT | wxTOP | wxBOTTOM  | wxALIGN_CENTER_VERTICAL, // draw border all around
00268                           5);       // border width
00269 //    m_incExposureBut = new wxBitmapButton(this, ID_EXPOSURE_INCREASE,
00270 //                                          wxArtProvider::GetBitmap(wxART_GO_FORWARD));
00271     m_exposureSpinBut = new wxSpinButton(this, ID_EXPOSURE_SPIN, wxDefaultPosition,
00272                                          wxDefaultSize, wxSP_VERTICAL);
00273     m_exposureSpinBut->SetRange(-0x8000, 0x7fff);
00274     m_exposureSpinBut->SetValue(0);
00275     blendModeSizer->Add(m_exposureSpinBut, 0, wxALIGN_CENTER_VERTICAL);
00276 
00277     m_topsizer->Add(blendModeSizer, 0, wxEXPAND | wxALL, 5);
00278 
00279     m_projParamSizer = new wxStaticBoxSizer(
00280     new wxStaticBox(this, -1, _("Projection Parameters")),
00281      wxHORIZONTAL);
00282 
00283     wxBitmapButton * resetProjButton=new wxBitmapButton(this, PROJ_PARAM_RESET_ID, 
00284         wxArtProvider::GetBitmap(wxART_REDO));
00285     resetProjButton->SetToolTip(_("Resets the projection's parameters to their default values."));
00286     m_projParamSizer->Add(resetProjButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
00287 
00288     m_projParamNamesLabel.resize(PANO_PROJECTION_MAX_PARMS);
00289     m_projParamTextCtrl.resize(PANO_PROJECTION_MAX_PARMS);
00290     m_projParamSlider.resize(PANO_PROJECTION_MAX_PARMS);
00291 
00292     for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++) {
00293 
00294         m_projParamNamesLabel[i] = new wxStaticText(this, PROJ_PARAM_NAMES_ID+i, _("param:"));
00295         m_projParamSizer->Add(m_projParamNamesLabel[i],
00296                         0,        // not vertically strechable
00297                         wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00298                         5);       // border width
00299         m_projParamTextCtrl[i] = new wxTextCtrl(this, PROJ_PARAM_VAL_ID+i, wxT("0"),
00300                                     wxDefaultPosition, wxSize(35,-1), wxTE_PROCESS_ENTER);
00301         m_projParamTextCtrl[i]->PushEventHandler(new TextKillFocusHandler(this));
00302         m_projParamSizer->Add(m_projParamTextCtrl[i],
00303                         0,        // not vertically strechable
00304                         wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00305                         5);       // border width
00306 
00307         m_projParamSlider[i] = new wxSlider(this, PROJ_PARAM_SLIDER_ID+i, 0, -90, 90);
00308         m_projParamSizer->Add(m_projParamSlider[i],
00309                         1,        // not vertically strechable
00310                         wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00311                         5);       // border width
00312     }
00313 
00314     m_topsizer->Add(m_projParamSizer, 0, wxEXPAND | wxALL, 5);
00315 
00316     // do not show projection param sizer
00317     m_topsizer->Show(m_projParamSizer, false, true);
00318 
00319     wxConfigBase * config = wxConfigBase::Get();
00320 
00321     // add a status bar
00322     CreateStatusBar(3);
00323     int widths[3] = {-3, 150, 150};
00324     SetStatusWidths(3, widths);
00325     SetStatusText(_("Left click to define new center point, right click to move point to horizon."),0);
00326     SetStatusText(wxT(""),1);
00327     SetStatusText(wxT(""),2);
00328 
00329     // the initial size as calculated by the sizers
00330     this->SetSizer( m_topsizer );
00331     m_topsizer->SetSizeHints( this );
00332 
00333     // set the minimize icon
00334 #ifdef __WXMSW__
00335     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
00336 #else
00337     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
00338 #endif
00339     SetIcon(myIcon);
00340 
00341     m_pano.addObserver(this);
00342 
00343     RestoreFramePosition(this, wxT("PreviewFrame"));
00344     
00345     m_PreviewPanel->SetBlendMode((PreviewPanel::BlendMode)oldMode );
00346 
00347     long aup = config->Read(wxT("/PreviewFrame/autoUpdate"),0l);
00348     m_PreviewPanel->SetAutoUpdate(aup != 0);
00349 
00350     m_ToolBar->ToggleTool(XRCID("preview_auto_update_tool"), aup !=0);
00351 
00352 #ifdef __WXMSW__
00353     // wxFrame does have a strange background color on Windows..
00354     this->SetBackgroundColour(m_PreviewPanel->GetBackgroundColour());
00355 #endif
00356 
00357     if (config->Read(wxT("/PreviewFrame/isShown"), 0l) != 0) {
00358         Show();
00359     }
00360     SetStatusText(_("Center panorama with left mouse button, set horizon with right button"),0);
00361     wxAcceleratorEntry entries[3];
00362 #ifdef __WXMAC
00363     entries[0].Set(wxACCEL_CMD,(int)'F',ID_FULL_SCREEN);
00364 #else
00365     entries[0].Set(wxACCEL_NORMAL,WXK_F11,ID_FULL_SCREEN);
00366 #endif
00367     entries[1].Set(wxACCEL_CMD,(int)'Z',ID_UNDO);
00368     entries[2].Set(wxACCEL_CMD,(int)'R',ID_REDO);
00369     wxAcceleratorTable accel(3, entries);
00370     SetAcceleratorTable(accel);
00371 #ifdef __WXGTK__
00372     // set explicit focus to button panel, otherwise the hotkey F11 is not right processed
00373     m_ButtonPanel->SetFocus();
00374 #endif
00375 }
00376 
00377 PreviewFrame::~PreviewFrame()
00378 {
00379     DEBUG_TRACE("dtor writing config");
00380     wxConfigBase * config = wxConfigBase::Get();
00381 
00382     StoreFramePosition(this, wxT("PreviewFrame"));
00383 
00384     if ( (!this->IsIconized()) && (! this->IsMaximized()) && this->IsShown()) {
00385         config->Write(wxT("/PreviewFrame/isShown"), 1l);
00386     } else {
00387         config->Write(wxT("/PreviewFrame/isShown"), 0l);
00388     }
00389 
00390     bool checked = m_ToolBar->GetToolState(XRCID("preview_auto_update_tool"));
00391     config->Write(wxT("/PreviewFrame/autoUpdate"), checked ? 1l: 0l);
00392     config->Write(wxT("/PreviewFrame/blendMode"), m_BlendModeChoice->GetSelection());
00393     for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++)
00394     {
00395         m_projParamTextCtrl[i]->PopEventHandler(true);
00396     };
00397     m_pano.removeObserver(this);
00398     DEBUG_TRACE("dtor end");
00399 }
00400 
00401 void PreviewFrame::OnChangeDisplayedImgs(wxCommandEvent & e)
00402 {
00403     int id = e.GetId() - ID_TOGGLE_BUT;
00404     int nImg = m_pano.getNrOfImages();
00405     HuginBase::UIntSet activeImages = m_pano.getActiveImages();
00406     DEBUG_DEBUG("toggle_button_id: " << id << " nImg:" << nImg << "  m_ToggleButtons.size(): " << m_ToggleButtons.size());
00407     if (id >= 0 && id < nImg) {
00408         if (e.IsChecked()) {
00409             activeImages.insert(id);
00410         } else {
00411             activeImages.erase(id);
00412         }
00413 //        m_PreviewPanel->SetDisplayedImages(m_displayedImgs);
00414         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00415             new PanoCommand::SetActiveImagesCmd(m_pano, activeImages)
00416         );
00417     } else {
00418         DEBUG_ERROR("invalid Togglebutton ID");
00419     }
00420 }
00421 
00422 void PreviewFrame::panoramaChanged(HuginBase::Panorama &pano)
00423 {
00424     const HuginBase::PanoramaOptions & opts = pano.getOptions();
00425 
00426     wxString projection;
00427     m_ProjectionChoice->SetSelection(opts.getProjection());
00428     m_VFOVSlider->Enable( opts.fovCalcSupported(opts.getProjection()) );
00429 
00430     m_outputModeChoice->SetSelection(opts.outputMode);
00431     if (opts.outputMode == HuginBase::PanoramaOptions::OUTPUT_HDR) {
00432         /*
00433         m_exposureTextCtrl->Hide();
00434         m_defaultExposureBut->Hide();
00435         m_decExposureBut->Hide();
00436         m_incExposureBut->Hide();
00437         */
00438     } else {
00439         /*
00440         m_exposureTextCtrl->Show();
00441         m_defaultExposureBut->Show();
00442         m_decExposureBut->Show();
00443         m_incExposureBut->Show();
00444         */
00445     }
00446     m_exposureTextCtrl->SetValue(wxString(hugin_utils::doubleToString(opts.outputExposureValue,2).c_str(), wxConvLocal));
00447 
00448     bool activeImgs = pano.getActiveImages().size() > 0;
00449     m_ToolBar->EnableTool(XRCID("preview_center_tool"), activeImgs);
00450     m_ToolBar->EnableTool(XRCID("preview_fit_pano_tool"), activeImgs);
00451     m_ToolBar->EnableTool(XRCID("preview_update_tool"), activeImgs);
00452     m_ToolBar->EnableTool(XRCID("preview_num_transform"), activeImgs);
00453     m_ToolBar->EnableTool(XRCID("preview_straighten_pano_tool"), pano.getNrOfImages() > 0);
00454 
00455     // TODO: enable display of parameters and set their limits, if projection has some.
00456     int nParam = opts.m_projFeatures.numberOfParameters;
00457     bool relayout = false;
00458     // if the projection format has changed
00459     if (opts.getProjection() != m_oldProjFormat) {
00460         DEBUG_DEBUG("Projection format changed");
00461         if (nParam) {
00462             // show parameters and update labels.
00463             m_topsizer->Show(m_projParamSizer, true, true);
00464             int i;
00465             for (i=0; i < nParam; i++) {
00466                 const pano_projection_parameter * pp = & (opts.m_projFeatures.parm[i]);
00467                 wxString str2(pp->name, wxConvLocal);
00468                 str2 = wxGetTranslation(str2);
00469                 m_projParamNamesLabel[i]->SetLabel(str2);
00470                 m_projParamSlider[i]->SetRange(hugin_utils::roundi(pp->minValue), hugin_utils::roundi(pp->maxValue));
00471             }
00472             for(;i < PANO_PROJECTION_MAX_PARMS; i++) {
00473                 m_projParamNamesLabel[i]->Hide();
00474                 m_projParamSlider[i]->Hide();
00475                 m_projParamTextCtrl[i]->Hide();
00476             }
00477             relayout = true;
00478         } else {
00479             m_topsizer->Show(m_projParamSizer, false, true);
00480             relayout = true;
00481         }
00482     }
00483     if (nParam) {
00484         // display new values
00485         std::vector<double> params = opts.getProjectionParameters();
00486         assert((int) params.size() == nParam);
00487         for (int i=0; i < nParam; i++) {
00488             wxString val = wxString(hugin_utils::doubleToString(params[i],1).c_str(), wxConvLocal);
00489             m_projParamTextCtrl[i]->SetValue(wxString(val.wc_str(), wxConvLocal));
00490             m_projParamSlider[i]->SetValue(hugin_utils::roundi(params[i]));
00491         }
00492     }
00493     if (relayout) {
00494         m_topsizer->Layout();
00495         Refresh();
00496     }
00497     SetStatusText(_("Center panorama with left mouse button, set horizon with right button"),0);
00498     SetStatusText(wxString::Format(wxT("%.1f x %.1f"), opts.getHFOV(), opts.getVFOV()),2);
00499     m_HFOVSlider->SetValue(hugin_utils::roundi(opts.getHFOV()));
00500     m_VFOVSlider->SetValue(hugin_utils::roundi(opts.getVFOV()));
00501 
00502     m_oldProjFormat = opts.getProjection();
00503     updatePano();
00504 }
00505 
00506 void PreviewFrame::panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &changed)
00507 {
00508     DEBUG_TRACE("");
00509 
00510     bool dirty = false;
00511 
00512     unsigned int nrImages = pano.getNrOfImages();
00513     unsigned int nrButtons = m_ToggleButtons.size();
00514 
00515 //    m_displayedImgs.clear();
00516 
00517     // remove items for nonexisting images
00518     for (int i=nrButtons-1; i>=(int)nrImages; i--)
00519     {
00520         m_ButtonSizer->Detach(m_ToggleButtons[i]);
00521         delete m_ToggleButtons[i];
00522         m_ToggleButtons.pop_back();
00523         dirty = true;
00524     }
00525 
00526     // add buttons
00527     if ( nrImages >= nrButtons ) {
00528         for(HuginBase::UIntSet::const_iterator it = changed.begin(); it != changed.end(); ++it){
00529             if (*it >= nrButtons) {
00530                 // create new item.
00531 //                wxImage * bmp = new wxImage(sz.GetWidth(), sz.GetHeight());
00532                 wxToggleButton * but = new wxToggleButton(m_ButtonPanel,
00533                                                           ID_TOGGLE_BUT + *it,
00534                                                           wxString::Format(wxT("%d"),*it),
00535                                                           wxDefaultPosition, wxDefaultSize,
00536                                                           wxBU_EXACTFIT);
00537                 wxSize sz = but->GetSize();
00538 //                but->SetSize(res.GetWidth(),sz.GetHeight());
00539                 // HACK.. set fixed width. that should work
00540                 // better than all that stupid dialogunit stuff, that
00541                 // breaks on wxWin 2.5
00542                 but->SetSize(20, sz.GetHeight());
00543                 but->SetValue(true);
00544                 m_ButtonSizer->Add(but,
00545                                    0,
00546                                    wxLEFT | wxTOP,
00547                                    5);
00548                 m_ToggleButtons.push_back(but);
00549                 dirty = true;
00550             }
00551         }
00552     }
00553 
00554     // update existing items
00555     HuginBase::UIntSet displayedImages = m_pano.getActiveImages();
00556     for (unsigned i=0; i < nrImages; i++) {
00557         m_ToggleButtons[i]->SetValue(set_contains(displayedImages, i));
00558         wxFileName tFilename(wxString (pano.getImage(i).getFilename().c_str(), HUGIN_CONV_FILENAME));
00559         m_ToggleButtons[i]->SetToolTip(tFilename.GetFullName());
00560     }
00561 
00562     if (dirty) {
00563         m_ButtonSizer->FitInside(m_ButtonPanel);
00564                 // Layout();
00565                 DEBUG_INFO("New m_ButtonPanel width: " << (m_ButtonPanel->GetSize()).GetWidth());
00566                 DEBUG_INFO("New m_ButtonPanel Height: " << (m_ButtonPanel->GetSize()).GetHeight());
00567     }
00568     updatePano();
00569 }
00570 
00571 
00572 void PreviewFrame::OnClose(wxCloseEvent& event)
00573 {
00574     DEBUG_TRACE("OnClose")
00575     // do not close, just hide if we're not forced
00576     if (event.CanVeto()) {
00577         event.Veto();
00578         Hide();
00579         DEBUG_DEBUG("hiding");
00580     } else {
00581         DEBUG_DEBUG("closing");
00582         this->Destroy();
00583     }
00584 }
00585 
00586 void PreviewFrame::OnAutoPreviewToggle(wxCommandEvent & e)
00587 {
00588     m_PreviewPanel->SetAutoUpdate(e.IsChecked());
00589     if (e.IsChecked()) {
00590         m_PreviewPanel->ForceUpdate();
00591     }
00592 }
00593 
00594 #if 0
00595 // need to add the wxChoice somewhere
00596 void PreviewFrame::OnProjectionChanged()
00597 {
00598     PanoramaOptions opt = m_pano.getOptions();
00599     int lt = m_ProjectionChoice->GetSelection();
00600     wxString Ip;
00601     switch ( lt ) {
00602     case PanoramaOptions::RECTILINEAR:       Ip = _("Rectilinear"); break;
00603     case PanoramaOptions::CYLINDRICAL:       Ip = _("Cylindrical"); break;
00604     case PanoramaOptions::EQUIRECTANGULAR:   Ip = _("Equirectangular"); break;
00605     }
00606     opt.projectionFormat = (PanoramaOptions::ProjectionFormat) lt;
00607     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00608         new PanoCommand::SetPanoOptionsCmd( pano, opt )
00609         );
00610     DEBUG_DEBUG ("Projection changed: "  << lt << ":" << Ip )
00611 
00612 
00613 }
00614 #endif
00615 
00616 void PreviewFrame::OnCenterHorizontally(wxCommandEvent & e)
00617 {
00618     if (m_pano.getActiveImages().size() == 0) return;
00619 
00620     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00621         new PanoCommand::CenterPanoCmd(m_pano)
00622         );
00623 }
00624 
00625 void PreviewFrame::OnStraighten(wxCommandEvent & e)
00626 {
00627     if (m_pano.getNrOfImages() == 0) return;
00628 
00629     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00630         new PanoCommand::StraightenPanoCmd(m_pano)
00631         );
00632 }
00633 
00634 void PreviewFrame::OnUpdate(wxCommandEvent& event)
00635 {
00636     m_PreviewPanel->ForceUpdate();
00637 }
00638 
00639 void PreviewFrame::updatePano()
00640 {
00641     if (m_ToolBar->GetToolState(XRCID("preview_auto_update_tool"))) {
00642         m_PreviewPanel->ForceUpdate();
00643     }
00644 }
00645 
00646 void PreviewFrame::OnFitPano(wxCommandEvent & e)
00647 {
00648     if (m_pano.getActiveImages().size() == 0) return;
00649 
00650     DEBUG_TRACE("");
00651     HuginBase::PanoramaOptions opt = m_pano.getOptions();
00652     HuginBase::CalculateFitPanorama fitPano(m_pano);
00653     fitPano.run();
00654     opt.setHFOV(fitPano.getResultHorizontalFOV());
00655     opt.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
00656 
00657     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00658         new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
00659         );
00660 
00661     DEBUG_INFO ( "new fov: [" << opt.getHFOV() << " "<< opt.getVFOV() << "] => height: " << opt.getHeight() );
00662     updatePano();
00663 }
00664 
00665 void PreviewFrame::OnShowAll(wxCommandEvent & e)
00666 {
00667     if (m_pano.getNrOfImages() == 0) return;
00668 
00669     DEBUG_ASSERT(m_pano.getNrOfImages() == m_ToggleButtons.size());
00670     HuginBase::UIntSet displayedImgs;
00671     for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
00672         displayedImgs.insert(i);
00673     }
00674     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00675         new PanoCommand::SetActiveImagesCmd(m_pano, displayedImgs)
00676         );
00677     updatePano();
00678 }
00679 
00680 void PreviewFrame::OnShowNone(wxCommandEvent & e)
00681 {
00682     if (m_pano.getNrOfImages() == 0) return;
00683 
00684     DEBUG_ASSERT(m_pano.getNrOfImages() == m_ToggleButtons.size());
00685     for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
00686         m_ToggleButtons[i]->SetValue(false);
00687     }
00688     HuginBase::UIntSet displayedImgs;
00689     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00690         new PanoCommand::SetActiveImagesCmd(m_pano, displayedImgs)
00691         );
00692     updatePano();
00693 }
00694 
00695 void PreviewFrame::OnNumTransform(wxCommandEvent & e)
00696 {
00697     if (m_pano.getNrOfImages() == 0) return;
00698 
00699     wxDialog dlg;
00700     wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("dlg_numtrans"));
00701     dlg.CentreOnParent();
00702     if (dlg.ShowModal() == wxID_OK ) {
00703         wxString text = XRCCTRL(dlg, "numtrans_yaw", wxTextCtrl)->GetValue();
00704         double y;
00705         if (!hugin_utils::str2double(text, y)) {
00706             wxLogError(_("Yaw value must be numeric."));
00707             return;
00708         }
00709         text = XRCCTRL(dlg, "numtrans_pitch", wxTextCtrl)->GetValue();
00710         double p;
00711         if (!hugin_utils::str2double(text, p)) {
00712             wxLogError(_("Pitch value must be numeric."));
00713             return;
00714         }
00715         text = XRCCTRL(dlg, "numtrans_roll", wxTextCtrl)->GetValue();
00716         double r;
00717         if (!hugin_utils::str2double(text, r)) {
00718             wxLogError(_("Roll value must be numeric."));
00719             return;
00720         }
00721         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00722             new PanoCommand::RotatePanoCmd(m_pano, y, p, r)
00723             );
00724         // update preview panel
00725         updatePano();
00726     } else {
00727         DEBUG_DEBUG("Numerical transform canceled");
00728     }
00729 }
00730 
00731 void PreviewFrame::OnTextCtrlChanged(wxCommandEvent & e)
00732 {
00733     HuginBase::PanoramaOptions opts = m_pano.getOptions();
00734     if (e.GetEventObject() == m_exposureTextCtrl) {
00735         // exposure
00736         wxString text = m_exposureTextCtrl->GetValue();
00737         DEBUG_INFO ("target exposure = " << text.mb_str(wxConvLocal) );
00738         double p = 0;
00739         if (text != wxT("")) {
00740             if (!hugin_utils::str2double(text, p)) {
00741                 wxLogError(_("Value must be numeric."));
00742                 return;
00743             }
00744         }
00745         opts.outputExposureValue = p;
00746     } else {
00747         int nParam = opts.m_projFeatures.numberOfParameters;
00748         std::vector<double> para = opts.getProjectionParameters();
00749         for (int i = 0; i < nParam; i++) {
00750             if (e.GetEventObject() == m_projParamTextCtrl[i]) {
00751                 wxString text = m_projParamTextCtrl[i]->GetValue();
00752                 DEBUG_INFO ("param " << i << ":  = " << text.mb_str(wxConvLocal) );
00753                 double p = 0;
00754                 if (text != wxT("")) {
00755                     if (!hugin_utils::str2double(text, p)) {
00756                         wxLogError(_("Value must be numeric."));
00757                         return;
00758                     }
00759                 }
00760                 para[i] = p;
00761             }
00762         }
00763         opts.setProjectionParameters(para);
00764     }
00765     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00766             new PanoCommand::SetPanoOptionsCmd( m_pano, opts )
00767                                            );
00768     // update preview panel
00769     updatePano();
00770 
00771 }
00772 
00773 void PreviewFrame::OnProjParameterReset(wxCommandEvent &e)
00774 {
00775     HuginBase::PanoramaOptions opts = m_pano.getOptions();
00776     opts.resetProjectionParameters();
00777     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00778         new PanoCommand::SetPanoOptionsCmd(m_pano, opts)
00779         );
00780 };
00781 
00782 void PreviewFrame::OnChangeFOV(wxScrollEvent & e)
00783 {
00784     DEBUG_TRACE("");
00785 
00786     HuginBase::PanoramaOptions opt = m_pano.getOptions();
00787 
00788     if (e.GetEventObject() == m_HFOVSlider) {
00789         DEBUG_DEBUG("HFOV changed (slider): " << e.GetInt() << " == " << m_HFOVSlider->GetValue());
00790         opt.setHFOV(e.GetInt());
00791     } else if (e.GetEventObject() == m_VFOVSlider) {
00792         DEBUG_DEBUG("VFOV changed (slider): " << e.GetInt());
00793         opt.setVFOV(e.GetInt());
00794     } else {
00795         int nParam = opt.m_projFeatures.numberOfParameters;
00796         std::vector<double> para = opt.getProjectionParameters();
00797         for (int i = 0; i < nParam; i++) {
00798             if (e.GetEventObject() == m_projParamSlider[i]) {
00799                 // update
00800                 para[i] = e.GetInt();
00801             }
00802         }
00803         opt.setProjectionParameters(para);
00804                 opt.setHFOV(m_HFOVSlider->GetValue());
00805                 opt.setVFOV(m_VFOVSlider->GetValue());
00806     }
00807 
00808     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00809         new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
00810         );
00811 }
00812 
00813 void PreviewFrame::OnBlendChoice(wxCommandEvent & e)
00814 {
00815     if (e.GetEventObject() == m_BlendModeChoice) {
00816         int sel = e.GetSelection();
00817         switch (sel) {
00818         case 0:
00819             m_PreviewPanel->SetBlendMode(PreviewPanel::BLEND_COPY);
00820             break;
00821         case 1:
00822             m_PreviewPanel->SetBlendMode(PreviewPanel::BLEND_DIFFERENCE);
00823             break;
00824         default:
00825             DEBUG_WARN("Unknown blend mode selected");
00826         }
00827     } else {
00828         DEBUG_WARN("wxChoice event from unknown object received");
00829     }
00830 }
00831 
00832 
00833 void PreviewFrame::OnDefaultExposure( wxCommandEvent & e )
00834 {
00835     if (m_pano.getNrOfImages() > 0) {
00836         HuginBase::PanoramaOptions opt = m_pano.getOptions();
00837         opt.outputExposureValue = HuginBase::CalculateMeanExposure::calcMeanExposure(m_pano);
00838         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00839                 new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
00840                                                );
00841         updatePano();
00842     }
00843 }
00844 
00845 void PreviewFrame::OnIncreaseExposure( wxSpinEvent & e )
00846 {
00847     HuginBase::PanoramaOptions opt = m_pano.getOptions();
00848     opt.outputExposureValue = opt.outputExposureValue + 1.0/3;
00849     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00850             new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
00851                                             );
00852     updatePano();
00853 }
00854 
00855 void PreviewFrame::OnDecreaseExposure( wxSpinEvent & e )
00856 {
00857     HuginBase::PanoramaOptions opt = m_pano.getOptions();
00858     opt.outputExposureValue = opt.outputExposureValue - 1.0/3;
00859     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00860             new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
00861                                            );
00862     updatePano();
00863 }
00864 
00865 void PreviewFrame::OnProjectionChoice( wxCommandEvent & e )
00866 {
00867     if (e.GetEventObject() == m_ProjectionChoice) {
00868         HuginBase::PanoramaOptions opt = m_pano.getOptions();
00869         int lt = m_ProjectionChoice->GetSelection();
00870         wxString Ip;
00871         opt.setProjection((HuginBase::PanoramaOptions::ProjectionFormat) lt);
00872         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00873                 new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
00874                                             );
00875         DEBUG_DEBUG ("Projection changed: "  << lt);
00876         updatePano();
00877 
00878     } else {
00879         DEBUG_WARN("wxChoice event from unknown object received");
00880     }
00881 }
00882 
00883 void PreviewFrame::OnOutputChoice( wxCommandEvent & e)
00884 {
00885     if (e.GetEventObject() == m_outputModeChoice) {
00886         HuginBase::PanoramaOptions opt = m_pano.getOptions();
00887         int lt = m_outputModeChoice->GetSelection();
00888         wxString Ip;
00889         opt.outputMode = ((HuginBase::PanoramaOptions::OutputMode) lt);
00890         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00891                 new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
00892                                                );
00893         updatePano();
00894 
00895     } else {
00896         DEBUG_WARN("wxChoice event from unknown object received");
00897     }
00898 }
00899 
00901 void PreviewFrame::updateProgressDisplay()
00902 {
00903     wxString msg;
00904     if (!m_message.empty())
00905     {
00906         msg = wxGetTranslation(wxString(m_message.c_str(), wxConvLocal));
00907         if (!m_filename.empty())
00908         {
00909             msg.Append(wxT(" "));
00910             msg.Append(wxString(ProgressDisplay::m_filename.c_str(), HUGIN_CONV_FILENAME));
00911         };
00912     };
00913     GetStatusBar()->SetStatusText(msg, 0);
00914 
00915 #ifdef __WXMSW__
00916     UpdateWindow(NULL);
00917 #endif
00918 }
00919 
00920 void PreviewFrame::OnFullScreen(wxCommandEvent & e)
00921 {
00922     ShowFullScreen(!IsFullScreen(), wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION);
00923 #ifdef __WXGTK__
00924     //workaround a wxGTK bug that also the toolbar is hidden, but not requested to hide
00925     GetToolBar()->Show(true);
00926 #endif
00927     m_PreviewPanel->ForceUpdate();
00928 };
00929 
00930 void PreviewFrame::OnUndo(wxCommandEvent &e)
00931 {
00932     if(PanoCommand::GlobalCmdHist::getInstance().canUndo())
00933     {
00934         wxCommandEvent dummy(wxEVT_COMMAND_MENU_SELECTED, XRCID("ID_EDITUNDO"));
00935         m_parent->GetEventHandler()->AddPendingEvent(dummy);
00936     }
00937     else
00938     {
00939         wxBell();
00940     };
00941 };
00942 
00943 void PreviewFrame::OnRedo(wxCommandEvent &e)
00944 {
00945     if(PanoCommand::GlobalCmdHist::getInstance().canRedo())
00946     {
00947         wxCommandEvent dummy(wxEVT_COMMAND_MENU_SELECTED, XRCID("ID_EDITREDO"));
00948         m_parent->GetEventHandler()->AddPendingEvent(dummy);
00949     }
00950     else
00951     {
00952         wxBell();
00953     };
00954 };
00955 

Generated on 16 Oct 2017 for Hugintrunk by  doxygen 1.4.7