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     wxString showAllLabel(_("All"));
00432     showAllLabel.Append(wxT("\u25bc"));
00433 #if wxCHECK_VERSION(2,9,2)
00434     m_selectAllButton = new wxButton(panel, ID_SHOW_ALL, showAllLabel, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
00435     m_selectAllButton->SetBitmap(bitmap, wxLEFT);
00436     m_selectAllButton->SetBitmapMargins(0, 0);
00437 #else
00438     m_selectAllButton = new wxBitmapButton(panel,ID_SHOW_ALL,bitmap);
00439 #endif
00440     m_selectAllButton->Connect(wxEVT_CONTEXT_MENU, wxContextMenuEventHandler(GLPreviewFrame::OnSelectContextMenu), NULL, this);
00441     m_selectAllMenu = wxXmlResource::Get()->LoadMenu(wxT("preview_select_menu"));
00442     // read last used setting
00443     long mode = cfg->Read(wxT("/GLPreviewFrame/SelectAllMode"), 0l);
00444     m_selectAllMode = static_cast<SelectAllMode>(mode);
00445     switch (m_selectAllMode)
00446     {
00447         case SELECT_MEDIAN_IMAGES:
00448             m_selectAllMenu->Check(XRCID("selectMenu_selectMedian"), true);
00449             break;
00450         case SELECT_DARKEST_IMAGES:
00451             m_selectAllMenu->Check(XRCID("selectMenu_selectDarkest"), true);
00452             break;
00453         case SELECT_BRIGHTEST_IMAGES:
00454             m_selectAllMenu->Check(XRCID("selectMenu_selectBrightest"), true);
00455             break;
00456         case SELECT_ALL_IMAGES:
00457         default:
00458             m_selectAllMenu->Check(XRCID("selectMenu_selectAll"), true);
00459             break;
00460     };
00461     m_selectKeepSelection = (cfg->Read(wxT("/GLPreviewFrame/SelectAllKeepSelection"), 1l) == 1l);
00462     if (m_selectKeepSelection)
00463     {
00464         m_selectAllMenu->Check(XRCID("selectMenu_keepCurrentSelection"), true);
00465     }
00466     else
00467     {
00468         m_selectAllMenu->Check(XRCID("selectMenu_resetSelection"), true);
00469     };
00470     bitmap.LoadFile(huginApp::Get()->GetXRCPath()+wxT("data/preview_show_none.png"),wxBITMAP_TYPE_PNG);
00471 #if wxCHECK_VERSION(2,9,2)
00472     wxButton* select_none=new wxButton(panel,ID_SHOW_NONE,_("None"),wxDefaultPosition,wxDefaultSize,wxBU_EXACTFIT);
00473     select_none->SetBitmap(bitmap,wxLEFT);
00474     select_none->SetBitmapMargins(0,0);
00475 #else
00476     wxBitmapButton * select_none = new wxBitmapButton(panel,ID_SHOW_NONE,bitmap);
00477     AddLabelToBitmapButton(m_selectAllButton, showAllLabel, false);
00478     AddLabelToBitmapButton(select_none,_("None"), false);
00479 #endif
00480 
00481     wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
00482     sizer->Add(m_selectAllButton,0,wxALIGN_CENTER_VERTICAL | wxLEFT | wxTOP | wxBOTTOM,5);
00483     sizer->Add(select_none,0,wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP | wxBOTTOM,5);
00484     panel->SetSizer(sizer);
00485     m_ToggleButtonSizer->Add(panel, 0, wxALIGN_CENTER_VERTICAL);
00486     m_ToggleButtonSizer->Add(m_ButtonPanel, 1, wxALIGN_CENTER_VERTICAL, 0);
00487 
00488     m_topsizer->Add(tool_panel, 0, wxEXPAND | wxALL, 2);
00489     m_topsizer->Add(toggle_panel, 0, wxEXPAND | wxBOTTOM, 5);
00490 
00491 #if wxCHECK_VERSION(2, 9, 1)
00492     m_infoBar = new wxInfoBar(this);
00493     m_infoBar->AddButton(ID_HIDE_HINTS,_("Hide"));
00494     m_infoBar->Connect(ID_HIDE_HINTS,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(GLPreviewFrame::OnHideProjectionHints),NULL,this);
00495     m_topsizer->Add(m_infoBar, 0, wxEXPAND);
00496 #endif
00497 
00498     //create panel that will hold gl canvases
00499     wxPanel * vis_panel = new wxPanel(this);
00500 
00501     wxPanel * preview_panel = new wxPanel(vis_panel);
00502     wxPanel * overview_panel = new wxPanel(vis_panel);
00503 
00504     // create our Viewers
00505     int args[] = {WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0};
00506     m_GLPreview = new GLPreview(preview_panel, pano, args, this);
00507     m_GLOverview = new GLOverview(overview_panel, pano, args, this, m_GLPreview->GetContext());
00508     m_GLOverview->SetMode(GLOverview::PANOSPHERE);
00509       
00510 #ifdef __WXGTK__
00511     // on wxGTK we can not create the OpenGL context with a hidden window
00512     // therefore we need to create the overview window open and later hide it
00513     overview_hidden=false;
00514 #endif
00515     m_GLOverview->SetActive(!overview_hidden);
00516 
00517     // set the AUI manager to our panel
00518     m_mgr = new GLwxAuiManager(this, m_GLPreview, m_GLOverview);
00519     m_mgr->SetManagedWindow(vis_panel);
00520     vis_panel->SetMinSize(wxSize(200,150));
00521     
00522     //create the sizer for the preview
00523     wxFlexGridSizer * flexSizer = new wxFlexGridSizer(2,0,5,5);
00524     flexSizer->AddGrowableCol(0);
00525     flexSizer->AddGrowableRow(0);
00526 
00527     //overview sizer
00528     wxBoxSizer * overview_sizer = new wxBoxSizer(wxVERTICAL);
00529 
00530 
00531     flexSizer->Add(m_GLPreview,
00532                   1,        // not vertically stretchable
00533                   wxEXPAND | // horizontally stretchable
00534                   wxALL,    // draw border all around
00535                   5);       // border width
00536 
00537     m_VFOVSlider = new wxSlider(preview_panel, -1, 1,
00538                                 1, 180,
00539                                 wxDefaultPosition, wxDefaultSize,
00540                                 wxSL_VERTICAL | wxSL_AUTOTICKS,
00541                                 wxDefaultValidator,
00542                                 _("VFOV"));
00543     m_VFOVSlider->SetLineSize(1);
00544     m_VFOVSlider->SetPageSize(10);
00545 #if wxCHECK_VERSION(3,0,0)
00546     m_VFOVSlider->SetTickFreq(5);
00547 #else
00548     m_VFOVSlider->SetTickFreq(5,0);
00549 #endif
00550     m_VFOVSlider->SetToolTip(_("drag to change the vertical field of view"));
00551 
00552     flexSizer->Add(m_VFOVSlider, 0, wxEXPAND);
00553 
00554     m_HFOVSlider = new wxSlider(preview_panel, -1, 1,
00555                                 1, 360,
00556                                 wxDefaultPosition, wxDefaultSize,
00557                                 wxSL_HORIZONTAL | wxSL_AUTOTICKS,
00558                                 wxDefaultValidator,
00559                                 _("HFOV"));
00560     m_HFOVSlider->SetPageSize(10);
00561     m_HFOVSlider->SetLineSize(1);
00562 #if wxCHECK_VERSION(3,0,0)
00563     m_HFOVSlider->SetTickFreq(5);
00564 #else
00565     m_HFOVSlider->SetTickFreq(5,0);
00566 #endif
00567 
00568     m_HFOVSlider->SetToolTip(_("drag to change the horizontal field of view"));
00569 
00570     m_exposureText = XRCCTRL(*this, "exposure_text", wxTextCtrl);
00571     DEBUG_ASSERT(m_exposureText);
00572     m_exposureText->PushEventHandler(new TextKillFocusHandler(this));
00573     m_HFOVText = XRCCTRL(*this, "pano_text_hfov" ,wxTextCtrl);
00574     DEBUG_ASSERT(m_HFOVText);
00575     m_HFOVText->PushEventHandler(new TextKillFocusHandler(this));
00576     m_VFOVText = XRCCTRL(*this, "pano_text_vfov" ,wxTextCtrl);
00577     DEBUG_ASSERT(m_VFOVText);
00578     m_VFOVText->PushEventHandler(new TextKillFocusHandler(this));
00579 
00580     m_ROILeftTxt = XRCCTRL(*this, "pano_val_roi_left", wxTextCtrl);
00581     DEBUG_ASSERT(m_ROILeftTxt);
00582     m_ROILeftTxt->PushEventHandler(new TextKillFocusHandler(this));
00583 
00584     m_ROIRightTxt = XRCCTRL(*this, "pano_val_roi_right", wxTextCtrl);
00585     DEBUG_ASSERT(m_ROIRightTxt);
00586     m_ROIRightTxt->PushEventHandler(new TextKillFocusHandler(this));
00587 
00588     m_ROITopTxt = XRCCTRL(*this, "pano_val_roi_top", wxTextCtrl);
00589     DEBUG_ASSERT(m_ROITopTxt);
00590     m_ROITopTxt->PushEventHandler(new TextKillFocusHandler(this));
00591 
00592     m_ROIBottomTxt = XRCCTRL(*this, "pano_val_roi_bottom", wxTextCtrl);
00593     DEBUG_ASSERT(m_ROIBottomTxt);
00594     m_ROIBottomTxt->PushEventHandler(new TextKillFocusHandler(this));
00595 
00596     m_GuideChoiceCrop = XRCCTRL(*this, "preview_guide_choice_crop", wxChoice);
00597     m_GuideChoiceProj = XRCCTRL(*this, "preview_guide_choice_proj", wxChoice);
00598     m_GuideChoiceDrag = XRCCTRL(*this, "preview_guide_choice_drag", wxChoice);
00599     int guide=cfg->Read(wxT("/GLPreviewFrame/guide"),0l);
00600     m_GuideChoiceCrop->SetSelection(guide);
00601     m_GuideChoiceProj->SetSelection(guide);
00602     m_GuideChoiceDrag->SetSelection(guide);
00603 
00604     flexSizer->Add(m_HFOVSlider, 0, wxEXPAND);
00605 
00606     wxPanel *overview_command_panel = wxXmlResource::Get()->LoadPanel(overview_panel,wxT("overview_command_panel"));
00607     m_OverviewModeChoice = XRCCTRL(*this, "overview_mode_choice", wxChoice);
00608     overview_command_panel->SetSize(0,0,200,20,wxSIZE_AUTO_WIDTH);
00609 
00610     overview_sizer->Add(overview_command_panel, 0, wxEXPAND);
00611     overview_sizer->Add(m_GLOverview, 1, wxEXPAND);
00612 
00613     bool showGrid;
00614     cfg->Read(wxT("/GLPreviewFrame/showPreviewGrid"),&showGrid,true);
00615     GetMenuBar()->FindItem(XRCID("action_show_grid"))->Check(showGrid);
00616 
00617     preview_panel->SetSizer(flexSizer);
00618     overview_panel->SetSizer(overview_sizer);
00619 
00620     m_mgr->AddPane(preview_panel, 
00621         wxAuiPaneInfo(
00622             ).Name(wxT("preview")
00623             ).MinSize(300,200
00624             ).CloseButton(false
00625             ).CaptionVisible(false
00626             ).Caption(_("Preview")
00627             ).Floatable(false
00628             ).Dockable(false
00629             ).Center(
00630             )
00631         );
00632 
00633     m_mgr->AddPane(overview_panel, 
00634         wxAuiPaneInfo(
00635             ).Name(wxT("overview")
00636             ).MinSize(300,200
00637             ).CloseButton(false
00638             ).CaptionVisible(
00639             ).Caption(_("Overview")
00640             ).FloatingSize(100,100
00641             ).FloatingPosition(500,500
00642             ).Dockable(true
00643             ).PinButton(
00644             ).Left(
00645             ).Show(!overview_hidden
00646             )
00647         );
00648 
00649 
00650     m_topsizer->Add(vis_panel, 1, wxEXPAND);
00651 
00652     //assistant related controls
00653     m_imagesText = XRCCTRL(*this, "ass_load_images_text", wxStaticText);
00654     DEBUG_ASSERT(m_imagesText);
00655 
00656     m_lensTypeChoice = XRCCTRL(*this, "ass_lens_type", wxChoice);
00657     DEBUG_ASSERT(m_lensTypeChoice);
00658     FillLensProjectionList(m_lensTypeChoice);
00659     m_lensTypeChoice->SetSelection(0);
00660 
00661     m_focalLengthText = XRCCTRL(*this, "ass_focal_length", wxTextCtrl);
00662     DEBUG_ASSERT(m_focalLengthText);
00663     m_focalLengthText->PushEventHandler(new TextKillFocusHandler(this));
00664 
00665     m_cropFactorText = XRCCTRL(*this, "ass_crop_factor", wxTextCtrl);
00666     DEBUG_ASSERT(m_cropFactorText);
00667     m_cropFactorText->PushEventHandler(new TextKillFocusHandler(this));
00668 
00669     m_alignButton = XRCCTRL(*this, "ass_align_button", wxButton);
00670     DEBUG_ASSERT(m_alignButton);
00671     m_alignButton->Disable();
00672 
00673     m_createButton = XRCCTRL(*this, "ass_create_button", wxButton);
00674     DEBUG_ASSERT(m_createButton);
00675     m_createButton->Disable();
00676 
00677     m_ProjectionChoice = XRCCTRL(*this,"projection_choice",wxChoice);
00678 
00679     /* populate with all available projection types */
00680     int nP = panoProjectionFormatCount();
00681     for(int n=0; n < nP; n++) {
00682         pano_projection_features proj;
00683         if (panoProjectionFeaturesQuery(n, &proj)) {
00684             wxString str2(proj.name, wxConvLocal);
00685             m_ProjectionChoice->Append(wxGetTranslation(str2));
00686         }
00687     }
00688     m_ProjectionChoice->SetSelection(2);
00689 
00691     // Blend mode
00692     // remaining blend mode should be added after OpenGL context has been created
00693     // see FillBlendMode()
00694     m_differenceIndex = -1;
00695     // create choice item
00696     m_BlendModeChoice = XRCCTRL(*this,"blend_mode_choice",wxChoice);
00697     m_BlendModeChoice->Append(_("normal"));
00698     m_BlendModeChoice->SetSelection(0);
00699 
00700     m_DragModeChoice = XRCCTRL(*this, "drag_mode_choice", wxChoice);
00701     SetGuiLevel(GUI_SIMPLE);
00702     bool individualDrag;
00703     cfg->Read(wxT("/GLPreviewFrame/individualDragMode"), &individualDrag, false);
00704     if(individualDrag)
00705     {
00706         m_DragModeChoice->SetSelection(1);
00707     }
00708     else
00709     {
00710         m_DragModeChoice->SetSelection(0);
00711     };
00712     // default drag mode
00713     GLPreviewFrame::DragChoiceLayout(0);
00714 
00715     // TODO implement hdr display in OpenGL, if possible?
00716     // Disabled until someone can figure out HDR display in OpenGL.
00717     /*
00719     // LDR, HDR
00720     blendModeSizer->Add(new wxStaticText(this, -1, _("Output:")),
00721                         0,        // not vertically strechable
00722                         wxALL | wxALIGN_CENTER_VERTICAL, // draw border all around
00723                         5);       // border width
00724 
00725     m_choices[0] = _("LDR");
00726     m_choices[1] = _("HDR");
00727     m_outputModeChoice = new wxChoice(this, ID_OUTPUTMODE_CHOICE,
00728                                       wxDefaultPosition, wxDefaultSize,
00729                                       2, m_choices);
00730     m_outputModeChoice->SetSelection(0);
00731     blendModeSizer->Add(m_outputModeChoice,
00732                         0,
00733                         wxALL | wxALIGN_CENTER_VERTICAL,
00734                         5);
00735     */
00736     
00738     // exposure
00739     m_defaultExposureBut = XRCCTRL(*this, "exposure_default_button", wxBitmapButton);
00740 
00741     m_exposureTextCtrl = XRCCTRL(*this, "exposure_text", wxTextCtrl);
00742     m_exposureSpinBut = XRCCTRL(*this, "exposure_spin", wxSpinButton); 
00743     m_exposureSpinBut->SetValue(0);
00744 
00745     m_projection_panel = XRCCTRL(*this, "projection_panel", wxPanel);
00746     m_projParamSizer = new wxBoxSizer(wxHORIZONTAL);
00747 
00748     wxBitmapButton * resetProjButton=new wxBitmapButton(m_projection_panel, PROJ_PARAM_RESET_ID, 
00749         wxArtProvider::GetBitmap(wxART_REDO));
00750     resetProjButton->SetToolTip(_("Resets the projection's parameters to their default values."));
00751     m_projParamSizer->Add(resetProjButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
00752 
00753     m_projParamNamesLabel.resize(PANO_PROJECTION_MAX_PARMS);
00754     m_projParamTextCtrl.resize(PANO_PROJECTION_MAX_PARMS);
00755     m_projParamSlider.resize(PANO_PROJECTION_MAX_PARMS);
00756 
00757     for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++) {
00758 
00759         wxBoxSizer* paramBoxSizer = new wxBoxSizer(wxVERTICAL);
00760         m_projParamNamesLabel[i] = new wxStaticText(m_projection_panel, PROJ_PARAM_NAMES_ID+i, _("param:"));
00761         paramBoxSizer->Add(m_projParamNamesLabel[i],
00762                         0,        // not vertically strechable
00763                         wxLEFT | wxRIGHT, // draw border all around
00764                         5);       // border width
00765         m_projParamTextCtrl[i] = new wxTextCtrl(m_projection_panel, PROJ_PARAM_VAL_ID+i, wxT("0"),
00766                                     wxDefaultPosition, wxSize(35,-1), wxTE_PROCESS_ENTER);
00767         m_projParamTextCtrl[i]->PushEventHandler(new TextKillFocusHandler(this));
00768         paramBoxSizer->Add(m_projParamTextCtrl[i],
00769                         0,        // not vertically strechable
00770                         wxLEFT | wxRIGHT, // draw border all around
00771                         5);       // border width
00772 
00773         m_projParamSizer->Add(paramBoxSizer);
00774         m_projParamSlider[i] = new wxSlider(m_projection_panel, PROJ_PARAM_SLIDER_ID+i, 0, -90, 90);
00775         m_projParamSizer->Add(m_projParamSlider[i],
00776                         1,        // not vertically strechable
00777                         wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL , // draw border all around
00778                         5);       // border width
00779     }
00780 
00781     m_projection_panel->GetSizer()->Add(m_projParamSizer, 1, wxALIGN_CENTER_VERTICAL);
00782 
00783     // do not show projection param sizer
00784     m_projection_panel->GetSizer()->Show(m_projParamSizer, false, true);
00785 
00786     // the initial size as calculated by the sizers
00787     this->SetSizer( m_topsizer );
00788     m_topsizer->SetSizeHints( this );
00789 
00790     // set the minimize icon
00791 #ifdef __WXMSW__
00792     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
00793 #else
00794     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
00795 #endif
00796     SetIcon(myIcon);
00797 
00798     m_pano.addObserver(this);
00799 
00800     RestoreFramePosition(this, wxT("GLPreviewFrame"));
00801     
00802 #ifdef __WXMSW__
00803     // wxFrame does have a strange background color on Windows..
00804     this->SetBackgroundColour(m_GLPreview->GetBackgroundColour());
00805 #endif
00806 
00807     m_showProjectionHints = cfg->Read(wxT("/GLPreviewFrame/ShowProjectionHints"), HUGIN_SHOW_PROJECTION_HINTS) == 1;
00808     m_degDigits = wxConfigBase::Get()->Read(wxT("/General/DegreeFractionalDigitsEdit"),3);
00809 
00810      // tell the manager to "commit" all the changes just made
00811     m_mgr->Update();
00812 
00813     if (cfg->Read(wxT("/GLPreviewFrame/isShown"), 0l) != 0)
00814     {
00815 #if defined __WXMSW__ || defined __WXMAC__
00816         InitPreviews();
00817         Show();
00818 #else
00819         Show();
00820         LoadOpenGLLayout();
00821 #endif
00822     }
00823     SetDropTarget(new PanoDropTarget(m_pano, true));
00824 #if defined __WXMAC__
00825     Layout();
00826     Update();
00827 #endif
00828 }
00829 
00830 void GLPreviewFrame::LoadOpenGLLayout()
00831 {
00832 #ifdef __WXGTK__
00833     if(loadedLayout)
00834     {
00835         return;
00836     };
00837     loadedLayout=true;
00838 #endif
00839     wxString OpenGLLayout=wxConfig::Get()->Read(wxT("/GLPreviewFrame/OpenGLLayout"));
00840     if(!OpenGLLayout.IsEmpty())
00841     {
00842         m_mgr->LoadPerspective(OpenGLLayout,true);
00843 #ifdef __WXGTK__
00844         if(!GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked())
00845         {
00846             wxAuiPaneInfo &inf = m_mgr->GetPane(wxT("overview"));
00847             if (inf.IsOk())
00848             {
00849                 inf.Hide();
00850             }
00851             m_GLOverview->SetActive(false);
00852         };
00853         m_mgr->Update();
00854         wxShowEvent dummy;
00855         dummy.SetShow(true);
00856         OnShowEvent(dummy);
00857 #endif
00858     };
00859     FillBlendChoice();
00860 };
00861 
00862 GLPreviewFrame::~GLPreviewFrame()
00863 {
00864     DEBUG_TRACE("dtor writing config");
00865     wxConfigBase * cfg = wxConfigBase::Get();
00866 
00867     StoreFramePosition(this, wxT("GLPreviewFrame"));
00868 
00869     if ( (!this->IsIconized()) && (! this->IsMaximized()) && this->IsShown()) {
00870         cfg->Write(wxT("/GLPreviewFrame/isShown"), 1l);
00871     } else {
00872         cfg->Write(wxT("/GLPreviewFrame/isShown"), 0l);
00873     }
00874 
00875     cfg->Write(wxT("/GLPreviewFrame/blendMode"), m_BlendModeChoice->GetSelection());
00876     cfg->Write(wxT("/GLPreviewFrame/OpenGLLayout"), m_mgr->SavePerspective());
00877     cfg->Write(wxT("/GLPreviewFrame/overview_hidden"), !(GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked()));
00878     cfg->Write(wxT("/GLPreviewFrame/showPreviewGrid"), GetMenuBar()->FindItem(XRCID("action_show_grid"))->IsChecked());
00879     cfg->Write(wxT("/GLPreviewFrame/individualDragMode"), individualDragging());
00880     cfg->Write(wxT("/GLPreviewFrame/guide"),m_GuideChoiceProj->GetSelection());
00881     
00882     // delete all of the tools. When the preview is never used we never get an
00883     // OpenGL context and therefore don't create the tools.
00884     if (crop_tool)
00885     {
00886         preview_helper->DeactivateTool(crop_tool); delete crop_tool;
00887         preview_helper->DeactivateTool(drag_tool); delete drag_tool;
00888         preview_helper->DeactivateTool(color_picker_tool); delete color_picker_tool;
00889         preview_helper->DeactivateTool(edit_cp_tool); delete edit_cp_tool;
00890         preview_helper->DeactivateTool(identify_tool); delete identify_tool;
00891         preview_helper->DeactivateTool(difference_tool); delete difference_tool;
00892         preview_helper->DeactivateTool(pano_mask_tool); delete pano_mask_tool;
00893         preview_helper->DeactivateTool(preview_control_point_tool); delete preview_control_point_tool;
00894         preview_helper->DeactivateTool(m_preview_layoutLinesTool); delete m_preview_layoutLinesTool;
00895         preview_helper->DeactivateTool(preview_projection_grid); delete preview_projection_grid;
00896         preview_helper->DeactivateTool(preview_guide_tool); delete preview_guide_tool;
00897     }
00898     if (panosphere_overview_identify_tool) {
00899         panosphere_overview_helper->DeactivateTool(overview_drag_tool); delete overview_drag_tool;
00900         panosphere_overview_helper->DeactivateTool(panosphere_overview_camera_tool); delete panosphere_overview_camera_tool;
00901         panosphere_overview_helper->DeactivateTool(panosphere_overview_identify_tool); delete panosphere_overview_identify_tool;
00902         panosphere_overview_helper->DeactivateTool(panosphere_sphere_tool); delete panosphere_sphere_tool;
00903         panosphere_overview_helper->DeactivateTool(overview_projection_grid); delete overview_projection_grid;
00904         panosphere_overview_helper->DeactivateTool(overview_outlines_tool); delete overview_outlines_tool;
00905         panosphere_overview_helper->DeactivateTool(panosphere_difference_tool); delete panosphere_difference_tool;
00906         panosphere_overview_helper->DeactivateTool(m_panosphere_layoutLinesTool); delete m_panosphere_layoutLinesTool;
00907         panosphere_overview_helper->DeactivateTool(panosphere_control_point_tool); delete panosphere_control_point_tool;
00908     }
00909     if (plane_overview_identify_tool) {
00910         plane_overview_helper->DeactivateTool(plane_overview_identify_tool); delete plane_overview_identify_tool;
00911         plane_overview_helper->DeactivateTool(plane_overview_camera_tool); delete plane_overview_camera_tool;
00912         plane_overview_helper->DeactivateTool(plane_difference_tool); delete plane_difference_tool;
00913         plane_overview_helper->DeactivateTool(plane_overview_outlines_tool); delete plane_overview_outlines_tool;
00914         plane_overview_helper->DeactivateTool(m_plane_layoutLinesTool); delete m_plane_layoutLinesTool;
00915         plane_overview_helper->DeactivateTool(plane_control_point_tool); delete plane_control_point_tool;
00916     }
00917     m_focalLengthText->PopEventHandler(true);
00918     m_cropFactorText->PopEventHandler(true);
00919     m_exposureText->PopEventHandler(true);
00920     m_HFOVText->PopEventHandler(true);
00921     m_VFOVText->PopEventHandler(true);
00922     m_ROILeftTxt->PopEventHandler(true);
00923     m_ROIRightTxt->PopEventHandler(true);
00924     m_ROITopTxt->PopEventHandler(true);
00925     m_ROIBottomTxt->PopEventHandler(true);
00926     for (int i=0; i < m_ToggleButtons.size(); i++)
00927     {
00928         m_ToggleButtons[i]->PopEventHandler(true);
00929         m_GroupToggleButtons[i]->PopEventHandler(true);
00930     }
00931     for (int i=0; i < PANO_PROJECTION_MAX_PARMS; i++)
00932     {
00933         m_projParamTextCtrl[i]->PopEventHandler(true);
00934     };
00935     m_pano.removeObserver(this);
00936 
00937      // deinitialize the frame manager
00938      m_mgr->UnInit();
00939      if (m_mgr) {
00940         delete m_mgr;
00941      }
00942      if(m_guiLevel!=GUI_SIMPLE)
00943      {
00944          delete m_filemenuSimple;
00945      }
00946      else
00947      {
00948          delete m_filemenuAdvanced;
00949      };
00950 
00951     DEBUG_TRACE("dtor end");
00952 }
00953 
00954 void GLPreviewFrame::InitPreviews()
00955 {
00956     if(preview_helper==NULL || panosphere_overview_helper==NULL || plane_overview_helper==NULL)
00957     {
00958         m_GLPreview->SetUpContext();
00959         m_GLOverview->SetUpContext();
00960         LoadOpenGLLayout();
00961     };
00962 };
00963 
00967 void GLPreviewFrame::updateBlendMode()
00968 {
00969     if (m_BlendModeChoice != NULL)
00970     {
00971         int index=m_BlendModeChoice->GetSelection();
00972         if(index==0)
00973         {
00974             // normal mode
00975             if (preview_helper != NULL 
00976                 && difference_tool != NULL)
00977             {
00978                 preview_helper->DeactivateTool(difference_tool);
00979             };
00980 
00981             if (panosphere_overview_helper != NULL 
00982                 && panosphere_difference_tool != NULL)
00983             {
00984                 panosphere_overview_helper->DeactivateTool(panosphere_difference_tool);
00985             };
00986 
00987             if (plane_overview_helper != NULL 
00988                 && plane_difference_tool != NULL)
00989             {
00990                 plane_overview_helper->DeactivateTool(plane_difference_tool);
00991             };
00992 
00993 
00994         }
00995         else
00996         {
00997             if(index==m_differenceIndex)
00998             {
00999                 // difference mode
01000                 if (preview_helper != NULL 
01001                     && identify_tool != NULL 
01002                     && difference_tool != NULL
01003                     && m_ToolBar_Identify != NULL )
01004                 {
01005                     identify_tool->setConstantOn(false);
01006 //                    preview_helper->DeactivateTool(identify_tool);
01007                     m_ToolBar_Identify->ToggleTool(XRCID("preview_identify_tool"), false);
01008                     preview_helper->ActivateTool(difference_tool);
01009                     CleanButtonColours();
01010                 };
01011 
01012                 // difference mode
01013                 if (panosphere_overview_helper != NULL 
01014                     && panosphere_overview_identify_tool != NULL 
01015                     && panosphere_difference_tool != NULL)
01016                 {
01017 //                    panosphere_overview_helper->DeactivateTool(panosphere_overview_identify_tool);
01018                     panosphere_overview_identify_tool->setConstantOn(false);
01019                     panosphere_overview_helper->ActivateTool(panosphere_difference_tool);
01020                 };
01021 
01022                 // difference mode
01023                 if (plane_overview_helper != NULL 
01024                     && plane_overview_identify_tool != NULL 
01025                     && plane_difference_tool != NULL)
01026                 {
01027 //                    plane_overview_helper->DeactivateTool(plane_overview_identify_tool);
01028                     plane_overview_identify_tool->setConstantOn(false);
01029                     plane_overview_helper->ActivateTool(plane_difference_tool);
01030                 };
01031 
01032             }
01033             else
01034             {
01035                 DEBUG_WARN("Unknown blend mode selected");
01036             };
01037         }
01038     }
01039 }
01040 
01041 void GLPreviewFrame::UpdateRoiDisplay(const HuginBase::PanoramaOptions opts)
01042 {
01043     m_ROILeftTxt->SetValue(wxString::Format(wxT("%d"), opts.getROI().left() ));
01044     m_ROIRightTxt->SetValue(wxString::Format(wxT("%d"), opts.getROI().right() ));
01045     m_ROITopTxt->SetValue(wxString::Format(wxT("%d"), opts.getROI().top() ));
01046     m_ROIBottomTxt->SetValue(wxString::Format(wxT("%d"), opts.getROI().bottom() ));
01047 };
01048 
01049 void GLPreviewFrame::panoramaChanged(HuginBase::Panorama &pano)
01050 {
01051     m_lensTypeChoice->Enable(pano.getNrOfImages()>0);
01052     m_focalLengthText->Enable(pano.getNrOfImages()>0);
01053     m_cropFactorText->Enable(pano.getNrOfImages()>0);
01054     m_alignButton->Enable(pano.getNrOfImages()>1);
01055 
01056     if(pano.getNrOfImages()==0)
01057     {
01058         m_createButton->Disable();
01059         m_imagesText->SetLabel(_("No images loaded."));
01060     }
01061     else
01062     {
01063         int images = pano.getNrOfImages();
01064         bool enableCreate = false;;
01065         if (images > 1)
01066         {
01067             while (images)
01068             {
01069                 --images;
01070                 const HuginBase::VariableMap & vars = pano.getImageVariables(images);
01071                 if (const_map_get(vars,"y").getValue() != 0.0)
01072                 {
01073                     enableCreate = true;
01074                     break;
01075                 }
01076                 if (const_map_get(vars,"p").getValue() != 0.0)
01077                 {
01078                     enableCreate = true;
01079                     break;
01080                 }
01081                 if (const_map_get(vars,"r").getValue() != 0.0)
01082                 {
01083                     enableCreate = true;
01084                     break;
01085                 }
01086             }
01087         }
01088 
01089         m_createButton->Enable(enableCreate);
01090 
01091         // in wxWidgets 2.9, format must have types that exactly match.
01092         // However std::size_t could be any unsiged integer, so we cast it to
01093         // unsigned long.int to be on the safe side.
01094         wxString imgMsg = wxString::Format(_("%lu images loaded."), (unsigned long int) pano.getNrOfImages());
01095         m_imagesText->SetLabel(imgMsg);
01096 
01097         // update data in lens display
01098         const HuginBase::SrcPanoImage& img = pano.getImage(0);
01099         SelectListValue(m_lensTypeChoice, img.getProjection());
01100         double focal_length = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(), img.getCropFactor(), img.getSize());
01101         m_focalLengthText->SetValue(hugin_utils::doubleTowxString(focal_length,m_degDigits));
01102         m_cropFactorText->SetValue(hugin_utils::doubleTowxString(img.getCropFactor(),m_degDigits));
01103     }
01104 
01105     if (pano.getNrOfImages() > 1)
01106     {
01107         // in wxWidgets 2.9, format must have types that exactly match.
01108         // However std::size_t could be any unsiged integer, so we cast it to
01109         // unsigned long.int to be on the safe side.
01110         wxString alignMsg = wxString::Format(_("Images are connected by %lu control points.\n"), (unsigned long int) pano.getCtrlPoints().size());
01111 
01112         if (m_pano.getNrOfCtrlPoints() > 0)
01113         {
01114             // find components..
01115             HuginGraph::ImageGraph graph(m_pano);
01116             const HuginGraph::ImageGraph::Components comps = graph.GetComponents();
01117             if (comps.size() > 1)
01118             {
01119                 alignMsg += wxString::Format(_("%lu unconnected image groups found: %s\n"), static_cast<unsigned long int>(comps.size()), Components2Str(comps).c_str());
01120             }
01121             else
01122             {
01123                 if (m_pano.needsOptimization())
01124                 {
01125                     alignMsg += _("Images or control points have changed, new alignment is needed.");
01126                 }
01127                 else
01128                 {
01129                     HuginBase::CalculateCPStatisticsError calcStats(m_pano, MainFrame::Get()->GetOptimizeOnlyActiveImages());
01130                     calcStats.run();
01131                     const double max = calcStats.getResultMax();
01132                     const double mean = calcStats.getResultMean();
01133 
01134                     if (max != 0.0)
01135                     {
01136                         alignMsg = alignMsg + wxString::Format(_("Mean error after optimization: %.1f pixel, max: %.1f"), mean, max); 
01137                     }
01138                 }
01139             }
01140         }
01141         XRCCTRL(*this, "ass_status_text", wxStaticText)->SetLabel(alignMsg);
01142         m_tool_notebook->GetPage(0)->Layout();
01143         Refresh();
01144     }
01145     else
01146     {
01147         XRCCTRL(*this, "ass_status_text", wxStaticText)->SetLabel(wxT(""));
01148     };
01149 
01150     GetMenuBar()->Enable(XRCID("ID_EDITUNDO"), PanoCommand::GlobalCmdHist::getInstance().canUndo());
01151     GetMenuBar()->Enable(XRCID("ID_EDITREDO"), PanoCommand::GlobalCmdHist::getInstance().canRedo());
01152 
01153     // TODO: update meaningful help text and dynamic links to relevant tabs
01154 
01155     const HuginBase::PanoramaOptions & opts = pano.getOptions();
01156 
01157     wxString projection;
01158     m_ProjectionChoice->SetSelection(opts.getProjection());
01159     m_VFOVSlider->Enable( opts.fovCalcSupported(opts.getProjection()) );
01160     
01161     // No HDR display yet.
01162     /*
01163     m_outputModeChoice->SetSelection(opts.outputMode);
01164     if (opts.outputMode == PanoramaOptions::OUTPUT_HDR) {
01165         m_exposureTextCtrl->Hide();
01166         m_defaultExposureBut->Hide();
01167         m_decExposureBut->Hide();
01168         m_incExposureBut->Hide();
01169     } else {
01170         m_exposureTextCtrl->Show();
01171         m_defaultExposureBut->Show();
01172         m_decExposureBut->Show();
01173         m_incExposureBut->Show();
01174     }*/
01175     m_exposureTextCtrl->SetValue(wxString(hugin_utils::doubleToString(opts.outputExposureValue,2).c_str(), wxConvLocal));
01176 
01177     bool activeImgs = pano.getActiveImages().size() > 0;
01178 
01179     // TODO: enable display of parameters and set their limits, if projection has some.
01180 
01181     int nParam = opts.m_projFeatures.numberOfParameters;
01182     bool relayout = false;
01183     // if the projection format has changed
01184     if (opts.getProjection() != m_oldProjFormat) {
01185         DEBUG_DEBUG("Projection format changed");
01186         if (nParam) {
01187             // show parameters and update labels.
01188             m_projection_panel->GetSizer()->Show(m_projParamSizer, true, true);
01189             int i;
01190             for (i=0; i < nParam; i++) {
01191                 const pano_projection_parameter * pp = & (opts.m_projFeatures.parm[i]);
01192                 wxString str2(pp->name, wxConvLocal);
01193                 str2 = wxGetTranslation(str2);
01194                 m_projParamNamesLabel[i]->SetLabel(str2);
01195                 m_projParamSlider[i]->SetRange(hugin_utils::roundi(pp->minValue), hugin_utils::roundi(pp->maxValue));
01196             }
01197             for(;i < PANO_PROJECTION_MAX_PARMS; i++) {
01198                 m_projParamNamesLabel[i]->Hide();
01199                 m_projParamSlider[i]->Hide();
01200                 m_projParamTextCtrl[i]->Hide();
01201             }
01202             relayout = true;
01203         } else {
01204             m_projection_panel->GetSizer()->Show(m_projParamSizer, false, true);
01205             relayout = true;
01206         }
01207     }
01208     if (nParam) {
01209         // display new values
01210         std::vector<double> params = opts.getProjectionParameters();
01211         assert((int) params.size() == nParam);
01212         for (int i=0; i < nParam; i++) {
01213             wxString val = wxString(hugin_utils::doubleToString(params[i],1).c_str(), wxConvLocal);
01214             m_projParamTextCtrl[i]->SetValue(wxString(val.wc_str(), wxConvLocal));
01215             m_projParamSlider[i]->SetValue(hugin_utils::roundi(params[i]));
01216         }
01217     }
01218     if (relayout) {
01219         m_projection_panel->Layout();
01220         Refresh();
01221     }
01222     SetStatusText(wxString::Format(wxT("%.1f x %.1f"), opts.getHFOV(), opts.getVFOV()),2);
01223     m_HFOVSlider->SetValue(hugin_utils::roundi(opts.getHFOV()));
01224     m_VFOVSlider->SetValue(hugin_utils::roundi(opts.getVFOV()));
01225     std::string val;
01226     val = hugin_utils::doubleToString(opts.getHFOV(),1);
01227     m_HFOVText->SetValue(wxString(val.c_str(), wxConvLocal));
01228     val = hugin_utils::doubleToString(opts.getVFOV(),1);
01229     m_VFOVText->SetValue(wxString(val.c_str(), wxConvLocal));
01230     m_VFOVText->Enable(opts.fovCalcSupported(opts.getProjection()));
01231 
01232     m_oldProjFormat = opts.getProjection();
01233 
01234 #if wxCHECK_VERSION(2,9,2)
01235     XRCCTRL(*this,"preview_autocrop_tool",wxButton)->Enable(activeImgs);
01236     XRCCTRL(*this,"preview_stack_autocrop_tool",wxButton)->Enable(activeImgs);
01237 #else
01238     XRCCTRL(*this,"preview_autocrop_tool",wxBitmapButton)->Enable(activeImgs);
01239     XRCCTRL(*this,"preview_stack_autocrop_tool",wxBitmapButton)->Enable(activeImgs);
01240 #endif
01241     UpdateRoiDisplay(opts);
01242     
01243     if(m_showProjectionHints)
01244     {
01245         ShowProjectionWarnings();
01246     };
01247     redrawPreview();
01248 }
01249 
01250 void GLPreviewFrame::panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &changed)
01251 {
01252     DEBUG_TRACE("");
01253 
01254     bool dirty = false;
01255 
01256     unsigned int nrImages = pano.getNrOfImages();
01257     unsigned int nrButtons = m_ToggleButtons.size();
01258     
01259     GetMenuBar()->Enable(XRCID("action_optimize"), nrImages > 0);
01260 
01261 //    m_displayedImgs.clear();
01262 
01263     // remove items for nonexisting images
01264     for (int i=nrButtons-1; i>=(int)nrImages; i--)
01265     {
01266         m_ButtonSizer->Detach(m_ToggleButtonPanel[i]);
01267         // Image toggle buttons have a event handler on the stack which
01268         // must be removed before the buttons get destroyed.
01269         m_ToggleButtons[i]->PopEventHandler();
01270         m_GroupToggleButtons[i]->PopEventHandler();
01271         delete m_ToggleButtons[i];
01272         delete m_GroupToggleButtons[i];
01273         delete m_ToggleButtonPanel[i];
01274         m_ToggleButtons.pop_back();
01275         m_GroupToggleButtons.pop_back();
01276         m_ToggleButtonPanel.pop_back();
01277         delete toogle_button_event_handlers[i];
01278         toogle_button_event_handlers.pop_back();
01279         delete toggle_group_button_event_handlers[i];
01280         toggle_group_button_event_handlers.pop_back();
01281         dirty = true;
01282     }
01283 
01284     //change overview mode to panosphere if the translation plane parameter are non zero
01285     if (m_GLOverview->GetMode() == GLOverview::PLANE)
01286     {
01287         if (HasNonZeroTranslationPlaneParameters())
01288         {
01289             m_GLOverview->SetMode(GLOverview::PANOSPHERE);
01290             m_OverviewModeChoice->SetSelection(0);
01291             //check if drag mode is mosaic, if so reset to normal
01292             if(drag_tool)
01293             {
01294                 if(drag_tool->getDragMode()==DragTool::drag_mode_mosaic)
01295                 {
01296                     m_DragModeChoice->SetSelection(m_DragModeChoice->GetSelection()-2);
01297                     drag_tool->setDragMode(DragTool::drag_mode_normal);
01298                     EnableGroupCheckboxes(individualDragging());
01299                     // adjust the layout
01300                     DragChoiceLayout(m_DragModeChoice->GetSelection());
01301                 };
01302             };
01303         }
01304     }
01305 
01306     // add buttons
01307     if ( nrImages >= nrButtons ) {
01308         for(HuginBase::UIntSet::const_iterator it = changed.begin(); it != changed.end(); ++it){
01309             if (*it >= nrButtons) {
01310                 // create new item.
01311 //                wxImage * bmp = new wxImage(sz.GetWidth(), sz.GetHeight());
01312                 //put wxToggleButton in a wxPanel because 
01313                 //on Windows the background colour of wxToggleButton can't be changed
01314                 wxPanel *pan = new wxPanel(m_ButtonPanel);
01315                 wxBoxSizer * siz = new wxBoxSizer(wxVERTICAL);
01316                 pan->SetSizer(siz);
01317 #ifdef USE_TOGGLE_BUTTON
01318                 wxToggleButton * but = new wxToggleButton(pan,
01319                                                           ID_TOGGLE_BUT + *it,
01320                                                           wxString::Format(wxT("%d"),*it),
01321                                                           wxDefaultPosition, wxDefaultSize,
01322                                                           wxBU_EXACTFIT);
01323 #else
01324                 wxCheckBox * but = new wxCheckBox(pan,
01325                                                   ID_TOGGLE_BUT + *it,
01326                                                   wxString::Format(wxT("%d"),*it));
01327 #endif
01328                 
01329                 wxCheckBox *butcheck = new wxCheckBox(pan, wxID_ANY, wxT(""));
01330 
01331 #ifdef __WXMSW__
01332                 //we need a border around the button to see the colored panel
01333                 //because changing backgroundcolor of wxToggleButton does not work in wxMSW
01334                 siz->AddSpacer(5);
01335                 siz->Add(butcheck, 0, wxALIGN_CENTRE_HORIZONTAL | wxFIXED_MINSIZE, 0);
01336                 siz->Add(but,0,wxLEFT | wxRIGHT | wxBOTTOM , 5);
01337 #else
01338                 siz->Add(but,0,wxALL ,0);
01339                 siz->Add(butcheck, 0, wxALL | wxFIXED_MINSIZE, 0);
01340 #endif
01341                 // for the identification tool to work, we need to find when the
01342                 // mouse enters and exits the button. We use a custom event
01343                 // handler, which will also toggle the images:
01344                 ImageToogleButtonEventHandler * event_handler = new
01345                     ImageToogleButtonEventHandler(*it,
01346                         m_ToolBar_Identify->FindById(XRCID("preview_identify_tool")),
01347                         &m_pano);
01348                 event_handler->AddIdentifyTool(&identify_tool);
01349                 event_handler->AddIdentifyTool(&panosphere_overview_identify_tool);
01350                 event_handler->AddIdentifyTool(&plane_overview_identify_tool);
01351                 toogle_button_event_handlers.push_back(event_handler);
01352                 but->PushEventHandler(event_handler);
01353 
01354                 ImageGroupButtonEventHandler * group_event_handler = new 
01355                     ImageGroupButtonEventHandler(*it, this, &m_pano);
01356                 group_event_handler->AddDragTool((DragTool**) &drag_tool);
01357                 group_event_handler->AddDragTool((DragTool**) &overview_drag_tool);
01358                 group_event_handler->AddIdentifyTool(&identify_tool);
01359                 group_event_handler->AddIdentifyTool(&panosphere_overview_identify_tool);
01360                 group_event_handler->AddIdentifyTool(&plane_overview_identify_tool);
01361                 toggle_group_button_event_handlers.push_back(group_event_handler);
01362                 butcheck->PushEventHandler(group_event_handler);
01363                 butcheck->Show(individualDragging() && m_mode==mode_drag);
01364 
01365                 but->SetValue(true);
01366                 m_ButtonSizer->Add(pan,
01367                                    0,
01368                                    wxLEFT | wxTOP,
01369                                    0);
01370                 m_ToggleButtons.push_back(but);
01371                 m_GroupToggleButtons.push_back(butcheck);
01372                 m_ToggleButtonPanel.push_back(pan);
01373                 dirty = true;
01374             }
01375         }
01376     }
01377 
01378     // update existing items
01379     HuginBase::UIntSet displayedImages = m_pano.getActiveImages();
01380     for (unsigned i=0; i < nrImages; i++) {
01381         m_ToggleButtons[i]->SetValue(set_contains(displayedImages, i));
01382         wxFileName tFilename(wxString (pano.getImage(i).getFilename().c_str(), HUGIN_CONV_FILENAME));
01383         m_ToggleButtons[i]->SetToolTip(tFilename.GetFullName());
01384     }
01385 
01386     if (dirty) {
01387 #if wxCHECK_VERSION(3,0,0)
01388         m_ButtonSizer->FitInside(m_ButtonPanel);
01389 #else
01390                 m_ButtonSizer->SetVirtualSizeHints(m_ButtonPanel);
01391 #endif
01392                 Layout();
01393                 DEBUG_INFO("New m_ButtonPanel width: " << (m_ButtonPanel->GetSize()).GetWidth());
01394                 DEBUG_INFO("New m_ButtonPanel Height: " << (m_ButtonPanel->GetSize()).GetHeight());
01395     }
01396     if(nrImages==0)
01397     {
01398         SetMode(mode_assistant);
01399         m_tool_notebook->ChangeSelection(mode_assistant);
01400     };
01401     for(size_t i=2; i<m_tool_notebook->GetPageCount();i++)
01402     {
01403         m_tool_notebook->GetPage(i)->Enable(nrImages!=0);
01404     };
01405     redrawPreview();
01406 }
01407 
01408 void GLPreviewFrame::redrawPreview()
01409 {
01410     m_GLPreview->Refresh();
01411     m_GLOverview->Refresh();
01412 }
01413 
01414 void GLPreviewFrame::OnShowEvent(wxShowEvent& e)
01415 {
01416 
01417     DEBUG_TRACE("OnShow");
01418     bool toggle_on = GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked();
01419     wxAuiPaneInfo &inf = m_mgr->GetPane(wxT("overview"));
01420     if (inf.IsOk()) {
01421 #if wxCHECK_VERSION(2,8,11)
01422         if (e.IsShown()) {
01423 #else
01424         if (e.GetShow()) {
01425 #endif
01426             if (!inf.IsShown() && toggle_on ) {
01427                 inf.Show();
01428                 m_mgr->Update();
01429             }
01430         } else {
01431             if (inf.IsFloating() && inf.IsShown()) {
01432                 DEBUG_DEBUG("hiding overview float");
01433                 inf.Hide();
01434                 m_mgr->Update();
01435             }
01436         }
01437     }
01438 
01439 }
01440 
01441 //the following methods are to substitude the GLViewer KeyUp and KeyDown methods
01442 //so that tools use key events that happen globally to the preview frame
01443 //however only key up event is sent, and not key down
01444 //so until this is resolved they will remain to be handled by GLViewer
01445 void GLPreviewFrame::KeyDown(wxKeyEvent& e)
01446 {
01447     if (preview_helper) {
01448         preview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), true);
01449     }
01450     if (GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked()) {
01451         if(m_GLOverview->GetMode() == GLOverview::PLANE) {
01452             if (plane_overview_helper) {
01453                 plane_overview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), true);
01454             }
01455         } else if (m_GLOverview->GetMode() == GLOverview::PANOSPHERE) {
01456             if (panosphere_overview_helper) {
01457                 panosphere_overview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), true);
01458             }
01459         }
01460     
01461     }
01462     e.Skip();
01463 }
01464 
01465 void GLPreviewFrame::KeyUp(wxKeyEvent& e)
01466 {
01467     if (preview_helper) {
01468         preview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), false);
01469     }
01470     if (GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked()) {
01471         if(m_GLOverview->GetMode() == GLOverview::PLANE) {
01472             if (plane_overview_helper) {
01473                 plane_overview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), false);
01474             }
01475         } else if (m_GLOverview->GetMode() == GLOverview::PANOSPHERE) {
01476             if (panosphere_overview_helper) {
01477                 panosphere_overview_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), false);
01478             }
01479         }
01480     
01481     }
01482     e.Skip();
01483 }
01484 
01485 
01486 
01487 void GLPreviewFrame::OnOverviewToggle(wxCommandEvent& e)
01488 {
01489     DEBUG_TRACE("overview toggle");
01490     bool toggle_on = GetMenuBar()->FindItem(XRCID("action_show_overview"))->IsChecked();
01491     wxAuiPaneInfo &inf = m_mgr->GetPane(wxT("overview"));
01492     if (inf.IsOk()) {
01493         if (inf.IsShown() && !toggle_on) {
01494             inf.Hide();
01495             m_GLOverview->SetActive(false);
01496             m_mgr->Update();
01497         } else if (!(inf.IsShown() && toggle_on)) {
01498             inf.Show();
01499 #if defined __WXMSW__ || defined __WXMAC__
01500             m_GLOverview->SetActive(true);
01501             m_mgr->Update();
01502 #else
01503             m_mgr->Update();
01504             m_GLOverview->SetActive(true);
01505 #endif
01506         }
01507     }
01508 }
01509 
01510 void GLPreviewFrame::OnSwitchPreviewGrid(wxCommandEvent & e)
01511 {
01512     if(GetMenuBar()->FindItem(XRCID("action_show_grid"))->IsChecked())
01513     {
01514         preview_helper->ActivateTool(preview_projection_grid);
01515         panosphere_overview_helper->ActivateTool(overview_projection_grid);
01516     }
01517     else
01518     {
01519         preview_helper->DeactivateTool(preview_projection_grid);
01520         panosphere_overview_helper->DeactivateTool(overview_projection_grid);
01521     }
01522     m_GLPreview->Refresh();
01523     m_GLOverview->Refresh();
01524 }
01525 
01526 void GLPreviewFrame::OnClose(wxCloseEvent& event)
01527 {
01528     DEBUG_TRACE("OnClose")
01529     // do not close, just hide if we're not forced
01530     if(m_guiLevel==GUI_SIMPLE)
01531     {
01532         if(!MainFrame::Get()->CloseProject(event.CanVeto()))
01533         {
01534            if (event.CanVeto())
01535            {
01536                event.Veto();
01537                return;
01538            };
01539         };
01540         MainFrame::Get()->Close(true);
01541     }
01542     else
01543     {
01544         if (event.CanVeto())
01545         {
01546             event.Veto();
01547             Hide();
01548             DEBUG_DEBUG("hiding");
01549         }
01550         else
01551         {
01552             DEBUG_DEBUG("closing");
01553             this->Destroy();
01554         }
01555     };
01556 }
01557 
01558 #if 0
01559 // need to add the wxChoice somewhere
01560 void PreviewFrame::OnProjectionChanged()
01561 {
01562     PanoramaOptions opt = m_pano.getOptions();
01563     int lt = m_ProjectionChoice->GetSelection();
01564     wxString Ip;
01565     switch ( lt ) {
01566     case PanoramaOptions::RECTILINEAR:       Ip = _("Rectilinear"); break;
01567     case PanoramaOptions::CYLINDRICAL:       Ip = _("Cylindrical"); break;
01568     case PanoramaOptions::EQUIRECTANGULAR:   Ip = _("Equirectangular"); break;
01569     }
01570     opt.projectionFormat = (PanoramaOptions::ProjectionFormat) lt;
01571     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01572         new PanoCommand::SetPanoOptionsCmd( pano, opt )
01573         );
01574     DEBUG_DEBUG ("Projection changed: "  << lt << ":" << Ip )
01575 
01576 
01577 }
01578 #endif
01579 
01580 void GLPreviewFrame::OnCenterHorizontally(wxCommandEvent & e)
01581 {
01582     if (m_pano.getActiveImages().size() == 0) return;
01583 
01584     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01585         new PanoCommand::CenterPanoCmd(m_pano)
01586         );
01587 }
01588 
01589 void GLPreviewFrame::OnStraighten(wxCommandEvent & e)
01590 {
01591     if (m_pano.getNrOfImages() == 0) return;
01592 
01593     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01594         new PanoCommand::StraightenPanoCmd(m_pano)
01595         );
01596 }
01597 
01598 void GLPreviewFrame::OnFitPano(wxCommandEvent & e)
01599 {
01600     if (m_pano.getActiveImages().size() == 0) return;
01601 
01602     DEBUG_TRACE("");
01603     HuginBase::PanoramaOptions opt = m_pano.getOptions();
01604     HuginBase::CalculateFitPanorama fitPano(m_pano);
01605     fitPano.run();
01606     opt.setHFOV(fitPano.getResultHorizontalFOV());
01607     opt.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
01608 
01609     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01610         new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
01611         );
01612 
01613     DEBUG_INFO ( "new fov: [" << opt.getHFOV() << " "<< opt.getVFOV() << "] => height: " << opt.getHeight() );
01614 }
01615 
01616 void GLPreviewFrame::OnShowAll(wxCommandEvent & e)
01617 {
01618     if (m_pano.getNrOfImages() == 0) return;
01619 
01620     HuginBase::UIntSet displayedImgs;
01621     if (m_selectAllMode == SELECT_ALL_IMAGES)
01622     {
01623         fill_set(displayedImgs, 0, m_pano.getNrOfImages() - 1);
01624     }
01625     else
01626     {
01627         if (m_selectKeepSelection)
01628         {
01629             displayedImgs = m_pano.getActiveImages();
01630         };
01631         std::vector<HuginBase::UIntVector> stackedImg = HuginBase::getSortedStacks(&m_pano);
01632         for (size_t i = 0; i < stackedImg.size(); ++i)
01633         {
01634             switch (m_selectAllMode)
01635             {
01636                 case SELECT_BRIGHTEST_IMAGES:
01637                     displayedImgs.insert(*(stackedImg[i].rbegin()));
01638                     break;
01639                 case SELECT_DARKEST_IMAGES:
01640                     displayedImgs.insert(*(stackedImg[i].begin()));
01641                     break;
01642                 case SELECT_MEDIAN_IMAGES:
01643                 default:
01644                     displayedImgs.insert(stackedImg[i][stackedImg[i].size() / 2]);
01645                     break;
01646             };
01647         };
01648     };
01649     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01650         new PanoCommand::SetActiveImagesCmd(m_pano, displayedImgs)
01651         );
01652 }
01653 
01654 void GLPreviewFrame::OnShowNone(wxCommandEvent & e)
01655 {
01656     if (m_pano.getNrOfImages() == 0) return;
01657 
01658     DEBUG_ASSERT(m_pano.getNrOfImages() == m_ToggleButtons.size());
01659     for (unsigned int i=0; i < m_pano.getNrOfImages(); i++) {
01660         m_ToggleButtons[i]->SetValue(false);
01661     }
01662     HuginBase::UIntSet displayedImgs;
01663     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01664         new PanoCommand::SetActiveImagesCmd(m_pano, displayedImgs)
01665         );
01666 }
01667 
01668 void GLPreviewFrame::OnNumTransform(wxCommandEvent & e)
01669 {
01670     if (m_pano.getNrOfImages() == 0) return;
01671 
01672     wxString text;
01673     double y;
01674     double p;
01675     double r;
01676     double x;
01677     double z;
01678 
01679     int index = m_DragModeChoice->GetSelection();
01680     switch (index) {
01681         case 0: //normal
01682         case 1: //normal, individual
01683             //@TODO limit numeric transform to selected images
01684             text = XRCCTRL(*this,"input_yaw",wxTextCtrl)->GetValue();
01685             if(!hugin_utils::stringToDouble(std::string(text.mb_str(wxConvLocal)), y))
01686             {
01687                 wxBell();
01688                 wxMessageBox(_("Yaw value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01689                 return;
01690             }
01691             text = XRCCTRL(*this,"input_pitch",wxTextCtrl)->GetValue();
01692             if (!hugin_utils::stringToDouble(std::string(text.mb_str(wxConvLocal)), p))
01693             {
01694                 wxBell();
01695                 wxMessageBox(_("Pitch value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01696                 return;
01697             }
01698             text = XRCCTRL(*this,"input_roll",wxTextCtrl)->GetValue();
01699             if (!hugin_utils::stringToDouble(std::string(text.mb_str(wxConvLocal)), r))
01700             {
01701                 wxBell();
01702                 wxMessageBox(_("Roll value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01703                 return;
01704             }
01705             PanoCommand::GlobalCmdHist::getInstance().addCommand(
01706                     new PanoCommand::RotatePanoCmd(m_pano, y, p, r)
01707                 );
01708             break;
01709         case 2: //mosaic
01710         case 3: //mosaic, individual
01711             //@TODO limit numeric transform to selected images
01712             text = XRCCTRL(*this,"input_x",wxTextCtrl)->GetValue();
01713             if (!hugin_utils::stringToDouble(std::string(text.mb_str(wxConvLocal)), x))
01714             {
01715                 wxBell();
01716                 wxMessageBox(_("X value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01717                 return;
01718             }
01719             text = XRCCTRL(*this,"input_y",wxTextCtrl)->GetValue();
01720             if (!hugin_utils::stringToDouble(std::string(text.mb_str(wxConvLocal)), y))
01721             {
01722                 wxBell();
01723                 wxMessageBox(_("Y value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01724                 return;
01725             }
01726             text = XRCCTRL(*this,"input_z",wxTextCtrl)->GetValue();
01727             if(!hugin_utils::stringToDouble(std::string(text.mb_str(wxConvLocal)), z))
01728             {
01729                 wxBell();
01730                 wxMessageBox(_("Z value must be numeric."),_("Warning"),wxOK | wxICON_ERROR,this);
01731                 return;
01732             }
01733             PanoCommand::GlobalCmdHist::getInstance().addCommand(
01734                     new PanoCommand::TranslatePanoCmd(m_pano, x, y, z)
01735                 );
01736             break;
01737     }
01738 }
01739 
01740 void GLPreviewFrame::OnExposureChanged(wxCommandEvent & e)
01741 {
01742     HuginBase::PanoramaOptions opts = m_pano.getOptions();
01743     // exposure
01744     wxString text = m_exposureTextCtrl->GetValue();
01745     DEBUG_INFO ("target exposure = " << text.mb_str(wxConvLocal) );
01746     double p = 0;
01747     if (text != wxT("")) {
01748         if (!hugin_utils::str2double(text, p)) {
01749             wxLogError(_("Value must be numeric."));
01750             return;
01751         }
01752     }
01753     opts.outputExposureValue = p;
01754     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01755             new PanoCommand::SetPanoOptionsCmd( m_pano, opts )
01756                                            );
01757 }
01758 
01759 void GLPreviewFrame::OnProjParameterChanged(wxCommandEvent & e)
01760 {
01761     HuginBase::PanoramaOptions opts = m_pano.getOptions();
01762     int nParam = opts.m_projFeatures.numberOfParameters;
01763     std::vector<double> para = opts.getProjectionParameters();
01764     for (int i = 0; i < nParam; i++) {
01765         if (e.GetEventObject() == m_projParamTextCtrl[i]) {
01766             wxString text = m_projParamTextCtrl[i]->GetValue();
01767             DEBUG_INFO ("param " << i << ":  = " << text.mb_str(wxConvLocal) );
01768             double p = 0;
01769             if (text != wxT("")) {
01770                 if (!hugin_utils::str2double(text, p)) {
01771                     wxLogError(_("Value must be numeric."));
01772                     return;
01773                 }
01774             }
01775             para[i] = p;
01776         }
01777     }
01778     opts.setProjectionParameters(para);
01779     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01780             new PanoCommand::SetPanoOptionsCmd( m_pano, opts )
01781                                            );
01782 }
01783 
01784 void GLPreviewFrame::OnProjParameterReset(wxCommandEvent &e)
01785 {
01786     HuginBase::PanoramaOptions opts = m_pano.getOptions();
01787     opts.resetProjectionParameters();
01788     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01789         new PanoCommand::SetPanoOptionsCmd(m_pano, opts)
01790         );
01791 };
01792 
01793 void GLPreviewFrame::OnChangeFOV(wxScrollEvent & e)
01794 {
01795     DEBUG_TRACE("");
01796 
01797     HuginBase::PanoramaOptions opt = m_pano.getOptions();
01798 
01799     if (e.GetEventObject() == m_HFOVSlider) {
01800         DEBUG_DEBUG("HFOV changed (slider): " << e.GetInt() << " == " << m_HFOVSlider->GetValue());
01801         opt.setHFOV(e.GetInt());
01802     } else if (e.GetEventObject() == m_VFOVSlider) {
01803         DEBUG_DEBUG("VFOV changed (slider): " << e.GetInt());
01804         opt.setVFOV(e.GetInt());
01805     } else if (e.GetEventObject() == XRCCTRL(*this,"layout_scale_slider",wxSlider)) {
01806         DEBUG_DEBUG("Layout scale changed (slider): " << e.GetInt());
01807         GLPreviewFrame::OnLayoutScaleChange(e);
01808     } else {
01809         int nParam = opt.m_projFeatures.numberOfParameters;
01810         std::vector<double> para = opt.getProjectionParameters();
01811         for (int i = 0; i < nParam; i++) {
01812             if (e.GetEventObject() == m_projParamSlider[i]) {
01813                 // update
01814                 para[i] = e.GetInt();
01815             }
01816         }
01817         opt.setProjectionParameters(para);
01818                 opt.setHFOV(m_HFOVSlider->GetValue());
01819                 opt.setVFOV(m_VFOVSlider->GetValue());
01820     }
01821 
01822     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01823         new PanoCommand::SetPanoOptionsCmd( m_pano, opt )
01824         );    
01825 }
01826 
01827 void GLPreviewFrame::OnTrackChangeFOV(wxScrollEvent & e)
01828 {
01829     DEBUG_TRACE("");
01830     DEBUG_TRACE("fov change " << e.GetInt());
01831     HuginBase::PanoramaOptions opt = m_pano.getOptions();
01832 
01833     if (e.GetEventObject() == m_HFOVSlider) {
01834         opt.setHFOV(e.GetInt());
01835     } else if (e.GetEventObject() == m_VFOVSlider) {
01836         opt.setVFOV(e.GetInt());
01837     } else {
01838         int nParam = opt.m_projFeatures.numberOfParameters;
01839         std::vector<double> para = opt.getProjectionParameters();
01840         for (int i = 0; i < nParam; i++) {
01841             if (e.GetEventObject() == m_projParamSlider[i]) {
01842                 // update
01843                 para[i] = e.GetInt();
01844             }
01845         }
01846         opt.setProjectionParameters(para);
01847     }
01848     // we only actually update the panorama fully when the mouse is released.
01849     // As we are dragging it we don't want to create undo events, but we would
01850     // like to update the display, so we change the GLViewer's ViewState and
01851     // request a redraw.
01852     m_GLPreview->m_view_state->SetOptions(&opt);
01853     m_GLPreview->Refresh();
01854 }
01855 
01856 void GLPreviewFrame::OnBlendChoice(wxCommandEvent & e)
01857 {
01858     if (e.GetEventObject() == m_BlendModeChoice)
01859     {
01860         updateBlendMode();
01861     }
01862     else
01863     {
01864         // FIXME DEBUG_WARN("wxChoice event from unknown object received");
01865     }
01866 }
01867 
01868 void GLPreviewFrame::OnDragChoice(wxCommandEvent & e)
01869 {
01870     if (drag_tool)
01871     {
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 23 May 2016 for Hugintrunk by  doxygen 1.4.7