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

Generated on 6 Feb 2016 for Hugintrunk by  doxygen 1.4.7