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

Generated on 23 Oct 2014 for Hugintrunk by  doxygen 1.4.7