//+----------------------------------------------------------------------------+ //| Description: Magic Set Editor - Program to make Magic (tm) cards | //| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" | //| License: GNU General Public License 2 or later (see file COPYING) | //+----------------------------------------------------------------------------+ #ifndef HEADER_GUI_SYMBOL_SELECTION #define HEADER_GUI_SYMBOL_SELECTION // ----------------------------------------------------------------------------- : Includes #include class Vector2D; DECLARE_POINTER_TYPE(Symbol); DECLARE_POINTER_TYPE(SymbolPart); DECLARE_POINTER_TYPE(SymbolShape); DECLARE_POINTER_TYPE(SymbolSymmetry); class SymbolGroup; // ----------------------------------------------------------------------------- : Selection enum SelectMode { SELECT_OVERRIDE // give a completely new selection , SELECT_IF_OUTSIDE // define a new selection if the affected part is not already selected , SELECT_TOGGLE // toggle selection of affected part }; /// The selected parts of a symbol, enforcing constraints class SymbolPartsSelection { public: inline SymbolPartsSelection() : root(nullptr) {} void setSymbol(const SymbolP& symbol); /// Clear selection void clear(); /// Select a part or toggle its selection /** Return true if the selection changed */ bool select(const SymbolPartP& part, SelectMode mode = SELECT_OVERRIDE); /// Toggle the selection of the parts in a rectangle (a,b) or (a,c) but not in both /** Return true if the selection changed */ bool selectRect(const Vector2D& a, const Vector2D& b, const Vector2D& c); /// Find a part by position (not just in the selection!) /** Returns SymbolPartP() if nothing is found. * Does not select inside groups unless the part in question is already selected. */ SymbolPartP find(const Vector2D& position) const; /// Get the selection inline const set& get() const { return selection; } /// Is the selection empty? inline bool empty() const { return selection.empty(); } /// Number of items selected inline size_t size() const { return selection.size(); } /// Is a part selected? inline bool selected(const SymbolPartP& part) const { return selection.find(part) != selection.end(); } /// Get any SymbolShape if there is one selected SymbolShapeP getAShape() const; /// Get any SymbolSymmetry if there is one selected SymbolSymmetryP getASymmetry() const; /// Get the only selected thing inline SymbolPartP getOnlyOne() const { assert(selection.size() == 1); return *selection.begin(); } private: Symbol* root; set selection; /// Find a part, in some root SymbolPartP find(const SymbolPartP& part, const Vector2D& pos) const; /// Select rect for some parent bool selectRect(const SymbolGroup& parent, const Vector2D& a, const Vector2D& b, const Vector2D& c); /// Make sure not both a parent and its child/decendant are selected void clearChildren (SymbolPart* part); }; // ----------------------------------------------------------------------------- : EOF #endif