selectionlib.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00050
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