cellSelector.h 3.96 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1 2 3
#ifndef _CELL_SELECTOR_H_
#define _CELL_SELECTOR_H_

4
#include <QObject>
Pierre Kraemer's avatar
Pierre Kraemer committed
5
#include <QString>
6
#include <QList>
Pierre Kraemer's avatar
Pierre Kraemer committed
7 8 9 10 11

#include "Topology/generic/dart.h"
#include "Topology/generic/genericmap.h"
#include "Topology/generic/cellmarker.h"

12 13
#include "slot_debug.h"

Sylvain Thery's avatar
Sylvain Thery committed
14 15 16 17 18 19 20 21 22
#ifdef WIN32
#if defined SCHNAPPSLIB_DLL_EXPORT
#define SCHNAPPS_API __declspec(dllexport)
#else
#define SCHNAPPS_API __declspec(dllimport)
#endif
#endif


Pierre Kraemer's avatar
Pierre Kraemer committed
23 24 25 26 27 28
namespace CGoGN
{

namespace SCHNApps
{

Sylvain Thery's avatar
Sylvain Thery committed
29
class SCHNAPPS_API CellSelectorGen : public QObject
Pierre Kraemer's avatar
Pierre Kraemer committed
30
{
31 32
	Q_OBJECT

Pierre Kraemer's avatar
Pierre Kraemer committed
33 34 35 36 37 38 39 40 41
public:
	static unsigned int selectorCount;

	CellSelectorGen(const QString& name);
	virtual ~CellSelectorGen()
	{}

	inline const QString& getName() { return m_name; }

42
	virtual unsigned int getOrbit() const = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
43

44
	virtual unsigned int getNbSelectedCells() const = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
45

46 47
	virtual void rebuild() = 0;

48 49 50 51
	inline void checkChange()
	{
		if(m_selectionChanged)
		{
52
			DEBUG_EMIT("selectedCellsChanged");
53 54 55 56 57
			emit(selectedCellsChanged());
			m_selectionChanged = false;
		}
	}

58 59
	inline void setMutuallyExclusive(bool b) { m_isMutuallyExclusive = b; }
	inline bool isMutuallyExclusive() const { return m_isMutuallyExclusive; }
60
	virtual void setMutuallyExclusiveSet(const QList<CellSelectorGen*>& mex) = 0;
61

62 63 64 65
signals:
	void selectedCellsChanged();

protected:
Pierre Kraemer's avatar
Pierre Kraemer committed
66
	QString m_name;
67
	bool m_isMutuallyExclusive;
68
	bool m_selectionChanged;
Pierre Kraemer's avatar
Pierre Kraemer committed
69 70
};

Pierre Kraemer's avatar
Pierre Kraemer committed
71
template <typename MAP, unsigned int ORBIT>
Pierre Kraemer's avatar
Pierre Kraemer committed
72 73
class CellSelector : public CellSelectorGen
{
74 75 76
	typedef Cell<ORBIT> CELL;
	typedef CellSelector<MAP, ORBIT> SELECTOR;

Pierre Kraemer's avatar
Pierre Kraemer committed
77
public:
Sylvain Thery's avatar
Sylvain Thery committed
78
	CellSelector(MAP& map, const QString& name) :
Pierre Kraemer's avatar
Pierre Kraemer committed
79
		CellSelectorGen(name),
80
		m_map(map),
Sylvain Thery's avatar
Sylvain Thery committed
81
		m_cm(map)
Pierre Kraemer's avatar
Pierre Kraemer committed
82 83 84 85 86
	{}

	~CellSelector()
	{}

87
	inline unsigned int getOrbit() const { return ORBIT; }
Pierre Kraemer's avatar
Pierre Kraemer committed
88

Pierre Kraemer's avatar
Pierre Kraemer committed
89
	inline const CellMarker<MAP, ORBIT>& getMarker() { return m_cm; }
90

91 92
	inline const std::vector<CELL>& getSelectedCells() { return m_cells; }

Sylvain Thery's avatar
Sylvain Thery committed
93
	inline unsigned int getNbSelectedCells() const { return (unsigned int)(m_cells.size()); }
94 95

