Symbol editor now has constraints on selection, but part list allows selection inside groups.

Added logical 'xor' operator for scripting.

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@534 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2007-07-09 20:43:16 +00:00
parent 31e60181ce
commit b409188013
19 changed files with 523 additions and 291 deletions
+52 -22
View File
@@ -105,6 +105,7 @@ void SymbolPartMatrixAction::transform(SymbolPart& part, const Matrix2D& m) {
// bounds change after transforming
s->calculateBounds();
} else if (SymbolSymmetry* s = part.isSymbolSymmetry()) {
s->center = (s->center - center) * m + center;
s->handle = s->handle * m;
} else if (SymbolGroup* g = part.isSymbolGroup()) {
FOR_EACH(p, g->parts) {
@@ -280,7 +281,8 @@ void SymbolPartScaleAction::transformPart(SymbolPart& part) {
pnt->delta_after = pnt->delta_after .mul(scale);
}
} else if (SymbolSymmetry* s = part.isSymbolSymmetry()) {
throw "TODO";
transform(s->center);
s->handle.mul(new_size.div(old_size));
} else if (SymbolGroup* g = part.isSymbolGroup()) {
FOR_EACH(p, g->parts) {
transformPart(*p);
@@ -450,8 +452,9 @@ void DuplicateSymbolPartsAction::getParts(set<SymbolPartP>& parts) {
// ----------------------------------------------------------------------------- : Reorder symbol parts
ReorderSymbolPartsAction::ReorderSymbolPartsAction(Symbol& symbol, size_t old_position, size_t new_position)
: symbol(symbol), old_position(old_position), new_position(new_position)
ReorderSymbolPartsAction::ReorderSymbolPartsAction(SymbolGroup& old_parent, size_t old_position, SymbolGroup& new_parent, size_t new_position)
: old_parent(&old_parent), new_parent(&new_parent)
, old_position(old_position), new_position(new_position)
{}
String ReorderSymbolPartsAction::getName(bool to_undo) const {
@@ -459,31 +462,58 @@ String ReorderSymbolPartsAction::getName(bool to_undo) const {
}
void ReorderSymbolPartsAction::perform(bool to_undo) {
assert(old_position < symbol.parts.size());
assert(new_position < symbol.parts.size());
SymbolPartP part = symbol.parts.at(old_position);
symbol.parts.erase( symbol.parts.begin() + old_position);
symbol.parts.insert(symbol.parts.begin() + new_position, part);
// remove from old
assert(old_position < old_parent->parts.size());
SymbolPartP part = old_parent->parts.at(old_position);
old_parent->parts.erase( old_parent->parts.begin() + old_position);
// add to new
assert(new_position <= new_parent->parts.size());
new_parent->parts.insert(new_parent->parts.begin() + new_position, part);
// next time the other way around
swap(old_parent, new_parent);
swap(old_position, new_position);
}
// ----------------------------------------------------------------------------- : Group symbol parts
GroupSymbolPartsActionBase::GroupSymbolPartsActionBase(Symbol& symbol)
: symbol(symbol)
{}
void GroupSymbolPartsActionBase::perform(bool to_undo) {
swap(symbol.parts, old_part_list);
UngroupReorderSymbolPartsAction::UngroupReorderSymbolPartsAction(SymbolGroup& group_parent, size_t group_pos, SymbolGroup& target_parent, size_t target_pos)
: group_parent(group_parent), group_pos(group_pos)
, target_parent(target_parent), target_pos(target_pos)
{
group = dynamic_pointer_cast<SymbolGroup>(group_parent.parts.at(group_pos));
assert(group);
}
GroupSymbolPartsAction::GroupSymbolPartsAction(Symbol& symbol, const set<SymbolPartP>& parts)
: GroupSymbolPartsActionBase(symbol)
String UngroupReorderSymbolPartsAction::getName(bool to_undo) const {
return _ACTION_("reorder parts");
}
void UngroupReorderSymbolPartsAction::perform(bool to_undo) {
if (!to_undo) {
group_parent.parts.erase(group_parent.parts.begin() + group_pos);
target_parent.parts.insert(target_parent.parts.begin() + target_pos, group->parts.begin(), group->parts.end());
} else {
target_parent.parts.erase(target_parent.parts.begin() + target_pos, target_parent.parts.begin() + target_pos + group->parts.size());
group_parent.parts.insert(group_parent.parts.begin() + group_pos, group);
}
}
// ----------------------------------------------------------------------------- : Group symbol parts
GroupSymbolPartsActionBase::GroupSymbolPartsActionBase(SymbolGroup& root)
: root(root)
{}
void GroupSymbolPartsActionBase::perform(bool to_undo) {
swap(root.parts, old_part_list);
}
GroupSymbolPartsAction::GroupSymbolPartsAction(SymbolGroup& root, const set<SymbolPartP>& parts, const SymbolGroupP& group)
: GroupSymbolPartsActionBase(root)
{
// group parts in the old parts list
bool done = false;
SymbolGroupP group(new SymbolGroup);
group->name = _("Group");
FOR_EACH(p, symbol.parts) {
FOR_EACH(p, root.parts) {
assert(p != group);
if (parts.find(p) != parts.end()) {
// add to group instead
group->parts.push_back(p);
@@ -502,11 +532,11 @@ String GroupSymbolPartsAction::getName(bool to_undo) const {
return _ACTION_("group parts");
}
UngroupSymbolPartsAction::UngroupSymbolPartsAction(Symbol& symbol, const set<SymbolPartP>& parts)
: GroupSymbolPartsActionBase(symbol)
UngroupSymbolPartsAction::UngroupSymbolPartsAction(SymbolGroup& root, const set<SymbolPartP>& parts)
: GroupSymbolPartsActionBase(root)
{
// break up the parts in the old parts list
FOR_EACH(p, symbol.parts) {
FOR_EACH(p, root.parts) {
if (parts.find(p) != parts.end() && p->isSymbolGroup()) {
// break up the group
SymbolGroup* g = p->isSymbolGroup();
+23 -7
View File
@@ -240,36 +240,52 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction {
/// Change the position of a part in a symbol, by moving a part.
class ReorderSymbolPartsAction : public SymbolPartListAction {
public:
ReorderSymbolPartsAction(Symbol& symbol, size_t old_position, size_t new_position);
ReorderSymbolPartsAction(SymbolGroup& old_parent, size_t old_position, SymbolGroup& new_parent, size_t new_position);
virtual String getName(bool to_undo) const;
virtual void perform(bool to_undo);
private:
Symbol& symbol; ///< Symbol to swap the parts in
SymbolGroup* old_parent, *new_parent;///< Parents to move from and to
public:
size_t old_position, new_position; ///< Positions to move from and to
};
/// Break up a single group, and put its contents at a specific position
class UngroupReorderSymbolPartsAction : public SymbolPartListAction {
public:
/// Remove all the given groups
UngroupReorderSymbolPartsAction(SymbolGroup& group_parent, size_t group_pos, SymbolGroup& target_parent, size_t target_pos);
virtual String getName(bool to_undo) const;
virtual void perform(bool to_undo);
private:
SymbolGroup& group_parent;
size_t group_pos;
SymbolGroupP group; ///< Group to destroy
SymbolGroup& target_parent;
size_t target_pos;
};
// ----------------------------------------------------------------------------- : Group symbol parts
/// Group multiple symbol parts together
class GroupSymbolPartsActionBase : public SymbolPartListAction {
public:
GroupSymbolPartsActionBase(Symbol& symbol);
GroupSymbolPartsActionBase(SymbolGroup& root);
virtual void perform(bool to_undo);
protected:
Symbol& symbol; ///< Symbol to group stuff in
SymbolGroup& root; ///< Symbol or group to group stuff in
vector<SymbolPartP> old_part_list; ///< Old part list of the symbol
};
/// Group multiple symbol parts together
class GroupSymbolPartsAction : public GroupSymbolPartsActionBase {
public:
GroupSymbolPartsAction(Symbol& symbol, const set<SymbolPartP>& parts);
GroupSymbolPartsAction(SymbolGroup& root, const set<SymbolPartP>& parts, const SymbolGroupP& group);
virtual String getName(bool to_undo) const;
};
@@ -277,11 +293,11 @@ class GroupSymbolPartsAction : public GroupSymbolPartsActionBase {
/// Break up one or more SymbolGroups
class UngroupSymbolPartsAction : public GroupSymbolPartsActionBase {
public:
UngroupSymbolPartsAction(Symbol& symbol, const set<SymbolPartP>& groups);
/// Remove all the given groups
UngroupSymbolPartsAction(SymbolGroup& root, const set<SymbolPartP>& groups);
virtual String getName(bool to_undo) const;
};
// ----------------------------------------------------------------------------- : EOF
#endif
+22 -11
View File
@@ -204,7 +204,12 @@ String SymbolSymmetry::typeName() const {
}
SymbolPartP SymbolSymmetry::clone() const {
return new_intrusive1<SymbolSymmetry>(*this);
SymbolSymmetryP part(new SymbolSymmetry(*this));
// also clone the parts inside
FOR_EACH(p, part->parts) {
p = p->clone();
}
return part;
}
IMPLEMENT_REFLECTION(SymbolSymmetry) {
@@ -213,20 +218,16 @@ IMPLEMENT_REFLECTION(SymbolSymmetry) {
REFLECT(copies);
REFLECT(center);
REFLECT(handle);
// Fixes after reading
REFLECT_IF_READING {
if (name.empty()) {
if (kind == SYMMETRY_REFLECTION) {
name = _("Mirror");
} else {
name = _("Symmetry");
}
}
}
REFLECT(parts);
REFLECT_IF_READING calculateBoundsNonRec();
}
// ----------------------------------------------------------------------------- : SymbolGroup
SymbolGroup::SymbolGroup() {
name = capitalize(_TYPE_("group"));
}
String SymbolGroup::typeName() const {
return _("group");
}
@@ -240,6 +241,14 @@ SymbolPartP SymbolGroup::clone() const {
return part;
}
bool SymbolGroup::isAncestor(const SymbolPart& that) const {
if (this == &that) return true;
FOR_EACH_CONST(p, parts) {
if (p->isAncestor(that)) return true;
}
return false;
}
void SymbolGroup::calculateBounds() {
FOR_EACH(p, parts) p->calculateBounds();
calculateBoundsNonRec();
@@ -256,12 +265,14 @@ void SymbolGroup::calculateBoundsNonRec() {
IMPLEMENT_REFLECTION(SymbolGroup) {
REFLECT_BASE(SymbolPart);
REFLECT(parts);
REFLECT_IF_READING calculateBoundsNonRec();
}
// ----------------------------------------------------------------------------- : Symbol
IMPLEMENT_REFLECTION(Symbol) {
REFLECT(parts);
REFLECT_IF_READING calculateBoundsNonRec();
}
// ----------------------------------------------------------------------------- : Default symbol
+30 -22
View File
@@ -133,6 +133,10 @@ class SymbolPart : public IntrusivePtrVirtualBase {
virtual SymbolGroup* isSymbolGroup() { return nullptr; }
virtual const SymbolGroup* isSymbolGroup() const { return nullptr; }
/// Does this part contain another?
/** also true if this==that*/
virtual bool isAncestor(const SymbolPart& that) const { return this == &that; }
/// Calculate the position and size of the part (min_pos and max_pos)
virtual void calculateBounds();
@@ -191,6 +195,30 @@ class SymbolShape : public SymbolPart {
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : SymbolGroup
/// A group of symbol parts
class SymbolGroup : public SymbolPart {
public:
vector<SymbolPartP> parts; ///< The parts in this group, first item is on top
SymbolGroup();
virtual String typeName() const;
virtual SymbolPartP clone() const;
virtual int icon() const { return SYMBOL_COMBINE_BORDER + 3; }
virtual SymbolGroup* isSymbolGroup() { return this; }
virtual const SymbolGroup* isSymbolGroup() const { return this; }
virtual bool isAncestor(const SymbolPart& that) const;
virtual void calculateBounds();
/// re-calculate the bounds, but not of the contained parts
void calculateBoundsNonRec();
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : SymbolSymmetry
enum SymbolSymmetryType
@@ -198,9 +226,9 @@ enum SymbolSymmetryType
, SYMMETRY_REFLECTION
};
/// A mirror, reflecting part of the symbol
/// A mirror, reflecting the part of the symbol in the group
/** Can handle rotation symmetry with any number of reflections */
class SymbolSymmetry : public SymbolPart {
class SymbolSymmetry : public SymbolGroup {
public:
SymbolSymmetryType kind; ///< What kind of symmetry
int copies; ///< How many times is the orignal reflected (including the original itself)
@@ -219,26 +247,6 @@ class SymbolSymmetry : public SymbolPart {
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : SymbolGroup
/// A group of symbol parts
class SymbolGroup : public SymbolPart {
public:
vector<SymbolPartP> parts; ///< The parts in this group, first item is on top
virtual String typeName() const;
virtual SymbolPartP clone() const;
virtual int icon() const { return SYMMETRY_REFLECTION + 1; }
virtual SymbolGroup* isSymbolGroup() { return this; }
virtual const SymbolGroup* isSymbolGroup() const { return this; }
virtual void calculateBounds();
/// re-calculate the bounds, but not of the contained parts
void calculateBoundsNonRec();
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : Symbol
/// An editable symbol, consists of any number of SymbolParts