ImagesList.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00027 #include <config.h>
00028 #include "panoinc_WX.h"
00029 #include "panoinc.h"
00030 
00031 #include "base_wx/wxPlatform.h"
00032 #include "hugin/ImagesList.h"
00033 #include "base_wx/wxImageCache.h"
00034 #include "base_wx/platform.h"
00035 
00036 #ifdef __WXMAC__
00037 #include "hugin/MainFrame.h"
00038 #endif
00039 
00040 wxDEFINE_EVENT(EVT_IMAGE_ADD,wxCommandEvent);
00041 wxDEFINE_EVENT(EVT_IMAGE_DEL,wxCommandEvent);
00042 
00043 //------------------------------------------------------------------------------
00044 
00045 BEGIN_EVENT_TABLE(ImagesList, wxListCtrl)
00046     EVT_LIST_ITEM_SELECTED(-1, ImagesList::OnItemSelected)
00047     EVT_LIST_ITEM_DESELECTED(-1, ImagesList::OnItemDeselected)
00048     EVT_LIST_COL_END_DRAG(-1, ImagesList::OnColumnWidthChange)
00049     EVT_CHAR(ImagesList::OnChar)
00050 END_EVENT_TABLE()
00051 
00052 // Define a constructor for the Images Panel
00053 ImagesList::ImagesList()
00054 {
00055     pano = 0;
00056 }
00057 
00058 bool ImagesList::Create(wxWindow* parent, wxWindowID id,
00059                         const wxPoint& pos,
00060                         const wxSize& size,
00061                         long style,
00062                         const wxString& name)
00063 {
00064     DEBUG_TRACE("List");
00065     if (! wxListCtrl::Create(parent, id, pos, size, wxLC_REPORT | style) ) {
00066         return false;
00067     }
00068 
00069     DEBUG_TRACE("List, adding columns");
00070 
00071     m_notifyParents = true;
00072     InsertColumn( 0, wxT("#"), wxLIST_FORMAT_RIGHT, 35 );
00073 
00074     // get a good size for the images
00075     wxPoint sz(1,11);
00076     sz = ConvertDialogToPixels(sz);
00077     m_iconHeight = sz.y;
00078     DEBUG_DEBUG("icon Height: " << m_iconHeight);
00079 
00080     //m_smallIcons = new wxImageList(m_iconHeight, m_iconHeight);
00081     //AssignImageList(m_smallIcons,wxIMAGE_LIST_SMALL);
00082     DEBUG_TRACE("");
00083     m_degDigits = wxConfigBase::Get()->Read(wxT("/General/DegreeFractionalDigits"),1);
00084     m_pixelDigits = wxConfigBase::Get()->Read(wxT("/General/PixelFractionalDigits"),1);
00085     m_distDigits = wxConfigBase::Get()->Read(wxT("/General/DistortionFractionalDigits"),3);
00086     m_singleSelect=(style & wxLC_SINGLE_SEL)!=0;
00087     return true;
00088 }
00089 
00090 void ImagesList::Init(HuginBase::Panorama * panorama)
00091 {
00092     pano = panorama;
00093     pano->addObserver(this);
00094     
00096     variable_groups = new HuginBase::StandardImageVariableGroups(*pano);
00097     DEBUG_ASSERT(variable_groups);
00098     
00099 #ifdef __WXMAC__
00100     SetDropTarget(new PanoDropTarget(*pano, true));
00101 #endif
00102 }
00103 
00104 ImagesList::~ImagesList(void)
00105 {
00106     DEBUG_TRACE("");
00107     pano->removeObserver(this);
00108     delete variable_groups;
00109 }
00110 
00111 void ImagesList::panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &changed)
00112 {
00113     DEBUG_TRACE("");
00114 
00115     Freeze();
00116     m_notifyParents = false;
00117     unsigned int nrImages = pano.getNrOfImages();
00118     unsigned int nrItems = GetItemCount();
00119 
00120     // remove items for nonexisting images
00121     for (int i=nrItems-1; i>=(int)nrImages; i--)
00122     {
00123         DEBUG_DEBUG("Deleting list item " << i);
00124 
00125         // deselect item
00126         DEBUG_DEBUG("item state before: " << GetItemState(i,wxLIST_STATE_SELECTED));
00127         SetItemState(i,0, wxLIST_STATE_SELECTED);
00128         DEBUG_DEBUG("item state after: " << GetItemState(i,wxLIST_STATE_SELECTED));
00129 
00130         RemoveItem(i);
00131         //m_smallIcons->Remove(i);
00132     }
00133     
00134     // Make sure the part numbers are up to date before writing them to the table.
00135     variable_groups->update();
00136 
00137     // update existing items
00138 //    if ( nrImages >= nrItems ) {
00139     for (HuginBase::UIntSet::const_iterator it = changed.begin(); it != changed.end(); ++it){
00140             if (*it >= nrItems) {
00141                 // create new item.
00142                 DEBUG_DEBUG("creating " << *it);
00143                 wxBitmap small0(m_iconHeight, m_iconHeight);
00144                 //createIcon(small0, *it, m_iconHeight);
00145                 //m_smallIcons->Add(small0);
00146 
00147                 CreateItem(*it);
00148 
00149             } else {
00150                 // update existing item
00151                 DEBUG_DEBUG("updating item" << *it);
00152                 wxBitmap small0(m_iconHeight, m_iconHeight);
00153                 //createIcon(small0, *it, m_iconHeight);
00154                 //m_smallIcons->Replace(*it, small0);
00155 
00156                 UpdateItem(*it);
00157             }
00158             ImageCache::getInstance().softFlush();
00159         }
00160 //    }
00161     
00162     // Update the part numbers. We do this for every image, as the images that
00163     // have changed may affect the part numbers for images that haven't changed.
00164     for (unsigned int i = 0; i < pano.getNrOfImages(); i++)
00165     {
00166         UpdatePartNumbersForItem(i);
00167     }
00168     
00169     Thaw();
00170     m_notifyParents = true;
00171     
00172     // HACK! need to notify clients anyway... send dummy event..
00173     // lets hope our clients query for the selected images with GetSelected()
00174     // and do not try to interpret the event.
00175     wxListEvent e;
00176     e.SetEventType(wxEVT_COMMAND_LIST_ITEM_SELECTED);
00177     e.m_itemIndex = -1;
00178     GetEventHandler()->ProcessEvent(e);
00179 }
00180 
00181 const HuginBase::UIntSet & ImagesList::GetSelected() const      
00182 { 
00183     return selectedItems; 
00184 }
00185 
00186 #if 0
00187 void ImagesList::createIcon(wxBitmap & bitmap, unsigned int imgNr, unsigned int size)
00188 {
00189     ImageCache::Entry * cacheEntry = ImageCache::getInstance().getSmallImage(
00190             pano->getImage(imgNr).getFilename());
00191     if (! cacheEntry) {
00192         return;
00193     }
00194     wxImage * s_img = cacheEntry->image; 
00195     if (!s_img->Ok()) {
00196         return;
00197     }
00198 
00199     float w = s_img->GetWidth();
00200     float h = s_img->GetHeight();
00201 
00202     // create scaled versions
00203     int bW,bH;
00204 
00205     if ( h > w ) {
00206         // portrait
00207         bW = roundi(w/h * size);
00208         bH = size;
00209     } else {
00210         // landscape
00211         bW = size;
00212         bH = roundi(h/w * size);
00213     }
00214     wxImage img = s_img->Scale(bW, bH);
00215     wxBitmap bimg(img);
00216 
00217     wxMemoryDC temp_dc;
00218     temp_dc.SelectObject(bitmap);
00219     temp_dc.Clear();
00220 /*
00221     wxBitmap maskb(size, size);
00222     wxMemoryDC mask_dc;
00223     mask_dc.SelectObject(maskb);
00224     mask_dc.Clear();
00225     mask_dc.SetBrush(wxBrush("WHITE",wxSOLID));
00226     mask_dc.SetPen(wxPen("WHITE",wxSOLID));
00227 */
00228     if (h > w) {
00229         temp_dc.DrawBitmap(bimg, (size-bW)>>1 ,0);
00230     } else {
00231         temp_dc.DrawBitmap(bimg,0,(size-bH)>>1);
00232     }
00233 //    wxMask * m = new wxMask(bitmap, wxColour(0,0,0));
00234 //    bitmap.SetMask(m);
00235 }
00236 #endif
00237 
00238 void ImagesList::CreateItem(unsigned int imgNr)
00239 {
00240     DEBUG_DEBUG("creating item " << imgNr);
00241     // create the new row
00242     InsertItem ( imgNr, wxString::Format(wxT("%d"),imgNr), imgNr );
00243     UpdateItem(imgNr);
00244 }
00245 
00246 void ImagesList::RemoveItem(unsigned int imgNr)
00247 {
00248     // call wxListCtrl's removal function
00249     wxListCtrl::DeleteItem(imgNr);
00250 }
00251 
00252 void ImagesList::SelectSingleImage(unsigned int imgNr)
00253 {
00254     unsigned int nrItems = GetItemCount();
00255     for (unsigned int i=0; i < nrItems ; i++) {
00256         int selected = GetItemState(i, wxLIST_STATE_SELECTED);
00257         if (i != imgNr && selected) {
00258             SetItemState(i, 0, wxLIST_STATE_SELECTED);
00259         }
00260     }
00261     SetItemState(imgNr, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00262 }
00263 
00264 void ImagesList::SelectImages(const HuginBase::UIntSet imgs)
00265 {
00266     unsigned int nrItems = GetItemCount();
00267     for (unsigned int i=0; i < nrItems ; i++){
00268         if(set_contains(imgs, i))
00269         {
00270             SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00271         }
00272         else
00273         {
00274             SetItemState(i, 0, wxLIST_STATE_SELECTED);
00275         };
00276     }
00277     SetItemState(*imgs.begin(), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00278     selectedItems=imgs;
00279 }
00280 
00281 void ImagesList::SelectImageRange(unsigned int imgStart,unsigned int imgEnd)
00282 {
00283     size_t nrItems = GetItemCount();
00284     size_t _imgStart=imgStart;
00285     size_t _imgEnd=imgEnd;
00286     if(imgEnd<imgStart)
00287     {
00288         _imgStart=imgEnd;
00289         _imgEnd=imgStart;
00290     }
00291     for (size_t i=0; i < nrItems ; i++)
00292     {
00293         int selected = GetItemState(i, wxLIST_STATE_SELECTED);
00294         if ((i < _imgStart || i>_imgEnd ) && selected)
00295         {
00296             SetItemState(i, 0, wxLIST_STATE_SELECTED);
00297         }
00298     }
00299     for(size_t i=_imgStart; i<=_imgEnd; i++)
00300     {
00301         SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00302     };
00303 };
00304 
00305 void ImagesList::SelectAll()
00306 {
00307     unsigned int nrItems = GetItemCount();
00308     for (unsigned int i=0; i < nrItems ; i++)
00309     {
00310         SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00311     }
00312 }
00313 
00314 void ImagesList::DeselectAll()
00315 {
00316     unsigned int nrItems = GetItemCount();
00317     for (unsigned int i=0; i < nrItems ; i++) {
00318         int selected = GetItemState(i, wxLIST_STATE_SELECTED);
00319         if (selected) {
00320             SetItemState(i, 0, wxLIST_STATE_SELECTED);
00321         }
00322     }
00323 }
00324 
00325 void ImagesList::OnItemSelected ( wxListEvent & e )
00326 {
00327     DEBUG_TRACE(e.GetIndex());
00328     if(e.GetIndex() < 0) return;
00329     selectedItems.insert((int)e.GetIndex());
00330     // allow other parents to receive this event, only if its
00331     // generated by the user, and not during an automatic update
00332     // triggered by a change to the panorama
00333     if (m_notifyParents) {
00334         e.Skip();
00335     }
00336 }
00337 
00338 void ImagesList::OnChar(wxKeyEvent &e)
00339 {
00340     switch(e.GetKeyCode())
00341     {
00342         case WXK_INSERT:
00343             {
00344                 wxCommandEvent ev(EVT_IMAGE_ADD,wxID_ANY);
00345                 GetParent()->GetEventHandler()->AddPendingEvent(ev);
00346                 break;
00347             };
00348         case WXK_DELETE:
00349             {
00350                 wxCommandEvent ev(EVT_IMAGE_DEL,wxID_ANY);
00351                 GetParent()->GetEventHandler()->AddPendingEvent(ev);
00352                 break;
00353             };
00354         case 1: //Ctrl+A
00355             {
00356                 if(!m_singleSelect && e.CmdDown())
00357                 {
00358                     SelectAll();
00359                 }
00360                 break;
00361             }
00362     };
00363     e.Skip();
00364 };
00365 
00366 
00367 void ImagesList::OnItemDeselected ( wxListEvent & e )
00368 {
00369     DEBUG_TRACE(e.GetIndex());
00370     if(e.GetIndex() < 0) return;
00371     selectedItems.erase((int)e.GetIndex());
00372     // allow other parents to receive this event, only if its
00373     // generated by the user, and not during an automatic update
00374     // triggered by a change to the panorama
00375     if (m_notifyParents) {
00376         e.Skip();
00377     }
00378 }
00379 
00380 #if 0
00381 void ImagesList::OnItemSelected ( wxListEvent & e )
00382 {
00383     DEBUG_TRACE("");
00384 
00385     // publicate the selected items
00386     selectedImages.clear();
00387 
00388     for ( int Nr=GetItemCount()-1 ; Nr>=0 ; --Nr ) {
00389         if ( GetItemState( Nr, wxLIST_STATE_SELECTED ) ) {
00390             selectedImages.insert(Nr);
00391         }
00392     }
00393     // notify other parties about changed notification..
00394 
00395     // let others recieve the event too
00396     e.Skip(true);
00397     DEBUG_TRACE("end");
00398 }
00399 #endif
00400 
00401 void ImagesList::OnColumnWidthChange( wxListEvent & e )
00402 {
00403     if(m_configClassName != wxT(""))
00404     {
00405         int colNum = e.GetColumn();
00406         wxConfigBase::Get()->Write( m_configClassName+wxString::Format(wxT("/ColumnWidth%d"),colNum), GetColumnWidth(colNum) );
00407     }
00408 }
00409 
00410 void ImagesList::UpdateItem(unsigned int imgNr)
00411 {
00412 
00413 }
00414 
00415 void ImagesList::UpdatePartNumbersForItem(unsigned int imgNr)
00416 {
00417 
00418 }
00419 
00420 IMPLEMENT_DYNAMIC_CLASS(ImagesList, wxListCtrl)
00421 
00422 // ============================================================================
00423 // ============================================================================
00424 // Mask
00425 
00426 ImagesListMask::ImagesListMask()
00427 {
00428 }
00429 
00430 bool ImagesListMask::Create(wxWindow* parent, wxWindowID id,
00431                              const wxPoint& pos,
00432                              const wxSize& size,
00433                              long style,
00434                              const wxString& name)
00435 {
00436     DEBUG_TRACE("");
00437     if (!ImagesList::Create(parent, id, pos, size, wxLC_SINGLE_SEL | style, name))
00438         return false;
00439 
00440     m_configClassName = wxT("/ImagesListMask");
00441 
00442     InsertColumn(1, _("Filename"), wxLIST_FORMAT_LEFT, 200 );
00443     InsertColumn(2, _("Number of masks"), wxLIST_FORMAT_RIGHT,120);
00444     InsertColumn(3, _("Crop"), wxLIST_FORMAT_RIGHT,120);
00445 
00446     //get saved width
00447     for ( int j=0; j < GetColumnCount() ; j++ )
00448     {
00449         // -1 is auto
00450         int width = wxConfigBase::Get()->Read(wxString::Format(m_configClassName+wxT("/ColumnWidth%d"), j ), -1);
00451         if(width != -1)
00452             SetColumnWidth(j, width);
00453     }
00454     return true;
00455 }
00456 
00457 
00458 void ImagesListMask::Init(HuginBase::Panorama * panorama)
00459 {
00460     ImagesList::Init(panorama);
00461 }
00462 
00463 void ImagesListMask::UpdateItem(unsigned int imgNr)
00464 {
00465     const HuginBase::SrcPanoImage & img = pano->getImage(imgNr);
00466     wxFileName fn(wxString (img.getFilename().c_str(), HUGIN_CONV_FILENAME));
00467     SetItem(imgNr, 1, fn.GetFullName() );
00468 
00469     wxString maskstr;
00470     if(img.hasMasks())
00471         maskstr=wxString::Format(wxT("%lu"), (unsigned long int) pano->getImage(imgNr).getMasks().size());
00472     else
00473         maskstr=wxT("-");
00474     SetItem(imgNr, 2, maskstr);
00475 
00476     wxString cropstr(wxT("-"));
00477     if ( img.getCropMode() != HuginBase::SrcPanoImage::NO_CROP )
00478     {
00479         vigra::Rect2D c = img.getCropRect();
00480         cropstr.Printf(wxT("%d,%d,%d,%d"), c.left(), c.right(), c.top(), c.bottom());
00481     }
00482     SetItem(imgNr, 3, cropstr);
00483 }
00484 
00485 void ImagesListMask::SetSingleSelect(bool isSingleSelect)
00486 {
00487     if(isSingleSelect)
00488     {
00489         SetSingleStyle(wxLC_SINGLE_SEL, true);
00490     }
00491     else
00492     {
00493         SetSingleStyle(wxLC_SINGLE_SEL, false);
00494     };
00495     m_singleSelect=(GetWindowStyle() & wxLC_SINGLE_SEL)!=0;
00496 
00497 };
00498 
00499 IMPLEMENT_DYNAMIC_CLASS(ImagesListMask, ImagesList)
00500 
00501 ImagesListMaskXmlHandler::ImagesListMaskXmlHandler()
00502     : wxXmlResourceHandler()
00503 {
00504     AddWindowStyles();
00505 }
00506 
00507 wxObject *ImagesListMaskXmlHandler::DoCreateResource()
00508 {
00509     XRC_MAKE_INSTANCE(cp, ImagesListMask)
00510 
00511     cp->Create(m_parentAsWindow,
00512                GetID(),
00513                GetPosition(), GetSize(),
00514                GetStyle(wxT("style")),
00515                GetName());
00516 
00517     SetupWindow( cp);
00518 
00519     return cp;
00520 }
00521 
00522 bool ImagesListMaskXmlHandler::CanHandle(wxXmlNode *node)
00523 {
00524     return IsOfClass(node, wxT("ImagesListMask"));
00525 }
00526 
00527 IMPLEMENT_DYNAMIC_CLASS(ImagesListMaskXmlHandler, wxXmlResourceHandler)
00528 

Generated on 26 Sep 2016 for Hugintrunk by  doxygen 1.4.7