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

Generated on 10 Feb 2016 for Hugintrunk by  doxygen 1.4.7