39 #include <wx/clipbrd.h>
43 EVT_LIST_ITEM_SELECTED(XRCID("mask_editor_images_list"),
MaskEditorPanel::OnImageSelect)
44 EVT_LIST_ITEM_DESELECTED(XRCID("mask_editor_images_list"),
MaskEditorPanel::OnImageSelect)
45 EVT_LIST_ITEM_SELECTED(XRCID("mask_editor_mask_list"),
MaskEditorPanel::OnMaskSelect)
46 EVT_LIST_ITEM_DESELECTED(XRCID("mask_editor_mask_list"),
MaskEditorPanel::OnMaskSelect)
47 EVT_LIST_COL_END_DRAG(XRCID("mask_editor_mask_list"),
MaskEditorPanel::OnColumnWidthChange)
49 EVT_CHOICE(XRCID("mask_editor_choice_masktype"),
MaskEditorPanel::OnMaskTypeChange)
56 EVT_CHECKBOX(XRCID("mask_editor_show_active_masks"),
MaskEditorPanel::OnShowActiveMasks)
57 EVT_COLOURPICKER_CHANGED(XRCID("mask_editor_colour_polygon_negative"),
MaskEditorPanel::OnColourChanged)
58 EVT_COLOURPICKER_CHANGED(XRCID("mask_editor_colour_polygon_positive"),
MaskEditorPanel::OnColourChanged)
59 EVT_COLOURPICKER_CHANGED(XRCID("mask_editor_colour_point_selected"),
MaskEditorPanel::OnColourChanged)
60 EVT_COLOURPICKER_CHANGED(XRCID("mask_editor_colour_point_unselected"),
MaskEditorPanel::OnColourChanged)
64 EVT_TEXT_ENTER (XRCID("crop_bottom_text") ,
MaskEditorPanel::OnSetBottom )
65 EVT_BUTTON ( XRCID("crop_reset_button") ,
MaskEditorPanel::OnResetButton )
66 EVT_CHECKBOX( XRCID("crop_autocenter_cb") ,
MaskEditorPanel::OnAutoCenter)
67 EVT_NOTEBOOK_PAGE_CHANGED(XRCID("mask_editor_mask_crop_notebook"),
MaskEditorPanel::OnModeChanged)
85 if (! wxPanel::Create(parent,
id, pos, size, style, name))
94 wxXmlResource::Get()->LoadPanel(
this, wxT(
"mask_panel"));
95 wxPanel * panel = XRCCTRL(*
this,
"mask_panel", wxPanel);
97 wxBoxSizer *topsizer =
new wxBoxSizer( wxVERTICAL );
98 topsizer->Add(panel, 1, wxEXPAND, 0);
108 m_maskList = XRCCTRL(*
this,
"mask_editor_mask_list", wxListCtrl);
109 m_maskList->InsertColumn( 0, wxT(
"#"), wxLIST_FORMAT_RIGHT, 35);
110 m_maskList->InsertColumn( 1, _(
"Mask type"), wxLIST_FORMAT_LEFT, 120);
112 m_maskCropCtrl = XRCCTRL(*
this,
"mask_editor_mask_crop_notebook", wxNotebook);
118 wxConfigBase *config=wxConfigBase::Get();
119 for (
int j=0; j <
m_maskList->GetColumnCount() ; j++ )
122 int width = config->Read(wxString::Format( wxT(
"/MaskEditorPanel/ColumnWidth%d"), j ), -1);
127 config->Read(wxT(
"/MaskEditorPanel/ShowActiveMasks"),&activeMasks,
false);
128 XRCCTRL(*
this,
"mask_editor_show_active_masks",wxCheckBox)->SetValue(activeMasks);
132 wxColour defaultColour;
134 wxColour colour = config->Read(wxT(
"/MaskEditorPanel/ColourPolygonNegative"), defaultColour.GetAsString(wxC2S_HTML_SYNTAX));
135 XRCCTRL(*
this,
"mask_editor_colour_polygon_negative",wxColourPickerCtrl)->SetColour(colour);
138 colour = config->Read(wxT(
"/MaskEditorPanel/ColourPolygonPositive"), defaultColour.GetAsString(wxC2S_HTML_SYNTAX));
139 XRCCTRL(*
this,
"mask_editor_colour_polygon_positive",wxColourPickerCtrl)->SetColour(colour);
142 colour = config->Read(wxT(
"/MaskEditorPanel/ColourPointSelected"), defaultColour.GetAsString(wxC2S_HTML_SYNTAX));
143 XRCCTRL(*
this,
"mask_editor_colour_point_selected",wxColourPickerCtrl)->SetColour(colour);
146 colour = config->Read(wxT(
"/MaskEditorPanel/ColourPointUnselected"), defaultColour.GetAsString(wxC2S_HTML_SYNTAX));
147 XRCCTRL(*
this,
"mask_editor_colour_point_unselected",wxColourPickerCtrl)->SetColour(colour);
151 m_maskType = XRCCTRL(*
this,
"mask_editor_choice_masktype", wxChoice);
156 XRCCTRL(*
this,
"mask_editor_choice_zoom", wxChoice)->Disable();
157 XRCCTRL(*
this,
"mask_editor_add", wxButton)->Disable();
158 XRCCTRL(*
this,
"mask_editor_load", wxButton)->Disable();
159 XRCCTRL(*
this,
"mask_editor_save", wxButton)->Disable();
160 XRCCTRL(*
this,
"mask_editor_copy", wxButton)->Disable();
161 XRCCTRL(*
this,
"mask_editor_paste", wxButton)->Disable();
162 XRCCTRL(*
this,
"mask_editor_delete", wxButton)->Disable();
168 m_cropLens = XRCCTRL(*
this,
"crop_all_images_lens", wxCheckBox);
170 bool doCropImagesLens;
171 config->Read(wxT(
"/MaskEditorPanel/CropImagesLens"), &doCropImagesLens,
true);
189 wxAcceleratorEntry entries[2];
190 entries[0].Set(wxACCEL_CMD,(
int)
'C',XRCID(
"mask_editor_copy"));
191 entries[1].Set(wxACCEL_CMD,(
int)
'V',XRCID(
"mask_editor_paste"));
192 wxAcceleratorTable accel(2, entries);
193 SetAcceleratorTable(accel);
196 wxCommandEvent dummy;
197 dummy.SetInt(XRCCTRL(*
this,
"mask_editor_choice_zoom",wxChoice)->GetSelection());
217 wxConfigBase* config = wxConfigBase::Get();
218 config->Write(wxT(
"/MaskEditorPanel/ShowActiveMasks"),XRCCTRL(*
this,
"mask_editor_show_active_masks",wxCheckBox)->GetValue());
220 config->Write(wxT(
"/MaskEditorPanel/CropImagesLens"),
m_cropLens->GetValue());
246 bool restoreMaskSelection=(imgNr==
GetImgNr());
247 bool updateImage=
true;
257 if (imgNr == UINT_MAX)
267 updateImage=(
m_File!=image.getFilename());
269 m_File=image.getFilename();
274 m_File=image.getFilename();
277 masksToDraw=image.getActiveMasks();
288 bool enableCtrl=(imgNr<UINT_MAX);
289 XRCCTRL(*
this,
"mask_editor_choice_zoom", wxChoice)->Enable(enableCtrl);
290 XRCCTRL(*
this,
"mask_editor_add", wxButton)->Enable(enableCtrl);
291 XRCCTRL(*
this,
"mask_editor_delete", wxButton)->Enable(enableCtrl &&
m_MaskNr<UINT_MAX);
292 XRCCTRL(*
this,
"mask_editor_load", wxButton)->Enable(enableCtrl);
293 XRCCTRL(*
this,
"mask_editor_save", wxButton)->Enable(enableCtrl &&
m_MaskNr<UINT_MAX);
294 XRCCTRL(*
this,
"mask_editor_paste", wxButton)->Enable(enableCtrl);
295 XRCCTRL(*
this,
"mask_editor_copy", wxButton)->Enable(enableCtrl &&
m_MaskNr<UINT_MAX);
298 ImageCache::getInstance().softFlush();
299 if(updateListSelection)
311 XRCCTRL(*
this,
"mask_editor_delete", wxButton)->Enable(
m_MaskNr<UINT_MAX);
312 XRCCTRL(*
this,
"mask_editor_save", wxButton)->Enable(
m_MaskNr<UINT_MAX);
313 XRCCTRL(*
this,
"mask_editor_copy", wxButton)->Enable(
m_MaskNr<UINT_MAX);
348 m_maskList->SetItemState(newMaskNr, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
368 ImageCache::getInstance().softFlush();
380 m_selectedImages.erase(i);
452 MainFrame::Get()->SetStatusText(_(
"Create a polygon mask by clicking with the left mouse button on image, set the last point with the right mouse button."),0);
461 wxFileDialog dlg(
this, _(
"Save mask"),
462 wxConfigBase::Get()->Read(wxT(
"/actualPath"), wxT(
"")),
463 wxT(
""), _(
"Mask files (*.msk)|*.msk|All files (*)|*"),
464 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
465 if (dlg.ShowModal() == wxID_OK)
467 wxString fn = dlg.GetPath();
468 if (fn.Right(4) != wxT(
".msk"))
470 fn.Append(wxT(
".msk"));
471 if (wxFile::Exists(fn))
473 int d = wxMessageBox(wxString::Format(_(
"File %s exists. Overwrite?"),
474 fn.c_str()), _(
"Save mask"),
475 wxYES_NO | wxICON_QUESTION);
481 wxFileName filename = fn;
493 wxFileDialog dlg(
this,_(
"Load mask"),
494 wxConfigBase::Get()->Read(wxT(
"/actualPath"),wxT(
"")),
495 wxT(
""),_(
"Mask files (*.msk)|*.msk|All files (*)|*"),
496 wxFD_OPEN, wxDefaultPosition);
497 if (dlg.ShowModal() != wxID_OK)
502 wxFileName filename(dlg.GetPath());
504 vigra::Size2D maskImageSize;
508 if(maskImageSize.area()==0 || loadedMasks.empty())
510 wxMessageBox(wxString::Format(_(
"Could not parse mask from file %s."),dlg.GetPath().c_str()),_(
"Warning"),wxOK | wxICON_EXCLAMATION,
this);
519 if(dlg.ShowModal()!=wxID_OK)
526 for(
unsigned int i=0;i<loadedMasks.size();i++)
537 std::ostringstream stream;
539 if (wxTheClipboard->Open())
543 wxTheClipboard->SetData(
new wxTextDataObject(wxString(stream.str().c_str(),wxConvLocal)));
544 wxTheClipboard->Close();
553 if (wxTheClipboard->Open())
555 vigra::Size2D maskImageSize;
557 if (wxTheClipboard->IsSupported( wxDF_TEXT ))
559 wxTextDataObject
data;
560 wxTheClipboard->GetData(data);
561 std::istringstream stream(std::string(data.GetText().mb_str()));
564 wxTheClipboard->Close();
565 if(maskImageSize.area()==0 || loadedMasks.empty())
576 if(dlg.ShowModal()!=wxID_OK)
583 for(
unsigned int i=0;i<loadedMasks.size();i++)
596 editedMasks.erase(editedMasks.begin()+
m_MaskNr);
606 const wxSize ctrlSize =
m_editImg->GetClientSize();
614 switch (e.GetSelection())
645 m_editImg->Scroll(posX*factor - ctrlSize.GetWidth() / 2, posY*factor - ctrlSize.GetHeight() / 2);
647 if (e.GetString() ==
"update_selection")
649 XRCCTRL(*
this,
"mask_editor_choice_zoom", wxChoice)->SetSelection(e.GetSelection());
655 if(e.GetId()==XRCID(
"mask_editor_colour_polygon_negative"))
658 wxConfigBase::Get()->Write(wxT(
"/MaskEditorPanel/ColourPolygonNegative"),e.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
661 if(e.GetId()==XRCID(
"mask_editor_colour_polygon_positive"))
664 wxConfigBase::Get()->Write(wxT(
"/MaskEditorPanel/ColourPolygonPositive"),e.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
667 if(e.GetId()==XRCID(
"mask_editor_colour_point_selected"))
670 wxConfigBase::Get()->Write(wxT(
"/MaskEditorPanel/ColourPointSelected"),e.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
675 wxConfigBase::Get()->Write(wxT(
"/MaskEditorPanel/ColourPointUnselected"),e.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
694 m_maskList->InsertItem(i,wxString::Format(wxT(
"%d"),i));
706 if(!restoreSelection && i==oldSelection)
707 m_maskList->SetItemState(i,0, wxLIST_STATE_SELECTED);
721 for(
unsigned int i=0;i<(
unsigned int)
m_maskList->GetItemCount();i++)
723 if(
m_maskList->GetItemState(i,wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED)
731 int colNum = e.GetColumn();
732 wxConfigBase::Get()->Write( wxString::Format(wxT(
"/MaskEditorPanel/ColumnWidth%d"),colNum),
m_maskList->GetColumnWidth(colNum) );
745 while (roll > 360) roll-= 360;
746 while (roll < 0) roll += 360;
748 while (pitch > 180) pitch -= 360;
749 while (pitch < -180) pitch += 360;
750 const bool headOver = (pitch > 90 || pitch < -90);
752 if (wxConfig::Get()->Read(
"/CPEditorPanel/AutoRot", 1L))
754 if (roll >= 315 || roll < 45)
760 if (roll >= 45 && roll < 135)
766 if (roll >= 135 && roll < 225)
795 m_cropCenter = vigra::Point2D(img.getSize().width()/2 + dx, img.getSize().height()/2 + dy);
804 if(updateFromImgCtrl)
808 std::vector<HuginBase::SrcPanoImage> srcImgs;
815 for (
auto j : lensImageVector)
819 std::copy(j.begin(), j.end(), std::inserter(imgs, imgs.begin()));
834 srcImgs.push_back(img);
875 wxLogError(_(
"Please enter a valid number"));
894 wxLogError(_(
"Please enter a valid number"));
913 wxLogError(_(
"Please enter a valid number"));
932 wxLogError(_(
"Please enter a valid number"));
940 m_cropRect.setLowerRight(vigra::Point2D(0,0));
994 wxNotebookEvent dummy;
1001 : wxXmlResourceHandler()
1010 cp->Create(m_parentAsWindow,
1012 GetPosition(), GetSize(),
1013 GetStyle(wxT(
"style")),
1023 return IsOfClass(node, wxT(
"MaskEditorPanel"));
void OnResetButton(wxCommandEvent &e)
ImageRotation
image rotation.
HuginBase::ConstStandardImageVariableGroups * m_imageGroups
void OnSetTop(wxCommandEvent &e)
void SaveMaskToStream(std::ostream &stream, vigra::Size2D imageSize, MaskPolygon &maskToWrite, size_t imgNr)
save the mask into stream
hugin_utils::FDiff2D getRadialDistortionCenter() const
std::vector< UIntSet > UIntSetVector
HuginBase::UIntSet m_selectedImages
void UpdateMaskList(bool restoreSelection=false)
updates the display after another image has been selected.
void UpdateCropFromImage()
updates the displayed crop in the text boxes (for dragging)
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
bool isCircularCrop() const
returns true, if projection requires cicular crop
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
void setActiveMask(unsigned int newMask, bool doUpdate=true)
mark mask with image as beeing editing
HuginBase::Panorama * m_pano
void LoadMaskFromStream(std::istream &stream, vigra::Size2D &imageSize, MaskPolygonVector &newMasks, size_t imgNr)
load the mask from stream
void OnMaskPaste(wxCommandEvent &e)
called when user wants to paste a mask from clipboard
void SelectMask(unsigned int newMaskNr)
selects the mask with index newMaskNr in the listbox
void SetUserColourPointUnselected(wxColour newColour)
xrc handler for handling mask editor panel
MaskImageCtrl * m_editImg
HuginBase::MaskPolygonVector getProcessedMask() const
return the processed mask
void OnImageSelect(wxListEvent &e)
called when user selected another image
bool set_contains(const _Container &c, const typename _Container::key_type &key)
virtual bool CanHandle(wxXmlNode *node)
#define DEBUG_ASSERT(cond)
HuginBase::SrcPanoImage::CropMode m_cropMode
include file for the hugin project
ImagesListMask * m_imagesListMask
void setImage(unsigned int imgNr, bool updateListSelection=false)
sets the image, which is currently edited
void SetSingleSelect(bool isSingleSelect)
sets the listbox to single item select or multiply item select
vigra::Rect2D getCrop()
returns the current crop rect
void OnMaskLoad(wxCommandEvent &e)
called when user wants to load a mask into the selected image
HuginBase::MaskPolygonVector m_currentMasks
void OnAutoCenter(wxCommandEvent &e)
wxTextCtrl * m_right_textctrl
void OnSetRight(wxCommandEvent &e)
void OnSetBottom(wxCommandEvent &e)
void SetUserColourPolygonNegative(wxColour newColour)
sets the colour for different parts
void SetUserColourPointSelected(wxColour newColour)
void setMask(unsigned int maskNr)
sets active mask number, set to UINT_MAX, if no mask is currently editing
std::set< unsigned int > UIntSet
void OnZoom(wxCommandEvent &e)
sets the actual zoom factor
update mask for given image
void SelectSingleImage(unsigned int imgNr)
Select an image.
void setImage(const std::string &filename, HuginBase::MaskPolygonVector newMask, HuginBase::MaskPolygonVector masksToDraw, ImageRotation rot)
set the current image and mask list, this loads also the image from cache
ConstImageVariableGroup & getLenses()
Get the ImageVariableGroup representing the group of lens variables.
UIntSetVector getPartsSet() const
return a vector which contains a HuginBase::UIntSet for each group with the corresponding images numb...
void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &imgNr)
notifies about changes to images
const HuginBase::UIntSet & GetSelected() const
get the currently selected images
HuginBase::MaskPolygon::MaskType m_defaultMaskType
void OnMaskTypeChange(wxCommandEvent &e)
handler when mask type was changed
HuginBase::MaskPolygonVector getNewMask() const
returns the vector of all mask (including new created mask)
std::size_t getNrOfImages() const
number of images.
static MainFrame * Get()
hack.. kind of a pseudo singleton...
void SwitchToCropMode()
switches the controls to crop mode
MaskType
enumeration with type of possible masks
void OnColourChanged(wxColourPickerEvent &e)
event handler for changing colours
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
void OnModeChanged(wxNotebookEvent &e)
ImageRotation getCurrentRotation()
returns the current rotation of displayed image
vigra::Point2D m_cropCenter
void OnColumnWidthChange(wxListEvent &e)
called, when column with of mask list box was changed
double getScale()
return scale factor, 0 for autoscale
void UpdateMask()
called when mask where changed in MaskImageCtrl
Make an ImageVariableGroup for lenses and other common concepts.
static GlobalCmdHist & getInstance()
void UpdateCrop(bool updateFromImgCtrl=false)
updated the crop in the Panorama object with the current values from GUI
void Init(HuginBase::Panorama *pano)
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
wxCheckBox * m_autocenter_cb
void OnMaskSave(wxCommandEvent &e)
called when user wants to save active mask
std::vector< MaskPolygon > MaskPolygonVector
void Init(HuginBase::Panorama *pano)
#define HUGIN_MASK_COLOUR_POINT_UNSELECTED
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxT("panel"))
void selectAllMarkers()
select all points of active mask
Dialog for loading masks.
void setNewMasks(HuginBase::MaskPolygonVector newMasks, HuginBase::MaskPolygonVector masksToDraw)
updates masks for currently selected image
void OnSetLeft(wxCommandEvent &e)
void addObserver(PanoramaObserver *o)
add a panorama observer.
include file for the hugin project
Handle EVT_KILL_FOCUS and convert it to a EVT_TEXT_ENTER event.
specialized to display the mask aspect of images
wxNotebook * m_maskCropCtrl
virtual ~MaskEditorPanel()
dtor.
options wxIntPtr wxIntPtr sortData std::vector< PanoInfo > * data
void DisplayCrop(int imgNr)
copies the crop information from the Panorama object to GUI
void setScale(double factor)
set the scaling factor for mask editing display.
#define HUGIN_MASK_COLOUR_POINT_SELECTED
void Init(MaskEditorPanel *parent)
void UpdateCropDisplay()
update GUI display
wxTextCtrl * m_bottom_textctrl
void SetMaskMode(bool newMaskMode)
sets the control to mask (newMaskMode=true) or crop (newMaskMode=false) mode
#define HUGIN_MASK_COLOUR_POLYGON_NEGATIVE
MaskImageCtrl::ImageRotation GetRot(const unsigned int imgNr)
determines, if the image should be rotated for display
void OnMaskDelete(wxCommandEvent &e)
called when user wants to delete active mask
void update()
Update part numbers for each variable group.
Definition of mask load dialog.
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
void SetUserColourPolygonPositive(wxColour newColour)
void OnMaskSelect(wxListEvent &e)
called when user selected another mask
void OnMaskAdd(wxCommandEvent &e)
called when user wants to create new polygon
void panoramaChanged(HuginBase::Panorama &pano)
called when the panorama changes and we should update our display
void OnShowActiveMasks(wxCommandEvent &e)
event handler for changing option if active masks should be drawn
#define HUGIN_MASK_COLOUR_POLYGON_POSITIVE
void startNewPolygon()
starts creating a new polygon
void AddMask()
called when new mask added in MaskImageCtrl
wxTextCtrl * m_top_textctrl
All variables of a source image.
void setCrop(HuginBase::SrcPanoImage::CropMode newCropMode, vigra::Rect2D newCropRect, bool isCentered, hugin_utils::FDiff2D center, bool isCircleCrop)
updates the crop mode and crop rect
virtual wxObject * DoCreateResource()
void initValues(const HuginBase::SrcPanoImage image, const HuginBase::MaskPolygonVector newMask, const vigra::Size2D maskSize)
sets the default values
wxTextCtrl * m_left_textctrl
unsigned int GetSelectedMask()
return index of currently selected masks, return UINT_MAX if no mask is selected
void setDrawingActiveMasks(bool newDrawActiveMasks)
set if active masks should be drawn
void OnMaskCopy(wxCommandEvent &e)
called when user wants to copy a mask to clipboard