Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CEGUIItemListBase.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIItemListBase.cpp
00003         created:        31/3/2005
00004         author:         Tomas Lindquist Olsen (based on original Listbox code by Paul D Turner)
00005         
00006         purpose:        Implementation of ItemListBase widget base class
00007 *************************************************************************/
00008 /*************************************************************************
00009     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Lesser General Public
00014     License as published by the Free Software Foundation; either
00015     version 2.1 of the License, or (at your option) any later version.
00016 
00017     This library is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020     Lesser General Public License for more details.
00021 
00022     You should have received a copy of the GNU Lesser General Public
00023     License along with this library; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 *************************************************************************/
00026 #include "CEGUIExceptions.h"
00027 #include "CEGUIWindowManager.h"
00028 #include "elements/CEGUIItemListBase.h"
00029 #include "elements/CEGUIItemEntry.h"
00030 
00031 #include <algorithm>
00032 
00033 // Start of CEGUI namespace section
00034 namespace CEGUI
00035 {
00036 
00037 /*************************************************************************
00038         Definition of Properties for this class
00039 *************************************************************************/
00040 ItemListBaseProperties::AutoResizeEnabled       ItemListBase::d_autoResizeEnabledProperty;
00041 
00042 
00043 /*************************************************************************
00044         Constants
00045 *************************************************************************/
00046 // event names
00047 const String ItemListBase::EventNamespace("ItemListBase");
00048 const String ItemListBase::EventListContentsChanged( (utf8*)"ListItemsChanged" );
00049 
00050         
00051 /*************************************************************************
00052         Constructor for ItemListBase base class.
00053 *************************************************************************/
00054 ItemListBase::ItemListBase(const String& type, const String& name)
00055         : Window(type, name),
00056         d_autoResize(false)
00057 {
00058         // add new events specific to ItemListBase.
00059         addItemListBaseEvents();
00060 
00061         // add properties for ItemListBase class
00062         addItemListBaseProperties();
00063 }
00064 
00065 
00066 /*************************************************************************
00067         Destructor for ItemListBase base class.
00068 *************************************************************************/
00069 ItemListBase::~ItemListBase(void)
00070 {
00071         resetList_impl();
00072 }
00073 
00074 
00075 /*************************************************************************
00076         Initialise the Window based object ready for use.
00077 *************************************************************************/
00078 void ItemListBase::initialise(void)
00079 {
00080         //layoutItemWidgets();
00081 }
00082 
00083 
00084 /*************************************************************************
00085         Return the item at index position 'index'.
00086 *************************************************************************/
00087 ItemEntry* ItemListBase::getItemFromIndex(size_t index) const
00088 {
00089         if (index < d_listItems.size())
00090         {
00091                 return d_listItems[index];
00092         }
00093         else
00094         {
00095                 throw InvalidRequestException((utf8*)"ItemListBase::getItemFromIndex - the specified index is out of range for this ItemListBase.");
00096         }
00097 }
00098 
00099 
00100 /*************************************************************************
00101         Return the index of ItemEntry \a item
00102 *************************************************************************/
00103 size_t ItemListBase::getItemIndex(const ItemEntry* item) const
00104 {
00105         ItemEntryList::const_iterator pos = std::find(d_listItems.begin(), d_listItems.end(), item);
00106 
00107         if (pos != d_listItems.end())
00108         {
00109                 return std::distance(d_listItems.begin(), pos);
00110         }
00111         else
00112         {
00113                 throw InvalidRequestException((utf8*)"ItemListBase::getItemIndex - the specified ItemEntry is not attached to this ItemListBase.");
00114         }
00115 
00116 }
00117 
00118 
00119 /*************************************************************************
00120         Search the list for an item with the specified text
00121 *************************************************************************/
00122 ItemEntry* ItemListBase::findItemWithText(const String& text, const ItemEntry* start_item)
00123 {
00124         // if start_item is NULL begin search at begining, else start at item after start_item
00125         size_t index = (start_item == NULL) ? 0 : (getItemIndex(start_item) + 1);
00126 
00127         while (index < d_listItems.size())
00128         {
00129                 // return pointer to this item if it's text matches
00130                 if (d_listItems[index]->getText() == text)
00131                 {
00132                         return d_listItems[index];
00133                 }
00134                 // no matching text, advance to next item
00135                 else
00136                 {
00137                         index++;
00138                 }
00139 
00140         }
00141 
00142         // no items matched.
00143         return NULL;
00144 }
00145 
00146 
00147 /*************************************************************************
00148         Return whether the specified ItemEntry is in the List
00149 *************************************************************************/
00150 bool ItemListBase::isItemInList(const ItemEntry* item) const
00151 {
00152         return std::find(d_listItems.begin(), d_listItems.end(), item) != d_listItems.end();
00153 }
00154 
00155 
00156 
00157 /*************************************************************************
00158         Remove all items from the list.
00159 *************************************************************************/
00160 void ItemListBase::resetList(void)
00161 {
00162         if (resetList_impl())
00163         {
00164                 WindowEventArgs args(this);
00165                 onListContentsChanged(args);
00166         }
00167 
00168 }
00169 
00170 
00171 /*************************************************************************
00172         Add the given ItemEntry to the list.
00173 *************************************************************************/
00174 void ItemListBase::addItem(ItemEntry* item)
00175 {
00176         if (item != NULL)
00177         {
00178                 // just stick it on the end.
00179                 d_listItems.push_back(item);
00180                 addChildWindow(item);
00181                 WindowEventArgs args(this);
00182                 onListContentsChanged(args);
00183         }
00184 
00185 }
00186 
00187 
00188 /*************************************************************************
00189         Insert an item into the list box after a specified item already in
00190         the list.
00191 *************************************************************************/
00192 void ItemListBase::insertItem(ItemEntry* item, const ItemEntry* position)
00193 {
00194         if (item != NULL)
00195         {
00196                 // if position is NULL begin insert at begining, else insert after item 'position'
00197                 ItemEntryList::iterator ins_pos;
00198 
00199                 if (position == NULL)
00200                 {
00201                         ins_pos = d_listItems.begin();
00202                 }
00203                 else
00204                 {
00205                         ins_pos = std::find(d_listItems.begin(), d_listItems.end(), position);
00206 
00207                         // throw if item 'position' is not in the list
00208                         if (ins_pos == d_listItems.end())
00209                         {
00210                                 throw InvalidRequestException((utf8*)"ItemListBase::insertItem - the specified ItemEntry for parameter 'position' is not attached to this ItemListBase.");
00211                         }
00212 
00213                 }
00214                 
00215                 d_listItems.insert(ins_pos, item);
00216                 addChildWindow(item);
00217 
00218                 WindowEventArgs args(this);
00219                 onListContentsChanged(args);
00220         }
00221 
00222 }
00223 
00224 
00225 /*************************************************************************
00226         Removes the given item from the list box.
00227 *************************************************************************/
00228 void ItemListBase::removeItem(ItemEntry* item)
00229 {
00230         if (item != NULL)
00231         {
00232                 ItemEntryList::iterator pos = std::find(d_listItems.begin(), d_listItems.end(), item);
00233 
00234                 // if item is in the list
00235                 if (pos != d_listItems.end())
00236                 {
00237                         // remove item
00238                         d_listItems.erase(pos);
00239 
00240                         removeChildWindow(item);
00241                         WindowManager::getSingleton().destroyWindow(item);
00242 
00243                         WindowEventArgs args(this);
00244                         onListContentsChanged(args);
00245                 }
00246 
00247         }
00248         
00249 }
00250 
00251 /*************************************************************************
00252         Set wheter or not this ItemListBase widget should automatically
00253         resize to fit its content.
00254 *************************************************************************/
00255 void ItemListBase::setAutoResizeEnabled(bool setting)
00256 {
00257         bool old = d_autoResize;
00258         d_autoResize = setting;
00259 
00260         // if not already enabled, trigger a resize
00261         if ( d_autoResize && !old )
00262         {
00263                 sizeToContent();
00264         }
00265 
00266 }
00267 
00268 /*************************************************************************
00269         Causes the list box to update it's internal state after changes have
00270         been made to one or more attached ItemEntry objects.    
00271 *************************************************************************/
00272 void ItemListBase::handleUpdatedItemData(void)
00273 {
00274         WindowEventArgs args(this);
00275         onListContentsChanged(args);
00276 }
00277 
00278 
00279 /*************************************************************************
00280         Add list box specific events
00281 *************************************************************************/
00282 void ItemListBase::addItemListBaseEvents(void)
00283 {
00284         addEvent(EventListContentsChanged);
00285 }
00286 
00287 
00288 /*************************************************************************
00289         Handler called internally when the list contents are changed    
00290 *************************************************************************/
00291 void ItemListBase::onListContentsChanged(WindowEventArgs& e)
00292 {       
00293         requestRedraw();
00294 
00295         // if auto resize is enabled - do it
00296         if ( d_autoResize )
00297         {
00298                 sizeToContent();
00299         }
00300         
00301         layoutItemWidgets();
00302         fireEvent(EventListContentsChanged, e, EventNamespace);
00303 }
00304 
00305 
00306 /*************************************************************************
00307         Handler for when we are sized
00308 *************************************************************************/
00309 void ItemListBase::onSized(WindowEventArgs& e)
00310 {
00311         // base class handling
00312         Window::onSized(e);
00313 
00314         //layoutItemWidgets();
00315 
00316         e.handled = true;
00317 }
00318 
00319 
00320 /*************************************************************************
00321         Remove all items from the list.
00322 *************************************************************************/
00323 bool ItemListBase::resetList_impl(void)
00324 {
00325         // just return false if the list is already empty
00326         if (getItemCount() == 0)
00327         {
00328                 return false;
00329         }
00330         // we have items to be removed and possible deleted
00331         else
00332         {
00333                 // delete any items we are supposed to ---------- DESTROYS ALL ITEMS !!!
00334                 for (size_t i = 0; i < getItemCount(); ++i)
00335                 {
00336                         removeChildWindow(d_listItems[i]);
00337                         WindowManager::getSingleton().destroyWindow(d_listItems[i]);
00338                 }
00339 
00340                 // clear out the list.
00341                 d_listItems.clear();
00342 
00343                 return true;
00344         }
00345 
00346 }
00347 
00348 
00349 /*************************************************************************
00350         Add ItemListBase specific properties
00351 *************************************************************************/
00352 void ItemListBase::addItemListBaseProperties(void)
00353 {
00354     addProperty(&d_autoResizeEnabledProperty);
00355 }
00356 
00357 
00358 /*************************************************************************
00359         Internal version of adding a child window.
00360 *************************************************************************/
00361 void ItemListBase::addChild_impl(Window* wnd)
00362 {
00363         Window::addChild_impl(wnd);
00364 
00365         // if this is an ItemEntry we add it like one. only if it is not already in the list!
00366         if (wnd->testClassName("ItemEntry")&&!isItemInList((ItemEntry*)wnd))
00367         {
00368                 // perform normal addItem - please no more infinite recursion !#?¤
00369                 d_listItems.push_back((ItemEntry*)wnd);
00370                 WindowEventArgs args(this);
00371                 onListContentsChanged(args);
00372         }
00373 
00374 }
00375 
00376 } // End of  CEGUI namespace section

Generated on Wed Sep 7 09:56:32 2005 for Crazy Eddies GUI System by  doxygen 1.4.3