CPImagesComboBox.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00013 /*  This program is free software; you can redistribute it and/or
00014  *  modify it under the terms of the GNU General Public
00015  *  License as published by the Free Software Foundation; either
00016  *  version 2 of the License, or (at your option) any later version.
00017  *
00018  *  This software is distributed in the hope that it will be useful,
00019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021  *  General Public License for more details.
00022  *
00023  *  You should have received a copy of the GNU General Public
00024  *  License along with this software. If not, see
00025  *  <http://www.gnu.org/licenses/>.
00026  *
00027  */
00028 
00029 #include "hugin/CPImagesComboBox.h"
00030 
00031 BEGIN_EVENT_TABLE(CPImagesComboBox,wxOwnerDrawnComboBox)
00032     EVT_MOUSEWHEEL(CPImagesComboBox::OnMouseWheel)
00033     EVT_KEY_DOWN(CPImagesComboBox::OnKeyDown)
00034 END_EVENT_TABLE()
00035 
00036 void CPImagesComboBox::OnMouseWheel(wxMouseEvent & e)
00037 {
00038     //mimic wxChoice behaviour
00039     //when popup is shown, there could be a scrollbar which processes the mouse wheel event
00040     if(!IsPopupShown())
00041     {
00042         if(e.GetWheelRotation()<0)
00043             SelectNext();
00044         else
00045             SelectPrev();
00046     }
00047     else
00048     {
00049         e.Skip();
00050     };
00051 };
00052 
00053 void CPImagesComboBox::OnKeyDown(wxKeyEvent & e)
00054 {
00055     if(!IsPopupShown())
00056     {
00057         //mimic wxChoice behaviour
00058         switch (e.GetKeyCode()){
00059             case WXK_DOWN:
00060             case WXK_RIGHT:
00061             case WXK_NUMPAD_DOWN:
00062             case WXK_NUMPAD_RIGHT:
00063                 SelectNext();
00064                 break;
00065             case WXK_UP:
00066             case WXK_LEFT:
00067             case WXK_NUMPAD_UP:
00068             case WXK_NUMPAD_LEFT:
00069                 SelectPrev();
00070                 break;
00071             case WXK_PAGEDOWN:
00072             case WXK_NUMPAD_PAGEDOWN:
00073                 SelectNext(5);
00074                 break;
00075             case WXK_PAGEUP:
00076             case WXK_NUMPAD_PAGEUP:
00077                 SelectPrev(5);
00078                 break;
00079             case WXK_HOME:
00080             case WXK_NUMPAD_HOME:
00081                 SelectPrev(GetCount());
00082                 break;
00083             case WXK_END:
00084             case WXK_NUMPAD_END:
00085                 SelectNext(GetCount());
00086                 break;
00087             case WXK_SPACE:
00088                 ShowPopup();
00089                 break;
00090             default:
00091                 e.Skip();
00092         };
00093     }
00094     else
00095     {
00096         e.Skip();
00097     }
00098 };
00099 
00100 void CPImagesComboBox::SelectNext(int step)
00101 {
00102     int index=min<int>(GetSelection()+step,GetCount()-1);
00103     if(index!=GetSelection())
00104     {
00105         Select(index);
00106         Update();
00107         NotifyParent();
00108     };
00109 };
00110 
00111 void CPImagesComboBox::SelectPrev(int step)
00112 {
00113     int index=max<int>(GetSelection()-step,0);
00114     if(index!=GetSelection())
00115     {
00116         Select(index);
00117         Update();
00118         NotifyParent();
00119     };
00120 };
00121 
00122 void CPImagesComboBox::NotifyParent()
00123 {
00124     //notify parent about changed selection
00125     //select doesn't send the corresponding event
00126     wxCommandEvent ne(wxEVT_COMMAND_COMBOBOX_SELECTED);
00127     ne.SetEventObject(this);
00128     ne.SetId(this->GetId());
00129     ne.SetInt(GetSelection());
00130     ProcessEvent(ne);
00131 };
00132 
00133 void CPImagesComboBox::Init()
00134 {
00135     CPConnection.resize(0);
00136     refImage=0;
00137 };
00138 
00139 void CPImagesComboBox::OnDrawItem(wxDC& dc,
00140                                   const wxRect& rect,
00141                                   int item,
00142                                   int WXUNUSED(flags)) const
00143 {
00144     if ( item == wxNOT_FOUND )
00145        return;
00146 
00147     wxCoord w, h;
00148     GetTextExtent(GetString(item), &w, &h);
00149     wxCoord maxWidth=0.73*rect.width-3;
00150 
00151     // TODO: note that since wxWidgets 2.9.0 you should not use wxT anymore <http://docs.wxwidgets.org/trunk/group__group__funcmacro__string.html#g437ea6ba615b75dac8603e96ec864160>
00152 
00153     // if image connected by control points, add number of CPs to width equation as well
00154     wxCoord qty_w = 0;
00155     wxString qty_cp = wxT("");
00156     if(CPConnection[item]>-1.0)
00157     {
00158         qty_cp = wxString::Format(wxT(" %d"), CPCount[item]);
00159         GetTextExtent(qty_cp, &qty_w, &h);
00160     }
00161 
00162     // determine if the string can fit inside the current combo box
00163     if (w +qty_w <= maxWidth)
00164     {
00165         // it can, draw it 
00166         dc.DrawText(GetString(item),rect.x + 3,rect.y + ((rect.height - dc.GetCharHeight())/2));
00167 
00168     }
00169     else // otherwise, truncate and add an ellipsis
00170     {
00171         // determine the base width
00172         wxString ellipsis(wxT("..."));
00173         wxCoord base_w;
00174         GetTextExtent(ellipsis, &base_w, &h);
00175 
00176         // continue until we have enough space or only one character left
00177         wxString drawntext = GetString(item);
00178         while (drawntext.length() > 1)
00179         {
00180             drawntext.RemoveLast();
00181             GetTextExtent(drawntext,&w,&h);
00182             if (w + base_w + qty_w <= maxWidth)
00183                 break;
00184         }
00185 
00186         // now draw the text
00187         dc.DrawText(drawntext, rect.x + 3, rect.y + ((rect.height - dc.GetCharHeight())/2));
00188         dc.DrawText(ellipsis, rect.x + 3 + w, rect.y + ((rect.height - dc.GetCharHeight())/2));
00189     }
00190 
00191     // draw rectangle when images are connected by control points
00192     if(CPConnection[item]>-1.0)
00193     {
00194         wxCoord x;
00195         x=rect.width / 5 *(1-min<double>(CPConnection[item],10)/10);
00196         //ensure that always a bar is drawn
00197         x=max<wxCoord>(5,x);
00198         const wxPen * oldPen = & dc.GetPen();
00199         const wxBrush * oldBrush= & dc.GetBrush();
00200         //inner rectangle with color proportional to max cp error (max. 10)
00201 #if wxCHECK_VERSION(3,0,0)
00202         wxPen MyPen(wxColour(255, 0, 0), 1, wxPENSTYLE_SOLID);
00203         wxBrush MyBrush(wxColour(255,0,0), wxBRUSHSTYLE_SOLID);
00204 #else
00205         wxPen MyPen(wxColour(255,0,0),1,wxSOLID);
00206         wxBrush MyBrush(wxColour(255,0,0),wxSOLID);
00207 #endif
00208         double red, green, blue;
00209 
00210         hugin_utils::ControlPointErrorColour(CPConnection[item],red,green,blue);
00211 
00212         //Scale colour to 0-255
00213         red *= 255;
00214         green *= 255;
00215 
00216         MyPen.SetColour(wxColour(red,green,0));
00217         MyBrush.SetColour(wxColour(red,green,0));
00218         dc.SetPen(MyPen);
00219         dc.SetBrush(MyBrush);
00220         dc.DrawRectangle(rect.x+0.75*rect.width,rect.y+rect.height/6+1,x,2*rect.height/3);
00221 /*
00222         // half the rectangle
00223         int half=rect.width/10;
00224         // color steps
00225         double step_red=255.0/half;
00226         double step_green=192.0/half;
00227         // starting color
00228         double red=255.0;
00229         double green=0.0;
00230         for(int i=0;i<x;i++)
00231         {
00232             MyPen.SetColour(wxColour(red,green,0));
00233             MyBrush.SetColour(wxColour(red,green,0));
00234             dc.SetPen(MyPen);
00235             dc.SetBrush(MyBrush);
00236             dc.DrawRectangle(rect.x+0.75*rect.width+i,rect.y+rect.height/6+1,1,2*rect.height/3);
00237             // gradient calculation
00238             if(i<half)
00239             {
00240                 // until half-way increase the green
00241                 green=green+step_green;
00242             }
00243             else
00244             {
00245                 // after half-way decrease the red
00246                 red=red-step_red;
00247             }
00248         }
00249 */
00250         //outer rectangle, same colour as text
00251         MyPen.SetColour(dc.GetTextForeground());
00252         dc.SetPen(MyPen);
00253         dc.SetBrush(*wxTRANSPARENT_BRUSH);
00254         dc.DrawRectangle(rect.x+0.75*rect.width,rect.y+rect.height/6+1,rect.width/5,2*rect.height/3);
00255         dc.SetPen(*oldPen);
00256         dc.SetBrush(*oldBrush);
00257 
00258         // draw number of connecting CPs
00259         dc.DrawText(qty_cp, rect.x - 3 - qty_w +0.75*rect.width , rect.y + ((rect.height - dc.GetCharHeight())/2));
00260 
00261     };
00262 };
00263 
00264 void CPImagesComboBox::CalcCPDistance(Panorama * pano)
00265 {
00266     CPConnection.clear();
00267     CPCount.clear();
00268     CPConnection.resize(this->GetCount(),-1.0);
00269     CPCount.resize(this->GetCount(),0);
00270     unsigned int noPts = pano->getNrOfCtrlPoints();
00271     // loop over all points to get the maximum error and to count the number of CPs
00272     for (unsigned int ptIdx = 0 ; ptIdx < noPts ; ptIdx++)
00273     {
00274         const HuginBase::ControlPoint & cp = pano->getCtrlPoint(ptIdx);
00275         if(cp.image1Nr==refImage)
00276         {
00277             CPConnection[cp.image2Nr]=max<double>(cp.error,CPConnection[cp.image2Nr]);
00278             CPCount[cp.image2Nr]++;
00279         }
00280         else if(cp.image2Nr==refImage)
00281         {
00282             CPConnection[cp.image1Nr]=max<double>(cp.error,CPConnection[cp.image1Nr]);
00283             CPCount[cp.image1Nr]++;
00284         };
00285     }
00286 };
00287 
00288 IMPLEMENT_DYNAMIC_CLASS(CPImagesComboBox, wxOwnerDrawnComboBox)
00289 
00290 IMPLEMENT_DYNAMIC_CLASS(CPImagesComboBoxXmlHandler, wxOwnerDrawnComboBoxXmlHandler)
00291 
00292 CPImagesComboBoxXmlHandler::CPImagesComboBoxXmlHandler()
00293                 : wxOwnerDrawnComboBoxXmlHandler()
00294 {
00295     AddWindowStyles();
00296 }
00297 
00298 wxObject *CPImagesComboBoxXmlHandler::DoCreateResource()
00299 {
00300     XRC_MAKE_INSTANCE(cp, CPImagesComboBox)
00301 
00302     cp->Create(m_parentAsWindow,
00303                    GetID(), wxEmptyString,
00304                    GetPosition(), GetSize(),
00305                    GetStyle(wxT("style")), wxDefaultValidator,
00306                    GetName());
00307 
00308     SetupWindow(cp);
00309 
00310     return cp;
00311 }
00312 
00313 bool CPImagesComboBoxXmlHandler::CanHandle(wxXmlNode *node)
00314 {
00315     return IsOfClass(node, wxT("CPImagesComboBox"));
00316 }

Generated on 1 Aug 2015 for Hugintrunk by  doxygen 1.4.7