GLPreviewFrame.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00026 // use toggle buttons or uncomment check boxes
00027 
00028 #ifndef __WXMAC__
00029 #define USE_TOGGLE_BUTTON 1
00030 #endif
00031 //wxMac now has toggle buttons, but you can't overide their colours.
00032 
00033 #include <bitset>
00034 #include <limits>
00035 #include <iostream>
00036 
00037 #include <config.h>
00038 
00039 #if !defined Hugin_shared || !defined _WINDOWS
00040 #define GLEW_STATIC
00041 #endif
00042 #include <GL/glew.h>
00043 
00044 #include "panoinc_WX.h"
00045 #include "panoinc.h"
00046 
00047 #include "base_wx/platform.h"
00048 #include "base_wx/wxPlatform.h"
00049 #include "base_wx/LensTools.h"
00050 #include "PT/ImageGraph.h"
00051 
00052 #include "base_wx/MyProgressDialog.h"
00053 #include "hugin/wxPanoCommand.h"
00054 
00055 #include "hugin/config_defaults.h"
00056 #include "hugin/GLPreviewFrame.h"
00057 #include "hugin/huginApp.h"
00058 #include "hugin/MainFrame.h"
00059 #include "hugin/ImagesPanel.h"
00060 #include "hugin/CommandHistory.h"
00061 #include "hugin/GLViewer.h"
00062 #include "hugin/TextKillFocusHandler.h"
00063 #include "hugin/PanoOperation.h"
00064 #include "hugin/PanoOutputDialog.h"
00065 
00066 extern "C" {
00067 #include <pano13/queryfeature.h>
00068 }
00069 
00070 #include "ToolHelper.h"
00071 #include "Tool.h"
00072 #include "DragTool.h"
00073 #include "PreviewCropTool.h"
00074 #include "PreviewIdentifyTool.h"
00075 #include "PreviewDifferenceTool.h"
00076 #include "PreviewPanoMaskTool.h"
00077 #include "PreviewControlPointTool.h"
00078 #include "PreviewLayoutLinesTool.h"
00079 #include "PreviewColorPickerTool.h"
00080 #include "PreviewGuideTool.h"
00081 
00082 #include "ProjectionGridTool.h"
00083 #include "PanosphereSphereTool.h"
00084 
00085 #include "OverviewCameraTool.h"
00086 #include "OverviewOutlinesTool.h"
00087 
00088 #include <wx/progdlg.h>
00089 #if wxCHECK_VERSION(2, 9, 1)
00090 #include <wx/infobar.h>
00091 #endif
00092 
00093 using namespace hugin_utils;
00094 
00095 // a random id, hope this doesn't break something..
00096 enum {
00097     ID_TOGGLE_BUT = wxID_HIGHEST+500,
00098     PROJ_PARAM_NAMES_ID = wxID_HIGHEST+1300,
00099     PROJ_PARAM_VAL_ID = wxID_HIGHEST+1400,
00100     PROJ_PARAM_SLIDER_ID = wxID_HIGHEST+1500,
00101     PROJ_PARAM_RESET_ID = wxID_HIGHEST+1550,
00102     ID_TOGGLE_BUT_LEAVE = wxID_HIGHEST+1600,
00103     ID_FULL_SCREEN = wxID_HIGHEST+1710,
00104     ID_SHOW_ALL = wxID_HIGHEST+1711,
00105     ID_SHOW_NONE = wxID_HIGHEST+1712,
00106     ID_HIDE_HINTS = wxID_HIGHEST+1715
00107 };
00108 
00110 enum{
00111     mode_assistant=0,
00112     mode_preview,
00113     mode_layout,
00114     mode_projection,
00115     mode_drag,
00116     mode_crop
00117 };
00118 
00119 //------------------------------------------------------------------------------
00120 BEGIN_EVENT_TABLE(GLwxAuiFloatingFrame, wxAuiFloatingFrame)
00121     EVT_ACTIVATE(GLwxAuiFloatingFrame::OnActivate)
00122 END_EVENT_TABLE()
00123 
00124 BEGIN_EVENT_TABLE(GLPreviewFrame, wxFrame)
00125     EVT_CLOSE(GLPreviewFrame::OnClose)
00126     EVT_SHOW(GLPreviewFrame::OnShowEvent)
00127     //for some reason only key up is sent, key down event is not sent
00128 //    EVT_KEY_DOWN(GLPreviewFrame::KeyDown)
00129 //    EVT_KEY_UP(GLPreviewFrame::KeyUp)
00130     EVT_BUTTON(XRCID("preview_center_tool"), GLPreviewFrame::OnCenterHorizontally)
00131     EVT_BUTTON(XRCID("preview_fit_pano_tool"), GLPreviewFrame::OnFitPano)
00132     EVT_BUTTON(XRCID("preview_fit_pano_tool2"), GLPreviewFrame::OnFitPano)
00133     EVT_BUTTON(XRCID("preview_straighten_pano_tool"), GLPreviewFrame::OnStraighten)
00134     EVT_BUTTON(XRCID("apply_num_transform"), GLPreviewFrame::OnNumTransform)
00135     EVT_BUTTON(ID_SHOW_ALL, GLPreviewFrame::OnShowAll)
00136     EVT_BUTTON(ID_SHOW_NONE, GLPreviewFrame::OnShowNone)
00137     EVT_CHECKBOX(XRCID("preview_photometric_tool"), GLPreviewFrame::OnPhotometric)
00138     EVT_TOOL(XRCID("preview_identify_tool"), GLPreviewFrame::OnIdentify)
00139     EVT_TOOL(XRCID("preview_color_picker_tool"), GLPreviewFrame::OnColorPicker)
00140     EVT_CHECKBOX(XRCID("preview_control_point_tool"), GLPreviewFrame::OnControlPoint)
00141     EVT_BUTTON(XRCID("preview_autocrop_tool"), GLPreviewFrame::OnAutocrop)
00142     EVT_BUTTON(XRCID("preview_stack_autocrop_tool"), GLPreviewFrame::OnStackAutocrop)
00143     EVT_NOTEBOOK_PAGE_CHANGED(XRCID("mode_toolbar_notebook"), GLPreviewFrame::OnSelectMode)
00144     EVT_NOTEBOOK_PAGE_CHANGING(XRCID("mode_toolbar_notebook"), GLPreviewFrame::OnToolModeChanging)
00145     EVT_BUTTON(ID_HIDE_HINTS, GLPreviewFrame::OnHideProjectionHints)
00146     EVT_BUTTON(XRCID("exposure_default_button"), GLPreviewFrame::OnDefaultExposure)
00147     EVT_SPIN_DOWN(XRCID("exposure_spin"), GLPreviewFrame::OnDecreaseExposure)
00148     EVT_SPIN_UP(XRCID("exposure_spin"), GLPreviewFrame::OnIncreaseExposure)
00149     EVT_CHOICE(XRCID("blend_mode_choice"), GLPreviewFrame::OnBlendChoice)
00150     EVT_CHOICE(XRCID("drag_mode_choice"), GLPreviewFrame::OnDragChoice)
00151     EVT_CHOICE(XRCID("projection_choice"), GLPreviewFrame::OnProjectionChoice)
00152     EVT_CHOICE(XRCID("overview_mode_choice"), GLPreviewFrame::OnOverviewModeChoice)
00153     EVT_CHOICE(XRCID("preview_guide_choice_crop"), GLPreviewFrame::OnGuideChanged)
00154     EVT_CHOICE(XRCID("preview_guide_choice_drag"), GLPreviewFrame::OnGuideChanged)
00155     EVT_CHOICE(XRCID("preview_guide_choice_proj"), GLPreviewFrame::OnGuideChanged)
00156     EVT_MENU(XRCID("action_show_overview"), GLPreviewFrame::OnOverviewToggle)
00157     EVT_MENU(XRCID("action_show_grid"), GLPreviewFrame::OnSwitchPreviewGrid)
00158 #ifndef __WXMAC__
00159         EVT_COMMAND_SCROLL(XRCID("layout_scale_slider"), GLPreviewFrame::OnLayoutScaleChange)
00160         EVT_SCROLL_CHANGED(GLPreviewFrame::OnChangeFOV)
00161         EVT_COMMAND_SCROLL_CHANGED(XRCID("layout_scale_slider"), GLPreviewFrame::OnLayoutScaleChange)
00162 #else
00163  #if wxCHECK_VERSION(2,9,0)
00164     EVT_SCROLL_THUMBRELEASE(GLPreviewFrame::OnChangeFOV)
00165     EVT_COMMAND_SCROLL(XRCID("layout_scale_slider"), GLPreviewFrame::OnLayoutScaleChange)
00166     EVT_SCROLL_CHANGED(GLPreviewFrame::OnChangeFOV)
00167     EVT_COMMAND_SCROLL_THUMBTRACK(XRCID("layout_scale_slider"), GLPreviewFrame::OnLayoutScaleChange)
00168  #else
00169         EVT_SCROLL_THUMBRELEASE(GLPreviewFrame::OnChangeFOV)
00170         EVT_SCROLL_ENDSCROLL(GLPreviewFrame::OnChangeFOV)
00171         EVT_COMMAND_SCROLL_THUMBRELEASE(XRCID("layout_scale_slider"), GLPreviewFrame::OnLayoutScaleChange)
00172         EVT_COMMAND_SCROLL_ENDSCROLL(XRCID("layout_scale_slider"), GLPreviewFrame::OnLayoutScaleChange)
00173         EVT_COMMAND_SCROLL_THUMBTRACK(XRCID("layout_scale_slider"), GLPreviewFrame::OnLayoutScaleChange)
00174  #endif
00175 #endif
00176         EVT_SCROLL_THUMBTRACK(GLPreviewFrame::OnTrackChangeFOV)
00177     EVT_TEXT_ENTER(XRCID("pano_text_hfov"), GLPreviewFrame::OnHFOVChanged )
00178     EVT_TEXT_ENTER(XRCID("pano_text_vfov"), GLPreviewFrame::OnVFOVChanged )
00179     EVT_TEXT_ENTER(XRCID("pano_val_roi_left"), GLPreviewFrame::OnROIChanged)
00180     EVT_TEXT_ENTER(XRCID("pano_val_roi_top"), GLPreviewFrame::OnROIChanged)
00181     EVT_TEXT_ENTER(XRCID("pano_val_roi_right"), GLPreviewFrame::OnROIChanged)
00182     EVT_TEXT_ENTER(XRCID("pano_val_roi_bottom"), GLPreviewFrame::OnROIChanged)
00183     EVT_BUTTON(XRCID("reset_crop_button"), GLPreviewFrame::OnResetCrop)
00184     EVT_TEXT_ENTER(XRCID("exposure_text"), GLPreviewFrame::OnExposureChanged)
00185     EVT_COMMAND_RANGE(PROJ_PARAM_VAL_ID,PROJ_PARAM_VAL_ID+PANO_PROJECTION_MAX_PARMS,wxEVT_COMMAND_TEXT_ENTER,GLPreviewFrame::OnProjParameterChanged)
00186     EVT_BUTTON(PROJ_PARAM_RESET_ID, GLPreviewFrame::OnProjParameterReset)
00187     EVT_TOOL(ID_FULL_SCREEN, GLPreviewFrame::OnFullScreen)
00188     EVT_COLOURPICKER_CHANGED(XRCID("preview_background"), GLPreviewFrame::OnPreviewBackgroundColorChanged)
00189     EVT_MENU(XRCID("ID_SHOW_FULL_SCREEN_PREVIEW"), GLPreviewFrame::OnFullScreen)
00190     EVT_MENU(XRCID("action_show_main_frame"), GLPreviewFrame::OnShowMainFrame)
00191     EVT_MENU(XRCID("action_exit_preview"), GLPreviewFrame::OnUserExit)
00192     EVT_CHOICE     ( XRCID("ass_lens_type"), GLPreviewFrame::OnLensTypeChanged)
00193     EVT_TEXT_ENTER ( XRCID("ass_focal_length"), GLPreviewFrame::OnFocalLengthChanged)
00194     EVT_TEXT_ENTER ( XRCID("ass_crop_factor"), GLPreviewFrame::OnCropFactorChanged)
00195     EVT_BUTTON     ( XRCID("ass_load_images_button"), GLPreviewFrame::OnLoadImages)
00196     EVT_BUTTON     ( XRCID("ass_align_button"), GLPreviewFrame::OnAlign)
00197     EVT_BUTTON     ( XRCID("ass_create_button"), GLPreviewFrame::OnCreate)
00198 END_EVENT_TABLE()
00199 
00200 BEGIN_EVENT_TABLE(ImageToogleButtonEventHandler, wxEvtHandler)
00201     EVT_ENTER_WINDOW(ImageToogleButtonEventHandler::OnEnter)
00202     EVT_LEAVE_WINDOW(ImageToogleButtonEventHandler::OnLeave)
00203 #ifdef USE_TOGGLE_BUTTON
00204     EVT_TOGGLEBUTTON(-1, ImageToogleButtonEventHandler::OnChange)
00205 #else
00206     EVT_CHECKBOX(-1, ImageToogleButtonEventHandler::OnChange)
00207 #endif    
00208 END_EVENT_TABLE()
00209 
00210 BEGIN_EVENT_TABLE(ImageGroupButtonEventHandler, wxEvtHandler)
00211     EVT_ENTER_WINDOW(ImageGroupButtonEventHandler::OnEnter)
00212     EVT_LEAVE_WINDOW(ImageGroupButtonEventHandler::OnLeave)
00213     EVT_CHECKBOX(-1, ImageGroupButtonEventHandler::OnChange)
00214 END_EVENT_TABLE()
00215 
00216 
00217 void AddLabelToBitmapButton(wxBitmapButton* button, wxString new_label,bool TextBelow=true)
00218 {
00219     int new_width=0;
00220     int new_height=0;
00221     int text_height=0;
00222     int text_width=0;
00223     button->GetTextExtent(new_label.append(wxT(" ")), &text_width,&text_height);
00224     if(TextBelow)
00225     {
00226         new_height=23+text_height;
00227         if(text_width<24)
00228             new_width=24;
00229         else
00230             new_width=text_width;
00231     }
00232     else
00233     {
00234         new_height=22;
00235         new_width=24+text_width;
00236     };
00237     wxBitmap new_bitmap(new_width,new_height);
00238     wxMemoryDC dc(new_bitmap);
00239     dc.SetBackground(wxBrush(button->GetBackgroundColour()));
00240     dc.Clear();
00241     if(TextBelow)
00242     {
00243         dc.DrawBitmap(button->GetBitmapLabel(),(new_width/2)-11,0,true);
00244         dc.SetFont(button->GetParent()->GetFont());
00245         dc.DrawText(new_label,(new_width-text_width)/2,23);
00246     }
00247     else
00248     {
00249         dc.DrawBitmap(button->GetBitmapLabel(),0,0,true);
00250         dc.SetFont(button->GetParent()->GetFont());
00251         dc.DrawText(new_label,24,(22-text_height)/2);
00252     };
00253     dc.SelectObject(wxNullBitmap);
00254     //some fiddeling with mask
00255     wxImage new_image=new_bitmap.ConvertToImage();
00256     wxColour bg=button->GetBackgroundColour();
00257     new_image.SetMaskColour(bg.Red(),bg.Green(),bg.Blue());
00258     wxBitmap new_bitmap_mask(new_image);
00259     button->SetBitmapLabel(new_bitmap_mask);
00260     button->Refresh();
00261 };
00262 
00263 #define PF_STYLE (wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
00264 GLwxAuiFloatingFrame* GLwxAuiManager::CreateFloatingFrame(wxWindow* parent, const wxAuiPaneInfo& p)
00265 {
00266     DEBUG_DEBUG("CREATING FLOATING FRAME");
00267     frame->PauseResize();
00268     GLwxAuiFloatingFrame* fl_frame = new GLwxAuiFloatingFrame(parent, this, p);
00269     DEBUG_DEBUG("CREATED FLOATING FRAME");
00270     return fl_frame;
00271 }
00272 
00273 void GLwxAuiFloatingFrame::OnActivate(wxActivateEvent& evt)
00274 {
00275     DEBUG_DEBUG("FRAME ACTIVATE");
00276     GLPreviewFrame * frame = ((GLwxAuiManager*) GetOwnerManager())->getPreviewFrame();
00277     frame->ContinueResize();
00278     evt.Skip();
00279 }
00280 
00281 void GLwxAuiFloatingFrame::OnMoveFinished()
00282 {
00283     DEBUG_DEBUG("FRAME ON MOVE FINISHED");
00284     GLPreviewFrame * frame = ((GLwxAuiManager*) GetOwnerManager())->getPreviewFrame();
00285     frame->PauseResize();
00286     wxAuiFloatingFrame::OnMoveFinished();
00287     DEBUG_DEBUG("FRAME AFTER ON MOVE FINISHED");
00288 }
00289 
00290 void GLPreviewFrame::PauseResize()
00291 {
00292     DEBUG_DEBUG("PAUSE RESIZE");
00293     GLresize = false;
00294 }
00295 
00296 void GLPreviewFrame::ContinueResize()
00297 {
00298     GLresize = true;
00299     wxSizeEvent event = wxSizeEvent(wxSize());
00300     m_GLPreview->Resized(event);
00301     m_GLOverview->Resized(event);
00302 }
00303 
00304 #include <iostream>
00305 GLPreviewFrame::GLPreviewFrame(wxFrame * frame, PT::Panorama &pano)
00306     : wxFrame(frame,-1, _("Fast Panorama preview"), wxDefaultPosition, wxDefaultSize,
00307               PF_STYLE),
00308       m_pano(pano)
00309 #if !wxCHECK_VERSION(2, 9, 1)
00310     ,
00311       m_projectionStatusPushed(false)
00312 #endif
00313 {
00314 
00315         DEBUG_TRACE("");
00316 
00317     // initialize pointer
00318     preview_helper = NULL;
00319     panosphere_overview_helper = NULL;
00320     plane_overview_helper = NULL;
00321     crop_tool = NULL;
00322     drag_tool = NULL;
00323     color_picker_tool = NULL;
00324     overview_drag_tool = NULL;
00325     identify_tool = NULL ;
00326     panosphere_overview_identify_tool = NULL;
00327     plane_overview_identify_tool = NULL;
00328     difference_tool = NULL;
00329     plane_difference_tool = NULL;
00330     panosphere_difference_tool = NULL;
00331     pano_mask_tool = NULL;
00332     preview_guide_tool = NULL;
00333     m_guiLevel=GUI_SIMPLE;
00334 #ifdef __WXGTK__
00335     loadedLayout=false;
00336 #endif
00337 
00338     m_mode = -1;
00339     m_oldProjFormat = -1;
00340     // add a status bar
00341     CreateStatusBar(3);
00342     int widths[3] = {-3, 150, 150};
00343     SetStatusWidths(3, widths);
00344     SetStatusText(wxT(""),1);
00345     SetStatusText(wxT(""),2);
00346     wxConfigBase * cfg = wxConfigBase::Get();
00347 
00348 #if wxCHECK_VERSION(2,9,2)
00349     wxPanel *tool_panel = wxXmlResource::Get()->LoadPanel(this,wxT("mode_panel_29"));
00350     XRCCTRL(*this,"preview_center_tool",wxButton)->SetBitmapMargins(0,0);
00351     XRCCTRL(*this,"preview_fit_pano_tool",wxButton)->SetBitmapMargins(0,0);
00352     XRCCTRL(*this,"preview_straighten_pano_tool",wxButton)->SetBitmapMargins(0,0);
00353     XRCCTRL(*this,"preview_fit_pano_tool2",wxButton)->SetBitmapMargins(0,0);
00354     XRCCTRL(*this,"preview_autocrop_tool",wxButton)->SetBitmapMargins(0,0);
00355     XRCCTRL(*this,"preview_stack_autocrop_tool",wxButton)->SetBitmapMargins(0,0);
00356 #else
00357     wxPanel *tool_panel = wxXmlResource::Get()->LoadPanel(this,wxT("mode_panel"));
00358     AddLabelToBitmapButton(XRCCTRL(*this,"preview_center_tool",wxBitmapButton),_("Center"));
00359     AddLabelToBitmapButton(XRCCTRL(*this,"preview_fit_pano_tool",wxBitmapButton),_("Fit"));
00360     AddLabelToBitmapButton(XRCCTRL(*this,"preview_straighten_pano_tool",wxBitmapButton),_("Straighten"));
00361     AddLabelToBitmapButton(XRCCTRL(*this,"preview_fit_pano_tool2",wxBitmapButton),_("Fit"));
00362     AddLabelToBitmapButton(XRCCTRL(*this,"preview_autocrop_tool",wxBitmapButton),_("Autocrop"));
00363     AddLabelToBitmapButton(XRCCTRL(*this,"preview_stack_autocrop_tool",wxBitmapButton),_("HDR Autocrop"));
00364 #endif
00365     m_tool_notebook = XRCCTRL(*this,"mode_toolbar_notebook",wxNotebook);
00366     m_ToolBar_Identify = XRCCTRL(*this,"preview_mode_toolbar",wxToolBar);
00367 
00368     //build menu bar
00369 #ifdef __WXMAC__
00370     wxApp::s_macExitMenuItemId = XRCID("action_exit_preview");
00371 #endif
00372     wxMenuBar* simpleMenu=wxXmlResource::Get()->LoadMenuBar(this, wxT("preview_simple_menu"));
00373     m_filemenuSimple=wxXmlResource::Get()->LoadMenu(wxT("preview_file_menu"));
00374     MainFrame::Get()->GetFileHistory()->UseMenu(m_filemenuSimple->FindItem(XRCID("menu_mru_preview"))->GetSubMenu());
00375     MainFrame::Get()->GetFileHistory()->AddFilesToMenu();
00376     simpleMenu->Insert(0, m_filemenuSimple, _("&File"));
00377     SetMenuBar(simpleMenu);
00378 
00379     // initialize preview background color
00380     wxString c = cfg->Read(wxT("/GLPreviewFrame/PreviewBackground"),wxT(HUGIN_PREVIEW_BACKGROUND));
00381     m_preview_background_color = wxColour(c);
00382     XRCCTRL(*this, "preview_background", wxColourPickerCtrl)->SetColour(m_preview_background_color);
00383     XRCCTRL(*this, "preview_background", wxColourPickerCtrl)->Refresh();
00384     XRCCTRL(*this, "preview_background", wxColourPickerCtrl)->Update();
00385   
00386     m_topsizer = new wxBoxSizer( wxVERTICAL );
00387 
00388     wxPanel * toggle_panel = new wxPanel(this);
00389 
00390     bool overview_hidden;
00391     cfg->Read(wxT("/GLPreviewFrame/overview_hidden"), &overview_hidden, false);
00392     GetMenuBar()->FindItem(XRCID("action_show_overview"))->Check(!overview_hidden);
00393 
00394     m_ToggleButtonSizer = new wxStaticBoxSizer(
00395         new wxStaticBox(toggle_panel, -1, _("displayed images")),
00396     wxHORIZONTAL );
00397     toggle_panel->SetSizer(m_ToggleButtonSizer);
00398 
00399         m_ButtonPanel = new wxScrolledWindow(toggle_panel, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
00400         // Set min height big enough to display scrollbars as well
00401     m_ButtonPanel->SetSizeHints(20, 42);
00402         //Horizontal scroll bars only
00403         m_ButtonPanel->SetScrollRate(10, 0);
00404     m_ButtonSizer = new wxBoxSizer(wxHORIZONTAL);
00405     m_ButtonPanel->SetAutoLayout(true);
00406         m_ButtonPanel->SetSizer(m_ButtonSizer);
00407 
00408     wxPanel *panel = new wxPanel(toggle_panel);
00409     wxBitmap bitmap;
00410     bitmap.LoadFile(huginApp::Get()->GetXRCPath()+wxT("data/preview_show_all.png"),wxBITMAP_TYPE_PNG);
00411 #if wxCHECK_VERSION(2,9,2)
00412     wxButton* select_all=new wxButton(panel,ID_SHOW_ALL,_("All"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00413     select_all->SetBitmap(bitmap,wxLEFT);
00414     select_all->SetBitmapMargins(0,0);
00415 #else
00416     wxBitmapButton * select_all = new wxBitmapButton(panel,ID_SHOW_ALL,bitmap);
00417 #endif
00418     bitmap.LoadFile(huginApp::Get()->GetXRCPath()+wxT("data/preview_show_none.png"),wxBITMAP_TYPE_PNG);
00419 #if wxCHECK_VERSION(2,9,2)
00420     wxButton* select_none=new wxButton(panel,ID_SHOW_NONE,_("None"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00421     select_none->SetBitmap(bitmap,wxLEFT);
00422     select_none->SetBitmapMargins(0,0);
00423 #else
00424     wxBitmapButton * select_none = new wxBitmapButton(panel,ID_SHOW_NONE,bitmap);
00425     AddLabelToBitmapButton(select_all,_("All"),false);
00426     AddLabelToBitmapButton(select_none,_("None"), false);
00427 #endif
00428 
00429     wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
00430     sizer->Add(select_all,0,wxALIGN_CENTER_VERTICAL | wxLEFT | wxTOP | wxBOTTOM,5);
00431     sizer->Add(select_none,0,wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP | wxBOTTOM,5);
00432     panel->SetSizer(sizer);
00433     m_ToggleButtonSizer->Add(panel, 0, wxALIGN_CENTER_VERTICAL);
00434     m_ToggleButtonSizer->Add(m_ButtonPanel, 1, wxEXPAND | wxADJUST_MINSIZE | wxALIGN_CENTER_VERTICAL, 0);
00435 
00436     m_topsizer->Add(tool_panel, 0, wxEXPAND | wxALL, 2);
00437     m_topsizer->Add(toggle_panel, 0, wxEXPAND | wxADJUST_MINSIZE | wxBOTTOM, 5);
00438 
00439 #if wxCHECK_VERSION(2, 9, 1)
00440     m_infoBar = new wxInfoBar(this);
00441     m_infoBar->AddButton(ID_HIDE_HINTS,_("Hide"));
00442     m_infoBar->Connect(ID_HIDE_HINTS,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(GLPreviewFrame::OnHideProjectionHints),NULL,this);
00443     m_topsizer->Add(m_infoBar, 0, wxEXPAND);
00444 #endif
00445 
00446     //create panel that will hold gl canvases
00447     wxPanel * vis_panel = new wxPanel(this);
00448 
00449     wxPanel * preview_panel = new wxPanel(vis_panel);
00450     wxPanel * overview_panel = new wxPanel(vis_panel);
00451 
00452     // create our Viewers
00453     int args[] = {WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0};
00454     m_GLPreview = new GLPreview(preview_panel, pano, args, this);
00455     m_GLOverview = new GLOverview(overview_panel, pano, args, this, m_GLPreview->GetContext());
00456     m_GLOverview->SetMode(GLOverview::PANOSPHERE);
00457       
00458 #ifdef __WXGTK__
00459     // on wxGTK we can not create the OpenGL context with a hidden window
00460     // therefore we need to create the overview window open and later hide it
00461     overview_hidden=false;
00462 #endif
00463     m_GLOverview->SetActive(!overview_hidden);
00464 
00465     // set the AUI manager to our panel
00466     m_mgr = new GLwxAuiManager(this, m_GLPreview, m_GLOverview);
00467     m_mgr->SetManagedWindow(vis_panel);
00468     vis_panel->SetMinSize(wxSize(200,150));
00469     
00470     //create the sizer for the preview
00471     wxFlexGridSizer * flexSizer = new wxFlexGridSizer(2,0,5,5);
00472     flexSizer->AddGrowableCol(0);
00473     flexSizer->AddGrowableRow(0);
00474 
00475     //overview sizer
00476     wxBoxSizer * overview_sizer = new wxBoxSizer(wxVERTICAL);
00477 
00478 
00479     flexSizer->Add(m_GLPreview,
00480                   1,        // not vertically stretchable
00481                   wxEXPAND | // horizontally stretchable
00482                   wxALL,    // draw border all around
00483                   5);       // border width
00484 
00485     m_VFOVSlider = new wxSlider(preview_panel, -1, 1,
00486                                 1, 180,
00487                                 wxDefaultPosition, wxDefaultSize,
00488                                 wxSL_VERTICAL | wxSL_AUTOTICKS,
00489                                 wxDefaultValidator,
00490                                 _("VFOV"));
00491     m_VFOVSlider->SetLineSize(2);
00492     m_VFOVSlider->SetPageSize(10);
00493     m_VFOVSlider->SetTickFreq(5,0);
00494     m_VFOVSlider->SetToolTip(_("drag to change the vertical field of view"));
00495 
00496     flexSizer->Add(m_VFOVSlider, 0, wxEXPAND);
00497 
00498     m_HFOVSlider = new wxSlider(preview_panel, -1, 1,
00499                                 1, 360,
00500                                 wxDefaultPosition, wxDefaultSize,
00501                                 wxSL_HORIZONTAL | wxSL_AUTOTICKS,
00502                                 wxDefaultValidator,
00503                                 _("HFOV"));
00504     m_HFOVSlider->SetPageSize(10);
00505     m_HFOVSlider->SetLineSize(2);
00506     m_HFOVSlider->SetTickFreq(5,0);
00507 
00508     m_HFOVSlider->SetToolTip(_("drag to change the horizontal field of view"));
00509 
00510     m_HFOVText = XRCCTRL(*this, "pano_text_hfov" ,wxTextCtrl);
00511     DEBUG_ASSERT(m_HFOVText);
00512     m_HFOVText->PushEventHandler(new TextKillFocusHandler(this));
00513     m_VFOVText = XRCCTRL(*this, "pano_text_vfov" ,wxTextCtrl);
00514     DEBUG_ASSERT(m_VFOVText);
00515     m_VFOVText->PushEventHandler(new TextKillFocusHandler(this));
00516 
00517     m_ROILeftTxt = XRCCTRL(*this, "pano_val_roi_left", wxTextCtrl);
00518     DEBUG_ASSERT(m_ROILeftTxt);
00519     m_ROILeftTxt->PushEventHandler(new TextKillFocusHandler(this));
00520 
00521     m_ROIRightTxt = XRCCTRL(*this, "pano_val_roi_right", wxTextCtrl);
00522     DEBUG_ASSERT(m_ROIRightTxt);
00523     m_ROIRightTxt->PushEventHandler(new TextKillFocusHandler(this));
00524 
00525     m_ROITopTxt = XRCCTRL(*this, "pano_val_roi_top", wxTextCtrl);
00526     DEBUG_ASSERT(m_ROITopTxt);
00527     m_ROITopTxt->PushEventHandler(new TextKillFocusHandler(this));
00528 
00529     m_ROIBottomTxt = XRCCTRL(*this, "pano_val_roi_bottom", wxTextCtrl);
00530     DEBUG_ASSERT(m_ROIBottomTxt);
00531     m_ROIBottomTxt->PushEventHandler(new TextKillFocusHandler(this));
00532 
00533     m_GuideChoiceCrop = XRCCTRL(*this, "preview_guide_choice_crop", wxChoice);
00534     m_GuideChoiceProj = XRCCTRL(*this, "preview_guide_choice_proj", wxChoice);
00535     m_GuideChoiceDrag = XRCCTRL(*this, "preview_guide_choice_drag", wxChoice);
00536     int guide=cfg->Read(wxT("/GLPreviewFrame/guide"),0l);
00537     m_GuideChoiceCrop->SetSelection(guide);
00538     m_GuideChoiceProj->SetSelection(guide);
00539     m_GuideChoiceDrag->SetSelection(guide);
00540 
00541     flexSizer->Add(m_HFOVSlider, 0, wxEXPAND);
00542 
00543     wxPanel *overview_command_panel = wxXmlResource::Get()->LoadPanel(overview_panel,wxT("overview_command_panel"));
00544     m_OverviewModeChoice = XRCCTRL(*this, "overview_mode_choice", wxChoice);
00545     overview_command_panel->SetSize(0,0,200,20,wxSIZE_AUTO_WIDTH);
00546 
00547     overview_sizer->Add(overview_command_panel, 0, wxEXPAND);
00548     overview_sizer->Add(m_GLOverview, 1, wxEXPAND);
00549 
00550     bool showGrid;
00551     cfg->Read(wxT("/GLPreviewFrame/showPreviewGrid"),&showGrid,true);
00552     GetMenuBar()->FindItem(XRCID("action_show_grid"))->Check(showGrid);
00553 
00554     preview_panel->SetSizer(flexSizer);
00555     overview_panel->SetSizer(overview_sizer);
00556 
00557     m_mgr->AddPane(preview_panel, 
00558         wxAuiPaneInfo(
00559             ).Name(wxT("preview")
00560             ).MinSize(300,200
00561             ).CloseButton(false
00562             ).CaptionVisible(false
00563             ).Caption(_("Preview")
00564             ).Floatable(false
00565             ).Dockable(false
00566             ).Center(
00567             )
00568         );
00569 
00570     m_mgr->AddPane(overview_panel, 
00571         wxAuiPaneInfo(
00572             ).Name(wxT("overview")
00573             ).MinSize(300,200
00574             ).CloseButton(false
00575             ).CaptionVisible(
00576             ).Caption(_("Overview")
00577             ).FloatingSize(100,100
00578             ).FloatingPosition(500,500
00579             ).Dockable(true
00580             ).PinButton(
00581             ).Left(
00582             ).Show(!overview_hidden
00583             )
00584         );
00585 
00586 
00587     m_topsizer->Add(vis_panel, 1, wxEXPAND);
00588 
00589     //assistant related controls
00590     m_imagesText = XRCCTRL(*this, "ass_load_images_text", wxStaticText);
00591     DEBUG_ASSERT(m_imagesText);
00592 
00593     m_lensTypeChoice = XRCCTRL(*this, "ass_lens_type", wxChoice);
00594     DEBUG_ASSERT(m_lensTypeChoice);
00595     FillLensProjectionList(m_lensTypeChoice);
00596     m_lensTypeChoice->SetSelection(0);
00597 
00598     m_focalLengthText = XRCCTRL(*this, "ass_focal_length", wxTextCtrl);
00599     DEBUG_ASSERT(m_focalLengthText);
00600     m_focalLengthText->PushEventHandler(new TextKillFocusHandler(this));
00601 
00602     m_cropFactorText = XRCCTRL(*this, "ass_crop_factor", wxTextCtrl);
00603     DEBUG_ASSERT(m_cropFactorText);
00604     m_cropFactorText->PushEventHandler(new TextKillFocusHandler(this));
00605 
00606     m_alignButton = XRCCTRL(*this, "ass_align_button", wxButton);
00607     DEBUG_ASSERT(m_alignButton);
00608     m_alignButton->Disable();
00609 
00610     m_createButton = XRCCTRL(*this, "ass_create_button", wxButton);
00611     DEBUG_ASSERT(m_createButton);
00612     m_createButton->Disable();
00613 
00614     m_ProjectionChoice = XRCCTRL(*this,"projection_choice",wxChoice);
00615 
00616     /* populate with all available projection types */
00617     int nP = panoProjectionFormatCount();
00618     for(int n=0; n < nP; n++) {
00619         pano_projection_features proj;
00620         if (panoProjectionFeaturesQuery(n, &proj)) {
00621             wxString str2(proj.name, wxConvLocal);
00622             m_ProjectionChoice->Append(wxGetTranslation(str2));
00623         }
00624     }
00625     m_ProjectionChoice->SetSelection(2);
00626 
00628     // Blend mode
00629     // remaining blend mode should be added after OpenGL context has been created
00630     // see FillBlendMode()
00631     m_differenceIndex = -1;
00632     // create choice item
00633     m_BlendModeChoice = XRCCTRL(*this,"blend_mode_choice",wxChoice);
00634     m_BlendModeChoice->Append(_("normal"));
00635     m_BlendModeChoice->SetSelection(0);
00636 
00637     m_DragModeChoice = XRCCTRL(*this, "drag_mode_choice", wxChoice);
00638     SetGuiLevel(GUI_SIMPLE);
00639     bool individualDrag;
00640     cfg->Read(wxT("/GLPreviewFrame/individualDragMode"), &individualDrag, false);
00641     if(individualDrag)
00642     {
00643         m_DragModeChoice->SetSelection(1);
00644     }
00645     else
00646     {
00647         m_DragModeChoice->SetSelection(0);
00648     };
00649     // default drag mode
00650     GLPreviewFrame::DragChoiceLayout(0);
00651 
00652     // TODO implement hdr display in OpenGL, if possible?
00653     // Disabled until someone can figure out HDR display in OpenGL.
00654     /*
00656     // LDR, HDR
00657     blendModeSizer->Add(new wxStaticText(this, -1, _("Output:")),
00658                         0,        // not vertically strechable
00659                         wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00660                         5);       // border width
00661 
00662     m_choices[0] = _("LDR");
00663     m_choices[1] = _("HDR");
00664     m_outputModeChoice = new wxChoice(this, ID_OUTPUTMODE_CHOICE,
00665                                       wxDefaultPosition, wxDefaultSize,
00666                                       2, m_choices);
00667     m_outputModeChoice->SetSelection(0);
00668     blendModeSizer->Add(m_outputModeChoice,
00669                         0,
00670                         wxALL | wxALIGN_CENTER_VERTICAL,
00671                         5);
00672     */
00673     
00675     // exposure
00676     m_defaultExposureBut = XRCCTRL(*this, "exposure_default_button", wxBitmapButton);
00677 
00678     m_exposureTextCtrl = XRCCTRL(*this, "exposure_text", wxTextCtrl);
00679     m_exposureSpinBut = XRCCTRL(*this, "exposure_spin", wxSpinButton); 
00680     m_exposureSpinBut->SetValue(0);
00681 
00682     m_projection_panel = XRCCTRL(*this, "projection_panel", wxPanel);
00683     m_projParamSizer = new wxBoxSizer(wxHORIZONTAL);
00684 
00685     wxBitmapButton * resetProjButton=new wxBitmapButton(m_projection_panel, PROJ_PARAM_RESET_ID, 
00686         wxArtProvider::GetBitmap(wxART_REDO));
00687     resetProjButton->SetToolTip(_("Resets the projection's parameters to their default values."));
00688     m_projParamSizer->Add(resetProjButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
00689 
00690     m_projParamNamesLabel.resize(PANO_PROJECTION_MAX_PARMS);
00691     m_projParamTextCtrl.resize(PANO_PROJECTION_MAX_PARMS);
00692     m_projParamSlider.resize(PANO_PROJECTION_MAX_PARMS);
00693 
00694     for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++) {
00695 
00696         m_projParamNamesLabel[i] = new wxStaticText(m_projection_panel, PROJ_PARAM_NAMES_ID+i, _("param:"));
00697         m_projParamSizer->Add(m_projParamNamesLabel[i],
00698                         0,        // not vertically strechable
00699                         wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, // draw border all around
00700                         5);       // border width
00701         m_projParamTextCtrl[i] = new wxTextCtrl(m_projection_panel, PROJ_PARAM_VAL_ID+i, wxT("0"),
00702                                     wxDefaultPosition, wxSize(35,-1), wxTE_PROCESS_ENTER);
00703         m_projParamTextCtrl[i]->PushEventHandler(new TextKillFocusHandler(this));
00704         m_projParamSizer->Add(m_projParamTextCtrl[i],
00705                         0,        // not vertically strechable
00706                         wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, // draw border all around
00707                         5);       // border width
00708 
00709         m_projParamSlider[i] = new wxSlider(m_projection_panel, PROJ_PARAM_SLIDER_ID+i, 0, -90, 90);
00710         m_projParamSizer->Add(m_projParamSlider[i],
00711                         1,        // not vertically strechable
00712                         wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL , // draw border all around
00713                         5);       // border width
00714     }
00715 
00716     m_projection_panel->GetSizer()->Add(m_projParamSizer, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL);
00717 
00718     // do not show projection param sizer
00719     m_projection_panel->GetSizer()->Show(m_projParamSizer, false, true);
00720 
00721     // the initial size as calculated by the sizers
00722     this->SetSizer( m_topsizer );
00723     m_topsizer->SetSizeHints( this );
00724 
00725     // set the minimize icon
00726 #ifdef __WXMSW__
00727     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
00728 #else
00729     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
00730 #endif
00731     SetIcon(myIcon);
00732 
00733     m_pano.addObserver(this);
00734 
00735     RestoreFramePosition(this, wxT("GLPreviewFrame"));
00736     
00737 #ifdef __WXMSW__
00738     // wxFrame does have a strange background color on Windows..
00739     this->SetBackgroundColour(m_GLPreview->GetBackgroundColour());
00740 #endif
00741 
00742     m_showProjectionHints = cfg->Read(wxT("/GLPreviewFrame/ShowProjectionHints"), HUGIN_SHOW_PROJECTION_HINTS) == 1;
00743     m_degDigits = wxConfigBase::Get()->Read(wxT("/General/DegreeFractionalDigitsEdit"),3);
00744 
00745      // tell the manager to "commit" all the changes just made
00746     m_mgr->Update();
00747 
00748     if (cfg->Read(wxT("/GLPreviewFrame/isShown"), 0l) != 0)
00749     {
00750 #if defined __WXMSW__ || defined __WXMAC__
00751         InitPreviews();
00752         Show();
00753 #else
00754         Show();
00755         LoadOpenGLLayout();
00756 #endif
00757     }
00758     SetDropTarget(new PanoDropTarget(m_pano, true));
00759 #if defined __WXMAC__
00760     Layout();
00761     Update();
00762 #endif
00763 }
00764 
00765 void GLPreviewFrame::LoadOpenGLLayout()
00766 {
00767 #ifdef __WXGTK__
00768     if(loadedLayout)
00769     {
00770         return;
00771     };
00772     loadedLayout=true;
00773 #endif
00774     wxString OpenGLLayout=wxConfig::Get()->Read(wxT("/GLPreviewFrame/OpenGLLayout"));
00775     if(!OpenGLLayout.IsEmpty())
00776     {
00777         m_mgr->LoadPerspective(OpenGLLayout,true);
00778 #ifdef __WXGTK__
00779         if(!GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked())
00780         {
00781             m_GLOverview->SetActive(false);
00782         };
00783         wxShowEvent dummy;
00784         dummy.SetShow(true);
00785         OnShowEvent(dummy);
00786 #endif
00787     };
00788     FillBlendChoice();
00789 };
00790 
00791 GLPreviewFrame::~GLPreviewFrame()
00792 {
00793     DEBUG_TRACE("dtor writing config");
00794     wxConfigBase * cfg = wxConfigBase::Get();
00795     wxSize sz = GetClientSize();
00796 
00797     StoreFramePosition(this, wxT("GLPreviewFrame"));
00798 
00799     if ( (!this->IsIconized()) && (! this->IsMaximized()) && this->IsShown()) {
00800         cfg->Write(wxT("/GLPreviewFrame/isShown"), 1l);
00801     } else {
00802         cfg->Write(wxT("/GLPreviewFrame/isShown"), 0l);
00803     }
00804 
00805     cfg->Write(wxT("/GLPreviewFrame/blendMode"), m_BlendModeChoice->GetSelection());
00806     cfg->Write(wxT("/GLPreviewFrame/OpenGLLayout"), m_mgr->SavePerspective());
00807     cfg->Write(wxT("/GLPreviewFrame/overview_hidden"), !(GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked()));
00808     cfg->Write(wxT("/GLPreviewFrame/showPreviewGrid"), GetMenuBar()->FindItem(XRCID("action_show_grid"))->IsChecked());
00809     cfg->Write(wxT("/GLPreviewFrame/individualDragMode"), individualDragging());
00810     cfg->Write(wxT("/GLPreviewFrame/guide"),m_GuideChoiceProj->GetSelection());
00811     
00812     // delete all of the tools. When the preview is never used we never get an
00813     // OpenGL context and therefore don't create the tools.
00814     if (color_picker_tool)
00815     {
00816         preview_helper->DeactivateTool(color_picker_tool);
00817         delete color_picker_tool;
00818     };
00819     if (crop_tool)
00820     {
00821         preview_helper->DeactivateTool(crop_tool); delete crop_tool;
00822         preview_helper->DeactivateTool(drag_tool); delete drag_tool;
00823         preview_helper->DeactivateTool(identify_tool); delete identify_tool;
00824         preview_helper->DeactivateTool(difference_tool); delete difference_tool;
00825         preview_helper->DeactivateTool(pano_mask_tool); delete pano_mask_tool;
00826     }
00827     if (panosphere_overview_identify_tool) {
00828         panosphere_overview_helper->DeactivateTool(overview_drag_tool); delete overview_drag_tool;
00829         panosphere_overview_helper->DeactivateTool(panosphere_overview_identify_tool); delete panosphere_overview_identify_tool;
00830         panosphere_overview_helper->DeactivateTool(panosphere_difference_tool); delete panosphere_difference_tool;
00831         panosphere_overview_helper->DeactivateTool(panosphere_sphere_tool); delete panosphere_sphere_tool;
00832     }
00833     if (plane_overview_identify_tool) {
00834         plane_overview_helper->DeactivateTool(plane_overview_identify_tool); delete plane_overview_identify_tool;
00835         plane_overview_helper->DeactivateTool(plane_difference_tool); delete plane_difference_tool;
00836     }
00837     if (preview_guide_tool) {
00838         preview_helper->DeactivateTool(preview_guide_tool);
00839         delete preview_guide_tool;
00840     };
00841     m_focalLengthText->PopEventHandler(true);
00842     m_cropFactorText->PopEventHandler(true);
00843     m_HFOVText->PopEventHandler(true);
00844     m_VFOVText->PopEventHandler(true);
00845     m_ROILeftTxt->PopEventHandler(true);
00846     m_ROIRightTxt->PopEventHandler(true);
00847     m_ROITopTxt->PopEventHandler(true);
00848     m_ROIBottomTxt->PopEventHandler(true);
00849     for (int i=0; i < m_ToggleButtons.size(); i++)
00850     {
00851         m_ToggleButtons[i]->PopEventHandler(true);
00852         m_GroupToggleButtons[i]->PopEventHandler(true);
00853     }
00854     for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++)
00855     {
00856         m_projParamTextCtrl[i]->PopEventHandler(true);
00857     };
00858     m_pano.removeObserver(this);
00859 
00860      // deinitialize the frame manager
00861      m_mgr->UnInit();
00862      if (m_mgr) {
00863         delete m_mgr;
00864      }
00865      if(m_guiLevel!=GUI_SIMPLE)
00866      {
00867          delete m_filemenuSimple;
00868      };
00869 
00870     DEBUG_TRACE("dtor end");
00871 }
00872 
00873 void GLPreviewFrame::InitPreviews()
00874 {
00875     if(preview_helper==NULL || panosphere_overview_helper==NULL || plane_overview_helper==NULL)
00876     {
00877         m_GLPreview->SetUpContext();
00878         m_GLOverview->SetUpContext();
00879         LoadOpenGLLayout();
00880     };
00881 };
00882 
00886 void GLPreviewFrame::updateBlendMode()
00887 {
00888     if (m_BlendModeChoice != NULL)
00889     {
00890         int index=m_BlendModeChoice->GetSelection();
00891         if(index==0)
00892         {
00893             // normal mode
00894             if (preview_helper != NULL 
00895                 && difference_tool != NULL)
00896             {
00897                 preview_helper->DeactivateTool(difference_tool);
00898             };
00899 
00900             if (panosphere_overview_helper != NULL 
00901                 && panosphere_difference_tool != NULL)
00902             {
00903                 panosphere_overview_helper->DeactivateTool(panosphere_difference_tool);
00904             };
00905 
00906             if (plane_overview_helper != NULL 
00907                 && plane_difference_tool != NULL)
00908             {
00909                 plane_overview_helper->DeactivateTool(plane_difference_tool);
00910             };
00911 
00912 
00913         }
00914         else
00915         {
00916             if(index==m_differenceIndex)
00917             {
00918                 // difference mode
00919                 if (preview_helper != NULL 
00920                     && identify_tool != NULL 
00921                     && difference_tool != NULL
00922                     && m_ToolBar_Identify != NULL )
00923                 {
00924                     identify_tool->setConstantOn(false);
00925 //                    preview_helper->DeactivateTool(identify_tool);
00926                     m_ToolBar_Identify->ToggleTool(XRCID("preview_identify_tool"), false);
00927                     preview_helper->ActivateTool(difference_tool);
00928                     CleanButtonColours();
00929                 };
00930 
00931                 // difference mode
00932                 if (panosphere_overview_helper != NULL 
00933                     && panosphere_overview_identify_tool != NULL 
00934                     && panosphere_difference_tool != NULL)
00935                 {
00936 //                    panosphere_overview_helper->DeactivateTool(panosphere_overview_identify_tool);
00937                     panosphere_overview_identify_tool->setConstantOn(false);
00938                     panosphere_overview_helper->ActivateTool(panosphere_difference_tool);
00939                 };
00940 
00941                 // difference mode
00942                 if (plane_overview_helper != NULL 
00943                     && plane_overview_identify_tool != NULL 
00944                     && plane_difference_tool != NULL)
00945                 {
00946 //                    plane_overview_helper->DeactivateTool(plane_overview_identify_tool);
00947                     plane_overview_identify_tool->setConstantOn(false);
00948                     plane_overview_helper->ActivateTool(plane_difference_tool);
00949                 };
00950 
00951             }
00952             else
00953             {
00954                 DEBUG_WARN("Unknown blend mode selected");
00955             };
00956         }
00957     }
00958 }
00959 
00960 void GLPreviewFrame::UpdateRoiDisplay(const PanoramaOptions opts)
00961 {
00962     m_ROILeftTxt->SetValue(wxString::Format(wxT("%d"), opts.getROI().left() ));
00963     m_ROIRightTxt->SetValue(wxString::Format(wxT("%d"), opts.getROI().right() ));
00964     m_ROITopTxt->SetValue(wxString::Format(wxT("%d"), opts.getROI().top() ));
00965     m_ROIBottomTxt->SetValue(wxString::Format(wxT("%d"), opts.getROI().bottom() ));
00966 };
00967 
00968 void GLPreviewFrame::panoramaChanged(Panorama &pano)
00969 {
00970     m_lensTypeChoice->Enable(pano.getNrOfImages()>0);
00971     m_focalLengthText->Enable(pano.getNrOfImages()>0);
00972     m_cropFactorText->Enable(pano.getNrOfImages()>0);
00973     m_alignButton->Enable(pano.getNrOfImages()>1);
00974 
00975     if(pano.getNrOfImages()==0)
00976     {
00977         m_createButton->Disable();
00978         m_imagesText->SetLabel(_("No images loaded."));
00979     }
00980     else
00981     {
00982         int images = pano.getNrOfImages();
00983         bool enableCreate = false;;
00984         if (images > 1)
00985         {
00986             while (images)
00987             {
00988                 --images;
00989                 const VariableMap & vars = pano.getImageVariables(images);
00990                 if (const_map_get(vars,"y").getValue() != 0.0)
00991                 {
00992                     enableCreate = true;
00993                     break;
00994                 }
00995                 if (const_map_get(vars,"p").getValue() != 0.0)
00996                 {
00997                     enableCreate = true;
00998                     break;
00999                 }
01000                 if (const_map_get(vars,"r").getValue() != 0.0)
01001                 {
01002                     enableCreate = true;
01003                     break;
01004                 }
01005             }
01006         }
01007 
01008         m_createButton->Enable(enableCreate);
01009 
01010         // in wxWidgets 2.9, format must have types that exactly match.
01011         // However std::size_t could be any unsiged integer, so we cast it to
01012         // unsigned long.int to be on the safe side.
01013         wxString imgMsg = wxString::Format(_("%lu images loaded."), (unsigned long int) pano.getNrOfImages());
01014         m_imagesText->SetLabel(imgMsg);
01015 
01016         // update data in lens display
01017         const SrcPanoImage& img=pano.getImage(0);
01018         SelectProjection(m_lensTypeChoice, img.getProjection());
01019         double focal_length = SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(), img.getExifCropFactor(), img.getSize());
01020         m_focalLengthText->SetValue(doubleTowxString(focal_length,m_degDigits));
01021         m_cropFactorText->SetValue(doubleTowxString(img.getExifCropFactor(),m_degDigits));
01022     }
01023 
01024     if (pano.getNrOfImages() > 1)
01025     {
01026         // in wxWidgets 2.9, format must have types that exactly match.
01027         // However std::size_t could be any unsiged integer, so we cast it to
01028         // unsigned long.int to be on the safe side.
01029         wxString alignMsg = wxString::Format(_("Images are connected by %lu control points.\n"), (unsigned long int) pano.getCtrlPoints().size());
01030 
01031         if (m_pano.getNrOfCtrlPoints() > 0)
01032         {
01033             // find components..
01034             CPGraph graph;
01035             createCPGraph(m_pano, graph);
01036             CPComponents comps;
01037             int n= findCPComponents(graph, comps);
01038             if (n > 1)
01039             {
01040                 alignMsg += wxString::Format(_("%d unconnected image groups found: "), n) + Components2Str(comps) + wxT("\n");
01041                 alignMsg += _("Please use the Control Points tab to connect all images with control points.\n");
01042             }
01043             else
01044             {
01045                 if (m_pano.needsOptimization())
01046                 {
01047                     alignMsg += _("Images or control points have changed, new alignment is needed.");
01048                 }
01049                 else
01050                 {
01051                     double min;
01052                     double max;
01053                     double mean;
01054                     double var;
01055                     m_pano.calcCtrlPntsErrorStats( min, max, mean, var);
01056 
01057                     if (max != 0.0)
01058                     {
01059                         wxString distStr;
01060                         if (mean < 3)
01061                             distStr = _("Very good fit.");
01062                         else if (mean < 5)
01063                             distStr = _("Good fit.");
01064                         else if (mean < 10)
01065                             distStr = _("Bad fit, some control points might be bad, or there are parallax and movement errors");
01066                         else
01067                             distStr = _("Very bad fit. Check for bad control points, lens parameters, or images with parallax or movement. The optimizer might have failed. Manual intervention required.");
01068 
01069                         alignMsg = alignMsg + wxString::Format(_("Mean error after optimization: %.1f pixel, max: %.1f\n"), mean, max)
01070                                 + distStr; 
01071                     }
01072                 }
01073             }
01074         }
01075         m_GLPreview->SetOverlayText(alignMsg);
01076     }
01077     else
01078     {
01079         m_GLPreview->SetOverlayText(_("Note: automatic alignment uses default settings from the preferences. If you want to use customized settings, run the CP detection, the geometrical optimization and the photometric optimization from the Photos tab in the panorama editor."));
01080     };
01081 
01082     GetMenuBar()->Enable(XRCID("ID_EDITUNDO"), GlobalCmdHist::getInstance().canUndo());
01083     GetMenuBar()->Enable(XRCID("ID_EDITREDO"), GlobalCmdHist::getInstance().canRedo());
01084 
01085     // TODO: update meaningful help text and dynamic links to relevant tabs
01086 
01087     const PanoramaOptions & opts = pano.getOptions();
01088 
01089     wxString projection;
01090     m_ProjectionChoice->SetSelection(opts.getProjection());
01091     m_VFOVSlider->Enable( opts.fovCalcSupported(opts.getProjection()) );
01092     
01093     // No HDR display yet.
01094     /*
01095     m_outputModeChoice->SetSelection(opts.outputMode);
01096     if (opts.outputMode == PanoramaOptions::OUTPUT_HDR) {
01097         m_exposureTextCtrl->Hide();
01098         m_defaultExposureBut->Hide();
01099         m_decExposureBut->Hide();
01100         m_incExposureBut->Hide();
01101     } else {
01102         m_exposureTextCtrl->Show();
01103         m_defaultExposureBut->Show();
01104         m_decExposureBut->Show();
01105         m_incExposureBut->Show();
01106     }*/
01107     m_exposureTextCtrl->SetValue(wxString(doubleToString(opts.outputExposureValue,2).c_str(), wxConvLocal));
01108 
01109     bool activeImgs = pano.getActiveImages().size() > 0;
01110 
01111     // TODO: enable display of parameters and set their limits, if projection has some.
01112 
01113     int nParam = opts.m_projFeatures.numberOfParameters;
01114     bool relayout = false;
01115     // if the projection format has changed
01116     if (opts.getProjection() != m_oldProjFormat) {
01117         DEBUG_DEBUG("Projection format changed");
01118         if (nParam) {
01119             // show parameters and update labels.
01120             m_projection_panel->GetSizer()->Show(m_projParamSizer, true, true);
01121             int i;
01122             for (i=0; i < nParam; i++) {
01123                 const pano_projection_parameter * pp = & (opts.m_projFeatures.parm[i]);
01124                 wxString str2(pp->name, wxConvLocal);
01125                 str2 = wxGetTranslation(str2);
01126                 m_projParamNamesLabel[i]->SetLabel(str2);
01127                 m_projParamSlider[i]->SetRange(roundi(pp->minValue), roundi(pp->maxValue));
01128             }
01129             for(;i < PANO_PROJECTION_MAX_PARMS; i++) {
01130                 m_projParamNamesLabel[i]->Hide();
01131                 m_projParamSlider[i]->Hide();
01132                 m_projParamTextCtrl[i]->Hide();
01133             }
01134             relayout = true;
01135         } else {
01136             m_projection_panel->GetSizer()->Show(m_projParamSizer, false, true);
01137             relayout = true;
01138         }
01139     }
01140     if (nParam) {
01141         // display new values
01142         std::vector<double> params = opts.getProjectionParameters();
01143         assert((int) params.size() == nParam);
01144         for (int i=0; i < nParam; i++) {
01145             wxString val = wxString(doubleToString(params[i],1).c_str(), wxConvLocal);
01146             m_projParamTextCtrl[i]->SetValue(wxString(val.wc_str(), wxConvLocal));
01147             m_projParamSlider[i]->SetValue(roundi(params[i]));
01148         }
01149     }
01150     if (relayout) {
01151         m_projection_panel->Layout();
01152         Refresh();
01153     }
01154     SetStatusText(wxString::Format(wxT("%.1f x %.1f"), opts.getHFOV(), opts.getVFOV()),2);
01155     m_HFOVSlider->SetValue(roundi(opts.getHFOV()));
01156     m_VFOVSlider->SetValue(roundi(opts.getVFOV()));
01157     std::string val;
01158     val = doubleToString(opts.getHFOV(),1);
01159     m_HFOVText->SetValue(wxString(val.c_str(), wxConvLocal));
01160     val = doubleToString(opts.getVFOV(),1);
01161     m_VFOVText->SetValue(wxString(val.c_str(), wxConvLocal));
01162     m_VFOVText->Enable(opts.fovCalcSupported(opts.getProjection()));
01163 
01164     m_oldProjFormat = opts.getProjection();
01165 
01166 #if wxCHECK_VERSION(2,9,2)
01167     XRCCTRL(*this,"preview_autocrop_tool",wxButton)->Enable(activeImgs);
01168     XRCCTRL(*this,"preview_stack_autocrop_tool",wxButton)->Enable(activeImgs);
01169 #else
01170     XRCCTRL(*this,"preview_autocrop_tool",wxBitmapButton)->Enable(activeImgs);
01171     XRCCTRL(*this,"preview_stack_autocrop_tool",wxBitmapButton)->Enable(activeImgs);
01172 #endif
01173     UpdateRoiDisplay(opts);
01174     
01175     if(m_showProjectionHints)
01176     {
01177         ShowProjectionWarnings();
01178     };
01179     redrawPreview();
01180 }
01181 
01182 void GLPreviewFrame::panoramaImagesChanged(Panorama &pano, const UIntSet &changed)
01183 {
01184     DEBUG_TRACE("");
01185 
01186     bool dirty = false;
01187 
01188     unsigned int nrImages = pano.getNrOfImages();
01189     unsigned int nrButtons = m_ToggleButtons.size();
01190 
01191 //    m_displayedImgs.clear();
01192 
01193     // remove items for nonexisting images
01194     for (int i=nrButtons-1; i>=(int)nrImages; i--)
01195     {
01196         m_ButtonSizer->Detach(m_ToggleButtonPanel[i]);
01197         // Image toggle buttons have a event handler on the stack which
01198         // must be removed before the buttons get destroyed.
01199         m_ToggleButtons[i]->PopEventHandler();
01200         m_GroupToggleButtons[i]->PopEventHandler();
01201         delete m_ToggleButtons[i];
01202         delete m_GroupToggleButtons[i];
01203         delete m_ToggleButtonPanel[i];
01204         m_ToggleButtons.pop_back();
01205         m_GroupToggleButtons.pop_back();
01206         m_ToggleButtonPanel.pop_back();
01207         delete toogle_button_event_handlers[i];
01208         toogle_button_event_handlers.pop_back();
01209         delete toggle_group_button_event_handlers[i];
01210         toggle_group_button_event_handlers.pop_back();
01211         dirty = true;
01212     }
01213 
01214     //change overview mode to panosphere if the translation plane parameter are non zero
01215     if (m_GLOverview->GetMode() == GLOverview::PLANE)
01216     {
01217         if (HasNonZeroTranslationPlaneParameters())
01218         {
01219             m_GLOverview->SetMode(GLOverview::PANOSPHERE);
01220             m_OverviewModeChoice->SetSelection(0);
01221             //check if drag mode is mosaic, if so reset to normal
01222             if(drag_tool)
01223             {
01224                 if(drag_tool->getDragMode()==DragTool::drag_mode_mosaic)
01225                 {
01226                     m_DragModeChoice->SetSelection(m_DragModeChoice->GetSelection()-2);
01227                     drag_tool->setDragMode(DragTool::drag_mode_normal);
01228                     EnableGroupCheckboxes(individualDragging());
01229                     // adjust the layout
01230                     DragChoiceLayout(m_DragModeChoice->GetSelection());
01231                 };
01232             };
01233         }
01234     }
01235 
01236     // add buttons
01237     if ( nrImages >= nrButtons ) {
01238         for(UIntSet::const_iterator it = changed.begin(); it != changed.end(); ++it){
01239             if (*it >= nrButtons) {
01240                 unsigned int imgNr = *it;
01241                 // create new item.
01242 //                wxImage * bmp = new wxImage(sz.GetWidth(), sz.GetHeight());
01243                 //put wxToggleButton in a wxPanel because 
01244                 //on Windows the background colour of wxToggleButton can't be changed
01245                 wxPanel *pan = new wxPanel(m_ButtonPanel);
01246                 wxBoxSizer * siz = new wxBoxSizer(wxVERTICAL);
01247                 pan->SetSizer(siz);
01248 #ifdef USE_TOGGLE_BUTTON
01249                 wxToggleButton * but = new wxToggleButton(pan,
01250                                                           ID_TOGGLE_BUT + *it,
01251                                                           wxString::Format(wxT("%d"),*it),
01252                                                           wxDefaultPosition, wxDefaultSize,
01253                                                           wxBU_EXACTFIT);
01254 #else
01255                 wxCheckBox * but = new wxCheckBox(pan,
01256                                                   ID_TOGGLE_BUT + *it,
01257                                                   wxString::Format(wxT("%d"),*it));
01258 #endif
01259                 
01260                 wxCheckBox *butcheck = new wxCheckBox(pan, wxID_ANY, wxT(""));
01261 
01262 #ifdef __WXMSW__
01263                 //we need a border around the button to see the colored panel
01264                 //because changing backgroundcolor of wxToggleButton does not work in wxMSW
01265                 siz->AddSpacer(5);
01266                 siz->Add(butcheck, 0, wxALIGN_CENTRE_HORIZONTAL | wxFIXED_MINSIZE, 0);
01267                 siz->Add(but,0,wxLEFT | wxRIGHT | wxBOTTOM , 5);
01268 #else
01269                 siz->Add(but,0,wxALL | wxADJUST_MINSIZE,0);
01270                 siz->Add(butcheck, 0, wxALL | wxFIXED_MINSIZE, 0);
01271 #endif
01272                 // for the identification tool to work, we need to find when the
01273                 // mouse enters and exits the button. We use a custom event
01274                 // handler, which will also toggle the images:
01275                 ImageToogleButtonEventHandler * event_handler = new
01276                     ImageToogleButtonEventHandler(*it,
01277                         m_ToolBar_Identify->FindById(XRCID("preview_identify_tool")),
01278                         &m_pano);
01279                 event_handler->AddIdentifyTool(&identify_tool);
01280                 event_handler->AddIdentifyTool(&panosphere_overview_identify_tool);
01281                 event_handler->AddIdentifyTool(&plane_overview_identify_tool);
01282                 toogle_button_event_handlers.push_back(event_handler);
01283                 but->PushEventHandler(event_handler);
01284 
01285                 ImageGroupButtonEventHandler * group_event_handler = new 
01286                     ImageGroupButtonEventHandler(*it, this, &m_pano);
01287                 group_event_handler->AddDragTool((DragTool**) &drag_tool);
01288                 group_event_handler->AddDragTool((DragTool**) &overview_drag_tool);
01289                 group_event_handler->AddIdentifyTool(&identify_tool);
01290                 group_event_handler->AddIdentifyTool(&panosphere_overview_identify_tool);
01291                 group_event_handler->AddIdentifyTool(&plane_overview_identify_tool);
01292                 toggle_group_button_event_handlers.push_back(group_event_handler);
01293                 butcheck->PushEventHandler(group_event_handler);
01294                 butcheck->Show(individualDragging() && m_mode==mode_drag);
01295 
01296                 but->SetValue(true);
01297                 m_ButtonSizer->Add(pan,
01298                                    0,
01299                                    wxLEFT | wxTOP | wxADJUST_MINSIZE,
01300                                    0);
01301                 m_ToggleButtons.push_back(but);
01302                 m_GroupToggleButtons.push_back(butcheck);
01303                 m_ToggleButtonPanel.push_back(pan);
01304                 dirty = true;
01305             }
01306         }
01307     }
01308 
01309     // update existing items
01310     UIntSet displayedImages = m_pano.getActiveImages();
01311     for (unsigned i=0; i < nrImages; i++) {
01312         m_ToggleButtons[i]->SetValue(set_contains(displayedImages, i));
01313         wxFileName tFilename(wxString (pano.getImage(i).getFilename().c_str(), HUGIN_CONV_FILENAME));
01314         m_ToggleButtons[i]->SetToolTip(tFilename.GetFullName());
01315     }
01316 
01317     if (dirty) {
01318                 m_ButtonSizer->SetVirtualSizeHints(m_ButtonPanel);
01319                 // Layout();
01320                 DEBUG_INFO("New m_ButtonPanel width: " << (m_ButtonPanel->GetSize()).GetWidth());
01321                 DEBUG_INFO("New m_ButtonPanel Height: " << (m_ButtonPanel->GetSize()).GetHeight());
01322     }
01323 
01324     if(nrImages==0)
01325     {
01326         SetMode(mode_assistant);
01327         m_tool_notebook->ChangeSelection(mode_assistant);
01328     };
01329     for(size_t i=2; i<m_tool_notebook->GetPageCount();i++)
01330     {
01331         m_tool_notebook->GetPage(i)->Enable(nrImages!=0);
01332     };
01333     redrawPreview();
01334 }
01335 
01336 void GLPreviewFrame::redrawPreview()
01337 {
01338     m_GLPreview->Refresh();
01339     m_GLOverview->Refresh();
01340 }
01341 
01342 void GLPreviewFrame::OnShowEvent(wxShowEvent& e)
01343 {
01344 
01345     DEBUG_TRACE("OnShow");
01346     bool toggle_on = GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked();
01347     wxAuiPaneInfo &inf = m_mgr->GetPane(wxT("overview"));
01348     if (inf.IsOk()) {
01349 #if wxCHECK_VERSION(2,8,11)
01350         if (e.IsShown()) {
01351 #else
01352         if (e.GetShow()) {
01353 #endif
01354             if (!inf.IsShown() && toggle_on ) {
01355                 inf.Show();
01356                 m_mgr->Update();
01357             }
01358         } else {
01359             if (inf.IsFloating() && inf.IsShown()) {
01360                 DEBUG_DEBUG("hiding overview float");
01361                 inf.Hide();
01362                 m_mgr->Update();
01363             }
01364         }
01365     }
01366 
01367 }
01368 
01369 //the following methods are to substitude the GLViewer KeyUp and KeyDown methods
01370 //so that tools use key events that happen globally to the preview frame
01371 //however only key up event is sent, and not key down
01372 //so until this is resolved they will remain to be handled by GLViewer
01373 void GLPreviewFrame::KeyDown(wxKeyEvent& e)
01374 {
01375     if (preview_helper) {
01376         preview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), true);
01377     }
01378     if (GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked()) {
01379         if(m_GLOverview->GetMode() == GLOverview::PLANE) {
01380             if (plane_overview_helper) {
01381                 plane_overview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), true);
01382             }
01383         } else if (m_GLOverview->GetMode() == GLOverview::PANOSPHERE) {
01384             if (panosphere_overview_helper) {
01385                 panosphere_overview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), true);
01386             }
01387         }
01388     
01389     }
01390     e.Skip();
01391 }
01392 
01393 void GLPreviewFrame::KeyUp(wxKeyEvent& e)
01394 {
01395     if (preview_helper) {
01396         preview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), false);
01397     }
01398     if (GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked()) {
01399         if(m_GLOverview->GetMode() == GLOverview::PLANE) {
01400             if (plane_overview_helper) {
01401                 plane_overview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), false);
01402             }
01403         } else if (m_GLOverview->GetMode() == GLOverview::PANOSPHERE) {
01404             if (panosphere_overview_helper) {
01405                 panosphere_overview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), false);
01406             }
01407         }
01408     
01409     }
01410     e.Skip();
01411 }
01412 
01413 
01414 
01415 void GLPreviewFrame::OnOverviewToggle(wxCommandEvent& e)
01416 {
01417     DEBUG_TRACE("overview toggle");
01418     bool toggle_on = GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked();
01419     wxAuiPaneInfo &inf = m_mgr->GetPane(wxT("overview"));
01420     if (inf.IsOk()) {
01421         if (inf.IsShown() && !toggle_on) {
01422             inf.Hide();
01423             m_GLOverview->SetActive(false);
01424             m_mgr->Update();
01425         } else if (!(inf.IsShown() && toggle_on)) {
01426             inf.Show();
01427 #if defined __WXMSW__ || defined __WXMAC__
01428             m_GLOverview->SetActive(true);
01429             m_mgr->Update();
01430 #else
01431             m_mgr->Update();
01432             m_GLOverview->SetActive(true);
01433 #endif
01434         }
01435     }
01436 }
01437 
01438 void GLPreviewFrame::OnSwitchPreviewGrid(wxCommandEvent & e)
01439 {
01440     if(GetMenuBar()->FindItem(XRCID("action_show_grid"))->IsChecked())
01441     {
01442         preview_helper->ActivateTool(preview_projection_grid);
01443         panosphere_overview_helper->ActivateTool(overview_projection_grid);
01444     }
01445     else
01446     {
01447         preview_helper->DeactivateTool(preview_projection_grid);
01448         panosphere_overview_helper->DeactivateTool(overview_projection_grid);
01449     }
01450     m_GLPreview->Refresh();
01451     m_GLOverview->Refresh();
01452 }
01453 
01454 void GLPreviewFrame::OnClose(wxCloseEvent& event)
01455 {
01456     DEBUG_TRACE("OnClose")
01457     // do not close, just hide if we're not forced
01458     if(m_guiLevel==GUI_SIMPLE)
01459     {
01460         if(!MainFrame::Get()->CloseProject(event.CanVeto()))
01461         {
01462            if (event.CanVeto())
01463            {
01464                event.Veto();
01465                return;
01466            };
01467         };
01468         MainFrame::Get()->Close(true);
01469     }
01470     else
01471     {
01472         if (event.CanVeto())
01473         {
01474             event.Veto();
01475             Hide();
01476             DEBUG_DEBUG("hiding");
01477         }
01478         else
01479         {
01480             DEBUG_DEBUG("closing");
01481             this->Destroy();
01482         }
01483     };
01484 }
01485 
01486 #if 0
01487 // need to add the wxChoice somewhere
01488 void PreviewFrame::OnProjectionChanged()
01489 {
01490     PanoramaOptions opt = m_pano.getOptions();
01491     int lt = m_ProjectionChoice->GetSelection();
01492     wxString Ip;
01493     switch ( lt ) {
01494     case PanoramaOptions::RECTILINEAR:       Ip = _("Rectilinear"); break;
01495     case PanoramaOptions::CYLINDRICAL:       Ip = _("Cylindrical"); break;
01496     case PanoramaOptions::EQUIRECTANGULAR:   Ip = _("Equirectangular"); break;
01497     }
01498     opt.projectionFormat = (PanoramaOptions::ProjectionFormat) lt;
01499     GlobalCmdHist::getInstance().addCommand(
01500         new PT::SetPanoOptionsCmd( pano, opt )
01501         );
01502     DEBUG_DEBUG ("Projection changed: "  << lt << ":" << Ip )
01503 
01504 
01505 }
01506 #endif
01507 
01508 void GLPreviewFrame::OnCenterHorizontally(wxCommandEvent & e)
01509 {
01510     if (m_pano.getActiveImages().size() == 0) return;
01511 
01512     GlobalCmdHist::getInstance().addCommand(
01513         new PT::CenterPanoCmd(m_pano)
01514         );
01515 }
01516 
01517 void GLPreviewFrame::OnStraighten(wxCommandEvent & e)
01518 {
01519     if (m_pano.getNrOfImages() == 0) return;
01520 
01521     GlobalCmdHist::getInstance().addCommand(
01522         new PT::StraightenPanoCmd(m_pano)
01523         );
01524 }
01525 
01526 void GLPreviewFrame::OnFitPano(wxCommandEvent & e)
01527 {
01528     if (m_pano.getActiveImages().size() == 0) return;
01529 
01530     DEBUG_TRACE("");
01531     PanoramaOptions opt = m_pano.getOptions();
01532 
01533     double hfov, height;
01534     m_pano.fitPano(hfov, height);
01535     opt.setHFOV(hfov);
01536     opt.setHeight(roundi(height));
01537 
01538     GlobalCmdHist::getInstance().addCommand(
01539         new PT::SetPanoOptionsCmd( m_pano, opt )
01540         );
01541 
01542     DEBUG_INFO ( "new fov: [" << opt.getHFOV() << " "<< opt.getVFOV() << "] => height: " << opt.getHeight() );
01543 }
01544 
01545 void GLPreviewFrame::OnShowAll(wxCommandEvent & e)
01546 {
01547     if (m_pano.getNrOfImages() == 0) return;
01548 
01549     DEBUG_ASSERT(m_pano.getNrOfImages() == m_ToggleButtons.size());
01550     UIntSet displayedImgs;
01551     for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
01552         displayedImgs.insert(i);
01553     }
01554     GlobalCmdHist::getInstance().addCommand(
01555         new PT::SetActiveImagesCmd(m_pano, displayedImgs)
01556         );
01557 }
01558 
01559 void GLPreviewFrame::OnShowNone(wxCommandEvent & e)
01560 {
01561     if (m_pano.getNrOfImages() == 0) return;
01562 
01563     DEBUG_ASSERT(m_pano.getNrOfImages() == m_ToggleButtons.size());
01564     for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
01565         m_ToggleButtons[i]->SetValue(false);
01566     }
01567     UIntSet displayedImgs;
01568     GlobalCmdHist::getInstance().addCommand(
01569         new PT::SetActiveImagesCmd(m_pano, displayedImgs)
01570         );
01571 }
01572 
01573 void GLPreviewFrame::OnNumTransform(wxCommandEvent & e)
01574 {
01575     if (m_pano.getNrOfImages() == 0) return;
01576 
01577     wxString text;
01578     double y;
01579     double p;
01580     double r;
01581     double x;
01582     double z;
01583 
01584     int index = m_DragModeChoice->GetSelection();
01585     switch (index) {
01586         case 0: //normal
01587         case 1: //normal, individual
01588             //@TODO limit numeric transform to selected images
01589             text = XRCCTRL(*this,"input_yaw",wxTextCtrl)->GetValue();
01590             if(!stringToDouble(std::string(text.mb_str(wxConvLocal)), y))
01591             {
01592                 wxBell();
01593                 wxMessageBox(_("Yaw value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01594                 return;
01595             }
01596             text = XRCCTRL(*this,"input_pitch",wxTextCtrl)->GetValue();
01597             if(!stringToDouble(std::string(text.mb_str(wxConvLocal)), p))
01598             {
01599                 wxBell();
01600                 wxMessageBox(_("Pitch value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01601                 return;
01602             }
01603             text = XRCCTRL(*this,"input_roll",wxTextCtrl)->GetValue();
01604             if(!stringToDouble(std::string(text.mb_str(wxConvLocal)), r))
01605             {
01606                 wxBell();
01607                 wxMessageBox(_("Roll value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01608                 return;
01609             }
01610             GlobalCmdHist::getInstance().addCommand(
01611                     new PT::RotatePanoCmd(m_pano, y, p, r)
01612                 );
01613             break;
01614         case 2: //mosaic
01615         case 3: //mosaic, individual
01616             //@TODO limit numeric transform to selected images
01617             text = XRCCTRL(*this,"input_x",wxTextCtrl)->GetValue();
01618             if(!stringToDouble(std::string(text.mb_str(wxConvLocal)), x))
01619             {
01620                 wxBell();
01621                 wxMessageBox(_("X value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01622                 return;
01623             }
01624             text = XRCCTRL(*this,"input_y",wxTextCtrl)->GetValue();
01625             if(!stringToDouble(std::string(text.mb_str(wxConvLocal)), y))
01626             {
01627                 wxBell();
01628                 wxMessageBox(_("Y value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01629                 return;
01630             }
01631             text = XRCCTRL(*this,"input_z",wxTextCtrl)->GetValue();
01632             if(!stringToDouble(std::string(text.mb_str(wxConvLocal)), z))
01633             {
01634                 wxBell();
01635                 wxMessageBox(_("Z value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01636                 return;
01637             }
01638             GlobalCmdHist::getInstance().addCommand(
01639                     new PT::TranslatePanoCmd(m_pano, x, y, z)
01640                 );
01641             break;
01642     }
01643 }
01644 
01645 void GLPreviewFrame::OnExposureChanged(wxCommandEvent & e)
01646 {
01647     PanoramaOptions opts = m_pano.getOptions();
01648     // exposure
01649     wxString text = m_exposureTextCtrl->GetValue();
01650     DEBUG_INFO ("target exposure = " << text.mb_str(wxConvLocal) );
01651     double p = 0;
01652     if (text != wxT("")) {
01653         if (!str2double(text, p)) {
01654             wxLogError(_("Value must be numeric."));
01655             return;
01656         }
01657     }
01658     opts.outputExposureValue = p;
01659     GlobalCmdHist::getInstance().addCommand(
01660             new PT::SetPanoOptionsCmd( m_pano, opts )
01661                                            );
01662 }
01663 
01664 void GLPreviewFrame::OnProjParameterChanged(wxCommandEvent & e)
01665 {
01666     PanoramaOptions opts = m_pano.getOptions();
01667     int nParam = opts.m_projFeatures.numberOfParameters;
01668     std::vector<double> para = opts.getProjectionParameters();
01669     for (int i = 0; i < nParam; i++) {
01670         if (e.GetEventObject() == m_projParamTextCtrl[i]) {
01671             wxString text = m_projParamTextCtrl[i]->GetValue();
01672             DEBUG_INFO ("param " << i << ":  = " << text.mb_str(wxConvLocal) );
01673             double p = 0;
01674             if (text != wxT("")) {
01675                 if (!str2double(text, p)) {
01676                     wxLogError(_("Value must be numeric."));
01677                     return;
01678                 }
01679             }
01680             para[i] = p;
01681         }
01682     }
01683     opts.setProjectionParameters(para);
01684     GlobalCmdHist::getInstance().addCommand(
01685             new PT::SetPanoOptionsCmd( m_pano, opts )
01686                                            );
01687 }
01688 
01689 void GLPreviewFrame::OnProjParameterReset(wxCommandEvent &e)
01690 {
01691     PanoramaOptions opts=m_pano.getOptions();
01692     opts.resetProjectionParameters();
01693     GlobalCmdHist::getInstance().addCommand(
01694         new PT::SetPanoOptionsCmd(m_pano, opts)
01695         );
01696 };
01697 
01698 void GLPreviewFrame::OnChangeFOV(wxScrollEvent & e)
01699 {
01700     DEBUG_TRACE("");
01701 
01702     PanoramaOptions opt = m_pano.getOptions();
01703 
01704     if (e.GetEventObject() == m_HFOVSlider) {
01705         DEBUG_DEBUG("HFOV changed (slider): " << e.GetInt() << " == " << m_HFOVSlider->GetValue());
01706         opt.setHFOV(e.GetInt());
01707     } else if (e.GetEventObject() == m_VFOVSlider) {
01708         DEBUG_DEBUG("VFOV changed (slider): " << e.GetInt());
01709         opt.setVFOV(e.GetInt());
01710     } else if (e.GetEventObject() == XRCCTRL(*this,"layout_scale_slider",wxSlider)) {
01711         DEBUG_DEBUG("Layout scale changed (slider): " << e.GetInt());
01712         GLPreviewFrame::OnLayoutScaleChange(e);
01713     } else {
01714         int nParam = opt.m_projFeatures.numberOfParameters;
01715         std::vector<double> para = opt.getProjectionParameters();
01716         for (int i = 0; i < nParam; i++) {
01717             if (e.GetEventObject() == m_projParamSlider[i]) {
01718                 // update
01719                 para[i] = e.GetInt();
01720             }
01721         }
01722         opt.setProjectionParameters(para);
01723                 opt.setHFOV(m_HFOVSlider->GetValue());
01724                 opt.setVFOV(m_VFOVSlider->GetValue());
01725     }
01726 
01727     GlobalCmdHist::getInstance().addCommand(
01728         new PT::SetPanoOptionsCmd( m_pano, opt )
01729         );    
01730 }
01731 
01732 void GLPreviewFrame::OnTrackChangeFOV(wxScrollEvent & e)
01733 {
01734     DEBUG_TRACE("");
01735     DEBUG_TRACE("fov change " << e.GetInt());
01736     PanoramaOptions opt = m_pano.getOptions();
01737 
01738     if (e.GetEventObject() == m_HFOVSlider) {
01739         opt.setHFOV(e.GetInt());
01740     } else if (e.GetEventObject() == m_VFOVSlider) {
01741         opt.setVFOV(e.GetInt());
01742     } else {
01743         int nParam = opt.m_projFeatures.numberOfParameters;
01744         std::vector<double> para = opt.getProjectionParameters();
01745         for (int i = 0; i < nParam; i++) {
01746             if (e.GetEventObject() == m_projParamSlider[i]) {
01747                 // update
01748                 para[i] = e.GetInt();
01749             }
01750         }
01751         opt.setProjectionParameters(para);
01752     }
01753     // we only actually update the panorama fully when the mouse is released.
01754     // As we are dragging it we don't want to create undo events, but we would
01755     // like to update the display, so we change the GLViewer's ViewState and
01756     // request a redraw.
01757     m_GLPreview->m_view_state->SetOptions(&opt);
01758     m_GLPreview->Refresh();
01759 }
01760 
01761 void GLPreviewFrame::OnBlendChoice(wxCommandEvent & e)
01762 {
01763     if (e.GetEventObject() == m_BlendModeChoice)
01764     {
01765         updateBlendMode();
01766     }
01767     else
01768     {
01769         // FIXME DEBUG_WARN("wxChoice event from unknown object received");
01770     }
01771 }
01772 
01773 void GLPreviewFrame::OnDragChoice(wxCommandEvent & e)
01774 {
01775     if (drag_tool)
01776     {
01777         DragTool::DragMode oldDragMode=drag_tool->getDragMode();
01778         DragTool::DragMode newDragMode=DragTool::drag_mode_normal;
01779         int index = m_DragModeChoice->GetSelection();
01780         switch (index) {
01781             case 0: //normal
01782             case 1:
01783                 newDragMode=DragTool::drag_mode_normal;
01784                 break;
01785             case 2: //mosaic
01786             case 3:
01787                 newDragMode=DragTool::drag_mode_mosaic;
01788                 break;
01789         }
01790         if(newDragMode==DragTool::drag_mode_mosaic)
01791         {
01792             if(HasNonZeroTranslationPlaneParameters())
01793             {
01794                 if(wxMessageBox(_("The mosaic/plane mode works only correct for a remapping plane of yaw=0 and pitch=0.\nBut your project has non-zero Tpy and Tpp parameters.\nShould the Tpy and Tpp parameters reset to zero?"),
01795 #ifdef __WXMSW__
01796                     _("Hugin"),
01797 #else
01798                     wxEmptyString,
01799 #endif
01800                     wxYES_NO | wxICON_QUESTION, this) == wxYES)
01801                 {
01802                     ResetTranslationPlaneParameters();
01803                 }
01804                 else
01805                 {
01806                     m_DragModeChoice->SetSelection(index-2);
01807                     return;
01808                 };
01809             };
01810             //switch overview mode to plane
01811             UpdateOverviewMode(1);
01812             m_OverviewModeChoice->SetSelection(1);
01813         }
01814         else
01815         {
01816             //new mode is normal
01817             //set overview back to panosphere mode
01818             UpdateOverviewMode(0);
01819             m_OverviewModeChoice->SetSelection(0);
01820             m_GLOverview->m_visualization_state->ForceRequireRedraw();
01821             m_GLOverview->m_visualization_state->SetDirtyViewport();
01822         };
01823         //update drag mode
01824         drag_tool->setDragMode(newDragMode);
01825         EnableGroupCheckboxes(individualDragging());
01826         // adjust the layout
01827         DragChoiceLayout(index);
01828     };
01829 };
01830 
01831 bool GLPreviewFrame::HasNonZeroTranslationPlaneParameters()
01832 {
01833     size_t nr = m_pano.getNrOfImages();
01834     for (size_t i = 0 ; i < nr; i++)
01835     {
01836         if (m_pano.getSrcImage(i).getTranslationPlaneYaw() != 0 ||
01837             m_pano.getSrcImage(i).getTranslationPlanePitch() != 0)
01838         {
01839             return true;
01840         };
01841     }
01842     return false;
01843 };
01844 
01845 void GLPreviewFrame::ResetTranslationPlaneParameters()
01846 {
01847     UIntSet imgs;
01848     Panorama newPan = m_pano.duplicate();
01849     size_t nr = newPan.getNrOfImages();
01850     for (size_t i = 0 ; i < nr ; i++)
01851     {
01852         SrcPanoImage img = newPan.getSrcImage(i);
01853         img.setTranslationPlaneYaw(0);
01854         img.setTranslationPlanePitch(0);
01855         newPan.setSrcImage(i,img);
01856         imgs.insert(i);
01857     }
01858     GlobalCmdHist::getInstance().addCommand(
01859         new PT::UpdateImagesVariablesCmd(m_pano, imgs, newPan.getVariables())
01860     );
01861 };
01862 
01863 bool GLPreviewFrame::UpdateOverviewMode(int newMode)
01864 {
01865     GLOverview::OverviewMode newOverviewMode=GLOverview::PANOSPHERE;
01866     if(newMode==1)
01867     {
01868         newOverviewMode=GLOverview::PLANE;
01869     };
01870     if(m_GLOverview->GetMode()==newOverviewMode)
01871     {
01872         return true;
01873     };
01874     if (m_GLOverview->GetMode() == GLOverview::PANOSPHERE)
01875     {
01876         if (!HasNonZeroTranslationPlaneParameters())
01877         {
01878             m_GLOverview->SetMode(GLOverview::PLANE);
01879             return true;
01880         }
01881         else
01882         {
01883             if(wxMessageBox(_("The mosaic/plane mode works only correct for a remapping plane of yaw=0 and pitch=0.\nBut your project has non-zero Tpy and Tpp parameters.\nShould the Tpy and Tpp parameters reset to zero?"),
01884 #ifdef __WXMSW__
01885                 _("Hugin"),
01886 #else
01887                 wxEmptyString,
01888 #endif
01889                 wxYES_NO | wxICON_QUESTION, this) == wxYES)
01890             {
01891                 ResetTranslationPlaneParameters();
01892                 m_GLOverview->SetMode(GLOverview::PLANE);
01893                 return true;
01894             }
01895             else
01896             {
01897                 return false;
01898             };
01899         };
01900     }
01901     else
01902     {
01903         m_GLOverview->SetMode(GLOverview::PANOSPHERE);
01904         return true;
01905     }
01906 };
01907 
01908 void GLPreviewFrame::OnOverviewModeChoice( wxCommandEvent & e)
01909 {
01910     if(UpdateOverviewMode(m_OverviewModeChoice->GetSelection()))
01911     {
01912         m_GLOverview->m_visualization_state->ForceRequireRedraw();
01913         m_GLOverview->m_visualization_state->SetDirtyViewport();
01914         //set drag mode to normal if new mode is panosphere mode
01915         if(m_GLOverview->GetMode()==GLOverview::PANOSPHERE && m_DragModeChoice->GetSelection()>1)
01916         {
01917             m_DragModeChoice->SetSelection(m_DragModeChoice->GetSelection()-2);
01918             OnDragChoice(e);
01919         };
01920     }
01921     else
01922     {
01923         //change mode was not successful or canceled by user, set mode choice back
01924         if(m_GLOverview->GetMode()==GLOverview::PANOSPHERE)
01925         {
01926             m_OverviewModeChoice->SetSelection(0);
01927         }
01928         else
01929         {
01930             m_OverviewModeChoice->SetSelection(1);
01931         };
01932     };
01933 };
01934 
01935 void GLPreviewFrame::DragChoiceLayout( int index )
01936 {
01937     // visibility of controls based on selected drag mode
01938     bool normalMode=index==0 || index==1;
01939     XRCCTRL(*this,"label_yaw",wxStaticText)->Show(normalMode);
01940     XRCCTRL(*this,"input_yaw",wxTextCtrl)->Show(normalMode);
01941     XRCCTRL(*this,"label_pitch",wxStaticText)->Show(normalMode);
01942     XRCCTRL(*this,"input_pitch",wxTextCtrl)->Show(normalMode);
01943     XRCCTRL(*this,"label_roll",wxStaticText)->Show(normalMode);
01944     XRCCTRL(*this,"input_roll",wxTextCtrl)->Show(normalMode);
01945     XRCCTRL(*this,"label_x",wxStaticText)->Show(!normalMode);
01946     XRCCTRL(*this,"input_x",wxTextCtrl)->Show(!normalMode);
01947     XRCCTRL(*this,"label_y",wxStaticText)->Show(!normalMode);
01948     XRCCTRL(*this,"input_y",wxTextCtrl)->Show(!normalMode);
01949     XRCCTRL(*this,"label_z",wxStaticText)->Show(!normalMode);
01950     XRCCTRL(*this,"input_z",wxTextCtrl)->Show(!normalMode);
01951     // redraw layout to compress empty space
01952     XRCCTRL(*this,"apply_num_transform",wxButton)->GetParent()->Layout();
01953 }
01954 
01955 void GLPreviewFrame::OnDefaultExposure( wxCommandEvent & e )
01956 {
01957     if (m_pano.getNrOfImages() > 0) {
01958         PanoramaOptions opt = m_pano.getOptions();
01959         opt.outputExposureValue = calcMeanExposure(m_pano);
01960         GlobalCmdHist::getInstance().addCommand(
01961                 new PT::SetPanoOptionsCmd( m_pano, opt )
01962                                                );
01963     }
01964 }
01965 
01966 void GLPreviewFrame::OnIncreaseExposure( wxSpinEvent & e )
01967 {
01968     PanoramaOptions opt = m_pano.getOptions();
01969     opt.outputExposureValue = opt.outputExposureValue + 1.0/3;
01970     GlobalCmdHist::getInstance().addCommand(
01971             new PT::SetPanoOptionsCmd( m_pano, opt )
01972                                             );
01973 }
01974 
01975 void GLPreviewFrame::OnDecreaseExposure( wxSpinEvent & e )
01976 {
01977     PanoramaOptions opt = m_pano.getOptions();
01978     opt.outputExposureValue = opt.outputExposureValue - 1.0/3;
01979     GlobalCmdHist::getInstance().addCommand(
01980             new PT::SetPanoOptionsCmd( m_pano, opt )
01981                                            );
01982 }
01983 
01984 void GLPreviewFrame::OnProjectionChoice( wxCommandEvent & e )
01985 {
01986     if (e.GetEventObject() == m_ProjectionChoice) {
01987         PanoramaOptions opt = m_pano.getOptions();
01988         int lt = m_ProjectionChoice->GetSelection();
01989         wxString Ip;
01990         opt.setProjection( (PanoramaOptions::ProjectionFormat) lt );
01991         GlobalCmdHist::getInstance().addCommand(
01992                 new PT::SetPanoOptionsCmd( m_pano, opt )
01993                                             );
01994         DEBUG_DEBUG ("Projection changed: "  << lt);
01995         m_projection_panel->Layout();
01996         Refresh();
01997     } else {
01998         // FIXME DEBUG_WARN("wxChoice event from unknown object received");
01999     }
02000 }
02001 
02002 /* We don't have an OpenGL hdr display yet
02003 void GLPreviewFrame::OnOutputChoice( wxCommandEvent & e)
02004 {
02005     if (e.GetEventObject() == m_outputModeChoice) {
02006         PanoramaOptions opt = m_pano.getOptions();
02007         int lt = m_outputModeChoice->GetSelection();
02008         wxString Ip;
02009         opt.outputMode = ( (PanoramaOptions::OutputMode) lt );
02010         GlobalCmdHist::getInstance().addCommand(
02011                 new PT::SetPanoOptionsCmd( m_pano, opt )
02012                                                );
02013 
02014     } else {
02015         // FIXME DEBUG_WARN("wxChoice event from unknown object received");
02016     }
02017 }
02018 */
02019 
02021 void GLPreviewFrame::updateProgressDisplay()
02022 {
02023     wxString msg;
02024     // build the message:
02025     for (std::vector<AppBase::ProgressTask>::iterator it = tasks.begin();
02026          it != tasks.end(); ++it)
02027     {
02028         wxString cMsg;
02029         if (it->getProgress() > 0) {
02030             cMsg.Printf(wxT("%s [%3.0f%%]: %s "),
02031                         wxString(it->getShortMessage().c_str(), wxConvLocal).c_str(),
02032                         100 * it->getProgress(),
02033                         wxString(it->getMessage().c_str(), wxConvLocal).c_str());
02034         } else {
02035             cMsg.Printf(wxT("%s %s"),wxString(it->getShortMessage().c_str(), wxConvLocal).c_str(),
02036                         wxString(it->getMessage().c_str(), wxConvLocal).c_str());
02037         }
02038         // append to main message
02039         if (it == tasks.begin()) {
02040             msg = cMsg;
02041         } else {
02042             msg.Append(wxT(" | "));
02043             msg.Append(cMsg);
02044         }
02045     }
02046 //    wxStatusBar *m_statbar = GetStatusBar();
02047     //DEBUG_TRACE("Statusmb : " << msg.mb_str(wxConvLocal));
02048     //m_statbar->SetStatusText(msg,0);
02049 
02050 #ifdef __WXMSW__
02051     UpdateWindow(NULL);
02052 #else
02053     // This is a bad call.. we just want to repaint the window, instead we will
02054     // process user events as well :( Unfortunately, there is not portable workaround...
02055 //    wxYield();
02056 #endif
02057 }
02058 
02059 void GLPreviewFrame::SetStatusMessage(wxString message)
02060 {
02061     SetStatusText(message, 0);
02062 }
02063 
02064 
02065 void GLPreviewFrame::OnPhotometric(wxCommandEvent & e)
02066 {
02067     m_GLPreview->SetPhotometricCorrect(e.IsChecked());
02068 }
02069 
02070 void GLPreviewFrame::MakePreviewTools(PreviewToolHelper *preview_helper_in)
02071 {
02072     // create the tool objects.
02073     // we delay this until we have an OpenGL context so that they are free to
02074     // create texture objects and display lists before they are used.
02075     preview_helper = preview_helper_in;
02076     crop_tool = new PreviewCropTool(preview_helper);
02077     drag_tool = new PreviewDragTool(preview_helper);
02078     color_picker_tool = new PreviewColorPickerTool(preview_helper);
02079     identify_tool = new PreviewIdentifyTool(preview_helper, this);
02080     preview_helper->ActivateTool(identify_tool);
02081     difference_tool = new PreviewDifferenceTool(preview_helper);
02082     pano_mask_tool = new PreviewPanoMaskTool(preview_helper);
02083     preview_control_point_tool = new PreviewControlPointTool(preview_helper);
02084     m_preview_layoutLinesTool = new PreviewLayoutLinesTool(preview_helper);
02085 
02086     preview_projection_grid = new PreviewProjectionGridTool(preview_helper);
02087     if(GetMenuBar()->FindItem(XRCID("action_show_grid"))->IsChecked())
02088     {
02089         preview_helper->ActivateTool(preview_projection_grid);
02090     };
02091     preview_guide_tool = new PreviewGuideTool(preview_helper);
02092     preview_guide_tool->SetGuideStyle((PreviewGuideTool::Guides)m_GuideChoiceProj->GetSelection());
02093 
02094     // activate tools that are always active.
02095     preview_helper->ActivateTool(pano_mask_tool);
02096     // update the blend mode which activates some tools
02097     updateBlendMode();
02098     m_GLPreview->SetPhotometricCorrect(true);
02099     // update toolbar
02100     SetMode(mode_assistant);
02101 }
02102 
02103 void GLPreviewFrame::MakePanosphereOverviewTools(PanosphereOverviewToolHelper *panosphere_overview_helper_in)
02104 {
02105     panosphere_overview_helper = panosphere_overview_helper_in;
02106     overview_drag_tool = new OverviewDragTool(panosphere_overview_helper);
02107     panosphere_overview_camera_tool = new PanosphereOverviewCameraTool(panosphere_overview_helper);
02108     panosphere_overview_helper->ActivateTool(panosphere_overview_camera_tool);
02109     panosphere_overview_identify_tool = new PreviewIdentifyTool(panosphere_overview_helper, this);
02110     panosphere_overview_helper->ActivateTool(panosphere_overview_identify_tool);
02111 
02112     panosphere_sphere_tool = new PanosphereSphereTool(panosphere_overview_helper, GetPreviewBackgroundColor());
02113     panosphere_overview_helper->ActivateTool(panosphere_sphere_tool);
02114     
02115     overview_projection_grid = new PanosphereOverviewProjectionGridTool(panosphere_overview_helper);
02116     if(GetMenuBar()->FindItem(XRCID("action_show_grid"))->IsChecked())
02117     {
02118         panosphere_overview_helper->ActivateTool(overview_projection_grid);
02119     }
02120     
02121     
02122     overview_outlines_tool = new PanosphereOverviewOutlinesTool(panosphere_overview_helper, m_GLPreview);
02123     panosphere_overview_helper->ActivateTool(overview_outlines_tool);
02124     panosphere_difference_tool = new PreviewDifferenceTool(panosphere_overview_helper);
02125 
02126     m_panosphere_layoutLinesTool = new PreviewLayoutLinesTool(panosphere_overview_helper);
02127     panosphere_control_point_tool = new PreviewControlPointTool(panosphere_overview_helper);
02128 
02129 
02130 
02131 }
02132 
02133 void GLPreviewFrame::MakePlaneOverviewTools(PlaneOverviewToolHelper *plane_overview_helper_in)
02134 {
02135     plane_overview_helper = plane_overview_helper_in;
02136     plane_overview_identify_tool = new PreviewIdentifyTool(plane_overview_helper, this);
02137     plane_overview_helper->ActivateTool(plane_overview_identify_tool);
02138     
02139     plane_overview_camera_tool = new PlaneOverviewCameraTool(plane_overview_helper);
02140     plane_overview_helper->ActivateTool(plane_overview_camera_tool);
02141     plane_difference_tool = new PreviewDifferenceTool(plane_overview_helper);
02142 
02143     plane_overview_outlines_tool = new PlaneOverviewOutlinesTool(plane_overview_helper, m_GLPreview);
02144     plane_overview_helper->ActivateTool(plane_overview_outlines_tool);
02145 
02146     m_plane_layoutLinesTool = new PreviewLayoutLinesTool(plane_overview_helper);
02147     plane_control_point_tool = new PreviewControlPointTool(plane_overview_helper);
02148 
02149 }
02150 
02151 void GLPreviewFrame::OnIdentify(wxCommandEvent & e)
02152 {
02153     SetStatusText(wxT(""), 0); // blank status text as it refers to an old tool.
02154     if (e.IsChecked())
02155     {
02156         m_BlendModeChoice->SetSelection(0);
02157         preview_helper->DeactivateTool(difference_tool);
02158         panosphere_overview_helper->DeactivateTool(panosphere_difference_tool);
02159         plane_overview_helper->DeactivateTool(plane_difference_tool);
02160         identify_tool->setConstantOn(true);
02161         panosphere_overview_identify_tool->setConstantOn(true);
02162         plane_overview_identify_tool->setConstantOn(true);
02163 //        TurnOffTools(preview_helper->ActivateTool(identify_tool));
02164 //        TurnOffTools(panosphere_overview_helper->ActivateTool(panosphere_overview_identify_tool));
02165 //        TurnOffTools(plane_overview_helper->ActivateTool(plane_overview_identify_tool));
02166     } else {
02167         identify_tool->setConstantOn(false);
02168         panosphere_overview_identify_tool->setConstantOn(false);
02169         plane_overview_identify_tool->setConstantOn(false);
02170 //        preview_helper->DeactivateTool(identify_tool);
02171 //        panosphere_overview_helper->DeactivateTool(panosphere_overview_identify_tool);
02172 //        plane_overview_helper->DeactivateTool(plane_overview_identify_tool);
02173         CleanButtonColours();
02174     }
02175     m_GLPreview->Refresh();
02176     m_GLOverview->Refresh();
02177 }
02178 
02179 void GLPreviewFrame::OnControlPoint(wxCommandEvent & e)
02180 {
02181     SetStatusText(wxT(""), 0); // blank status text as it refers to an old tool.
02182     if (e.IsChecked())
02183     {
02184         TurnOffTools(preview_helper->ActivateTool(preview_control_point_tool));
02185         TurnOffTools(panosphere_overview_helper->ActivateTool(panosphere_control_point_tool));
02186         TurnOffTools(plane_overview_helper->ActivateTool(plane_control_point_tool));
02187     } else {
02188         preview_helper->DeactivateTool(preview_control_point_tool);
02189         panosphere_overview_helper->DeactivateTool(panosphere_control_point_tool);
02190         plane_overview_helper->DeactivateTool(plane_control_point_tool);
02191     }
02192     m_GLPreview->Refresh();
02193     m_GLOverview->Refresh();
02194 }
02195 
02196 void GLPreviewFrame::TurnOffTools(std::set<Tool*> tools)
02197 {
02198     std::set<Tool*>::iterator i;
02199     for (i = tools.begin(); i != tools.end(); i++)
02200     {
02201         if (*i == crop_tool)
02202         {
02203             // cover up the guidelines
02204             m_GLPreview->Refresh();
02205         } else if (*i == drag_tool)
02206         {
02207             // cover up its boxes
02208             m_GLPreview->Refresh();
02209         } else if (*i == identify_tool)
02210         {
02211             // disabled the identify tool, toggle its button off.
02212             m_ToolBar_Identify->ToggleTool(XRCID("preview_identify_tool"), false);
02213             // cover up its indicators and restore normal button colours.
02214             m_GLPreview->Refresh();
02215             m_GLOverview->Refresh();
02216             CleanButtonColours();
02217         } else if (*i == preview_control_point_tool)
02218         {
02219             // disabled the control point tool.
02220             XRCCTRL(*this,"preview_control_point_tool",wxCheckBox)->SetValue(false);
02221             // cover up the control point lines.
02222             m_GLPreview->Refresh();
02223             m_GLOverview->Refresh();
02224         }
02225     }
02226 }
02227 
02228 void GLPreviewFrame::SetImageButtonColour(unsigned int image_nr,
02229                                           unsigned char red,
02230                                           unsigned char green,
02231                                           unsigned char blue)
02232 {
02233     // 0, 0, 0 indicates we want to go back to the system colour.
02234     // TODO: Maybe we should test this better on different themes.
02235     // On OS X, the background colour is ignored on toggle buttons, but not
02236     // checkboxes.
02237     if (red || green || blue)
02238     {
02239         // the identify tool wants us to highlight an image button in the given
02240         // colour, to match up with the display in the preview.
02241 #if defined __WXMSW__
02242         // on windows change the color of the surrounding wxPanel
02243         m_ToggleButtonPanel[image_nr]->SetBackgroundColour(wxColour(red, green, blue));
02244 #else
02245         // change the color of the wxToggleButton 
02246         m_ToggleButtons[image_nr]->SetBackgroundStyle(wxBG_STYLE_COLOUR);
02247         m_ToggleButtons[image_nr]->SetBackgroundColour(
02248                                                     wxColour(red, green, blue));
02249         // black should be visible on the button's vibrant colours.
02250         m_ToggleButtons[image_nr]->SetForegroundColour(wxColour(0, 0, 0));
02251 #endif
02252     } else {
02253         // return to the normal colour
02254 #if defined __WXMSW__
02255         m_ToggleButtonPanel[image_nr]->SetBackgroundColour(this->GetBackgroundColour());
02256 #else
02257         m_ToggleButtons[image_nr]->SetBackgroundStyle(wxBG_STYLE_SYSTEM);
02258         m_ToggleButtons[image_nr]->SetBackgroundColour(wxNullColour);
02259         m_ToggleButtons[image_nr]->SetForegroundColour(wxNullColour);
02260 #endif
02261     }
02262 #if defined __WXMSW__
02263     m_ToggleButtonPanel[image_nr]->Refresh();
02264 #else
02265     m_ToggleButtons[image_nr]->Refresh();
02266 #endif
02267 }
02268 
02269 void GLPreviewFrame::CleanButtonColours()
02270 {
02271     // when we turn off the identification tool, any buttons that were coloured
02272     // to match the image in the preview should be given back the system themed
02273     // colours.
02274     unsigned int nr_images = m_pano.getNrOfImages();
02275     for (unsigned image = 0; image < nr_images; image++)
02276     {
02277 #if defined __WXMSW__
02278         m_ToggleButtonPanel[image]->SetBackgroundColour(this->GetBackgroundColour());
02279         m_ToggleButtonPanel[image]->Refresh();
02280 #else
02281         m_ToggleButtons[image]->SetBackgroundStyle(wxBG_STYLE_SYSTEM);
02282         m_ToggleButtons[image]->SetBackgroundColour(wxNullColour);
02283         m_ToggleButtons[image]->SetForegroundColour(wxNullColour);
02284         m_ToggleButtons[image]->Refresh();
02285 #endif
02286     }
02287 }
02288 
02289 void GLPreviewFrame::OnColorPicker(wxCommandEvent &e)
02290 {
02291     // blank status text as it refers to an old tool.
02292     SetStatusText(wxT(""), 0); 
02293     if (e.IsChecked())
02294     {
02295         preview_helper->ActivateTool(color_picker_tool);
02296     }
02297     else
02298     {
02299         preview_helper->DeactivateTool(color_picker_tool);
02300     };
02301 };
02302 
02303 void GLPreviewFrame::UpdateGlobalWhiteBalance(double redFactor, double blueFactor)
02304 {
02305     GlobalCmdHist::getInstance().addCommand(
02306         new PT::UpdateWhiteBalance(m_pano, redFactor, blueFactor)
02307         );
02308     //now toggle button and deactivate tool
02309     XRCCTRL(*this,"preview_color_picker_toolbar",wxToolBar)->ToggleTool(XRCID("preview_color_picker_tool"),false);
02310     //direct deactivation of tool does not work because this function is called by the tool itself
02311     //so we are send an event to deactivate the tool
02312     wxCommandEvent e(wxEVT_COMMAND_TOOL_CLICKED, XRCID("preview_color_picker_tool"));
02313     e.SetInt(0);
02314     GetEventHandler()->AddPendingEvent(e);
02315 };
02316 
02317 ImageToogleButtonEventHandler::ImageToogleButtonEventHandler(
02318                                   unsigned int image_number_in,
02319                                   wxToolBarToolBase* identify_toolbutton_in,
02320                                   PT::Panorama * m_pano_in)
02321 {
02322     image_number = image_number_in;
02323     identify_toolbutton = identify_toolbutton_in;
02324     m_pano = m_pano_in;
02325 }
02326 
02327 void ImageToogleButtonEventHandler::OnEnter(wxMouseEvent & e)
02328 {
02329     // When using the identify tool, we want to identify image locations when
02330     // the user moves the mouse over the image buttons, but only if the image
02331     // is being shown.
02332     if ( 
02333         identify_toolbutton->IsToggled() && 
02334         m_pano->getActiveImages().count(image_number))
02335     {
02336         std::vector<PreviewIdentifyTool**>::iterator it;
02337         for(it = identify_tools.begin() ; it != identify_tools.end() ; it++) {
02338             (*(*it))->ShowImageNumber(image_number);
02339         }
02340     }
02341     e.Skip();
02342 }
02343 
02344 void ImageToogleButtonEventHandler::OnLeave(wxMouseEvent & e)
02345 {
02346     // if the mouse left one of the image toggle buttons with the identification
02347     // tool active, we should stop showing the image indicator for that button.
02348     if ( 
02349         identify_toolbutton->IsToggled() && 
02350         m_pano->getActiveImages().count(image_number))
02351     {
02352         std::vector<PreviewIdentifyTool**>::iterator it;
02353         for(it = identify_tools.begin() ; it != identify_tools.end() ; it++) {
02354             (*(*it))->StopShowingImages();
02355         }
02356     }
02357     e.Skip();
02358 }
02359 
02360 void ImageToogleButtonEventHandler::OnChange(wxCommandEvent & e)
02361 {
02362     // the user is turning on or off an image using its button. We want to turn
02363     // the indicators on and off if appropriate correctly to. We use OnEnter
02364     // and OnLeave for the indicators, but these only work when the image is
02365     // showing, so we are carefull of the order:
02366     UIntSet activeImages = m_pano->getActiveImages();
02367     wxMouseEvent null_event;
02368     if (e.IsChecked()) {
02369         activeImages.insert(image_number);
02370         GlobalCmdHist::getInstance().addCommand(
02371             new PT::SetActiveImagesCmd(*m_pano, activeImages)
02372         );
02373         OnEnter(null_event);
02374     } else {
02375         OnLeave(null_event);
02376         activeImages.erase(image_number);
02377         GlobalCmdHist::getInstance().addCommand(
02378             new PT::SetActiveImagesCmd(*m_pano, activeImages)
02379         );
02380     }
02381 }
02382 
02383 void ImageToogleButtonEventHandler::AddIdentifyTool(PreviewIdentifyTool** identify_tool_in) {
02384     identify_tools.push_back(identify_tool_in);
02385 }
02386 
02387 ImageGroupButtonEventHandler::ImageGroupButtonEventHandler(unsigned int image_number, GLPreviewFrame* frame_in, PT::Panorama* m_pano) 
02388     : image_number(image_number), frame(frame_in), m_pano(m_pano) {}
02389 
02390 void ImageGroupButtonEventHandler::AddIdentifyTool(PreviewIdentifyTool** identify_tool_in) {
02391     identify_tools.push_back(identify_tool_in);
02392 }
02393 
02394 
02395 void ImageGroupButtonEventHandler::OnEnter(wxMouseEvent & e)
02396 {
02397     //mark the image
02398     if (m_pano->getActiveImages().count(image_number))
02399     {
02400         std::vector<PreviewIdentifyTool**>::iterator it;
02401         for(it = identify_tools.begin() ; it != identify_tools.end() ; it++) {
02402             (*(*it))->ShowImageNumber(image_number);
02403         }
02404     }
02405     e.Skip();
02406 }
02407 
02408 void ImageGroupButtonEventHandler::OnLeave(wxMouseEvent & e)
02409 {
02410     //unmark the image
02411     if (m_pano->getActiveImages().count(image_number))
02412     {
02413         std::vector<PreviewIdentifyTool**>::iterator it;
02414         for(it = identify_tools.begin() ; it != identify_tools.end() ; it++) {
02415             (*(*it))->StopShowingImages();
02416         }
02417     }
02418     e.Skip();
02419 }
02420 
02421 void ImageGroupButtonEventHandler::OnChange(wxCommandEvent & e)
02422 {
02423     wxMouseEvent null_event;
02424     if (e.IsChecked()) {
02425         frame->AddImageToDragGroup(image_number,false);
02426         OnEnter(null_event);
02427     } else {
02428         OnLeave(null_event);
02429         frame->RemoveImageFromDragGroup(image_number,false);
02430     }
02431 }
02432 
02433 void ImageGroupButtonEventHandler::AddDragTool(DragTool** drag_tool_in) {
02434     drag_tools.push_back(drag_tool_in);
02435 }
02436 
02437 bool GLPreviewFrame::individualDragging()
02438 {
02439     return m_DragModeChoice->GetSelection()==1 || 
02440            m_DragModeChoice->GetSelection()==3;
02441 }
02442 
02443 void GLPreviewFrame::ToggleImageInDragGroup(unsigned int image_nr, bool update_check_box) {
02444     if (imageDragGroup.count(image_nr) == 0) {
02445         this->AddImageToDragGroup(image_nr, update_check_box);
02446     } else {
02447         this->RemoveImageFromDragGroup(image_nr, update_check_box);
02448     }
02449 }
02450 void GLPreviewFrame::RemoveImageFromDragGroup(unsigned int image_nr, bool update_check_box) {
02451     imageDragGroup.erase(image_nr);
02452     if (update_check_box) {
02453         m_GroupToggleButtons[image_nr]->SetValue(false);
02454     }
02455 }
02456 void GLPreviewFrame::AddImageToDragGroup(unsigned int image_nr, bool update_check_box) {
02457     imageDragGroup.insert(image_nr);
02458     if (update_check_box) {
02459         m_GroupToggleButtons[image_nr]->SetValue(true);
02460     }
02461 }
02462 void GLPreviewFrame::SetDragGroupImages(UIntSet imageDragGroup_in, bool update_check_box) {
02463     imageDragGroup.swap(imageDragGroup_in);
02464     std::vector<wxCheckBox*>::iterator it;
02465     unsigned int nr = 0;
02466     for(it = m_GroupToggleButtons.begin() ; it != m_GroupToggleButtons.end() ; it++) {
02467         (*it)->SetValue(imageDragGroup.count(nr++)>0);
02468     }
02469 }
02470 UIntSet GLPreviewFrame::GetDragGroupImages() {
02471     return imageDragGroup;
02472 }
02473 void GLPreviewFrame::ClearDragGroupImages(bool update_check_box) {
02474     imageDragGroup.clear();
02475     std::vector<wxCheckBox*>::iterator it;
02476     for(it = m_GroupToggleButtons.begin() ; it != m_GroupToggleButtons.end() ; it++) {
02477         (*it)->SetValue(false);
02478     }
02479 }
02480 
02481 void GLPreviewFrame::EnableGroupCheckboxes(bool isShown)
02482 {
02483     std::vector<wxCheckBox*>::iterator it;
02484     for(it = m_GroupToggleButtons.begin() ; it != m_GroupToggleButtons.end() ; it++)
02485     {
02486         (*it)->Show(isShown);
02487     }
02488 #ifdef __WXMSW__
02489     m_ButtonPanel->Layout();
02490     m_ButtonPanel->Refresh();
02491 #endif
02492 };
02493 
02495 void GLPreviewFrame::FillBlendChoice()
02496 {
02497     if(PreviewDifferenceTool::CheckOpenGLCanDifference())
02498         m_differenceIndex=m_BlendModeChoice->Append(_("difference"));
02499     // update size
02500     m_BlendModeChoice->InvalidateBestSize();
02501     m_BlendModeChoice->GetParent()->Layout();
02502     Refresh();
02503     // get blend mode last state
02504     unsigned int oldMode = wxConfigBase::Get()->Read(wxT("/GLPreviewFrame/blendMode"), 0l);
02505     // limit old state to max available states
02506     if (oldMode >= m_BlendModeChoice->GetCount())
02507     {
02508         oldMode = 0;
02509     }
02510     m_BlendModeChoice->SetSelection(oldMode);
02511     updateBlendMode();
02512 };
02513 
02514 void GLPreviewFrame::OnAutocrop(wxCommandEvent &e)
02515 {
02516     DEBUG_INFO("Dirty ROI Calc\n");
02517     if (m_pano.getActiveImages().size() == 0)
02518     {
02519         return;
02520     };
02521 
02522     vigra::Rect2D newROI;
02523     {
02524         ProgressReporterDialog progress(2, _("Autocrop"), _("Calculating optimal crop"),this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_ELAPSED_TIME);
02525         progress.increaseProgress(1);
02526         progress.Pulse();
02527         vigra::Size2D newSize;
02528         m_pano.calcOptimalROI(newROI, newSize);
02529     };
02530 #ifdef __WXMSW__
02531     //try to workaround an issue that the main window lost it focus after wxProgressDialog is destroyed
02532     Raise();
02533 #endif
02534 
02535     PanoramaOptions opt = m_pano.getOptions();
02536     //set the ROI - fail if the right/bottom is zero, meaning all zero
02537     if(newROI.right() != 0 && newROI.bottom() != 0)
02538     {
02539         opt.setROI(newROI);
02540         GlobalCmdHist::getInstance().addCommand(
02541             new PT::SetPanoOptionsCmd(m_pano, opt )
02542             );
02543     }
02544 }
02545 
02546 void GLPreviewFrame::OnStackAutocrop(wxCommandEvent &e)
02547 {
02548     DEBUG_INFO("Dirty ROI Calc\n");
02549     if (m_pano.getActiveImages().size() == 0)
02550     {
02551         return;
02552     };
02553 
02554     vigra::Rect2D newROI;
02555     {
02556         ProgressReporterDialog progress(2, _("Autocrop"), _("Calculating optimal crop"),this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_ELAPSED_TIME);
02557         progress.increaseProgress(1);
02558         progress.Pulse();
02559         vigra::Size2D newSize;
02560         m_pano.calcOptimalStackROI(newROI, newSize);
02561     };
02562 #ifdef __WXMSW__
02563     //try to workaround an issue that the main window lost it focus after wxProgressDialog is destroyed
02564     Raise();
02565 #endif
02566 
02567     PanoramaOptions opt = m_pano.getOptions();
02568     //set the ROI - fail if the right/bottom is zero, meaning all zero
02569     if(newROI.right() != 0 && newROI.bottom() != 0)
02570     {
02571         opt.setROI(newROI);
02572         GlobalCmdHist::getInstance().addCommand(
02573             new PT::SetPanoOptionsCmd(m_pano, opt )
02574             );
02575     }
02576 }
02577 
02578 void GLPreviewFrame::OnFullScreen(wxCommandEvent & e)
02579 {
02580     ShowFullScreen(!IsFullScreen(), wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION);
02581 };
02582 
02583 void GLPreviewFrame::SetMode(int newMode)
02584 {
02585     if(m_mode==newMode)
02586         return;
02587     SetStatusText(wxT(""), 0); // blank status text as it refers to an old tool.
02588     switch(m_mode)
02589     {
02590         case mode_assistant:
02591         case mode_preview:
02592             // switch off identify and show cp tool
02593             identify_tool->setConstantOn(false);
02594             panosphere_overview_identify_tool->setConstantOn(false);
02595             plane_overview_identify_tool->setConstantOn(false);
02596             preview_helper->DeactivateTool(color_picker_tool);
02597             XRCCTRL(*this,"preview_color_picker_toolbar",wxToolBar)->ToggleTool(XRCID("preview_color_picker_tool"),false);
02598 //            preview_helper->DeactivateTool(identify_tool);
02599 //            panosphere_overview_helper->DeactivateTool(panosphere_overview_identify_tool);
02600 //            plane_overview_helper->DeactivateTool(plane_overview_identify_tool);
02601             
02602             CleanButtonColours();
02603             m_ToolBar_Identify->ToggleTool(XRCID("preview_identify_tool"),false);
02604             preview_helper->DeactivateTool(preview_control_point_tool);
02605             panosphere_overview_helper->DeactivateTool(panosphere_control_point_tool);
02606             plane_overview_helper->DeactivateTool(plane_control_point_tool);
02607             XRCCTRL(*this,"preview_control_point_tool",wxCheckBox)->SetValue(false);
02608             break;
02609         case mode_layout:
02610             // disable layout mode.
02611             preview_helper->DeactivateTool(m_preview_layoutLinesTool);
02612             panosphere_overview_helper->DeactivateTool(m_panosphere_layoutLinesTool);
02613             plane_overview_helper->DeactivateTool(m_plane_layoutLinesTool);
02614             m_GLPreview->SetLayoutMode(false);
02615             m_GLOverview->SetLayoutMode(false);
02616             // Switch the panorama mask back on.
02617             preview_helper->ActivateTool(pano_mask_tool);
02618             //restore blend mode
02619             m_BlendModeChoice->SetSelection(non_layout_blend_mode);
02620             updateBlendMode();
02621             break;
02622         case mode_projection:
02623             preview_helper->DeactivateTool(preview_guide_tool);
02624             break;
02625         case mode_drag:
02626             preview_helper->DeactivateTool(preview_guide_tool);
02627             preview_helper->DeactivateTool(drag_tool);
02628             panosphere_overview_helper->DeactivateTool(overview_drag_tool);
02629             if (individualDragging()) {
02630                 std::vector<wxCheckBox*>::iterator it;
02631                 for(it = m_GroupToggleButtons.begin() ; it != m_GroupToggleButtons.end() ; it++) {
02632                     (*it)->Show(false);
02633                 }
02634             }
02635             break;
02636         case mode_crop:
02637             preview_helper->DeactivateTool(preview_guide_tool);
02638             preview_helper->DeactivateTool(crop_tool);
02639             break;
02640     };
02641     m_mode=newMode;
02642     wxScrollEvent dummy;
02643     switch(m_mode)
02644     {
02645         case mode_assistant:
02646         case mode_preview:
02647             break;
02648         case mode_layout:
02649             //save blend mode setting, set to normal for layout mode
02650             non_layout_blend_mode=m_BlendModeChoice->GetSelection();
02651             m_BlendModeChoice->SetSelection(0);
02652             updateBlendMode();
02653             // turn off things not used in layout mode.
02654             preview_helper->DeactivateTool(pano_mask_tool);
02655             m_GLPreview->SetLayoutMode(true);
02656             m_GLOverview->SetLayoutMode(true);
02657             preview_helper->ActivateTool(m_preview_layoutLinesTool);
02658             panosphere_overview_helper->ActivateTool(m_panosphere_layoutLinesTool);
02659             plane_overview_helper->ActivateTool(m_plane_layoutLinesTool);
02660             // we need to update the meshes after switch to layout mode
02661             // otherwise the following update of scale has no meshes to scale
02662             m_GLPreview->Update();
02663             m_GLOverview->Update();
02664             OnLayoutScaleChange(dummy);
02665             break;
02666         case mode_projection:
02667             preview_helper->ActivateTool(preview_guide_tool);
02668             break;
02669         case mode_drag:
02670             preview_helper->ActivateTool(preview_guide_tool);
02671             TurnOffTools(preview_helper->ActivateTool(drag_tool));
02672             TurnOffTools(panosphere_overview_helper->ActivateTool(overview_drag_tool));
02673             if (individualDragging()) {
02674                 std::vector<wxCheckBox*>::iterator it;
02675                 for(it = m_GroupToggleButtons.begin() ; it != m_GroupToggleButtons.end() ; it++) {
02676                     (*it)->Show(true);
02677                 }
02678             }
02679             break;
02680         case mode_crop:
02681             TurnOffTools(preview_helper->ActivateTool(crop_tool));
02682             preview_helper->ActivateTool(preview_guide_tool);
02683             break;
02684     };
02685     m_GLPreview->SetOverlayVisibility(m_mode==mode_assistant);
02686     //enable group checkboxes only for drag mode tab
02687     EnableGroupCheckboxes(m_mode==mode_drag && individualDragging());
02688     m_GLPreview->Refresh();
02689 };
02690 
02691 void GLPreviewFrame::OnSelectMode(wxNotebookEvent &e)
02692 {
02693     if(m_mode!=-1)
02694         SetMode(e.GetSelection());
02695 };
02696 
02697 void GLPreviewFrame::OnToolModeChanging(wxNotebookEvent &e)
02698 {
02699     if(m_pano.getNrOfImages()==0 && e.GetOldSelection()==0)
02700     {
02701         wxBell();
02702         e.Veto();
02703     };
02704 };
02705 
02706 void GLPreviewFrame::OnROIChanged ( wxCommandEvent & e )
02707 {
02708     PanoramaOptions opt = m_pano.getOptions();
02709     long left, right, top, bottom;
02710     if (!m_ROITopTxt->GetValue().ToLong(&top)) {
02711         wxLogError(_("Top needs to be an integer bigger than 0"));
02712         return;
02713     }
02714     if (!m_ROILeftTxt->GetValue().ToLong(&left)) {
02715         wxLogError(_("left needs to be an integer bigger than 0"));
02716         return;
02717     }
02718     if (!m_ROIRightTxt->GetValue().ToLong(&right)) {
02719         wxLogError(_("right needs to be an integer bigger than 0"));
02720         return;
02721     }
02722     if (!m_ROIBottomTxt->GetValue().ToLong(&bottom)) {
02723         wxLogError(_("bottom needs to be an integer bigger than 0"));
02724         return;
02725     }
02726     opt.setROI(vigra::Rect2D(left, top, right, bottom));
02727     // make sure that left is really to the left of right
02728     if(opt.getROI().width()<1) {
02729         wxLogError(_("left boundary must be smaller than right"));
02730         UpdateRoiDisplay(m_pano.getOptions());
02731         return;
02732     }
02733     // make sure that top is really higher than bottom
02734     if(opt.getROI().height()<1) {
02735         wxLogError(_("top boundary must be smaller than bottom"));
02736         UpdateRoiDisplay(m_pano.getOptions());
02737         return;
02738     }
02739 
02740     GlobalCmdHist::getInstance().addCommand(
02741             new PT::SetPanoOptionsCmd( m_pano, opt )
02742                                            );
02743 };
02744 
02745 void GLPreviewFrame::OnResetCrop(wxCommandEvent &e)
02746 {
02747     PanoramaOptions opt=m_pano.getOptions();
02748     opt.setROI(vigra::Rect2D(0,0,opt.getWidth(),opt.getHeight()));
02749     GlobalCmdHist::getInstance().addCommand(new PT::SetPanoOptionsCmd(m_pano,opt));
02750 };
02751 
02752 void GLPreviewFrame::OnHFOVChanged ( wxCommandEvent & e )
02753 {
02754     PanoramaOptions opt = m_pano.getOptions();
02755 
02756 
02757     wxString text = m_HFOVText->GetValue();
02758     DEBUG_INFO ("HFOV = " << text.mb_str(wxConvLocal) );
02759     if (text == wxT("")) {
02760         return;
02761     }
02762 
02763     double hfov;
02764     if (!str2double(text, hfov)) {
02765         wxLogError(_("Value must be numeric."));
02766         return;
02767     }
02768 
02769     if ( hfov <=0 || hfov > opt.getMaxHFOV()) {
02770         wxLogError(wxString::Format(
02771             _("Invalid HFOV value. Maximum HFOV for this projection is %lf."),
02772             opt.getMaxHFOV()));
02773         hfov=opt.getMaxHFOV();
02774     }
02775     opt.setHFOV(hfov);
02776     // recalculate panorama height...
02777     GlobalCmdHist::getInstance().addCommand(
02778         new PT::SetPanoOptionsCmd( m_pano, opt )
02779         );
02780 
02781     DEBUG_INFO ( "new hfov: " << hfov )
02782 };
02783 
02784 void GLPreviewFrame::OnVFOVChanged ( wxCommandEvent & e )
02785 {
02786     PanoramaOptions opt = m_pano.getOptions();
02787 
02788     wxString text = m_VFOVText->GetValue();
02789     DEBUG_INFO ("VFOV = " << text.mb_str(wxConvLocal) );
02790     if (text == wxT("")) {
02791         return;
02792     }
02793 
02794     double vfov;
02795     if (!str2double(text, vfov)) {
02796         wxLogError(_("Value must be numeric."));
02797         return;
02798     }
02799 
02800     if ( vfov <=0 || vfov > opt.getMaxVFOV()) {
02801         wxLogError(wxString::Format(
02802             _("Invalid VFOV value. Maximum VFOV for this projection is %lf."),
02803             opt.getMaxVFOV()));
02804         vfov = opt.getMaxVFOV();
02805     }
02806     opt.setVFOV(vfov);
02807     // recalculate panorama height...
02808     GlobalCmdHist::getInstance().addCommand(
02809         new PT::SetPanoOptionsCmd( m_pano, opt )
02810         );
02811 
02812     DEBUG_INFO ( "new vfov: " << vfov )
02813 };
02814 
02815 void GLPreviewFrame::OnLayoutScaleChange(wxScrollEvent &e)
02816 {
02817     if(m_mode==mode_layout)
02818     {
02819         double scale_factor=XRCCTRL(*this,"layout_scale_slider",wxSlider)->GetValue();
02820         m_GLPreview->SetLayoutScale(10.0 - sqrt(scale_factor));
02821         m_GLOverview->SetLayoutScale(10.0 - sqrt(scale_factor));
02822         m_GLPreview->Refresh();
02823         m_GLOverview->Refresh();
02824     };
02825 };
02826 
02827 void GLPreviewFrame::ShowProjectionWarnings()
02828 {
02829     PanoramaOptions opts = m_pano.getOptions();
02830     double hfov = opts.getHFOV();
02831     double vfov = opts.getVFOV();
02832     double maxfov = hfov > vfov ? hfov : vfov;
02833     wxString message;
02834     // If this is set to true, offer rectilinear as an alternative if it fits.
02835     bool rectilinear_option = false;
02836     switch (opts.getProjection()) {
02837         case HuginBase::PanoramaOptions::RECTILINEAR:
02838             if (maxfov > 120.0) {
02839                             // wide rectilinear image
02840                 message = _("With a wide field of view, panoramas with rectilinear projection get very stretched towards the edges.\n");
02841                 if (vfov < 110) {
02842                     message += _("Since the field of view is only very wide in the horizontal direction, try a cylindrical projection instead.");
02843                 } else {
02844                     message += _("For a very wide panorama, try equirectangular projection instead.");
02845                 }
02846                 message += _(" You could also try Panini projection.");
02847             }
02848             break;
02849         case HuginBase::PanoramaOptions::CYLINDRICAL:
02850             if (vfov > 120.0) {
02851                 message = _("With a wide vertical field of view, panoramas with cylindrical projection get very stretched at the top and bottom.\nAn equirectangular projection would fit the same content in less vertical space.");
02852             } else rectilinear_option = true;
02853             break;
02854         case HuginBase::PanoramaOptions::EQUIRECTANGULAR:
02855             if (vfov < 110.0 && hfov > 120.0)
02856             {
02857                 message = _("Since the vertical field of view is not too wide, you could try setting the panorama projection to cylindrical.\nCylindrical projection preserves vertical lines, unlike equirectangular.");
02858             } else rectilinear_option = true;
02859             break;
02860         case HuginBase::PanoramaOptions::FULL_FRAME_FISHEYE:
02861             if (maxfov < 280.0) {
02862                 rectilinear_option = true;
02863                 message = _("Stereographic projection is conformal, unlike this Fisheye panorama projection.\nA conformal projection preserves angles around a point, which often makes it easier on the eye.");
02864             }
02865             break;
02866         case HuginBase::PanoramaOptions::STEREOGRAPHIC:
02867             if (maxfov > 300.0) {
02868                 message = _("Panoramas with stereographic projection and a very wide field of view stretch the image around the edges a lot.\nThe Fisheye panorama projection compresses it, so you can fit in a wide field of view and still have a reasonable coverage of the middle.");
02869             } else rectilinear_option = true;
02870             break;
02871         default:
02872             rectilinear_option = true;
02873     }
02874     if (rectilinear_option && maxfov < 110.0) {
02875         message = _("Setting the panorama to rectilinear projection would keep the straight lines straight.");
02876     }
02877     if (message.IsEmpty()) {
02878         // no message needed.
02879 #if wxCHECK_VERSION(2, 9, 1)
02880         m_infoBar->Dismiss();
02881 #else
02882         if (m_projectionStatusPushed) {
02883             m_projectionStatusPushed = false;
02884             GetStatusBar()->PopStatusText();
02885         }
02886 #endif
02887     } else {
02888 #if wxCHECK_VERSION(2, 9, 1)
02889         m_infoBar->ShowMessage(message, wxICON_INFORMATION);
02890 #else
02891         if (m_projectionStatusPushed) {
02892             GetStatusBar()->PopStatusText();
02893         }
02898         GetStatusBar()->PushStatusText(message);
02899         m_projectionStatusPushed = true;
02900 #endif
02901     }
02902 };
02903 
02904 void GLPreviewFrame::SetShowProjectionHints(bool new_value)
02905 {
02906     m_showProjectionHints=new_value;
02907 #if wxCHECK_VERSION(2,9,1)
02908     if(!m_showProjectionHints)
02909     {
02910         m_infoBar->Dismiss();
02911     };
02912 #endif
02913 };
02914 
02915 void GLPreviewFrame::OnHideProjectionHints(wxCommandEvent &e)
02916 {
02917     wxMessageBox(_("You have hidden the infobar, which shows hints about selection of projection.\nIf you want to see the bar again, activate the bar in the preferences again."),
02918 #ifdef __WXMSW__
02919         _("Hugin"),
02920 #else
02921         wxT(""),
02922 #endif
02923         wxOK | wxICON_INFORMATION, this);
02924 
02925     wxConfigBase* cfg=wxConfigBase::Get();
02926     cfg->Write(wxT("/GLPreviewFrame/ShowProjectionHints"), false);
02927     m_showProjectionHints=false;
02928     cfg->Flush();
02929     e.Skip();
02930 };
02931 
02932 void GLPreviewFrame::UpdateIdentifyTools(std::set<unsigned int> new_image_set)
02933 {
02934     if(identify_tool)
02935     {
02936         identify_tool->UpdateWithNewImageSet(new_image_set);
02937     };
02938     if(panosphere_overview_identify_tool)
02939     {
02940         panosphere_overview_identify_tool->UpdateWithNewImageSet(new_image_set);
02941     };
02942     if(plane_overview_identify_tool)
02943     {
02944         plane_overview_identify_tool->UpdateWithNewImageSet(new_image_set);
02945     };
02946 }
02947 
02948 void GLPreviewFrame::OnPreviewBackgroundColorChanged(wxColourPickerEvent & e) {
02949     m_preview_background_color = XRCCTRL(*this, "preview_background", wxColourPickerCtrl)->GetColour();
02950     wxString c = m_preview_background_color.GetAsString(wxC2S_HTML_SYNTAX);
02951     wxConfigBase* cfg=wxConfigBase::Get();
02952     cfg->Write(wxT("/GLPreviewFrame/PreviewBackground"), c);
02953     cfg->Flush();
02954     panosphere_sphere_tool->SetPreviewBackgroundColor(m_preview_background_color);
02955     m_GLPreview->SetViewerBackground(m_preview_background_color);
02956     m_GLOverview->SetViewerBackground(m_preview_background_color);
02957     redrawPreview();
02958 }
02959 
02960 wxColor GLPreviewFrame::GetPreviewBackgroundColor() {
02961   return m_preview_background_color;
02962 }
02963 
02964 void GLPreviewFrame::OnGuideChanged(wxCommandEvent &e)
02965 {
02966     if(preview_guide_tool)
02967     {
02968         int selection=e.GetSelection();
02969         preview_guide_tool->SetGuideStyle((PreviewGuideTool::Guides)selection);
02970         //synchronize wxChoice in projection and crop tab
02971         m_GuideChoiceCrop->SetSelection(selection);
02972         m_GuideChoiceProj->SetSelection(selection);
02973         m_GuideChoiceDrag->SetSelection(selection);
02974         redrawPreview();
02975     };
02976 };
02977 
02978 void GLPreviewFrame::SetGuiLevel(GuiLevel newLevel)
02979 {
02980     int old_selection=m_DragModeChoice->GetSelection();
02981     if(old_selection==wxNOT_FOUND)
02982     {
02983         old_selection=0;
02984     };
02985     m_DragModeChoice->Clear();
02986     m_DragModeChoice->Append(_("normal"));
02987     m_DragModeChoice->Append(_("normal, individual"));
02988     if(newLevel==GUI_EXPERT)
02989     {
02990         m_DragModeChoice->Append(_("mosaic"));
02991         m_DragModeChoice->Append(_("mosaic, individual"));
02992         m_DragModeChoice->SetSelection(old_selection);
02993     }
02994     else
02995     {
02996         if(old_selection>1)
02997         {
02998             m_DragModeChoice->SetSelection(old_selection-2);
02999         }
03000         else
03001         {
03002             m_DragModeChoice->SetSelection(old_selection);
03003         };
03004     };
03005     DragChoiceLayout(m_DragModeChoice->GetSelection());
03006     wxCommandEvent dummy;
03007     OnDragChoice(dummy);
03008 
03009     old_selection=m_OverviewModeChoice->GetSelection();
03010     m_OverviewModeChoice->Clear();
03011     m_OverviewModeChoice->Append(_("Panosphere"));
03012     if(newLevel==GUI_EXPERT)
03013     {
03014         m_OverviewModeChoice->Append(_("Mosaic plane"));
03015     };
03016     if(newLevel==GUI_EXPERT && old_selection==1)
03017     {
03018         m_OverviewModeChoice->SetSelection(1);
03019     }
03020     else
03021     {
03022         m_GLOverview->SetMode(GLOverview::PANOSPHERE);
03023         m_OverviewModeChoice->SetSelection(0);
03024     };
03025     wxPanel* panel=XRCCTRL(*this, "overview_command_panel", wxPanel);
03026     panel->Show(newLevel==GUI_EXPERT);
03027     panel->GetParent()->Layout();
03028     if(newLevel==GUI_SIMPLE)
03029     {
03030 #ifdef __WXMAC__
03031         wxApp::s_macExitMenuItemId = XRCID("action_exit_preview");
03032 #endif
03033         if(m_guiLevel!=GUI_SIMPLE)
03034         {
03035             GetMenuBar()->Insert(0, m_filemenuSimple, _("&File"));
03036         };
03037         SetTitle(MainFrame::Get()->GetTitle());
03038     }
03039     else
03040     {
03041 #ifdef __WXMAC__
03042         wxApp::s_macExitMenuItemId = XRCID("action_exit_hugin");
03043 #endif
03044         if(m_guiLevel==GUI_SIMPLE)
03045         {
03046             GetMenuBar()->Remove(0);
03047         };
03048         SetTitle(_("Fast Panorama preview"));
03049     };
03050     m_guiLevel=newLevel;
03051     // update menu items
03052     switch(m_guiLevel)
03053     {
03054         case GUI_SIMPLE:
03055             GetMenuBar()->FindItem(XRCID("action_gui_simple"))->Check();
03056             break;
03057         case GUI_ADVANCED:
03058             GetMenuBar()->FindItem(XRCID("action_gui_advanced"))->Check();
03059             break;
03060         case GUI_EXPERT:
03061             GetMenuBar()->FindItem(XRCID("action_gui_expert"))->Check();
03062             break;
03063     };
03064 };
03065 
03066 void GLPreviewFrame::OnShowMainFrame(wxCommandEvent &e)
03067 {
03068     MainFrame::Get()->Show();
03069     MainFrame::Get()->Raise();
03070 };
03071 
03072 void GLPreviewFrame::OnUserExit(wxCommandEvent &e)
03073 {
03074     Close();
03075 };
03076 
03077 void GLPreviewFrame::OnLoadImages( wxCommandEvent & e )
03078 {
03079     // load the images.
03080     PanoOperation::AddImageOperation addImage;
03081     UIntSet images;
03082     PanoCommand* cmd=addImage.GetCommand(wxGetActiveWindow(), m_pano, images, m_guiLevel);
03083     if(cmd==NULL)
03084     {
03085         return;
03086     }
03087     //distribute images only if the existing images are not connected
03088     //otherwise it would destruct the existing image pattern
03089     bool distributeImages=m_pano.getNrOfCtrlPoints()==0;
03090 
03091     long autoAlign = wxConfigBase::Get()->Read(wxT("/Assistant/autoAlign"), HUGIN_ASS_AUTO_ALIGN); 
03092     if (autoAlign)
03093     {
03094         GlobalCmdHist::getInstance().addCommand(cmd);
03095         wxCommandEvent dummy;
03096         OnAlign(dummy);
03097     }
03098     else
03099     {
03100         std::vector<PanoCommand*> cmds;
03101         cmds.push_back(cmd);
03102         if(distributeImages)
03103         {
03104             cmds.push_back(new PT::DistributeImagesCmd(m_pano));
03105             cmds.push_back(new PT::CenterPanoCmd(m_pano));
03106         };
03107         GlobalCmdHist::getInstance().addCommand(new PT::CombinedPanoCommand(m_pano, cmds));
03108     };
03109 }
03110 
03111 void GLPreviewFrame::OnAlign( wxCommandEvent & e )
03112 {
03113     MainFrame::Get()->RunAssistant(this);
03114     // enable stitch button
03115     m_createButton->Enable();
03116 }
03117 
03118 void GLPreviewFrame::OnCreate( wxCommandEvent & e )
03119 {
03120     PanoOutputDialog dlg(this, m_pano, m_guiLevel);
03121     if(dlg.ShowModal()==wxID_OK)
03122     {
03123         GlobalCmdHist::getInstance().addCommand(
03124             new PT::SetPanoOptionsCmd(m_pano, dlg.GetNewPanoramaOptions())
03125             );
03126         wxCommandEvent dummy;
03127         MainFrame::Get()->OnDoStitch(dummy);
03128     };
03129 }
03130 
03131 void GLPreviewFrame::OnLensTypeChanged (wxCommandEvent & e)
03132 {
03133     // uses enum Lens::LensProjectionFormat from PanoramaMemento.h
03134     size_t var = GetSelectedProjection(m_lensTypeChoice);
03135     const SrcPanoImage& img=m_pano.getImage(0);
03136     if (img.getProjection() != (Lens::LensProjectionFormat) var)
03137     {
03138         double fl = SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(), img.getExifCropFactor(), img.getSize());
03139         UIntSet imgs;
03140         imgs.insert(0);
03141         std::vector<PanoCommand*> commands;
03142         commands.push_back(
03143                 new PT::ChangeImageProjectionCmd(
03144                                     m_pano,
03145                                     imgs,
03146                                     (HuginBase::SrcPanoImage::Projection) var
03147                                 )
03148             );
03149         
03150         commands.push_back(new PT::UpdateFocalLengthCmd(m_pano, imgs, fl));
03151         GlobalCmdHist::getInstance().addCommand(
03152                 new PT::CombinedPanoCommand(m_pano, commands));
03153     }
03154 }
03155 
03156 void GLPreviewFrame::OnFocalLengthChanged(wxCommandEvent & e)
03157 {
03158     if (m_pano.getNrOfImages() == 0)
03159     {
03160         return;
03161     };
03162 
03163     // always change first lens
03164     wxString text = m_focalLengthText->GetValue();
03165     DEBUG_INFO("focal length: " << text.mb_str(wxConvLocal));
03166     double val;
03167     if (!str2double(text, val))
03168     {
03169         return;
03170     }
03171     //no negative values, no zero input please
03172     if (val<0.1)
03173     {
03174         wxBell();
03175         return;
03176     };    
03177 
03178     // always change first lens...
03179     UIntSet images0;
03180     images0.insert(0);
03181     GlobalCmdHist::getInstance().addCommand(
03182         new PT::UpdateFocalLengthCmd(m_pano, images0, val)
03183     );
03184 }
03185 
03186 void GLPreviewFrame::OnCropFactorChanged(wxCommandEvent & e)
03187 {
03188     if (m_pano.getNrOfImages() == 0)
03189     {
03190         return;
03191     };
03192 
03193     wxString text = m_cropFactorText->GetValue();
03194     DEBUG_INFO("crop factor: " << text.mb_str(wxConvLocal));
03195     double val;
03196     if (!str2double(text, val))
03197     {
03198         return;
03199     }
03200     //no negative values, no zero input please
03201     if (val<0.1)
03202     {
03203         wxBell();
03204         return;
03205     };    
03206 
03207     UIntSet images;
03208     images.insert(0);
03209     GlobalCmdHist::getInstance().addCommand(
03210         new PT::UpdateCropFactorCmd(m_pano,images,val)
03211     );
03212 }
03213 

Generated on Mon Jul 28 01:25:32 2014 for Hugintrunk by  doxygen 1.3.9.1