Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImagesList.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
27 #include "hugin_config.h"
28 #include "panoinc_WX.h"
29 #include "panoinc.h"
30 
31 #include "base_wx/wxPlatform.h"
32 #include "hugin/ImagesList.h"
33 #include "base_wx/wxImageCache.h"
34 #include "base_wx/platform.h"
35 
36 #ifdef __WXMAC__
37 #include "hugin/MainFrame.h"
38 #endif
39 
40 wxDEFINE_EVENT(EVT_IMAGE_ADD,wxCommandEvent);
41 wxDEFINE_EVENT(EVT_IMAGE_DEL,wxCommandEvent);
42 
43 //------------------------------------------------------------------------------
44 
45 BEGIN_EVENT_TABLE(ImagesList, wxListCtrl)
46  EVT_LIST_ITEM_SELECTED(-1, ImagesList::OnItemSelected)
47  EVT_LIST_ITEM_DESELECTED(-1, ImagesList::OnItemDeselected)
48  EVT_LIST_COL_END_DRAG(-1, ImagesList::OnColumnWidthChange)
49  EVT_CHAR(ImagesList::OnChar)
51 
52 // Define a constructor for the Images Panel
54 {
55  pano = 0;
56 }
57 
58 bool ImagesList::Create(wxWindow* parent, wxWindowID id,
59  const wxPoint& pos,
60  const wxSize& size,
61  long style,
62  const wxString& name)
63 {
64  DEBUG_TRACE("List");
65  if (! wxListCtrl::Create(parent, id, pos, size, wxLC_REPORT | style) ) {
66  return false;
67  }
68 
69  DEBUG_TRACE("List, adding columns");
70 
71  m_notifyParents = true;
72  InsertColumn( 0, wxT("#"), wxLIST_FORMAT_RIGHT, 35 );
73 
74  // get a good size for the images
75  wxPoint sz(1,11);
76  sz = ConvertDialogToPixels(sz);
77  m_iconHeight = sz.y;
78  DEBUG_DEBUG("icon Height: " << m_iconHeight);
79 
80  //m_smallIcons = new wxImageList(m_iconHeight, m_iconHeight);
81  //AssignImageList(m_smallIcons,wxIMAGE_LIST_SMALL);
82  DEBUG_TRACE("");
83  m_degDigits = wxConfigBase::Get()->Read(wxT("/General/DegreeFractionalDigits"),1);
84  m_pixelDigits = wxConfigBase::Get()->Read(wxT("/General/PixelFractionalDigits"),1);
85  m_distDigits = wxConfigBase::Get()->Read(wxT("/General/DistortionFractionalDigits"),3);
86  m_singleSelect=(style & wxLC_SINGLE_SEL)!=0;
87  return true;
88 }
89 
91 {
92  pano = panorama;
93  pano->addObserver(this);
94 
98 
99 #ifdef __WXMAC__
100  SetDropTarget(new PanoDropTarget(*pano, true));
101 #endif
102 }
103 
105 {
106  DEBUG_TRACE("");
107  pano->removeObserver(this);
108  delete variable_groups;
109 }
110 
112 {
113  DEBUG_TRACE("");
114 
115  Freeze();
116  m_notifyParents = false;
117  unsigned int nrImages = pano.getNrOfImages();
118  unsigned int nrItems = GetItemCount();
119 
120  // remove items for nonexisting images
121  for (int i=nrItems-1; i>=(int)nrImages; i--)
122  {
123  DEBUG_DEBUG("Deleting list item " << i);
124 
125  // deselect item
126  DEBUG_DEBUG("item state before: " << GetItemState(i,wxLIST_STATE_SELECTED));
127  SetItemState(i,0, wxLIST_STATE_SELECTED);
128  DEBUG_DEBUG("item state after: " << GetItemState(i,wxLIST_STATE_SELECTED));
129 
130  RemoveItem(i);
131  //m_smallIcons->Remove(i);
132  }
133 
134  // Make sure the part numbers are up to date before writing them to the table.
136 
137  // update existing items
138 // if ( nrImages >= nrItems ) {
139  for (HuginBase::UIntSet::const_iterator it = changed.begin(); it != changed.end(); ++it){
140  if (*it >= nrItems) {
141  // create new item.
142  DEBUG_DEBUG("creating " << *it);
143  wxBitmap small0(m_iconHeight, m_iconHeight);
144  //createIcon(small0, *it, m_iconHeight);
145  //m_smallIcons->Add(small0);
146 
147  CreateItem(*it);
148 
149  } else {
150  // update existing item
151  DEBUG_DEBUG("updating item" << *it);
152  wxBitmap small0(m_iconHeight, m_iconHeight);
153  //createIcon(small0, *it, m_iconHeight);
154  //m_smallIcons->Replace(*it, small0);
155 
156  UpdateItem(*it);
157  }
158  ImageCache::getInstance().softFlush();
159  }
160 // }
161 
162  // Update the part numbers. We do this for every image, as the images that
163  // have changed may affect the part numbers for images that haven't changed.
164  for (unsigned int i = 0; i < pano.getNrOfImages(); i++)
165  {
167  }
168 
169  Thaw();
170  m_notifyParents = true;
171 
172  // HACK! need to notify clients anyway... send dummy event..
173  // lets hope our clients query for the selected images with GetSelected()
174  // and do not try to interpret the event.
175  wxListEvent e;
176  e.SetEventType(wxEVT_COMMAND_LIST_ITEM_SELECTED);
177  e.m_itemIndex = -1;
178  GetEventHandler()->ProcessEvent(e);
179 }
180 
182 {
183  return selectedItems;
184 }
185 
186 #if 0
187 void ImagesList::createIcon(wxBitmap & bitmap, unsigned int imgNr, unsigned int size)
188 {
189  ImageCache::Entry * cacheEntry = ImageCache::getInstance().getSmallImage(
190  pano->getImage(imgNr).getFilename());
191  if (! cacheEntry) {
192  return;
193  }
194  wxImage * s_img = cacheEntry->image;
195  if (!s_img->Ok()) {
196  return;
197  }
198 
199  float w = s_img->GetWidth();
200  float h = s_img->GetHeight();
201 
202  // create scaled versions
203  int bW,bH;
204 
205  if ( h > w ) {
206  // portrait
207  bW = roundi(w/h * size);
208  bH = size;
209  } else {
210  // landscape
211  bW = size;
212  bH = roundi(h/w * size);
213  }
214  wxImage img = s_img->Scale(bW, bH);
215  wxBitmap bimg(img);
216 
217  wxMemoryDC temp_dc;
218  temp_dc.SelectObject(bitmap);
219  temp_dc.Clear();
220 /*
221  wxBitmap maskb(size, size);
222  wxMemoryDC mask_dc;
223  mask_dc.SelectObject(maskb);
224  mask_dc.Clear();
225  mask_dc.SetBrush(wxBrush("WHITE",wxSOLID));
226  mask_dc.SetPen(wxPen("WHITE",wxSOLID));
227 */
228  if (h > w) {
229  temp_dc.DrawBitmap(bimg, (size-bW)>>1 ,0);
230  } else {
231  temp_dc.DrawBitmap(bimg,0,(size-bH)>>1);
232  }
233 // wxMask * m = new wxMask(bitmap, wxColour(0,0,0));
234 // bitmap.SetMask(m);
235 }
236 #endif
237 
238 void ImagesList::CreateItem(unsigned int imgNr)
239 {
240  DEBUG_DEBUG("creating item " << imgNr);
241  // create the new row
242  InsertItem ( imgNr, wxString::Format(wxT("%d"),imgNr), imgNr );
243  UpdateItem(imgNr);
244 }
245 
246 void ImagesList::RemoveItem(unsigned int imgNr)
247 {
248  // call wxListCtrl's removal function
249  wxListCtrl::DeleteItem(imgNr);
250 }
251 
252 void ImagesList::SelectSingleImage(unsigned int imgNr)
253 {
254  unsigned int nrItems = GetItemCount();
255  for (unsigned int i=0; i < nrItems ; i++) {
256  int selected = GetItemState(i, wxLIST_STATE_SELECTED);
257  if (i != imgNr && selected) {
258  SetItemState(i, 0, wxLIST_STATE_SELECTED);
259  }
260  }
261  SetItemState(imgNr, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
262 }
263 
265 {
266  unsigned int nrItems = GetItemCount();
267  for (unsigned int i=0; i < nrItems ; i++){
268  if(set_contains(imgs, i))
269  {
270  SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
271  }
272  else
273  {
274  SetItemState(i, 0, wxLIST_STATE_SELECTED);
275  };
276  }
277  SetItemState(*imgs.begin(), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
278  selectedItems=imgs;
279 }
280 
281 void ImagesList::SelectImageRange(unsigned int imgStart,unsigned int imgEnd)
282 {
283  size_t nrItems = GetItemCount();
284  size_t _imgStart=imgStart;
285  size_t _imgEnd=imgEnd;
286  if(imgEnd<imgStart)
287  {
288  _imgStart=imgEnd;
289  _imgEnd=imgStart;
290  }
291  for (size_t i=0; i < nrItems ; i++)
292  {
293  int selected = GetItemState(i, wxLIST_STATE_SELECTED);
294  if ((i < _imgStart || i>_imgEnd ) && selected)
295  {
296  SetItemState(i, 0, wxLIST_STATE_SELECTED);
297  }
298  }
299  for(size_t i=_imgStart; i<=_imgEnd; i++)
300  {
301  SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
302  };
303 };
304 
306 {
307  unsigned int nrItems = GetItemCount();
308  for (unsigned int i=0; i < nrItems ; i++)
309  {
310  SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
311  }
312 }
313 
315 {
316  unsigned int nrItems = GetItemCount();
317  for (unsigned int i=0; i < nrItems ; i++) {
318  int selected = GetItemState(i, wxLIST_STATE_SELECTED);
319  if (selected) {
320  SetItemState(i, 0, wxLIST_STATE_SELECTED);
321  }
322  }
323 }
324 
325 void ImagesList::OnItemSelected ( wxListEvent & e )
326 {
327  DEBUG_TRACE(e.GetIndex());
328  if(e.GetIndex() < 0) return;
329  selectedItems.insert((int)e.GetIndex());
330  // allow other parents to receive this event, only if its
331  // generated by the user, and not during an automatic update
332  // triggered by a change to the panorama
333  if (m_notifyParents) {
334  e.Skip();
335  }
336 }
337 
338 void ImagesList::OnChar(wxKeyEvent &e)
339 {
340  switch(e.GetKeyCode())
341  {
342  case WXK_INSERT:
343  {
344  wxCommandEvent ev(EVT_IMAGE_ADD,wxID_ANY);
345  GetParent()->GetEventHandler()->AddPendingEvent(ev);
346  break;
347  };
348  case WXK_DELETE:
349  {
350  wxCommandEvent ev(EVT_IMAGE_DEL,wxID_ANY);
351  GetParent()->GetEventHandler()->AddPendingEvent(ev);
352  break;
353  };
354  case 1: //Ctrl+A
355  {
356  if(!m_singleSelect && e.CmdDown())
357  {
358  SelectAll();
359  }
360  break;
361  }
362  };
363  e.Skip();
364 };
365 
366 
367 void ImagesList::OnItemDeselected ( wxListEvent & e )
368 {
369  DEBUG_TRACE(e.GetIndex());
370  if(e.GetIndex() < 0) return;
371  selectedItems.erase((int)e.GetIndex());
372  // allow other parents to receive this event, only if its
373  // generated by the user, and not during an automatic update
374  // triggered by a change to the panorama
375  if (m_notifyParents) {
376  e.Skip();
377  }
378 }
379 
380 #if 0
381 void ImagesList::OnItemSelected ( wxListEvent & e )
382 {
383  DEBUG_TRACE("");
384 
385  // publicate the selected items
386  selectedImages.clear();
387 
388  for ( int Nr=GetItemCount()-1 ; Nr>=0 ; --Nr ) {
389  if ( GetItemState( Nr, wxLIST_STATE_SELECTED ) ) {
390  selectedImages.insert(Nr);
391  }
392  }
393  // notify other parties about changed notification..
394 
395  // let others recieve the event too
396  e.Skip(true);
397  DEBUG_TRACE("end");
398 }
399 #endif
400 
401 void ImagesList::OnColumnWidthChange( wxListEvent & e )
402 {
403  if(m_configClassName != wxT(""))
404  {
405  int colNum = e.GetColumn();
406  wxConfigBase::Get()->Write( m_configClassName+wxString::Format(wxT("/ColumnWidth%d"),colNum), GetColumnWidth(colNum) );
407  }
408 }
409 
410 void ImagesList::UpdateItem(unsigned int imgNr)
411 {
412 
413 }
414 
415 void ImagesList::UpdatePartNumbersForItem(unsigned int imgNr)
416 {
417 
418 }
419 
421 
422 // ============================================================================
423 // ============================================================================
424 // Mask
425 
427 {
428 }
429 
430 bool ImagesListMask::Create(wxWindow* parent, wxWindowID id,
431  const wxPoint& pos,
432  const wxSize& size,
433  long style,
434  const wxString& name)
435 {
436  DEBUG_TRACE("");
437  if (!ImagesList::Create(parent, id, pos, size, wxLC_SINGLE_SEL | style, name))
438  return false;
439 
440  m_configClassName = wxT("/ImagesListMask");
441 
442  InsertColumn(1, _("Filename"), wxLIST_FORMAT_LEFT, 200 );
443  InsertColumn(2, _("Number of masks"), wxLIST_FORMAT_RIGHT,120);
444  InsertColumn(3, _("Crop"), wxLIST_FORMAT_RIGHT,120);
445 
446  //get saved width
447  for ( int j=0; j < GetColumnCount() ; j++ )
448  {
449  // -1 is auto
450  int width = wxConfigBase::Get()->Read(wxString::Format(m_configClassName+wxT("/ColumnWidth%d"), j ), -1);
451  if(width != -1)
452  SetColumnWidth(j, width);
453  }
454  return true;
455 }
456 
457 
459 {
460  ImagesList::Init(panorama);
461 }
462 
463 void ImagesListMask::UpdateItem(unsigned int imgNr)
464 {
465  const HuginBase::SrcPanoImage & img = pano->getImage(imgNr);
466  wxFileName fn(wxString (img.getFilename().c_str(), HUGIN_CONV_FILENAME));
467  SetItem(imgNr, 1, fn.GetFullName() );
468 
469  wxString maskstr;
470  if(img.hasMasks())
471  maskstr=wxString::Format(wxT("%lu"), (unsigned long int) pano->getImage(imgNr).getMasks().size());
472  else
473  maskstr=wxT("-");
474  SetItem(imgNr, 2, maskstr);
475 
476  wxString cropstr(wxT("-"));
477  if ( img.getCropMode() != HuginBase::SrcPanoImage::NO_CROP )
478  {
479  vigra::Rect2D c = img.getCropRect();
480  cropstr.Printf(wxT("%d,%d,%d,%d"), c.left(), c.right(), c.top(), c.bottom());
481  }
482  SetItem(imgNr, 3, cropstr);
483 }
484 
485 void ImagesListMask::SetSingleSelect(bool isSingleSelect)
486 {
487  if(isSingleSelect)
488  {
489  SetSingleStyle(wxLC_SINGLE_SEL, true);
490  }
491  else
492  {
493  SetSingleStyle(wxLC_SINGLE_SEL, false);
494  };
495  m_singleSelect=(GetWindowStyle() & wxLC_SINGLE_SEL)!=0;
496 
497 };
498 
500 
502  : wxXmlResourceHandler()
503 {
504  AddWindowStyles();
505 }
506 
508 {
509  XRC_MAKE_INSTANCE(cp, ImagesListMask)
510 
511  cp->Create(m_parentAsWindow,
512  GetID(),
513  GetPosition(), GetSize(),
514  GetStyle(wxT("style")),
515  GetName());
516 
517  SetupWindow( cp);
518 
519  return cp;
520 }
521 
523 {
524  return IsOfClass(node, wxT("ImagesListMask"));
525 }
526 
528 
wxDEFINE_EVENT(EVT_QUEUE_PROGRESS, wxCommandEvent)
implementation of huginApp Class
HuginBase::Panorama * pano
Definition: ImagesList.h:129
void OnItemDeselected(wxListEvent &e)
Definition: ImagesList.cpp:367
int roundi(T x)
Definition: hugin_math.h:73
void SelectImages(const HuginBase::UIntSet imgs)
selects the given images
Definition: ImagesList.cpp:264
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
Definition: Panorama.cpp:1551
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
#define DEBUG_TRACE(msg)
Definition: utils.h:67
void OnItemSelected(wxListEvent &e)
Definition: ImagesList.cpp:325
virtual bool CanHandle(wxXmlNode *node)
Definition: ImagesList.cpp:522
bool set_contains(const _Container &c, const typename _Container::key_type &key)
Definition: stl_utils.h:74
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
int m_distDigits
Definition: ImagesList.h:152
simple class that forward the drop to the mainframe
Definition: MainFrame.h:65
END_EVENT_TABLE()
include file for the hugin project
void DeselectAll()
Deselects all images.
Definition: ImagesList.cpp:314
HuginBase::StandardImageVariableGroups * variable_groups
Definition: ImagesList.h:132
void SetSingleSelect(bool isSingleSelect)
sets the listbox to single item select or multiply item select
Definition: ImagesList.cpp:485
virtual wxObject * DoCreateResource()
Definition: ImagesList.cpp:507
bool hasMasks() const
returns true, if image has masks associated
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
virtual ~ImagesList(void)
Definition: ImagesList.cpp:104
Model for a panorama.
Definition: Panorama.h:152
void SelectSingleImage(unsigned int imgNr)
Select an image.
Definition: ImagesList.cpp:252
const HuginBase::UIntSet & GetSelected() const
get the currently selected images
Definition: ImagesList.cpp:181
void OnChar(wxKeyEvent &e)
event handler to capture special key code
Definition: ImagesList.cpp:338
virtual void UpdateItem(unsigned int imgNr)
update the information in an already existing list item
Definition: ImagesList.cpp:463
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
void OnColumnWidthChange(wxListEvent &e)
Definition: ImagesList.cpp:401
int m_iconHeight
Definition: ImagesList.h:150
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
virtual void UpdateItem(unsigned int imgNr)
update the information in an already existing list item
Definition: ImagesList.cpp:410
virtual void RemoveItem(unsigned int imgNr)
remove an existing list item
Definition: ImagesList.cpp:246
IMPEX double h[25][1024]
Definition: emor.cpp:169
void Init(HuginBase::Panorama *pano)
Definition: ImagesList.cpp:458
void SelectImageRange(unsigned int imgStart, unsigned int imgEnd)
Select an image range.
Definition: ImagesList.cpp:281
void SelectAll()
Select all images.
Definition: ImagesList.cpp:305
void addObserver(PanoramaObserver *o)
add a panorama observer.
Definition: Panorama.cpp:1546
include file for the hugin project
specialized to display the mask aspect of images
Definition: ImagesList.h:167
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"))
Definition: ImagesList.cpp:430
virtual void CreateItem(unsigned int imgNr)
create an list item for imgNr
Definition: ImagesList.cpp:238
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
int m_pixelDigits
Definition: ImagesList.h:153
virtual void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &imgNr)
receive the update signal and update display accordingly
Definition: ImagesList.cpp:111
virtual void UpdatePartNumbersForItem(unsigned int imgNr)
Update the part numbers (e.g.
Definition: ImagesList.cpp:415
void update()
Update part numbers for each variable group.
platform/compiler specific stuff.
HuginBase::UIntSet selectedItems
create icons for an image
Definition: ImagesList.h:146
int m_degDigits
Definition: ImagesList.h:151
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
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"))
Definition: ImagesList.cpp:58
All variables of a source image.
Definition: SrcPanoImage.h:194
wxString m_configClassName
Definition: ImagesList.h:160
multi use list.
Definition: ImagesList.h:60
bool m_notifyParents
Definition: ImagesList.h:156
void Init(HuginBase::Panorama *pano)
Definition: ImagesList.cpp:90
bool m_singleSelect
Definition: ImagesList.h:157