selectionlib.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #if !defined (INCLUDED_SELECTIONLIB_H)
00023 #define INCLUDED_SELECTIONLIB_H
00024 
00025 #include "iselection.h"
00026 #include "generic/callback.h"
00027 #include "scenelib.h"
00028 #include <stdlib.h>
00029 
00030 class SelectableBool: public Selectable
00031 {
00032         bool m_selected;
00033     public:
00034         SelectableBool () :
00035             m_selected(false)
00036         {
00037         }
00038 
00039         void setSelected (bool select = true)
00040         {
00041             m_selected = select;
00042         }
00043         bool isSelected () const
00044         {
00045             return m_selected;
00046         }
00047 };
00048 
00049 // greebo: A selectable with an attached callback function that is called upon selection (change)
00050 // in the case of the PatchInstance the callback points to PatchInstance::selectedChangedComponent()
00051 class ObservedSelectable: public Selectable
00052 {
00053         SelectionChangeCallback m_onchanged;
00054         bool m_selected;
00055     public:
00056         ObservedSelectable (const SelectionChangeCallback& onchanged) :
00057             m_onchanged(onchanged), m_selected(false)
00058         {
00059         }
00060         ObservedSelectable (const ObservedSelectable& other) :
00061             Selectable(other), m_onchanged(other.m_onchanged), m_selected(false)
00062         {
00063             setSelected(other.isSelected());
00064         }
00065         ObservedSelectable& operator= (const ObservedSelectable& other)
00066         {
00067             setSelected(other.isSelected());
00068             return *this;
00069         }
00070         ~ObservedSelectable ()
00071         {
00072             setSelected(false);
00073         }
00074 
00075         void setSelected (bool select)
00076         {
00077             if (select ^ m_selected) {
00078                 m_selected = select;
00079 
00080                 m_onchanged(*this);
00081             }
00082         }
00083         bool isSelected () const
00084         {
00085             return m_selected;
00086         }
00087 };
00088 
00089 class SelectableInstance: public scene::Instance
00090 {
00091         class TypeCasts
00092         {
00093                 InstanceTypeCastTable m_casts;
00094             public:
00095                 TypeCasts ()
00096                 {
00097                     InstanceContainedCast<SelectableInstance, Selectable>::install(m_casts);
00098                 }
00099                 InstanceTypeCastTable& get ()
00100                 {
00101                     return m_casts;
00102                 }
00103         };
00104 
00105         ObservedSelectable m_selectable;
00106     public:
00107 
00108         typedef LazyStatic<TypeCasts> StaticTypeCasts;
00109 
00110         SelectableInstance (const scene::Path& path, scene::Instance* parent, void* instance = 0,
00111                 InstanceTypeCastTable& casts = StaticTypeCasts::instance().get()) :
00112             Instance(path, parent, instance != 0 ? instance : this, casts), m_selectable(SelectedChangedCaller(*this))
00113         {
00114         }
00115 
00116         Selectable& get (NullType<Selectable> )
00117         {
00118             return m_selectable;
00119         }
00120 
00121         Selectable& getSelectable ()
00122         {
00123             return m_selectable;
00124         }
00125         const Selectable& getSelectable () const
00126         {
00127             return m_selectable;
00128         }
00129 
00130         void selectedChanged (const Selectable& selectable)
00131         {
00132             GlobalSelectionSystem().getObserver(SelectionSystem::ePrimitive)(selectable);
00133             GlobalSelectionSystem().onSelectedChanged(*this, selectable);
00134 
00135             Instance::selectedChanged();
00136         }
00137         typedef MemberCaller1<SelectableInstance, const Selectable&, &SelectableInstance::selectedChanged>
00138                 SelectedChangedCaller;
00139 };
00140 
00141 template<typename Iterator>
00142 inline bool range_check (Iterator start, Iterator finish, Iterator iter)
00143 {
00144     for (; start != finish; ++start) {
00145         if (start == iter) {
00146             return true;
00147         }
00148     }
00149     return false;
00150 }
00151 
00152 #include <list>
00153 
00154 template<typename Selected>
00155 class SelectionList
00156 {
00157         typedef std::list<Selected*> List;
00158         List m_selection;
00159     public:
00160         typedef typename List::iterator iterator;
00161         typedef typename List::const_iterator const_iterator;
00162 
00163         iterator begin ()
00164         {
00165             return m_selection.begin();
00166         }
00167         const_iterator begin () const
00168         {
00169             return m_selection.begin();
00170         }
00171         iterator end ()
00172         {
00173             return m_selection.end();
00174         }
00175         const_iterator end () const
00176         {
00177             return m_selection.end();
00178         }
00179         bool empty () const
00180         {
00181             return m_selection.empty();
00182         }
00183         std::size_t size () const
00184         {
00185             return m_selection.size();
00186         }
00187         Selected& back ()
00188         {
00189             return *m_selection.back();
00190         }
00191         Selected& back () const
00192         {
00193             return *m_selection.back();
00194         }
00195         void append (Selected& selected)
00196         {
00197             m_selection.push_back(&selected);
00198         }
00199         void erase (Selected& selected)
00200         {
00201             typename List::reverse_iterator i = std::find(m_selection.rbegin(), m_selection.rend(), &selected);
00202             ASSERT_MESSAGE(i != m_selection.rend(), "selection-tracking error");
00203             ASSERT_MESSAGE(range_check(m_selection.begin(), m_selection.end(), --i.base()), "selection-tracking error");
00204             m_selection.erase(--i.base());
00205         }
00206 };
00207 
00208 #endif

Generated by  doxygen 1.6.2