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, write to the Free Software
00025  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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         wxPen MyPen(wxColour(255,0,0),1,wxSOLID);
00202         wxBrush MyBrush(wxColour(255,0,0),wxSOLID);
00203         double red, green, blue;
00204 
00205         hugin_utils::ControlPointErrorColour(CPConnection[item],red,green,blue);
00206 
00207         //Scale colour to 0-255
00208         red *= 255;
00209         green *= 255;
00210 
00211         MyPen.SetColour(wxColour(red,green,0));
00212         MyBrush.SetColour(wxColour(red,green,0));
00213         dc.SetPen(MyPen);
00214         dc.SetBrush(MyBrush);
00215         dc.DrawRectangle(rect.x+0.75*rect.width,rect.y+rect.height/6+1,x,2*rect.height/3);
00216 /*
00217         // half the rectangle
00218         int half=rect.width/10;
00219         // color steps
00220         double step_red=255.0/half;
00221         double step_green=192.0/half;
00222         // starting color
00223         double red=255.0;
00224         double green=0.0;
00225         for(int i=0;i<x;i++)
00226         {
00227             MyPen.SetColour(wxColour(red,green,0));
00228             MyBrush.SetColour(wxColour(red,green,0));
00229             dc.SetPen(MyPen);
00230             dc.SetBrush(MyBrush);
00231             dc.DrawRectangle(rect.x+0.75*rect.width+i,rect.y+rect.height/6+1,1,2*rect.height/3);
00232             // gradient calculation
00233             if(i<half)
00234             {
00235                 // until half-way increase the green
00236                 green=green+step_green;
00237             }
00238             else
00239             {
00240                 // after half-way decrease the red
00241                 red=red-step_red;
00242             }
00243         }
00244 */
00245         //outer rectangle, same colour as text
00246         MyPen.SetColour(dc.GetTextForeground());
00247         dc.SetPen(MyPen);
00248         dc.SetBrush(*wxTRANSPARENT_BRUSH);
00249         dc.DrawRectangle(rect.x+0.75*rect.width,rect.y+rect.height/6+1,rect.width/5,2*rect.height/3);
00250         dc.SetPen(*oldPen);
00251         dc.SetBrush(*oldBrush);
00252 
00253         // draw number of connecting CPs
00254         dc.DrawText(qty_cp, rect.x - 3 - qty_w +0.75*rect.width , rect.y + ((rect.height - dc.GetCharHeight())/2));
00255 
00256     };
00257 };
00258 
00259 void CPImagesComboBox::CalcCPDistance(Panorama * pano)
00260 {
00261     CPConnection.clear();
00262     CPCount.clear();
00263     CPConnection.resize(this->GetCount(),-1.0);
00264     CPCount.resize(this->GetCount(),0);
00265     unsigned int noPts = pano->getNrOfCtrlPoints();
00266     // loop over all points to get the maximum error and to count the number of CPs
00267     for (unsigned int ptIdx = 0 ; ptIdx < noPts ; ptIdx++)
00268     {
00269         const ControlPoint & cp = pano->getCtrlPoint(ptIdx);
00270         if(cp.image1Nr==refImage)
00271         {
00272             CPConnection[cp.image2Nr]=max<double>(cp.error,CPConnection[cp.image2Nr]);
00273             CPCount[cp.image2Nr]++;
00274         }
00275         else if(cp.image2Nr==refImage)
00276         {
00277             CPConnection[cp.image1Nr]=max<double>(cp.error,CPConnection[cp.image1Nr]);
00278             CPCount[cp.image1Nr]++;
00279         };
00280     }
00281 };
00282 
00283 IMPLEMENT_DYNAMIC_CLASS(CPImagesComboBox, wxOwnerDrawnComboBox)
00284 
00285 IMPLEMENT_DYNAMIC_CLASS(CPImagesComboBoxXmlHandler, wxOwnerDrawnComboBoxXmlHandler)
00286 
00287 CPImagesComboBoxXmlHandler::CPImagesComboBoxXmlHandler()
00288                 : wxOwnerDrawnComboBoxXmlHandler()
00289 {
00290     AddWindowStyles();
00291 }
00292 
00293 wxObject *CPImagesComboBoxXmlHandler::DoCreateResource()
00294 {
00295     XRC_MAKE_INSTANCE(cp, CPImagesComboBox)
00296 
00297     cp->Create(m_parentAsWindow,
00298                    GetID(), wxEmptyString,
00299                    GetPosition(), GetSize(),
00300                    GetStyle(wxT("style")), wxDefaultValidator,
00301                    GetName());
00302 
00303     SetupWindow(cp);
00304 
00305     return cp;
00306 }
00307 
00308 bool CPImagesComboBoxXmlHandler::CanHandle(wxXmlNode *node)
00309 {
00310     return IsOfClass(node, wxT("CPImagesComboBox"));
00311 }

Generated on Wed Aug 20 01:25:30 2014 for Hugintrunk by  doxygen 1.3.9.1