	inline void select(CELL c, bool emitSignal = true)
Pierre Kraemer's avatar
Pierre Kraemer committed
96
	{
97
		if(!m_cm.isMarked(c))
Pierre Kraemer's avatar
Pierre Kraemer committed
98
		{
99 100
			m_cm.mark(c);
			m_cells.push_back(c);
101 102
			if(m_isMutuallyExclusive && !m_mutuallyExclusive.empty())
			{
103 104
				foreach(SELECTOR* cs, m_mutuallyExclusive)
					cs->unselect(c, emitSignal);
105
			}
106
			if(emitSignal)
107 108
			{
				DEBUG_EMIT("selectedCellsChanged");
109
				emit(selectedCellsChanged());
110
			}
111 112
			else
				m_selectionChanged = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
113 114 115
		}
	}

116
	inline void select(const std::vector<CELL>& c)
Pierre Kraemer's avatar
Pierre Kraemer committed
117
	{
118 119 120 121
		for(unsigned int i = 0; i < c.size(); ++i)
			select(c[i], false);
		checkChange();
		if(m_isMutuallyExclusive && !m_mutuallyExclusive.empty())
Pierre Kraemer's avatar
Pierre Kraemer committed
122
		{
123 124 125 126 127 128 129 130 131 132
			foreach(SELECTOR* cs, m_mutuallyExclusive)
				cs->checkChange();
		}
	}

	inline void unselect(CELL c, bool emitSignal = true)
	{
		if(m_cm.isMarked(c))
		{
			unsigned int emb = m_map.getEmbedding(c);
Pierre Kraemer's avatar
Pierre Kraemer committed
133 134 135 136
			bool found = false;
			unsigned int i;
			for(i = 0; i < m_cells.size() && !found; ++i)
			{
137
				if(m_map.template getEmbedding<ORBIT>(m_cells[i]) == emb)
Pierre Kraemer's avatar
Pierre Kraemer committed
138 139 140 141 142 143 144
					found = true ;
			}
			if(found)
			{
				m_cm.unmark(m_cells[i-1]);
				m_cells[i-1] = m_cells.back();
				m_cells.pop_back();
145
				if(emitSignal)
146 147
				{
					DEBUG_EMIT("selectedCellsChanged");
148
					emit(selectedCellsChanged());
149
				}
150 151
				else
					m_selectionChanged = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
152 153 154 155
			}
		}
	}

156 157 158 159 160 161 162 163
	inline void unselect(const std::vector<CELL>& c)
	{
		for(unsigned int i = 0; i < c.size(); ++i)
			unselect(c[i], false);
		checkChange();
	}

	inline bool isSelected(CELL c)
Pierre Kraemer's avatar
Pierre Kraemer committed
164
	{
165
		return m_cm.isMarked(c);
Pierre Kraemer's avatar
Pierre Kraemer committed
166 167
	}

168 169 170
	void rebuild()
	{
		m_cells.clear();
171
		foreach_cell<ORBIT>(m_map, [&] (CELL c)
172
		{
173 174 175
			if(m_cm.isMarked(c))
				m_cells.push_back(c);
		});
176 177 178
		emit(selectedCellsChanged());
	}

179 180 181 182 183 184 185 186 187 188 189 190 191 192
	inline void setMutuallyExclusiveSet(const QList<CellSelectorGen*>& mex)
	{
		m_mutuallyExclusive.clear();
		foreach(CellSelectorGen* cs, mex)
		{
			if(cs != this)
			{
				SELECTOR* s = dynamic_cast<SELECTOR*>(cs);
				if (s)
					m_mutuallyExclusive.append(s);
			}
		}
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
193
private:
Pierre Kraemer's avatar
Pierre Kraemer committed
194 195
	MAP& m_map;
	CellMarker<MAP, ORBIT> m_cm;
196 197 198 199

	std::vector<CELL> m_cells;

	QList<SELECTOR*> m_mutuallyExclusive;
Pierre Kraemer's avatar
Pierre Kraemer committed
200 201 202 203 204 205 206
};

} // namespace SCHNApps

} // namespace CGoGN

#endif