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

Generated on Thu May 23 01:25:33 2013 for Hugintrunk by  doxygen 1.3.9.1