PreviewFrame.cpp

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

Generated on 30 Jul 2016 for Hugintrunk by  doxygen 1.4.7