mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Switched to a new coding style, which plays nicely with the Reader/Writer. This new style allows REFLECT to be used instead of REFLECT_N in most places.
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@15 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
+37
-37
@@ -23,15 +23,15 @@ SymbolPartMoveAction::SymbolPartMoveAction(const set<SymbolPartP>& parts)
|
|||||||
, constrain(false)
|
, constrain(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String SymbolPartMoveAction::getName(bool toUndo) const {
|
String SymbolPartMoveAction::getName(bool to_undo) const {
|
||||||
return parts.size() == 1 ? _("Move shape") : _("Move shapes");
|
return parts.size() == 1 ? _("Move shape") : _("Move shapes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPartMoveAction::perform(bool toUndo) {
|
void SymbolPartMoveAction::perform(bool to_undo) {
|
||||||
// move the points back
|
// move the points back
|
||||||
FOR_EACH(p, parts) {
|
FOR_EACH(p, parts) {
|
||||||
p->minPos -= moved;
|
p->min_pos -= moved;
|
||||||
p->maxPos -= moved;
|
p->max_pos -= moved;
|
||||||
FOR_EACH(pnt, p->points) {
|
FOR_EACH(pnt, p->points) {
|
||||||
pnt->pos -= moved;
|
pnt->pos -= moved;
|
||||||
}
|
}
|
||||||
@@ -45,8 +45,8 @@ void SymbolPartMoveAction::move(const Vector2D& deltaDelta) {
|
|||||||
Vector2D d = constrainVector(delta, constrain);
|
Vector2D d = constrainVector(delta, constrain);
|
||||||
Vector2D dd = d - moved;
|
Vector2D dd = d - moved;
|
||||||
FOR_EACH(p, parts) {
|
FOR_EACH(p, parts) {
|
||||||
p->minPos += dd;
|
p->min_pos += dd;
|
||||||
p->maxPos += dd;
|
p->max_pos += dd;
|
||||||
FOR_EACH(pnt, p->points) {
|
FOR_EACH(pnt, p->points) {
|
||||||
pnt->pos += dd;
|
pnt->pos += dd;
|
||||||
}
|
}
|
||||||
@@ -66,8 +66,8 @@ void SymbolPartMatrixAction::transform(const Vector2D& mx, const Vector2D& my) {
|
|||||||
FOR_EACH(p, parts) {
|
FOR_EACH(p, parts) {
|
||||||
FOR_EACH(pnt, p->points) {
|
FOR_EACH(pnt, p->points) {
|
||||||
pnt->pos = (pnt->pos - center).mul(mx,my) + center;
|
pnt->pos = (pnt->pos - center).mul(mx,my) + center;
|
||||||
pnt->deltaBefore = pnt->deltaBefore.mul(mx,my);
|
pnt->delta_before = pnt->delta_before.mul(mx,my);
|
||||||
pnt->deltaAfter = pnt->deltaAfter .mul(mx,my);
|
pnt->delta_after = pnt->delta_after .mul(mx,my);
|
||||||
}
|
}
|
||||||
// bounds change after transforming
|
// bounds change after transforming
|
||||||
p->calculateBounds();
|
p->calculateBounds();
|
||||||
@@ -81,11 +81,11 @@ SymbolPartRotateAction::SymbolPartRotateAction(const set<SymbolPartP>& parts, co
|
|||||||
, angle(0)
|
, angle(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String SymbolPartRotateAction::getName(bool toUndo) const {
|
String SymbolPartRotateAction::getName(bool to_undo) const {
|
||||||
return parts.size() == 1 ? _("Rotate shape") : _("Rotate shapes");
|
return parts.size() == 1 ? _("Rotate shape") : _("Rotate shapes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPartRotateAction::perform(bool toUndo) {
|
void SymbolPartRotateAction::perform(bool to_undo) {
|
||||||
// move the points back
|
// move the points back
|
||||||
rotateBy(-angle);
|
rotateBy(-angle);
|
||||||
angle = -angle;
|
angle = -angle;
|
||||||
@@ -119,11 +119,11 @@ SymbolPartShearAction::SymbolPartShearAction(const set<SymbolPartP>& parts, cons
|
|||||||
, constrain(false)
|
, constrain(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String SymbolPartShearAction::getName(bool toUndo) const {
|
String SymbolPartShearAction::getName(bool to_undo) const {
|
||||||
return parts.size() == 1 ? _("Shear shape") : _("Shear shapes");
|
return parts.size() == 1 ? _("Shear shape") : _("Shear shapes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPartShearAction::perform(bool toUndo) {
|
void SymbolPartShearAction::perform(bool to_undo) {
|
||||||
// move the points back
|
// move the points back
|
||||||
// the vector shear = (x,y) is used as:
|
// the vector shear = (x,y) is used as:
|
||||||
// <1 x>
|
// <1 x>
|
||||||
@@ -161,19 +161,19 @@ SymbolPartScaleAction::SymbolPartScaleAction(const set<SymbolPartP>& parts, int
|
|||||||
oldMin = Vector2D::infinity();
|
oldMin = Vector2D::infinity();
|
||||||
Vector2D oldMax = -Vector2D::infinity();
|
Vector2D oldMax = -Vector2D::infinity();
|
||||||
FOR_EACH(p, parts) {
|
FOR_EACH(p, parts) {
|
||||||
oldMin = piecewise_min(oldMin, p->minPos);
|
oldMin = piecewise_min(oldMin, p->min_pos);
|
||||||
oldMax = piecewise_max(oldMax, p->maxPos);
|
oldMax = piecewise_max(oldMax, p->max_pos);
|
||||||
}
|
}
|
||||||
// new == old
|
// new == old
|
||||||
newMin = newRealMin = oldMin;
|
newMin = newRealMin = oldMin;
|
||||||
newSize = newRealSize = oldSize = oldMax - oldMin;
|
newSize = newRealSize = oldSize = oldMax - oldMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
String SymbolPartScaleAction::getName(bool toUndo) const {
|
String SymbolPartScaleAction::getName(bool to_undo) const {
|
||||||
return parts.size() == 1 ? _("Scale shape") : _("Scale shapes");
|
return parts.size() == 1 ? _("Scale shape") : _("Scale shapes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPartScaleAction::perform(bool toUndo) {
|
void SymbolPartScaleAction::perform(bool to_undo) {
|
||||||
swap(oldMin, newMin);
|
swap(oldMin, newMin);
|
||||||
swap(oldSize, newSize);
|
swap(oldSize, newSize);
|
||||||
transformAll();
|
transformAll();
|
||||||
@@ -207,17 +207,17 @@ void SymbolPartScaleAction::update() {
|
|||||||
void SymbolPartScaleAction::transformAll() {
|
void SymbolPartScaleAction::transformAll() {
|
||||||
Vector2D scale = newSize.div(oldSize);
|
Vector2D scale = newSize.div(oldSize);
|
||||||
FOR_EACH(p, parts) {
|
FOR_EACH(p, parts) {
|
||||||
p->minPos = transform(p->minPos);
|
p->min_pos = transform(p->min_pos);
|
||||||
p->maxPos = transform(p->maxPos);
|
p->max_pos = transform(p->max_pos);
|
||||||
// make sure that max >= min
|
// make sure that max >= min
|
||||||
if (p->minPos.x > p->maxPos.x) swap(p->minPos.x, p->maxPos.x);
|
if (p->min_pos.x > p->max_pos.x) swap(p->min_pos.x, p->max_pos.x);
|
||||||
if (p->minPos.y > p->maxPos.y) swap(p->minPos.y, p->maxPos.y);
|
if (p->min_pos.y > p->max_pos.y) swap(p->min_pos.y, p->max_pos.y);
|
||||||
// scale all points
|
// scale all points
|
||||||
FOR_EACH(pnt, p->points) {
|
FOR_EACH(pnt, p->points) {
|
||||||
pnt->pos = transform(pnt->pos);
|
pnt->pos = transform(pnt->pos);
|
||||||
// also scale handles
|
// also scale handles
|
||||||
pnt->deltaBefore = pnt->deltaBefore.mul(scale);
|
pnt->delta_before = pnt->delta_before.mul(scale);
|
||||||
pnt->deltaAfter = pnt->deltaAfter .mul(scale);
|
pnt->delta_after = pnt->delta_after .mul(scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,11 +230,11 @@ CombiningModeAction::CombiningModeAction(const set<SymbolPartP>& parts, SymbolPa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String CombiningModeAction::getName(bool toUndo) const {
|
String CombiningModeAction::getName(bool to_undo) const {
|
||||||
return _("Change combine mode");
|
return _("Change combine mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombiningModeAction::perform(bool toUndo) {
|
void CombiningModeAction::perform(bool to_undo) {
|
||||||
FOR_EACH(pm, parts) {
|
FOR_EACH(pm, parts) {
|
||||||
swap(pm.first->combine, pm.second);
|
swap(pm.first->combine, pm.second);
|
||||||
}
|
}
|
||||||
@@ -246,11 +246,11 @@ SymbolPartNameAction::SymbolPartNameAction(const SymbolPartP& part, const String
|
|||||||
: part(part), partName(name)
|
: part(part), partName(name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String SymbolPartNameAction::getName(bool toUndo) const {
|
String SymbolPartNameAction::getName(bool to_undo) const {
|
||||||
return _("Change shape name");
|
return _("Change shape name");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPartNameAction::perform(bool toUndo) {
|
void SymbolPartNameAction::perform(bool to_undo) {
|
||||||
swap(part->name, partName);
|
swap(part->name, partName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,12 +260,12 @@ AddSymbolPartAction::AddSymbolPartAction(Symbol& symbol, const SymbolPartP& part
|
|||||||
: symbol(symbol), part(part)
|
: symbol(symbol), part(part)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String AddSymbolPartAction::getName(bool toUndo) const {
|
String AddSymbolPartAction::getName(bool to_undo) const {
|
||||||
return _("Add ") + part->name;
|
return _("Add ") + part->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddSymbolPartAction::perform(bool toUndo) {
|
void AddSymbolPartAction::perform(bool to_undo) {
|
||||||
if (toUndo) {
|
if (to_undo) {
|
||||||
assert(!symbol.parts.empty());
|
assert(!symbol.parts.empty());
|
||||||
symbol.parts.erase (symbol.parts.begin());
|
symbol.parts.erase (symbol.parts.begin());
|
||||||
} else {
|
} else {
|
||||||
@@ -287,12 +287,12 @@ RemoveSymbolPartsAction::RemoveSymbolPartsAction(Symbol& symbol, const set<Symbo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String RemoveSymbolPartsAction::getName(bool toUndo) const {
|
String RemoveSymbolPartsAction::getName(bool to_undo) const {
|
||||||
return removals.size() == 1 ? _("Remove shape") : _("Remove shapes");
|
return removals.size() == 1 ? _("Remove shape") : _("Remove shapes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveSymbolPartsAction::perform(bool toUndo) {
|
void RemoveSymbolPartsAction::perform(bool to_undo) {
|
||||||
if (toUndo) {
|
if (to_undo) {
|
||||||
// reinsert the parts
|
// reinsert the parts
|
||||||
// ascending order, this is the reverse of removal
|
// ascending order, this is the reverse of removal
|
||||||
FOR_EACH(r, removals) {
|
FOR_EACH(r, removals) {
|
||||||
@@ -325,12 +325,12 @@ DuplicateSymbolPartsAction::DuplicateSymbolPartsAction(Symbol& symbol, const set
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String DuplicateSymbolPartsAction::getName(bool toUndo) const {
|
String DuplicateSymbolPartsAction::getName(bool to_undo) const {
|
||||||
return duplications.size() == 1 ? _("Duplicate shape") : _("Duplicate shapes");
|
return duplications.size() == 1 ? _("Duplicate shape") : _("Duplicate shapes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DuplicateSymbolPartsAction::perform(bool toUndo) {
|
void DuplicateSymbolPartsAction::perform(bool to_undo) {
|
||||||
if (toUndo) {
|
if (to_undo) {
|
||||||
// remove the clones
|
// remove the clones
|
||||||
// walk in reverse order, otherwise we will shift the vector
|
// walk in reverse order, otherwise we will shift the vector
|
||||||
FOR_EACH_REVERSE(d, duplications) {
|
FOR_EACH_REVERSE(d, duplications) {
|
||||||
@@ -359,11 +359,11 @@ ReorderSymbolPartsAction::ReorderSymbolPartsAction(Symbol& symbol, size_t partId
|
|||||||
: symbol(symbol), partId1(partId1), partId2(partId2)
|
: symbol(symbol), partId1(partId1), partId2(partId2)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String ReorderSymbolPartsAction::getName(bool toUndo) const {
|
String ReorderSymbolPartsAction::getName(bool to_undo) const {
|
||||||
return _("Reorder");
|
return _("Reorder");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReorderSymbolPartsAction::perform(bool toUndo) {
|
void ReorderSymbolPartsAction::perform(bool to_undo) {
|
||||||
assert(partId1 < symbol.parts.size());
|
assert(partId1 < symbol.parts.size());
|
||||||
assert(partId2 < symbol.parts.size());
|
assert(partId2 < symbol.parts.size());
|
||||||
swap(symbol.parts[partId1], symbol.parts[partId2]);
|
swap(symbol.parts[partId1], symbol.parts[partId2]);
|
||||||
|
|||||||
+20
-20
@@ -33,8 +33,8 @@ class SymbolPartMoveAction : public SymbolPartAction {
|
|||||||
public:
|
public:
|
||||||
SymbolPartMoveAction(const set<SymbolPartP>& parts);
|
SymbolPartMoveAction(const set<SymbolPartP>& parts);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
/// Update this action to move some more
|
/// Update this action to move some more
|
||||||
void move(const Vector2D& delta);
|
void move(const Vector2D& delta);
|
||||||
@@ -70,8 +70,8 @@ class SymbolPartRotateAction : public SymbolPartMatrixAction {
|
|||||||
public:
|
public:
|
||||||
SymbolPartRotateAction(const set<SymbolPartP>& parts, const Vector2D& center);
|
SymbolPartRotateAction(const set<SymbolPartP>& parts, const Vector2D& center);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
/// Update this action to rotate to a different angle
|
/// Update this action to rotate to a different angle
|
||||||
void rotateTo(double newAngle);
|
void rotateTo(double newAngle);
|
||||||
@@ -93,8 +93,8 @@ class SymbolPartShearAction : public SymbolPartMatrixAction {
|
|||||||
public:
|
public:
|
||||||
SymbolPartShearAction(const set<SymbolPartP>& parts, const Vector2D& center);
|
SymbolPartShearAction(const set<SymbolPartP>& parts, const Vector2D& center);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
/// Change shear by a given amount
|
/// Change shear by a given amount
|
||||||
void move(const Vector2D& deltaShear);
|
void move(const Vector2D& deltaShear);
|
||||||
@@ -114,8 +114,8 @@ class SymbolPartScaleAction : public SymbolPartAction {
|
|||||||
public:
|
public:
|
||||||
SymbolPartScaleAction(const set<SymbolPartP>& parts, int scaleX, int scaleY);
|
SymbolPartScaleAction(const set<SymbolPartP>& parts, int scaleX, int scaleY);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
/// Change min and max coordinates
|
/// Change min and max coordinates
|
||||||
void move(const Vector2D& deltaMin, const Vector2D& deltaMax);
|
void move(const Vector2D& deltaMin, const Vector2D& deltaMax);
|
||||||
@@ -145,8 +145,8 @@ class CombiningModeAction : public SymbolPartListAction {
|
|||||||
public:
|
public:
|
||||||
CombiningModeAction(const set<SymbolPartP>& parts, SymbolPartCombine mode);
|
CombiningModeAction(const set<SymbolPartP>& parts, SymbolPartCombine mode);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vector<pair<SymbolPartP,SymbolPartCombine> > parts; ///< Affected parts with new combining modes
|
vector<pair<SymbolPartP,SymbolPartCombine> > parts; ///< Affected parts with new combining modes
|
||||||
@@ -159,8 +159,8 @@ class SymbolPartNameAction : public SymbolPartListAction {
|
|||||||
public:
|
public:
|
||||||
SymbolPartNameAction(const SymbolPartP& part, const String& name);
|
SymbolPartNameAction(const SymbolPartP& part, const String& name);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SymbolPartP part; ///< Affected part
|
SymbolPartP part; ///< Affected part
|
||||||
@@ -174,8 +174,8 @@ class AddSymbolPartAction : public SymbolPartListAction {
|
|||||||
public:
|
public:
|
||||||
AddSymbolPartAction(Symbol& symbol, const SymbolPartP& part);
|
AddSymbolPartAction(Symbol& symbol, const SymbolPartP& part);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Symbol& symbol; ///< Symbol to add the part to
|
Symbol& symbol; ///< Symbol to add the part to
|
||||||
@@ -189,8 +189,8 @@ class RemoveSymbolPartsAction : public SymbolPartListAction {
|
|||||||
public:
|
public:
|
||||||
RemoveSymbolPartsAction(Symbol& symbol, const set<SymbolPartP>& parts);
|
RemoveSymbolPartsAction(Symbol& symbol, const set<SymbolPartP>& parts);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Symbol& symbol;
|
Symbol& symbol;
|
||||||
@@ -205,8 +205,8 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction {
|
|||||||
public:
|
public:
|
||||||
DuplicateSymbolPartsAction(Symbol& symbol, const set<SymbolPartP>& parts);
|
DuplicateSymbolPartsAction(Symbol& symbol, const set<SymbolPartP>& parts);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
/// Fill a set with all the new parts
|
/// Fill a set with all the new parts
|
||||||
void getParts(set<SymbolPartP>& parts);
|
void getParts(set<SymbolPartP>& parts);
|
||||||
@@ -225,8 +225,8 @@ class ReorderSymbolPartsAction : public SymbolPartListAction {
|
|||||||
public:
|
public:
|
||||||
ReorderSymbolPartsAction(Symbol& symbol, size_t partId1, size_t partId2);
|
ReorderSymbolPartsAction(Symbol& symbol, size_t partId1, size_t partId2);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Symbol& symbol; ///< Symbol to swap the parts in
|
Symbol& symbol; ///< Symbol to swap the parts in
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ ControlPointMoveAction::ControlPointMoveAction(const set<ControlPointP>& points)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String ControlPointMoveAction::getName(bool toUndo) const {
|
String ControlPointMoveAction::getName(bool to_undo) const {
|
||||||
return points.size() == 1 ? _("Move point") : _("Move points");
|
return points.size() == 1 ? _("Move point") : _("Move points");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlPointMoveAction::perform(bool toUndo) {
|
void ControlPointMoveAction::perform(bool to_undo) {
|
||||||
/*
|
/*
|
||||||
set<ControlPointP>::const_iterator it = points.begin();
|
set<ControlPointP>::const_iterator it = points.begin();
|
||||||
vector<Vector2D> ::iterator it2 = oldValues.begin();
|
vector<Vector2D> ::iterator it2 = oldValues.begin();
|
||||||
@@ -77,23 +77,23 @@ void ControlPointMoveAction::move (const Vector2D& deltaDelta) {
|
|||||||
HandleMoveAction::HandleMoveAction(const SelectedHandle& handle)
|
HandleMoveAction::HandleMoveAction(const SelectedHandle& handle)
|
||||||
: handle(handle)
|
: handle(handle)
|
||||||
, constrain(false)
|
, constrain(false)
|
||||||
, oldHandle(handle.getHandle())
|
, old_handle(handle.getHandle())
|
||||||
, oldOther (handle.getOther())
|
, old_other (handle.getOther())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String HandleMoveAction::getName(bool toUndo) const {
|
String HandleMoveAction::getName(bool to_undo) const {
|
||||||
return _("Move handle");
|
return _("Move handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleMoveAction::perform(bool toUndo) {
|
void HandleMoveAction::perform(bool to_undo) {
|
||||||
swap(oldHandle, handle.getHandle());
|
swap(old_handle, handle.getHandle());
|
||||||
swap(oldOther, handle.getOther());
|
swap(old_other, handle.getOther());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleMoveAction::move(const Vector2D& deltaDelta) {
|
void HandleMoveAction::move(const Vector2D& deltaDelta) {
|
||||||
delta += deltaDelta;
|
delta += deltaDelta;
|
||||||
handle.getHandle() = constrainVector(oldHandle + delta, constrain);
|
handle.getHandle() = constrainVector(old_handle + delta, constrain);
|
||||||
handle.getOther() = oldOther;
|
handle.getOther() = old_other;
|
||||||
handle.onUpdateHandle();
|
handle.onUpdateHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,25 +113,25 @@ void ControlPointUpdate::perform() {
|
|||||||
SegmentModeAction::SegmentModeAction(const ControlPointP& p1, const ControlPointP& p2, SegmentMode mode)
|
SegmentModeAction::SegmentModeAction(const ControlPointP& p1, const ControlPointP& p2, SegmentMode mode)
|
||||||
: point1(p1), point2(p2)
|
: point1(p1), point2(p2)
|
||||||
{
|
{
|
||||||
if (p1->segmentAfter == mode) return;
|
if (p1->segment_after == mode) return;
|
||||||
point1.other.segmentAfter = point2.other.segmentBefore = mode;
|
point1.other.segment_after = point2.other.segment_before = mode;
|
||||||
if (mode == SEGMENT_LINE) {
|
if (mode == SEGMENT_LINE) {
|
||||||
point1.other.deltaAfter = Vector2D(0,0);
|
point1.other.delta_after = Vector2D(0,0);
|
||||||
point2.other.deltaBefore = Vector2D(0,0);
|
point2.other.delta_before = Vector2D(0,0);
|
||||||
point1.other.lock = LOCK_FREE;
|
point1.other.lock = LOCK_FREE;
|
||||||
point2.other.lock = LOCK_FREE;
|
point2.other.lock = LOCK_FREE;
|
||||||
} else if (mode == SEGMENT_CURVE) {
|
} else if (mode == SEGMENT_CURVE) {
|
||||||
point1.other.deltaAfter = (p2->pos - p1->pos) / 3.0f;
|
point1.other.delta_after = (p2->pos - p1->pos) / 3.0f;
|
||||||
point2.other.deltaBefore = (p1->pos - p2->pos) / 3.0f;
|
point2.other.delta_before = (p1->pos - p2->pos) / 3.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String SegmentModeAction::getName(bool toUndo) const {
|
String SegmentModeAction::getName(bool to_undo) const {
|
||||||
SegmentMode mode = toUndo ? point1.point->segmentAfter : point1.other.segmentAfter;
|
SegmentMode mode = to_undo ? point1.point->segment_after : point1.other.segment_after;
|
||||||
if (mode == SEGMENT_LINE) return _("Convert to line");
|
if (mode == SEGMENT_LINE) return _("Convert to line");
|
||||||
else return _("Convert to curve");
|
else return _("Convert to curve");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SegmentModeAction::perform(bool toUndo) {
|
void SegmentModeAction::perform(bool to_undo) {
|
||||||
point1.perform();
|
point1.perform();
|
||||||
point2.perform();
|
point2.perform();
|
||||||
}
|
}
|
||||||
@@ -146,11 +146,11 @@ LockModeAction::LockModeAction(const ControlPointP& p, LockMode lock)
|
|||||||
point.other.onUpdateLock();
|
point.other.onUpdateLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
String LockModeAction::getName(bool toUndo) const {
|
String LockModeAction::getName(bool to_undo) const {
|
||||||
return _("Lock point");
|
return _("Lock point");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LockModeAction::perform(bool toUndo) {
|
void LockModeAction::perform(bool to_undo) {
|
||||||
point.perform();
|
point.perform();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,12 +161,12 @@ CurveDragAction::CurveDragAction(const ControlPointP& point1, const ControlPoint
|
|||||||
: SegmentModeAction(point1, point2, SEGMENT_CURVE)
|
: SegmentModeAction(point1, point2, SEGMENT_CURVE)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
String CurveDragAction::getName(bool toUndo) const {
|
String CurveDragAction::getName(bool to_undo) const {
|
||||||
return _("Move curve");
|
return _("Move curve");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurveDragAction::perform(bool toUndo) {
|
void CurveDragAction::perform(bool to_undo) {
|
||||||
SegmentModeAction::perform(toUndo);
|
SegmentModeAction::perform(to_undo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurveDragAction::move(const Vector2D& delta, double t) {
|
void CurveDragAction::move(const Vector2D& delta, double t) {
|
||||||
@@ -186,8 +186,8 @@ void CurveDragAction::move(const Vector2D& delta, double t) {
|
|||||||
// delta = p' - p
|
// delta = p' - p
|
||||||
// pointDelta = x * t * (1-t)
|
// pointDelta = x * t * (1-t)
|
||||||
Vector2D pointDelta = delta / (3 * (t * t + (1-t) * (1-t)));
|
Vector2D pointDelta = delta / (3 * (t * t + (1-t) * (1-t)));
|
||||||
point1.point->deltaAfter += pointDelta / t;
|
point1.point->delta_after += pointDelta / t;
|
||||||
point2.point->deltaBefore += pointDelta / (1-t);
|
point2.point->delta_before += pointDelta / (1-t);
|
||||||
point1.point->onUpdateHandle(HANDLE_AFTER);
|
point1.point->onUpdateHandle(HANDLE_AFTER);
|
||||||
point2.point->onUpdateHandle(HANDLE_BEFORE);
|
point2.point->onUpdateHandle(HANDLE_BEFORE);
|
||||||
}
|
}
|
||||||
@@ -195,40 +195,40 @@ void CurveDragAction::move(const Vector2D& delta, double t) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Add control point
|
// ----------------------------------------------------------------------------- : Add control point
|
||||||
|
|
||||||
ControlPointAddAction::ControlPointAddAction(const SymbolPartP& part, UInt insertAfter, double t)
|
ControlPointAddAction::ControlPointAddAction(const SymbolPartP& part, UInt insert_after, double t)
|
||||||
: point1(part->getPoint(insertAfter))
|
: point1(part->getPoint(insert_after))
|
||||||
, point2(part->getPoint(insertAfter + 1))
|
, point2(part->getPoint(insert_after + 1))
|
||||||
, part(part)
|
, part(part)
|
||||||
, insertAfter(insertAfter)
|
, insert_after(insert_after)
|
||||||
, newPoint(new ControlPoint())
|
, new_point(new ControlPoint())
|
||||||
{
|
{
|
||||||
// calculate new point
|
// calculate new point
|
||||||
if (point1.other.segmentAfter == SEGMENT_CURVE) {
|
if (point1.other.segment_after == SEGMENT_CURVE) {
|
||||||
// calculate new handles using de Casteljau's subdivision algorithm
|
// calculate new handles using de Casteljau's subdivision algorithm
|
||||||
deCasteljau(point1.other, point2.other, t, *newPoint);
|
deCasteljau(point1.other, point2.other, t, *new_point);
|
||||||
// unlock if needed
|
// unlock if needed
|
||||||
if (point1.other.lock == LOCK_SIZE) point1.other.lock = LOCK_DIR;
|
if (point1.other.lock == LOCK_SIZE) point1.other.lock = LOCK_DIR;
|
||||||
if (point2.other.lock == LOCK_SIZE) point2.other.lock = LOCK_DIR;
|
if (point2.other.lock == LOCK_SIZE) point2.other.lock = LOCK_DIR;
|
||||||
newPoint->lock = LOCK_DIR;
|
new_point->lock = LOCK_DIR;
|
||||||
newPoint->segmentBefore = SEGMENT_CURVE;
|
new_point->segment_before = SEGMENT_CURVE;
|
||||||
newPoint->segmentAfter = SEGMENT_CURVE;
|
new_point->segment_after = SEGMENT_CURVE;
|
||||||
} else {
|
} else {
|
||||||
newPoint->pos = point1.other.pos * (1 - t) + point2.other.pos * t;
|
new_point->pos = point1.other.pos * (1 - t) + point2.other.pos * t;
|
||||||
newPoint->lock = LOCK_FREE;
|
new_point->lock = LOCK_FREE;
|
||||||
newPoint->segmentBefore = SEGMENT_LINE;
|
new_point->segment_before = SEGMENT_LINE;
|
||||||
newPoint->segmentAfter = SEGMENT_LINE;
|
new_point->segment_after = SEGMENT_LINE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String ControlPointAddAction::getName(bool toUndo) const {
|
String ControlPointAddAction::getName(bool to_undo) const {
|
||||||
return _("Add control point");
|
return _("Add control point");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlPointAddAction::perform(bool toUndo) {
|
void ControlPointAddAction::perform(bool to_undo) {
|
||||||
if (toUndo) { // remove the point
|
if (to_undo) { // remove the point
|
||||||
part->points.erase( part->points.begin() + insertAfter + 1);
|
part->points.erase( part->points.begin() + insert_after + 1);
|
||||||
} else {
|
} else {
|
||||||
part->points.insert(part->points.begin() + insertAfter + 1, newPoint);
|
part->points.insert(part->points.begin() + insert_after + 1, new_point);
|
||||||
}
|
}
|
||||||
// update points before/after
|
// update points before/after
|
||||||
point1.perform();
|
point1.perform();
|
||||||
@@ -249,8 +249,8 @@ class SinglePointRemoveAction : public Action {
|
|||||||
public:
|
public:
|
||||||
SinglePointRemoveAction(const SymbolPartP& part, UInt position);
|
SinglePointRemoveAction(const SymbolPartP& part, UInt position);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const { return _("Delete point"); }
|
virtual String getName(bool to_undo) const { return _("Delete point"); }
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SymbolPartP part;
|
SymbolPartP part;
|
||||||
@@ -266,21 +266,21 @@ SinglePointRemoveAction::SinglePointRemoveAction(const SymbolPartP& part, UInt p
|
|||||||
, point1(part->getPoint(position - 1))
|
, point1(part->getPoint(position - 1))
|
||||||
, point2(part->getPoint(position + 1))
|
, point2(part->getPoint(position + 1))
|
||||||
{
|
{
|
||||||
if (point1.other.segmentAfter == SEGMENT_CURVE || point2.other.segmentBefore == SEGMENT_CURVE) {
|
if (point1.other.segment_after == SEGMENT_CURVE || point2.other.segment_before == SEGMENT_CURVE) {
|
||||||
// try to preserve curve
|
// try to preserve curve
|
||||||
Vector2D before = point->deltaBefore;
|
Vector2D before = point->delta_before;
|
||||||
Vector2D after = point->deltaAfter;
|
Vector2D after = point->delta_after;
|
||||||
|
|
||||||
// convert both segments to curves first
|
// convert both segments to curves first
|
||||||
if (point1.other.segmentAfter != SEGMENT_CURVE) {
|
if (point1.other.segment_after != SEGMENT_CURVE) {
|
||||||
point1.other.deltaAfter = -
|
point1.other.delta_after = -
|
||||||
before = (point1.other.pos - point->pos) / 3.0;
|
before = (point1.other.pos - point->pos) / 3.0;
|
||||||
point1.other.segmentAfter = SEGMENT_CURVE;
|
point1.other.segment_after = SEGMENT_CURVE;
|
||||||
}
|
}
|
||||||
if (point2.other.segmentBefore != SEGMENT_CURVE) {
|
if (point2.other.segment_before != SEGMENT_CURVE) {
|
||||||
point2.other.deltaBefore = -
|
point2.other.delta_before = -
|
||||||
after = (point2.other.pos - point->pos) / 3.0;
|
after = (point2.other.pos - point->pos) / 3.0;
|
||||||
point2.other.segmentBefore = SEGMENT_CURVE;
|
point2.other.segment_before = SEGMENT_CURVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The inverse of adding a point, reconstruct the original handles
|
// The inverse of adding a point, reconstruct the original handles
|
||||||
@@ -290,8 +290,8 @@ SinglePointRemoveAction::SinglePointRemoveAction(const SymbolPartP& part, UInt p
|
|||||||
double al = after .length() + 0.00000001;
|
double al = after .length() + 0.00000001;
|
||||||
double totl = bl + al;
|
double totl = bl + al;
|
||||||
// set new handle sizes
|
// set new handle sizes
|
||||||
point1.other.deltaAfter *= totl / bl;
|
point1.other.delta_after *= totl / bl;
|
||||||
point2.other.deltaBefore *= totl / al;
|
point2.other.delta_before *= totl / al;
|
||||||
|
|
||||||
// Also take in acount cases where the point does not correspond to a freshly added point.
|
// Also take in acount cases where the point does not correspond to a freshly added point.
|
||||||
// distance from the point to the curve as it would be in the above case can be used,
|
// distance from the point to the curve as it would be in the above case can be used,
|
||||||
@@ -301,8 +301,8 @@ SinglePointRemoveAction::SinglePointRemoveAction(const SymbolPartP& part, UInt p
|
|||||||
Vector2D p = c.pointAt(t);
|
Vector2D p = c.pointAt(t);
|
||||||
Vector2D distP = point->pos - p;
|
Vector2D distP = point->pos - p;
|
||||||
// adjust handle sizes
|
// adjust handle sizes
|
||||||
point1.other.deltaAfter *= ssqrt(distP.dot(point1.other.deltaAfter) /point1.other.deltaAfter.lengthSqr()) + 1;
|
point1.other.delta_after *= ssqrt(distP.dot(point1.other.delta_after) /point1.other.delta_after.lengthSqr()) + 1;
|
||||||
point2.other.deltaBefore *= ssqrt(distP.dot(point2.other.deltaBefore)/point2.other.deltaBefore.lengthSqr()) + 1;
|
point2.other.delta_before *= ssqrt(distP.dot(point2.other.delta_before)/point2.other.delta_before.lengthSqr()) + 1;
|
||||||
|
|
||||||
// unlock if needed
|
// unlock if needed
|
||||||
if (point1.other.lock == LOCK_SIZE) point1.other.lock = LOCK_DIR;
|
if (point1.other.lock == LOCK_SIZE) point1.other.lock = LOCK_DIR;
|
||||||
@@ -312,8 +312,8 @@ SinglePointRemoveAction::SinglePointRemoveAction(const SymbolPartP& part, UInt p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SinglePointRemoveAction::perform(bool toUndo) {
|
void SinglePointRemoveAction::perform(bool to_undo) {
|
||||||
if (toUndo) {
|
if (to_undo) {
|
||||||
// reinsert the point
|
// reinsert the point
|
||||||
part->points.insert(part->points.begin() + position, point);
|
part->points.insert(part->points.begin() + position, point);
|
||||||
} else {
|
} else {
|
||||||
@@ -336,8 +336,8 @@ class ControlPointRemoveAction : public Action {
|
|||||||
public:
|
public:
|
||||||
ControlPointRemoveAction(const SymbolPartP& part, const set<ControlPointP>& toDelete);
|
ControlPointRemoveAction(const SymbolPartP& part, const set<ControlPointP>& toDelete);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vector<SinglePointRemoveActionP> removals;
|
vector<SinglePointRemoveActionP> removals;
|
||||||
@@ -355,17 +355,17 @@ ControlPointRemoveAction::ControlPointRemoveAction(const SymbolPartP& part, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String ControlPointRemoveAction::getName(bool toUndo) const {
|
String ControlPointRemoveAction::getName(bool to_undo) const {
|
||||||
return removals.size() == 1 ? _("Delete point") : _("Delete points");
|
return removals.size() == 1 ? _("Delete point") : _("Delete points");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlPointRemoveAction::perform(bool toUndo) {
|
void ControlPointRemoveAction::perform(bool to_undo) {
|
||||||
if (toUndo) {
|
if (to_undo) {
|
||||||
FOR_EACH(r, removals) r->perform(toUndo);
|
FOR_EACH(r, removals) r->perform(to_undo);
|
||||||
} else {
|
} else {
|
||||||
// in reverse order, because positions of later points will
|
// in reverse order, because positions of later points will
|
||||||
// change after removal of earlier points.
|
// change after removal of earlier points.
|
||||||
FOR_EACH_REVERSE(r, removals) r->perform(toUndo);
|
FOR_EACH_REVERSE(r, removals) r->perform(to_undo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class ControlPointMoveAction : public Action {
|
|||||||
public:
|
public:
|
||||||
ControlPointMoveAction(const set<ControlPointP>& points);
|
ControlPointMoveAction(const set<ControlPointP>& points);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
/// Update this action to move some more
|
/// Update this action to move some more
|
||||||
void move(const Vector2D& delta);
|
void move(const Vector2D& delta);
|
||||||
@@ -52,16 +52,16 @@ class HandleMoveAction : public Action {
|
|||||||
public:
|
public:
|
||||||
HandleMoveAction(const SelectedHandle& handle);
|
HandleMoveAction(const SelectedHandle& handle);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
/// Update this action to move some more
|
/// Update this action to move some more
|
||||||
void move(const Vector2D& delta);
|
void move(const Vector2D& delta);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SelectedHandle handle; ///< The handle to move
|
SelectedHandle handle; ///< The handle to move
|
||||||
Vector2D oldHandle; ///< Old value of this handle
|
Vector2D old_handle; ///< Old value of this handle
|
||||||
Vector2D oldOther; ///< Old value of other handle, needed for contraints
|
Vector2D old_other; ///< Old value of other handle, needed for contraints
|
||||||
Vector2D delta; ///< Amount we moved
|
Vector2D delta; ///< Amount we moved
|
||||||
public:
|
public:
|
||||||
bool constrain; ///< Constrain movement?
|
bool constrain; ///< Constrain movement?
|
||||||
@@ -90,8 +90,8 @@ class SegmentModeAction : public Action {
|
|||||||
public:
|
public:
|
||||||
SegmentModeAction(const ControlPointP& p1, const ControlPointP& p2, SegmentMode mode);
|
SegmentModeAction(const ControlPointP& p1, const ControlPointP& p2, SegmentMode mode);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ControlPointUpdate point1, point2;
|
ControlPointUpdate point1, point2;
|
||||||
@@ -104,8 +104,8 @@ class LockModeAction : public Action {
|
|||||||
public:
|
public:
|
||||||
LockModeAction(const ControlPointP& p, LockMode mode);
|
LockModeAction(const ControlPointP& p, LockMode mode);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ControlPointUpdate point; ///< The affected point
|
ControlPointUpdate point; ///< The affected point
|
||||||
@@ -120,8 +120,8 @@ class CurveDragAction : public SegmentModeAction {
|
|||||||
public:
|
public:
|
||||||
CurveDragAction(const ControlPointP& point1, const ControlPointP& point2);
|
CurveDragAction(const ControlPointP& point1, const ControlPointP& point2);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
// Move the curve by this much, it is grabbed at time t
|
// Move the curve by this much, it is grabbed at time t
|
||||||
void move(const Vector2D& delta, double t);
|
void move(const Vector2D& delta, double t);
|
||||||
@@ -133,17 +133,17 @@ class CurveDragAction : public SegmentModeAction {
|
|||||||
class ControlPointAddAction : public Action {
|
class ControlPointAddAction : public Action {
|
||||||
public:
|
public:
|
||||||
/// Insert a new point in part, after position insertAfter_, at the time t on the segment
|
/// Insert a new point in part, after position insertAfter_, at the time t on the segment
|
||||||
ControlPointAddAction(const SymbolPartP& part, UInt insertAfter, double t);
|
ControlPointAddAction(const SymbolPartP& part, UInt insert_after, double t);
|
||||||
|
|
||||||
virtual String getName(bool toUndo) const;
|
virtual String getName(bool to_undo) const;
|
||||||
virtual void perform(bool toUndo);
|
virtual void perform(bool to_undo);
|
||||||
|
|
||||||
inline ControlPointP getNewPoint() const { return newPoint; }
|
inline ControlPointP getNewPoint() const { return new_point; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SymbolPartP part; ///< SymbolPart we are in
|
SymbolPartP part; ///< SymbolPart we are in
|
||||||
ControlPointP newPoint; ///< The point to insert
|
ControlPointP new_point; ///< The point to insert
|
||||||
UInt insertAfter; ///< Insert after index .. in the array
|
UInt insert_after; ///< Insert after index .. in the array
|
||||||
ControlPointUpdate point1, point2; ///< Update the points around the new point
|
ControlPointUpdate point1, point2; ///< Update the points around the new point
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -22,11 +22,11 @@ Card::Card() {
|
|||||||
if (!game_for_new_cards()) {
|
if (!game_for_new_cards()) {
|
||||||
throw InternalError(_("game_for_new_cards not set"));
|
throw InternalError(_("game_for_new_cards not set"));
|
||||||
}
|
}
|
||||||
data.init(game_for_new_cards()->cardFields);
|
data.init(game_for_new_cards()->card_fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
Card::Card(const Game& game) {
|
Card::Card(const Game& game) {
|
||||||
data.init(game.cardFields);
|
data.init(game.card_fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
String Card::identification() const {
|
String Card::identification() const {
|
||||||
|
|||||||
+24
-11
@@ -12,16 +12,16 @@
|
|||||||
// ----------------------------------------------------------------------------- : Field
|
// ----------------------------------------------------------------------------- : Field
|
||||||
|
|
||||||
Field::Field()
|
Field::Field()
|
||||||
: index (0) // sensible default?
|
: index (0) // sensible default?
|
||||||
, editable (true)
|
, editable (true)
|
||||||
, saveValue (true)
|
, save_value (true)
|
||||||
, showStatistics (true)
|
, show_statistics (true)
|
||||||
, identifying (false)
|
, identifying (false)
|
||||||
, cardListColumn (-1)
|
, card_list_column (-1)
|
||||||
, cardListWidth (100)
|
, card_list_width (100)
|
||||||
, cardListAllow (true)
|
, card_list_allow (true)
|
||||||
// , cardListAlign (ALIGN_LEFT)
|
// , card_list_align (ALIGN_LEFT)
|
||||||
, tabIndex (0)
|
, tab_index (0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Field::~Field() {}
|
Field::~Field() {}
|
||||||
@@ -29,8 +29,17 @@ Field::~Field() {}
|
|||||||
IMPLEMENT_REFLECTION(Field) {
|
IMPLEMENT_REFLECTION(Field) {
|
||||||
if (!tag.reading()) {
|
if (!tag.reading()) {
|
||||||
String type = typeName();
|
String type = typeName();
|
||||||
REFLECT_N("type", type);
|
REFLECT(type);
|
||||||
}
|
}
|
||||||
|
REFLECT(editable);
|
||||||
|
REFLECT(save_value);
|
||||||
|
REFLECT(show_statistics);
|
||||||
|
REFLECT(identifying);
|
||||||
|
REFLECT(card_list_column);
|
||||||
|
REFLECT(card_list_width);
|
||||||
|
REFLECT(card_list_allow);
|
||||||
|
// REFLECT(card_list_align);
|
||||||
|
REFLECT(tab_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@@ -49,6 +58,8 @@ shared_ptr<Field> read_new<Field>(Reader& reader) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Style
|
// ----------------------------------------------------------------------------- : Style
|
||||||
|
|
||||||
|
Style::~Style() {}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION(Style) {
|
IMPLEMENT_REFLECTION(Style) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +69,8 @@ void initObject(const FieldP& field, StyleP& style) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Value
|
// ----------------------------------------------------------------------------- : Value
|
||||||
|
|
||||||
|
Value::~Value() {}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION(Value) {
|
IMPLEMENT_REFLECTION(Value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -24,19 +24,19 @@ class Field {
|
|||||||
Field();
|
Field();
|
||||||
virtual ~Field();
|
virtual ~Field();
|
||||||
|
|
||||||
UInt index; ///< Used by IndexMap
|
UInt index; ///< Used by IndexMap
|
||||||
String name; ///< Name of the field, for refering to it from scripts and files
|
String name; ///< Name of the field, for refering to it from scripts and files
|
||||||
String description; ///< Description, used in status bar
|
String description; ///< Description, used in status bar
|
||||||
bool editable; ///< Can values of this field be edited?
|
bool editable; ///< Can values of this field be edited?
|
||||||
bool saveValue; ///< Should values of this field be written to files? Can be false for script generated fields.
|
bool save_value; ///< Should values of this field be written to files? Can be false for script generated fields.
|
||||||
bool showStatistics; ///< Should this field appear as a group by choice in the statistics panel?
|
bool show_statistics; ///< Should this field appear as a group by choice in the statistics panel?
|
||||||
bool identifying; ///< Does this field give Card::identification()?
|
bool identifying; ///< Does this field give Card::identification()?
|
||||||
int cardListColumn; ///< What column to use in the card list? -1 = don't list
|
int card_list_column; ///< What column to use in the card list? -1 = don't list
|
||||||
UInt cardListWidth; ///< Width of the card list column (pixels).
|
UInt card_list_width; ///< Width of the card list column (pixels).
|
||||||
bool cardListAllow; ///< Is this field allowed to appear in the card list.
|
bool card_list_allow; ///< Is this field allowed to appear in the card list.
|
||||||
String cardListName; ///< Alternate name to use in card list.
|
String card_list_name; ///< Alternate name to use in card list.
|
||||||
// Alignment cardListAlign; ///< Alignment of the card list colummn.
|
// Alignment card_list_align; ///< Alignment of the card list colummn.
|
||||||
int tabIndex; ///< Tab index in editor
|
int tab_index; ///< Tab index in editor
|
||||||
// Vector<DependendScript> dependendScripts; // scripts that depend on values of this field
|
// Vector<DependendScript> dependendScripts; // scripts that depend on values of this field
|
||||||
|
|
||||||
/// Creates a new Value corresponding to this Field
|
/// Creates a new Value corresponding to this Field
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <data/field/text.hpp>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : TextField
|
||||||
|
|
||||||
|
TextField::TextField()
|
||||||
|
: multi_line(false), move_cursor_with_sort(false)
|
||||||
|
, default_name(_("Default"))
|
||||||
|
{}
|
||||||
|
|
||||||
|
StyleP TextField::newStyle(const FieldP& thisP) const {
|
||||||
|
assert(thisP.get() == this);
|
||||||
|
return new_shared<TextStyle>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueP TextField::newValue(const FieldP& thisP) const {
|
||||||
|
assert(thisP.get() == this);
|
||||||
|
return new_shared<TextValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldP TextField::clone() const {
|
||||||
|
return new_shared1<TextField>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
String TextField::typeName() const {
|
||||||
|
return _("text");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_REFLECTION(TextField) {
|
||||||
|
REFLECT_BASE(Field);
|
||||||
|
REFLECT(multi_line);
|
||||||
|
// REFLECT(script);
|
||||||
|
// REFLECT_N("default", default_script);
|
||||||
|
REFLECT(move_cursor_with_sort);
|
||||||
|
REFLECT(default_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : TextStyle
|
||||||
|
|
||||||
|
StyleP TextStyle::clone() const {
|
||||||
|
return new_shared1<TextStyle>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_REFLECTION(TextStyle) {
|
||||||
|
REFLECT_BASE(Style);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : TextValue
|
||||||
|
|
||||||
|
ValueP TextValue::clone() const {
|
||||||
|
return new_shared1<TextValue>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_REFLECTION(TextValue) {
|
||||||
|
REFLECT_BASE(Value);
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#ifndef HEADER_DATA_FIELD_TEXT
|
||||||
|
#define HEADER_DATA_FIELD_TEXT
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <util/prec.hpp>
|
||||||
|
#include <data/field.hpp>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : TextField
|
||||||
|
|
||||||
|
/// A field that stores tagged text
|
||||||
|
class TextField : public Field {
|
||||||
|
public:
|
||||||
|
TextField();
|
||||||
|
|
||||||
|
// Script script;
|
||||||
|
// Script default_script;
|
||||||
|
bool multi_line; ///< Are newlines allowed in the text?
|
||||||
|
bool move_cursor_with_sort; ///< When the text is reordered by a script should the cursor position be updated?
|
||||||
|
String default_name; ///< Name of "default" value
|
||||||
|
|
||||||
|
virtual ValueP newValue(const FieldP& thisP) const;
|
||||||
|
virtual StyleP newStyle(const FieldP& thisP) const;
|
||||||
|
virtual FieldP clone() const;
|
||||||
|
virtual String typeName() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : TextStyle
|
||||||
|
|
||||||
|
/// The Style for a TextField
|
||||||
|
class TextStyle : public Style {
|
||||||
|
public:
|
||||||
|
// FontInfo font; ///< Font to use for the text
|
||||||
|
// SymbolFontInfo symbol_font; ///< Symbol font for symbols in the text
|
||||||
|
bool always_symbol; ///< Should everything be drawn as symbols?
|
||||||
|
bool allow_formatting; ///< Is formating (bold/italic/..) allowed?
|
||||||
|
// Alignment alignment; ///< Alignment inside the box
|
||||||
|
int angle; ///< Angle of the text inside the box
|
||||||
|
int padding_left, padding_left_min; ///< Padding
|
||||||
|
int padding_right, padding_right_min; ///< Padding
|
||||||
|
int padding_top, padding_top_min; ///< Padding
|
||||||
|
int padding_bottom, padding_bottom_min; ///< Padding
|
||||||
|
double line_height_soft; ///< Line height for soft linebreaks
|
||||||
|
double line_height_hard; ///< Line height for hard linebreaks
|
||||||
|
double line_height_line; ///< Line height for <line> tags
|
||||||
|
String mask_filename; ///< Filename of the mask
|
||||||
|
// ContourMaskP mask; ///< Mask to fit the text to (may be null)
|
||||||
|
|
||||||
|
virtual StyleP clone() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : TextValue
|
||||||
|
|
||||||
|
/// The Value in a TextField
|
||||||
|
class TextValue : public Value {
|
||||||
|
public:
|
||||||
|
virtual ValueP clone() const;
|
||||||
|
|
||||||
|
String value;
|
||||||
|
private:
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
#endif
|
||||||
+9
-9
@@ -25,18 +25,18 @@ String Game::typeName() const { return _("game"); }
|
|||||||
|
|
||||||
IMPLEMENT_REFLECTION(Game) {
|
IMPLEMENT_REFLECTION(Game) {
|
||||||
// ioMseVersion(io, fileName, fileVersion);
|
// ioMseVersion(io, fileName, fileVersion);
|
||||||
REFLECT_N("full name", fullName);
|
REFLECT(full_name);
|
||||||
REFLECT_N("icon", iconFilename);
|
REFLECT_N("icon", icon_filename);
|
||||||
// REFLECT_N("init script", initScript);
|
// REFLECT(init_script);
|
||||||
REFLECT_N("set field", setFields);
|
REFLECT(set_fields);
|
||||||
REFLECT_N("card field", cardFields);
|
REFLECT(card_fields);
|
||||||
// REFLECT_N("keyword parameter type", keywordParams);
|
// REFLECT_N("keyword parameter type", keyword_params);
|
||||||
// REFLECT_N("keyword separator type", keywordSeparators);
|
// REFLECT_N("keyword separator type", keyword_separators);
|
||||||
// REFLECT_N("keyword", keywords);
|
// REFLECT_N("keyword", keywords);
|
||||||
// REFLECT_N("word list", wordLists);
|
// REFLECT_N("word list", word_lists);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::validate() {
|
void Game::validate() {
|
||||||
// a default for the full name
|
// a default for the full name
|
||||||
if (fullName.empty()) fullName = name();
|
if (full_name.empty()) full_name = name();
|
||||||
}
|
}
|
||||||
+4
-4
@@ -19,10 +19,10 @@ DECLARE_POINTER_TYPE(Game);
|
|||||||
|
|
||||||
class Game : public Packaged {
|
class Game : public Packaged {
|
||||||
public:
|
public:
|
||||||
String fullName;
|
String full_name;
|
||||||
String iconFilename;
|
String icon_filename;
|
||||||
vector<FieldP> setFields;
|
vector<FieldP> set_fields;
|
||||||
vector<FieldP> cardFields;
|
vector<FieldP> card_fields;
|
||||||
|
|
||||||
/// Loads the game with a particular name, for example "magic"
|
/// Loads the game with a particular name, for example "magic"
|
||||||
static GameP byName(const String& name);
|
static GameP byName(const String& name);
|
||||||
|
|||||||
+31
-31
@@ -30,11 +30,11 @@ IMPLEMENT_REFLECTION(ColumnSettings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION(GameSettings) {
|
IMPLEMENT_REFLECTION(GameSettings) {
|
||||||
REFLECT_N("default style", defaultStyle);
|
REFLECT(default_style);
|
||||||
REFLECT_N("default export", defaultExport);
|
REFLECT(default_export);
|
||||||
// REFLECT_N("cardlist columns", columns);
|
// REFLECT_N("cardlist columns", columns);
|
||||||
REFLECT_N("sort cards by", sortCardsBy);
|
REFLECT(sort_cards_by);
|
||||||
REFLECT_N("sort cards ascending", sortCardsAscending);
|
REFLECT(sort_cards_ascending);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION(StyleSettings) {
|
IMPLEMENT_REFLECTION(StyleSettings) {
|
||||||
@@ -46,12 +46,12 @@ IMPLEMENT_REFLECTION(StyleSettings) {
|
|||||||
Settings settings;
|
Settings settings;
|
||||||
|
|
||||||
Settings::Settings()
|
Settings::Settings()
|
||||||
: setWindowMaximized (false)
|
: set_window_maximized (false)
|
||||||
, setWindowWidth (790)
|
, set_window_width (790)
|
||||||
, setWindowHeight (300)
|
, set_window_height (300)
|
||||||
, cardNotesHeight (40)
|
, card_notes_height (40)
|
||||||
, updatesUrl (_("http://magicseteditor.sourceforge.net/updates"))
|
, updates_url (_("http://magicseteditor.sourceforge.net/updates"))
|
||||||
, checkUpdates (CHECK_IF_CONNECTED)
|
, check_updates (CHECK_IF_CONNECTED)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Settings::addRecentFile(const String& filename) {
|
void Settings::addRecentFile(const String& filename) {
|
||||||
@@ -60,18 +60,18 @@ void Settings::addRecentFile(const String& filename) {
|
|||||||
fn.Normalize();
|
fn.Normalize();
|
||||||
String filenameAbs = fn.GetFullPath();
|
String filenameAbs = fn.GetFullPath();
|
||||||
// remove duplicates
|
// remove duplicates
|
||||||
recentSets.erase(
|
recent_sets.erase(
|
||||||
remove(recentSets.begin(), recentSets.end(), filenameAbs),
|
remove(recent_sets.begin(), recent_sets.end(), filenameAbs),
|
||||||
recentSets.end()
|
recent_sets.end()
|
||||||
);
|
);
|
||||||
// add to front of list
|
// add to front of list
|
||||||
recentSets.insert(recentSets.begin(), filenameAbs);
|
recent_sets.insert(recent_sets.begin(), filenameAbs);
|
||||||
// enforce size limit
|
// enforce size limit
|
||||||
if (recentSets.size() > maxRecentSets) recentSets.resize(maxRecentSets);
|
if (recent_sets.size() > max_recent_sets) recent_sets.resize(max_recent_sets);
|
||||||
}
|
}
|
||||||
|
|
||||||
GameSettings& Settings::gameSettingsFor(const Game& game) {
|
GameSettings& Settings::gameSettingsFor(const Game& game) {
|
||||||
GameSettingsP& gs = settings.gameSettings[game.name()];
|
GameSettingsP& gs = settings.game_settings[game.name()];
|
||||||
if (!gs) gs.reset(new GameSettings);
|
if (!gs) gs.reset(new GameSettings);
|
||||||
return *gs;
|
return *gs;
|
||||||
}
|
}
|
||||||
@@ -84,29 +84,29 @@ StyleSettings& Settings::styleSettingsFor(const CardStyle& style) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String userSettingsDir() {
|
String user_settings_dir() {
|
||||||
return _(""); // TODO
|
return _(""); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
String Settings::settingsFile() {
|
String Settings::settingsFile() {
|
||||||
// return userSettingsDir() + _("mse.config");
|
// return user_settings_dir() + _("mse.config");
|
||||||
return userSettingsDir() + _("mse8.config"); // use different file during development of C++ port
|
return user_settings_dir() + _("mse8.config"); // use different file during development of C++ port
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION(Settings) {
|
IMPLEMENT_REFLECTION(Settings) {
|
||||||
// ioMseVersion(io, "settings", fileVersion);
|
// ioMseVersion(io, "settings", file_version);
|
||||||
REFLECT_N("recent set", recentSets);
|
REFLECT_N("recent_set", recent_sets);
|
||||||
REFLECT_N("window maximized", setWindowMaximized);
|
REFLECT(set_window_maximized);
|
||||||
REFLECT_N("window width", setWindowWidth);
|
REFLECT(set_window_width);
|
||||||
REFLECT_N("window height", setWindowHeight);
|
REFLECT(set_window_height);
|
||||||
REFLECT_N("card notes height", cardNotesHeight);
|
REFLECT(card_notes_height);
|
||||||
REFLECT_N("default game", defaultGame);
|
REFLECT(default_game);
|
||||||
REFLECT_N("apprentice location", apprenticeLocation);
|
REFLECT(apprentice_location);
|
||||||
REFLECT_N("updates url", updatesUrl);
|
REFLECT(updates_url);
|
||||||
REFLECT_N("check updates", checkUpdates);
|
REFLECT(check_updates);
|
||||||
// ioAll(io, "game settings", gameSettings);
|
// ioAll(io, game_settings);
|
||||||
// ioStyleSettings(io);
|
// ioStyleSettings(io);
|
||||||
// REFLECT_N("default style settings", defaultStyleSettings);
|
// REFLECT(default_style_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::read() {
|
void Settings::read() {
|
||||||
|
|||||||
+23
-23
@@ -40,11 +40,11 @@ class ColumnSettings {
|
|||||||
/// Settings for a Game
|
/// Settings for a Game
|
||||||
class GameSettings {
|
class GameSettings {
|
||||||
public:
|
public:
|
||||||
String defaultStyle;
|
String default_style;
|
||||||
String defaultExport;
|
String default_export;
|
||||||
map<String, ColumnSettings> columns;
|
map<String, ColumnSettings> columns;
|
||||||
String sortCardsBy;
|
String sort_cards_by;
|
||||||
bool sortCardsAscending;
|
bool sort_cards_ascending;
|
||||||
|
|
||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
};
|
};
|
||||||
@@ -53,11 +53,11 @@ class GameSettings {
|
|||||||
class StyleSettings {
|
class StyleSettings {
|
||||||
public:
|
public:
|
||||||
// Rendering/display settings
|
// Rendering/display settings
|
||||||
/* SimpleDefaultable<double> cardZoom = 1.0;
|
/* SimpleDefaultable<double> card_zoom = 1.0;
|
||||||
SimpleDefaultable<int> cardAngle = 0;
|
SimpleDefaultable<int> card_angle = 0;
|
||||||
SimpleDefaultable<bool> cardAntiAlias = true;
|
SimpleDefaultable<bool> card_anti_alias = true;
|
||||||
SimpleDefaultable<bool> cardBorders = true;
|
SimpleDefaultable<bool> card_borders = true;
|
||||||
SimpleDefaultable<bool> cardNormalExport = true;
|
SimpleDefaultable<bool> card_normal_export = true;
|
||||||
*/
|
*/
|
||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
|
|
||||||
@@ -77,20 +77,20 @@ class Settings {
|
|||||||
Settings();
|
Settings();
|
||||||
|
|
||||||
// --------------------------------------------------- : Recently opened sets
|
// --------------------------------------------------- : Recently opened sets
|
||||||
vector<String> recentSets;
|
vector<String> recent_sets;
|
||||||
static const UInt maxRecentSets = 4; // store this many recent sets
|
static const UInt max_recent_sets = 4; // store this many recent sets
|
||||||
|
|
||||||
/// Add a file to the list of recent files
|
/// Add a file to the list of recent files
|
||||||
void addRecentFile(const String& filename);
|
void addRecentFile(const String& filename);
|
||||||
|
|
||||||
// --------------------------------------------------- : Set window size
|
// --------------------------------------------------- : Set window size
|
||||||
bool setWindowMaximized;
|
bool set_window_maximized;
|
||||||
UInt setWindowWidth;
|
UInt set_window_width;
|
||||||
UInt setWindowHeight;
|
UInt set_window_height;
|
||||||
UInt cardNotesHeight;
|
UInt card_notes_height;
|
||||||
|
|
||||||
// --------------------------------------------------- : Default pacakge selections
|
// --------------------------------------------------- : Default pacakge selections
|
||||||
String defaultGame;
|
String default_game;
|
||||||
|
|
||||||
// --------------------------------------------------- : Game/style specific
|
// --------------------------------------------------- : Game/style specific
|
||||||
|
|
||||||
@@ -100,18 +100,18 @@ class Settings {
|
|||||||
StyleSettings& styleSettingsFor(const CardStyle& style);
|
StyleSettings& styleSettingsFor(const CardStyle& style);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
map<String,GameSettingsP> gameSettings;
|
map<String,GameSettingsP> game_settings;
|
||||||
map<String,StyleSettingsP> styleSettings;
|
map<String,StyleSettingsP> style_settings;
|
||||||
StyleSettings defaultStyleSettings;
|
StyleSettings default_style_settings;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------------------------------------- : Special game stuff
|
// --------------------------------------------------- : Special game stuff
|
||||||
String apprenticeLocation;
|
String apprentice_location;
|
||||||
String mwsLocation;
|
String mws_location;
|
||||||
|
|
||||||
// --------------------------------------------------- : Update checking
|
// --------------------------------------------------- : Update checking
|
||||||
String updatesUrl;
|
String updates_url;
|
||||||
CheckUpdates checkUpdates;
|
CheckUpdates check_updates;
|
||||||
|
|
||||||
// --------------------------------------------------- : The io
|
// --------------------------------------------------- : The io
|
||||||
|
|
||||||
|
|||||||
+30
-30
@@ -27,30 +27,30 @@ IMPLEMENT_REFLECTION_ENUM(SegmentMode) {
|
|||||||
IMPLEMENT_REFLECTION(ControlPoint) {
|
IMPLEMENT_REFLECTION(ControlPoint) {
|
||||||
REFLECT_N("position", pos);
|
REFLECT_N("position", pos);
|
||||||
REFLECT_N("lock", lock);
|
REFLECT_N("lock", lock);
|
||||||
REFLECT_N("line after", segmentAfter);
|
REFLECT_N("line_after", segment_after);
|
||||||
if (tag.reading() || segmentBefore == SEGMENT_CURVE) {
|
if (tag.reading() || segment_before == SEGMENT_CURVE) {
|
||||||
REFLECT_N("handle before", deltaBefore);
|
REFLECT_N("handle_before", delta_before);
|
||||||
}
|
}
|
||||||
if (tag.reading() || segmentAfter == SEGMENT_CURVE) {
|
if (tag.reading() || segment_after == SEGMENT_CURVE) {
|
||||||
REFLECT_N("handle after", deltaAfter);
|
REFLECT_N("handle_after", delta_after);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlPoint::ControlPoint()
|
ControlPoint::ControlPoint()
|
||||||
: segmentBefore(SEGMENT_LINE), segmentAfter(SEGMENT_LINE)
|
: segment_before(SEGMENT_LINE), segment_after(SEGMENT_LINE)
|
||||||
, lock(LOCK_FREE)
|
, lock(LOCK_FREE)
|
||||||
{}
|
{}
|
||||||
ControlPoint::ControlPoint(double x, double y)
|
ControlPoint::ControlPoint(double x, double y)
|
||||||
: segmentBefore(SEGMENT_LINE), segmentAfter(SEGMENT_LINE)
|
: segment_before(SEGMENT_LINE), segment_after(SEGMENT_LINE)
|
||||||
, lock(LOCK_FREE)
|
, lock(LOCK_FREE)
|
||||||
, pos(x,y)
|
, pos(x,y)
|
||||||
{}
|
{}
|
||||||
ControlPoint::ControlPoint(double x, double y, double xb, double yb, double xa, double ya, LockMode lock)
|
ControlPoint::ControlPoint(double x, double y, double xb, double yb, double xa, double ya, LockMode lock)
|
||||||
: segmentBefore(SEGMENT_CURVE), segmentAfter(SEGMENT_CURVE)
|
: segment_before(SEGMENT_CURVE), segment_after(SEGMENT_CURVE)
|
||||||
, lock(lock)
|
, lock(lock)
|
||||||
, pos(x,y)
|
, pos(x,y)
|
||||||
, deltaBefore(xb,yb)
|
, delta_before(xb,yb)
|
||||||
, deltaAfter(xa,ya)
|
, delta_after(xa,ya)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void ControlPoint::onUpdateHandle(WhichHandle wh) {
|
void ControlPoint::onUpdateHandle(WhichHandle wh) {
|
||||||
@@ -64,31 +64,31 @@ void ControlPoint::onUpdateHandle(WhichHandle wh) {
|
|||||||
void ControlPoint::onUpdateLock() {
|
void ControlPoint::onUpdateLock() {
|
||||||
// The lock has changed, avarage the handle values
|
// The lock has changed, avarage the handle values
|
||||||
if (lock == LOCK_DIR) {
|
if (lock == LOCK_DIR) {
|
||||||
// deltaBefore = x * deltaAfter
|
// delta_before = x * delta_after
|
||||||
Vector2D dir = (deltaBefore - deltaAfter).normalized();
|
Vector2D dir = (delta_before - delta_after).normalized();
|
||||||
deltaBefore = dir * deltaBefore.length();
|
delta_before = dir * delta_before.length();
|
||||||
deltaAfter = dir * -deltaAfter.length();
|
delta_after = dir * -delta_after.length();
|
||||||
} else if (lock == LOCK_SIZE) {
|
} else if (lock == LOCK_SIZE) {
|
||||||
// deltaBefore = -deltaAfter
|
// delta_before = -delta_after
|
||||||
deltaBefore = (deltaBefore - deltaAfter) * 0.5;
|
delta_before = (delta_before - delta_after) * 0.5;
|
||||||
deltaAfter = -deltaBefore;
|
delta_after = -delta_before;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D& ControlPoint::getHandle(WhichHandle wh) {
|
Vector2D& ControlPoint::getHandle(WhichHandle wh) {
|
||||||
if (wh == HANDLE_BEFORE) {
|
if (wh == HANDLE_BEFORE) {
|
||||||
return deltaBefore;
|
return delta_before;
|
||||||
} else {
|
} else {
|
||||||
assert(wh == HANDLE_AFTER);
|
assert(wh == HANDLE_AFTER);
|
||||||
return deltaAfter;
|
return delta_after;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vector2D& ControlPoint::getOther(WhichHandle wh) {
|
Vector2D& ControlPoint::getOther(WhichHandle wh) {
|
||||||
if (wh == HANDLE_BEFORE) {
|
if (wh == HANDLE_BEFORE) {
|
||||||
return deltaAfter;
|
return delta_after;
|
||||||
} else {
|
} else {
|
||||||
assert(wh == HANDLE_AFTER);
|
assert(wh == HANDLE_AFTER);
|
||||||
return deltaBefore;
|
return delta_before;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,13 +112,13 @@ IMPLEMENT_REFLECTION(SymbolPart) {
|
|||||||
// enforce constraints
|
// enforce constraints
|
||||||
enforceConstraints();
|
enforceConstraints();
|
||||||
calculateBounds();
|
calculateBounds();
|
||||||
if (maxPos.x > 100 && maxPos.y > 100) {
|
if (max_pos.x > 100 && max_pos.y > 100) {
|
||||||
// this is a <= 0.1.2 symbol, points range [0...500] instead of [0...1]
|
// this is a <= 0.1.2 symbol, points range [0...500] instead of [0...1]
|
||||||
// adjust it
|
// adjust it
|
||||||
FOR_EACH(p, points) {
|
FOR_EACH(p, points) {
|
||||||
p->pos /= 500.0;
|
p->pos /= 500.0;
|
||||||
p->deltaBefore /= 500.0;
|
p->delta_before /= 500.0;
|
||||||
p->deltaAfter /= 500.0;
|
p->delta_after /= 500.0;
|
||||||
}
|
}
|
||||||
if (name.empty()) name = _("Shape");
|
if (name.empty()) name = _("Shape");
|
||||||
calculateBounds();
|
calculateBounds();
|
||||||
@@ -127,7 +127,7 @@ IMPLEMENT_REFLECTION(SymbolPart) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SymbolPart::SymbolPart()
|
SymbolPart::SymbolPart()
|
||||||
: combine(PART_OVERLAP), rotationCenter(.5, .5)
|
: combine(PART_OVERLAP), rotation_center(.5, .5)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SymbolPartP SymbolPart::clone() const {
|
SymbolPartP SymbolPart::clone() const {
|
||||||
@@ -143,16 +143,16 @@ void SymbolPart::enforceConstraints() {
|
|||||||
for (int i = 0 ; i < (int)points.size() ; ++i) {
|
for (int i = 0 ; i < (int)points.size() ; ++i) {
|
||||||
ControlPointP p1 = getPoint(i);
|
ControlPointP p1 = getPoint(i);
|
||||||
ControlPointP p2 = getPoint(i + 1);
|
ControlPointP p2 = getPoint(i + 1);
|
||||||
p2->segmentBefore = p1->segmentAfter;
|
p2->segment_before = p1->segment_after;
|
||||||
p1->onUpdateLock();
|
p1->onUpdateLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPart::calculateBounds() {
|
void SymbolPart::calculateBounds() {
|
||||||
minPos = Vector2D::infinity();
|
min_pos = Vector2D::infinity();
|
||||||
maxPos = -Vector2D::infinity();
|
max_pos = -Vector2D::infinity();
|
||||||
for (int i = 0 ; i < (int)points.size() ; ++i) {
|
for (int i = 0 ; i < (int)points.size() ; ++i) {
|
||||||
segmentBounds(*getPoint(i), *getPoint(i + 1), minPos, maxPos);
|
segment_bounds(*getPoint(i), *getPoint(i + 1), min_pos, max_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -21,12 +21,12 @@ DECLARE_POINTER_TYPE(Symbol);
|
|||||||
// ----------------------------------------------------------------------------- : ControlPoint
|
// ----------------------------------------------------------------------------- : ControlPoint
|
||||||
|
|
||||||
/// Mode of locking for control points in a bezier curve
|
/// Mode of locking for control points in a bezier curve
|
||||||
/** Specificly: the relation between deltaBefore and deltaAfter
|
/** Specificly: the relation between delta_before and delta_after
|
||||||
*/
|
*/
|
||||||
enum LockMode
|
enum LockMode
|
||||||
{ LOCK_FREE ///< no locking
|
{ LOCK_FREE ///< no locking
|
||||||
, LOCK_DIR ///< deltaBefore = x * deltaAfter
|
, LOCK_DIR ///< delta_before = x * delta_after
|
||||||
, LOCK_SIZE ///< deltaBefore = -deltaAfter
|
, LOCK_SIZE ///< delta_before = -delta_after
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Is the segment between two ControlPoints a line or a curve?
|
/// Is the segment between two ControlPoints a line or a curve?
|
||||||
@@ -47,19 +47,19 @@ enum WhichHandle
|
|||||||
class ControlPoint {
|
class ControlPoint {
|
||||||
public:
|
public:
|
||||||
Vector2D pos; ///< position of the control point itself
|
Vector2D pos; ///< position of the control point itself
|
||||||
Vector2D deltaBefore; ///< delta to bezier control point, for curve before point
|
Vector2D delta_before; ///< delta to bezier control point, for curve before point
|
||||||
Vector2D deltaAfter; ///< delta to bezier control point, for curve after point
|
Vector2D delta_after; ///< delta to bezier control point, for curve after point
|
||||||
SegmentMode segmentBefore, segmentAfter;
|
SegmentMode segment_before, segment_after;
|
||||||
LockMode lock;
|
LockMode lock;
|
||||||
|
|
||||||
/// Default constructor
|
/// Default constructor
|
||||||
ControlPoint();
|
ControlPoint();
|
||||||
/// Constructor for straight lines, takes only the position
|
/// Constructor for straight lines, takes only the position
|
||||||
ControlPoint(double x, double y);
|
ControlPoint(double x, double y);
|
||||||
/// Constructor for curves lines, takes postions, deltaBefore, deltaAfter and lock mode
|
/// Constructor for curves lines, takes postions, delta_before, delta_after and lock mode
|
||||||
ControlPoint(double x, double y, double xb, double yb, double xa, double ya, LockMode lock = LOCK_FREE);
|
ControlPoint(double x, double y, double xb, double yb, double xa, double ya, LockMode lock = LOCK_FREE);
|
||||||
|
|
||||||
/// Must be called after deltaBefore/deltaAfter has changed, enforces lock constraints
|
/// Must be called after delta_before/delta_after has changed, enforces lock constraints
|
||||||
void onUpdateHandle(WhichHandle wh);
|
void onUpdateHandle(WhichHandle wh);
|
||||||
/// Must be called after lock has changed, enforces lock constraints
|
/// Must be called after lock has changed, enforces lock constraints
|
||||||
void onUpdateLock();
|
void onUpdateLock();
|
||||||
@@ -124,10 +124,10 @@ class SymbolPart {
|
|||||||
/// How is this part combined with parts below it?
|
/// How is this part combined with parts below it?
|
||||||
SymbolPartCombine combine;
|
SymbolPartCombine combine;
|
||||||
// Center of rotation, relative to the part, when the part is scaled to [0..1]
|
// Center of rotation, relative to the part, when the part is scaled to [0..1]
|
||||||
Vector2D rotationCenter;
|
Vector2D rotation_center;
|
||||||
/// Position and size of the part
|
/// Position and size of the part
|
||||||
/// this is the smallest axis aligned bounding box that fits around the part
|
/// this is the smallest axis aligned bounding box that fits around the part
|
||||||
Vector2D minPos, maxPos;
|
Vector2D min_pos, max_pos;
|
||||||
|
|
||||||
SymbolPart();
|
SymbolPart();
|
||||||
|
|
||||||
|
|||||||
+47
-47
@@ -21,8 +21,8 @@ BezierCurve::BezierCurve(const Vector2D& p0, const Vector2D& p1, const Vector2D&
|
|||||||
|
|
||||||
BezierCurve::BezierCurve(const ControlPoint& p0, const ControlPoint& p3) {
|
BezierCurve::BezierCurve(const ControlPoint& p0, const ControlPoint& p3) {
|
||||||
// calculate coefficients
|
// calculate coefficients
|
||||||
c = p0.deltaAfter * 3.0;
|
c = p0.delta_after * 3.0;
|
||||||
b = (p3.pos + p3.deltaBefore - p0.pos - p0.deltaAfter) * 3.0 - c;
|
b = (p3.pos + p3.delta_before - p0.pos - p0.delta_after) * 3.0 - c;
|
||||||
a = (p3.pos - p0.pos) - c - b;
|
a = (p3.pos - p0.pos) - c - b;
|
||||||
d = p0.pos;
|
d = p0.pos;
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ void deCasteljau(Vector2D a1, Vector2D a2, Vector2D a3, Vector2D a4,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void deCasteljau(ControlPoint& a, ControlPoint& b, double t, ControlPoint& mid) {
|
void deCasteljau(ControlPoint& a, ControlPoint& b, double t, ControlPoint& mid) {
|
||||||
deCasteljau(a.pos, a.deltaAfter, b.deltaBefore, b.pos, t, mid);
|
deCasteljau(a.pos, a.delta_after, b.delta_before, b.pos, t, mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deCasteljau(const Vector2D& a1, Vector2D& a21, Vector2D& a34, const Vector2D& a4, double t, ControlPoint& out) {
|
void deCasteljau(const Vector2D& a1, Vector2D& a21, Vector2D& a34, const Vector2D& a4, double t, ControlPoint& out) {
|
||||||
@@ -51,15 +51,15 @@ void deCasteljau(const Vector2D& a1, Vector2D& a21, Vector2D& a34, const Vector2
|
|||||||
Vector2D mid23h21 = (a1 + half21) * (1-t) + mid23 * t;
|
Vector2D mid23h21 = (a1 + half21) * (1-t) + mid23 * t;
|
||||||
Vector2D mid23h34 = (a4 + half34) * t + mid23 * (1-t);
|
Vector2D mid23h34 = (a4 + half34) * t + mid23 * (1-t);
|
||||||
out.pos = mid23h21 * (1-t) + mid23h34 * t;
|
out.pos = mid23h21 * (1-t) + mid23h34 * t;
|
||||||
out.deltaBefore = mid23h21 - out.pos;
|
out.delta_before = mid23h21 - out.pos;
|
||||||
out.deltaAfter = mid23h34 - out.pos;
|
out.delta_after = mid23h34 - out.pos;
|
||||||
a21 = half21;
|
a21 = half21;
|
||||||
a34 = half34;
|
a34 = half34;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Drawing
|
// ----------------------------------------------------------------------------- : Drawing
|
||||||
|
|
||||||
void curveSubdivide(const BezierCurve& c, const Vector2D& p0, const Vector2D& p1, double t0, double t1, const Rotation& rot, vector<wxPoint>& out, UInt level) {
|
void curve_subdivide(const BezierCurve& c, const Vector2D& p0, const Vector2D& p1, double t0, double t1, const Rotation& rot, vector<wxPoint>& out, UInt level) {
|
||||||
if (level <= 0) return;
|
if (level <= 0) return;
|
||||||
double midtime = (t0+t1) * 0.5f;
|
double midtime = (t0+t1) * 0.5f;
|
||||||
Vector2D midpoint = c.pointAt(midtime);
|
Vector2D midpoint = c.pointAt(midtime);
|
||||||
@@ -70,70 +70,70 @@ void curveSubdivide(const BezierCurve& c, const Vector2D& p0, const Vector2D& p1
|
|||||||
double treshold = fabs( atan2(d0.x,d0.y) - atan2(d1.x,d1.y)) * (p0-p1).lengthSqr();
|
double treshold = fabs( atan2(d0.x,d0.y) - atan2(d1.x,d1.y)) * (p0-p1).lengthSqr();
|
||||||
bool subdivide = treshold >= .0001;
|
bool subdivide = treshold >= .0001;
|
||||||
// subdivide left
|
// subdivide left
|
||||||
curveSubdivide(c, p0, midpoint, t0, midtime, rot, out, level - 1);
|
curve_subdivide(c, p0, midpoint, t0, midtime, rot, out, level - 1);
|
||||||
// add midpoint
|
// add midpoint
|
||||||
if (subdivide) {
|
if (subdivide) {
|
||||||
out.push_back(rot.tr(midpoint));
|
out.push_back(rot.tr(midpoint));
|
||||||
}
|
}
|
||||||
// subdivide right
|
// subdivide right
|
||||||
curveSubdivide(c, midpoint, p1, midtime, t1, rot, out, level - 1);
|
curve_subdivide(c, midpoint, p1, midtime, t1, rot, out, level - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void segmentSubdivide(const ControlPoint& p0, const ControlPoint& p1, const Rotation& rot, vector<wxPoint>& out) {
|
void segment_subdivide(const ControlPoint& p0, const ControlPoint& p1, const Rotation& rot, vector<wxPoint>& out) {
|
||||||
assert(p0.segmentAfter == p1.segmentBefore);
|
assert(p0.segment_after == p1.segment_before);
|
||||||
// always the start
|
// always the start
|
||||||
out.push_back(rot.tr(p0.pos));
|
out.push_back(rot.tr(p0.pos));
|
||||||
if (p0.segmentAfter == SEGMENT_CURVE) {
|
if (p0.segment_after == SEGMENT_CURVE) {
|
||||||
// need more points?
|
// need more points?
|
||||||
BezierCurve curve(p0,p1);
|
BezierCurve curve(p0,p1);
|
||||||
curveSubdivide(curve, p0.pos, p1.pos, 0, 1, rot, out, 5);
|
curve_subdivide(curve, p0.pos, p1.pos, 0, 1, rot, out, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Bounds
|
// ----------------------------------------------------------------------------- : Bounds
|
||||||
|
|
||||||
void segmentBounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max) {
|
void segment_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max) {
|
||||||
assert(p1.segmentAfter == p2.segmentBefore);
|
assert(p1.segment_after == p2.segment_before);
|
||||||
if (p1.segmentAfter == SEGMENT_LINE) {
|
if (p1.segment_after == SEGMENT_LINE) {
|
||||||
lineBounds (p1.pos, p2.pos, min, max);
|
line_bounds (p1.pos, p2.pos, min, max);
|
||||||
} else {
|
} else {
|
||||||
bezierBounds(p1, p2, min, max);
|
bezier_bounds(p1, p2, min, max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bezierBounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max) {
|
void bezier_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max) {
|
||||||
assert(p1.segmentAfter == SEGMENT_CURVE);
|
assert(p1.segment_after == SEGMENT_CURVE);
|
||||||
// First of all, the corners should be in the bounding box
|
// First of all, the corners should be in the bounding box
|
||||||
pointBounds(p1.pos, min, max);
|
point_bounds(p1.pos, min, max);
|
||||||
pointBounds(p2.pos, min, max);
|
point_bounds(p2.pos, min, max);
|
||||||
// Solve the derivative of the bezier curve to find its extremes
|
// Solve the derivative of the bezier curve to find its extremes
|
||||||
// It's only a quadtratic equation :)
|
// It's only a quadtratic equation :)
|
||||||
BezierCurve curve(p1,p2);
|
BezierCurve curve(p1,p2);
|
||||||
double roots[4];
|
double roots[4];
|
||||||
UInt count;
|
UInt count;
|
||||||
count = solveQuadratic(3*curve.a.x, 2*curve.b.x, curve.c.x, roots);
|
count = solve_quadratic(3*curve.a.x, 2*curve.b.x, curve.c.x, roots);
|
||||||
count += solveQuadratic(3*curve.a.y, 2*curve.b.y, curve.c.y, roots + count);
|
count += solve_quadratic(3*curve.a.y, 2*curve.b.y, curve.c.y, roots + count);
|
||||||
// now check them for min/max
|
// now check them for min/max
|
||||||
for (UInt i = 0 ; i < count ; ++i) {
|
for (UInt i = 0 ; i < count ; ++i) {
|
||||||
double t = roots[i];
|
double t = roots[i];
|
||||||
if (t >=0 && t <= 1) {
|
if (t >=0 && t <= 1) {
|
||||||
pointBounds(curve.pointAt(t), min, max);
|
point_bounds(curve.pointAt(t), min, max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lineBounds(const Vector2D& p1, const Vector2D& p2, Vector2D& min, Vector2D& max) {
|
void line_bounds(const Vector2D& p1, const Vector2D& p2, Vector2D& min, Vector2D& max) {
|
||||||
pointBounds(p1, min, max);
|
point_bounds(p1, min, max);
|
||||||
pointBounds(p2, min, max);
|
point_bounds(p2, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pointBounds(const Vector2D& p, Vector2D& min, Vector2D& max) {
|
void point_bounds(const Vector2D& p, Vector2D& min, Vector2D& max) {
|
||||||
min = piecewise_min(min, p);
|
min = piecewise_min(min, p);
|
||||||
max = piecewise_max(max, p);
|
max = piecewise_max(max, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is a point inside the bounds <min...max>?
|
// Is a point inside the bounds <min...max>?
|
||||||
bool pointInBounds(const Vector2D& p, const Vector2D& min, const Vector2D& max) {
|
bool point_in_bounds(const Vector2D& p, const Vector2D& min, const Vector2D& max) {
|
||||||
return p.x >= min.x && p.y >= min.y &&
|
return p.x >= min.x && p.y >= min.y &&
|
||||||
p.x <= max.x && p.y <= max.y;
|
p.x <= max.x && p.y <= max.y;
|
||||||
}
|
}
|
||||||
@@ -142,9 +142,9 @@ bool pointInBounds(const Vector2D& p, const Vector2D& min, const Vector2D& max)
|
|||||||
// ----------------------------------------------------------------------------- : Point tests
|
// ----------------------------------------------------------------------------- : Point tests
|
||||||
|
|
||||||
// As a point inside a symbol part?
|
// As a point inside a symbol part?
|
||||||
bool pointInPart(const Vector2D& pos, const SymbolPart& part) {
|
bool point_in_part(const Vector2D& pos, const SymbolPart& part) {
|
||||||
// Step 1. compare bounding box of the part
|
// Step 1. compare bounding box of the part
|
||||||
if (!pointInBounds(pos, part.minPos, part.maxPos)) return false;
|
if (!point_in_bounds(pos, part.min_pos, part.max_pos)) return false;
|
||||||
|
|
||||||
// Step 2. trace ray outward, count intersections
|
// Step 2. trace ray outward, count intersections
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -152,10 +152,10 @@ bool pointInPart(const Vector2D& pos, const SymbolPart& part) {
|
|||||||
for(size_t i = 0 ; i < size ; ++i) {
|
for(size_t i = 0 ; i < size ; ++i) {
|
||||||
ControlPointP p1 = part.getPoint((int) i);
|
ControlPointP p1 = part.getPoint((int) i);
|
||||||
ControlPointP p2 = part.getPoint((int) i + 1);
|
ControlPointP p2 = part.getPoint((int) i + 1);
|
||||||
if (p1->segmentAfter == SEGMENT_LINE) {
|
if (p1->segment_after == SEGMENT_LINE) {
|
||||||
count += intersectLineRay (p1->pos, p2->pos, pos);
|
count += intersect_line_ray (p1->pos, p2->pos, pos);
|
||||||
} else {
|
} else {
|
||||||
count += intersectBezierRay(*p1, *p2, pos);
|
count += intersect_bezier_ray(*p1, *p2, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,23 +165,23 @@ bool pointInPart(const Vector2D& pos, const SymbolPart& part) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Finding points
|
// ----------------------------------------------------------------------------- : Finding points
|
||||||
|
|
||||||
bool posOnSegment(const Vector2D& pos, double range, const ControlPoint& p1, const ControlPoint& p2, Vector2D& pOut, double& tOut) {
|
bool pos_on_segment(const Vector2D& pos, double range, const ControlPoint& p1, const ControlPoint& p2, Vector2D& pOut, double& tOut) {
|
||||||
if (p1.segmentAfter == SEGMENT_CURVE) {
|
if (p1.segment_after == SEGMENT_CURVE) {
|
||||||
return posOnBezier(pos, range, p1, p2, pOut, tOut);
|
return pos_on_bezier(pos, range, p1, p2, pOut, tOut);
|
||||||
} else {
|
} else {
|
||||||
return posOnLine (pos, range, p1.pos, p2.pos, pOut, tOut);
|
return pos_on_line (pos, range, p1.pos, p2.pos, pOut, tOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool posOnBezier(const Vector2D& pos, double range, const ControlPoint& p1, const ControlPoint& p2, Vector2D& pOut, double& tOut) {
|
bool pos_on_bezier(const Vector2D& pos, double range, const ControlPoint& p1, const ControlPoint& p2, Vector2D& pOut, double& tOut) {
|
||||||
assert(p1.segmentAfter == SEGMENT_CURVE);
|
assert(p1.segment_after == SEGMENT_CURVE);
|
||||||
// Find intersections with the horizontal and vertical lines through p0
|
// Find intersections with the horizontal and vertical lines through p0
|
||||||
// theoretically we would need to check in all directions, but this covers enough
|
// theoretically we would need to check in all directions, but this covers enough
|
||||||
BezierCurve curve(p1, p2);
|
BezierCurve curve(p1, p2);
|
||||||
double roots[6];
|
double roots[6];
|
||||||
UInt count;
|
UInt count;
|
||||||
count = solveCubic(curve.a.y, curve.b.y, curve.c.y, curve.d.y - pos.y, roots);
|
count = solve_cubic(curve.a.y, curve.b.y, curve.c.y, curve.d.y - pos.y, roots);
|
||||||
count += solveCubic(curve.a.x, curve.b.x, curve.c.x, curve.d.x - pos.x, roots + count); // append intersections
|
count += solve_cubic(curve.a.x, curve.b.x, curve.c.x, curve.d.x - pos.x, roots + count); // append intersections
|
||||||
// take the best intersection point
|
// take the best intersection point
|
||||||
double bestDistSqr = std::numeric_limits<double>::max(); //infinity
|
double bestDistSqr = std::numeric_limits<double>::max(); //infinity
|
||||||
for(UInt i = 0 ; i < count ; ++i) {
|
for(UInt i = 0 ; i < count ; ++i) {
|
||||||
@@ -199,7 +199,7 @@ bool posOnBezier(const Vector2D& pos, double range, const ControlPoint& p1, cons
|
|||||||
return bestDistSqr <= range * range;
|
return bestDistSqr <= range * range;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool posOnLine(const Vector2D& pos, double range, const Vector2D& p1, const Vector2D& p2, Vector2D& pOut, double& t) {
|
bool pos_on_line(const Vector2D& pos, double range, const Vector2D& p1, const Vector2D& p2, Vector2D& pOut, double& t) {
|
||||||
Vector2D p21 = p2 - p1;
|
Vector2D p21 = p2 - p1;
|
||||||
double p21len = p21.lengthSqr();
|
double p21len = p21.lengthSqr();
|
||||||
if (p21len < 0.00001) return false; // line is too short
|
if (p21len < 0.00001) return false; // line is too short
|
||||||
@@ -212,13 +212,13 @@ bool posOnLine(const Vector2D& pos, double range, const Vector2D& p1, const Vect
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Intersection
|
// ----------------------------------------------------------------------------- : Intersection
|
||||||
|
|
||||||
UInt intersectBezierRay(const ControlPoint& p1, const ControlPoint& p2, const Vector2D& pos) {
|
UInt intersect_bezier_ray(const ControlPoint& p1, const ControlPoint& p2, const Vector2D& pos) {
|
||||||
// Looking only at the y coordinate
|
// Looking only at the y coordinate
|
||||||
// we can use the cubic formula to find roots, points where the horizontal line
|
// we can use the cubic formula to find roots, points where the horizontal line
|
||||||
// through pos intersects the (extended) curve
|
// through pos intersects the (extended) curve
|
||||||
BezierCurve curve(p1,p2);
|
BezierCurve curve(p1,p2);
|
||||||
double roots[3];
|
double roots[3];
|
||||||
UInt count = solveCubic(curve.a.y, curve.b.y, curve.c.y, curve.d.y - pos.y, roots);
|
UInt count = solve_cubic(curve.a.y, curve.b.y, curve.c.y, curve.d.y - pos.y, roots);
|
||||||
// now check if the solutions are left of pos.x
|
// now check if the solutions are left of pos.x
|
||||||
UInt solsInRange = 0;
|
UInt solsInRange = 0;
|
||||||
for(UInt i = 0 ; i < count ; ++i) {
|
for(UInt i = 0 ; i < count ; ++i) {
|
||||||
@@ -230,7 +230,7 @@ UInt intersectBezierRay(const ControlPoint& p1, const ControlPoint& p2, const Ve
|
|||||||
return solsInRange;
|
return solsInRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intersectLineRay(const Vector2D& p1, const Vector2D& p2, const Vector2D& pos) {
|
bool intersect_line_ray(const Vector2D& p1, const Vector2D& p2, const Vector2D& pos) {
|
||||||
// Vector2D intersection = p1 + t * (p2 - p1)
|
// Vector2D intersection = p1 + t * (p2 - p1)
|
||||||
// intersection.y == pos.y
|
// intersection.y == pos.y
|
||||||
// == p1.y + t * (p2.y - p1.y)
|
// == p1.y + t * (p2.y - p1.y)
|
||||||
@@ -245,7 +245,7 @@ bool intersectLineRay(const Vector2D& p1, const Vector2D& p2, const Vector2D& po
|
|||||||
} else {
|
} else {
|
||||||
double dx = p2.x - p1.x;
|
double dx = p2.x - p1.x;
|
||||||
double t = (pos.y - p1.y) / dy;
|
double t = (pos.y - p1.y) / dy;
|
||||||
if (t < 0.0 || t >= 1.0) return false;
|
if (t < 0.0 || t >= 1.0) return false;
|
||||||
double intersectX = p1.x + t * dx;
|
double intersectX = p1.x + t * dx;
|
||||||
return intersectX <= pos.x; // intersection is left of pos
|
return intersectX <= pos.x; // intersection is left of pos
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -67,7 +67,7 @@ void deCasteljau(const Vector2D& a1, Vector2D& a21, Vector2D& a34, const Vector2
|
|||||||
/** Adds the resulting corner points of those lines to out, the last point is not added.
|
/** Adds the resulting corner points of those lines to out, the last point is not added.
|
||||||
* All points are converted to display coordinates using rot.tr
|
* All points are converted to display coordinates using rot.tr
|
||||||
*/
|
*/
|
||||||
void segmentSubdivide(const ControlPoint& p0, const ControlPoint& p1, const Rotation& rot, vector<wxPoint>& out);
|
void segment_subdivide(const ControlPoint& p0, const ControlPoint& p1, const Rotation& rot, vector<wxPoint>& out);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Bounds
|
// ----------------------------------------------------------------------------- : Bounds
|
||||||
|
|
||||||
@@ -76,30 +76,30 @@ void segmentSubdivide(const ControlPoint& p0, const ControlPoint& p1, const Rota
|
|||||||
* min is only changed if the minimum is smaller then the current value in min,
|
* min is only changed if the minimum is smaller then the current value in min,
|
||||||
* max only if the maximum is larger.
|
* max only if the maximum is larger.
|
||||||
*/
|
*/
|
||||||
void segmentBounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max);
|
void segment_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max);
|
||||||
|
|
||||||
/// Find a bounding box that fits a curve between p1 and p2, stores the results in min and max.
|
/// Find a bounding box that fits a curve between p1 and p2, stores the results in min and max.
|
||||||
/** min is only changed if the minimum is smaller then the current value in min,
|
/** min is only changed if the minimum is smaller then the current value in min,
|
||||||
* max only if the maximum is larger
|
* max only if the maximum is larger
|
||||||
*/
|
*/
|
||||||
void bezierBounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max);
|
void bezier_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max);
|
||||||
|
|
||||||
/// Find a bounding box that fits around p1 and p2, stores the result in min and max
|
/// Find a bounding box that fits around p1 and p2, stores the result in min and max
|
||||||
/** min is only changed if the minimum is smaller then the current value in min,
|
/** min is only changed if the minimum is smaller then the current value in min,
|
||||||
* max only if the maximum is larger
|
* max only if the maximum is larger
|
||||||
*/
|
*/
|
||||||
void lineBounds(const Vector2D& p1, const Vector2D& p2, Vector2D& min, Vector2D& max);
|
void line_bounds(const Vector2D& p1, const Vector2D& p2, Vector2D& min, Vector2D& max);
|
||||||
|
|
||||||
/// Find a bounding 'box' that fits around a single point
|
/// Find a bounding 'box' that fits around a single point
|
||||||
/** min is only changed if the minimum is smaller then the current value in min,
|
/** min is only changed if the minimum is smaller then the current value in min,
|
||||||
* max only if the maximum is larger
|
* max only if the maximum is larger
|
||||||
*/
|
*/
|
||||||
void pointBounds(const Vector2D& p, Vector2D& min, Vector2D& max);
|
void point_bounds(const Vector2D& p, Vector2D& min, Vector2D& max);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Point tests
|
// ----------------------------------------------------------------------------- : Point tests
|
||||||
|
|
||||||
/// Is a point inside the given symbol part?
|
/// Is a point inside the given symbol part?
|
||||||
bool pointInPart(const Vector2D& p, const SymbolPart& part);
|
bool point_in_part(const Vector2D& p, const SymbolPart& part);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Finding points
|
// ----------------------------------------------------------------------------- : Finding points
|
||||||
|
|
||||||
@@ -107,24 +107,24 @@ bool pointInPart(const Vector2D& p, const SymbolPart& part);
|
|||||||
/// the line between p1 and p2 can also be a bezier curve
|
/// the line between p1 and p2 can also be a bezier curve
|
||||||
/** Returns the time on the segment in tOut, and the point on the segment in pOut
|
/** Returns the time on the segment in tOut, and the point on the segment in pOut
|
||||||
*/
|
*/
|
||||||
bool posOnSegment(const Vector2D& pos, double range, const ControlPoint& p1, const ControlPoint& p2, Vector2D& pOut, double& tOut);
|
bool pos_on_segment(const Vector2D& pos, double range, const ControlPoint& p1, const ControlPoint& p2, Vector2D& pOut, double& tOut);
|
||||||
|
|
||||||
/// Finds the position of p0 on the line between p1 and p2, returns true if the point is on (or near)
|
/// Finds the position of p0 on the line between p1 and p2, returns true if the point is on (or near)
|
||||||
/// the bezier curve between p1 and p2
|
/// the bezier curve between p1 and p2
|
||||||
bool posOnBezier (const Vector2D& pos, double range, const ControlPoint& p1, const ControlPoint& p2, Vector2D& pOut, double& tOut);
|
bool pos_on_bezier (const Vector2D& pos, double range, const ControlPoint& p1, const ControlPoint& p2, Vector2D& pOut, double& tOut);
|
||||||
|
|
||||||
/// Finds the position of p0 on the line p1-p2, returns true if the point is withing range of the line
|
/// Finds the position of p0 on the line p1-p2, returns true if the point is withing range of the line
|
||||||
/// if that is the case then (x,y) = p1 + (p2-p1) * out
|
/// if that is the case then (x,y) = p1 + (p2-p1) * out
|
||||||
bool posOnLine (const Vector2D& pos, double range, const Vector2D& p1, const Vector2D& p2, Vector2D& pOut, double& tOut);
|
bool pos_on_line (const Vector2D& pos, double range, const Vector2D& p1, const Vector2D& p2, Vector2D& pOut, double& tOut);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Intersection
|
// ----------------------------------------------------------------------------- : Intersection
|
||||||
|
|
||||||
/// Counts the number of intersections between the ray/halfline from (-inf, pos.y) to pos
|
/// Counts the number of intersections between the ray/halfline from (-inf, pos.y) to pos
|
||||||
/// and the bezier curve between p1 and p2.
|
/// and the bezier curve between p1 and p2.
|
||||||
UInt intersectBezierRay(const ControlPoint& p1, const ControlPoint& p2, const Vector2D& pos);
|
UInt intersect_bezier_ray(const ControlPoint& p1, const ControlPoint& p2, const Vector2D& pos);
|
||||||
|
|
||||||
// Does the line between p1 and p2 intersect the ray (half line) from (-inf, pos.y) to pos?
|
// Does the line between p1 and p2 intersect the ray (half line) from (-inf, pos.y) to pos?
|
||||||
bool intersectLineRay(const Vector2D& p1, const Vector2D& p2, const Vector2D& pos);
|
bool intersect_line_ray(const Vector2D& p1, const Vector2D& p2, const Vector2D& pos);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ COMBINE_FUN(COMBINE_SHADOW, (b * a * a) / (255 * 255) )
|
|||||||
/// Combine image b onto image a using some combining mode.
|
/// Combine image b onto image a using some combining mode.
|
||||||
/// The results are stored in the image A.
|
/// The results are stored in the image A.
|
||||||
template <ImageCombine combine>
|
template <ImageCombine combine>
|
||||||
void combineImageDo(Image& a, Image b) {
|
void combine_image_do(Image& a, Image b) {
|
||||||
UInt size = a.GetWidth() * a.GetHeight() * 3;
|
UInt size = a.GetWidth() * a.GetHeight() * 3;
|
||||||
Byte *dataA = a.GetData(), *dataB = b.GetData();
|
Byte *dataA = a.GetData(), *dataB = b.GetData();
|
||||||
// for each pixel: apply function
|
// for each pixel: apply function
|
||||||
@@ -97,7 +97,7 @@ void combineImageDo(Image& a, Image b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void combineImage(Image& a, const Image& b, ImageCombine combine) {
|
void combine_image(Image& a, const Image& b, ImageCombine combine) {
|
||||||
// Images must have same size
|
// Images must have same size
|
||||||
assert(a.GetWidth() == b.GetWidth());
|
assert(a.GetWidth() == b.GetWidth());
|
||||||
assert(a.GetHeight() == b.GetHeight());
|
assert(a.GetHeight() == b.GetHeight());
|
||||||
@@ -108,7 +108,7 @@ void combineImage(Image& a, const Image& b, ImageCombine combine) {
|
|||||||
}
|
}
|
||||||
// Combine image data, by dispatching to combineImageDo
|
// Combine image data, by dispatching to combineImageDo
|
||||||
switch(combine) {
|
switch(combine) {
|
||||||
#define DISPATCH(comb) case comb: combineImageDo<comb>(a,b); return
|
#define DISPATCH(comb) case comb: combine_image_do<comb>(a,b); return
|
||||||
DISPATCH(COMBINE_NORMAL);
|
DISPATCH(COMBINE_NORMAL);
|
||||||
DISPATCH(COMBINE_ADD);
|
DISPATCH(COMBINE_ADD);
|
||||||
DISPATCH(COMBINE_SUBTRACT);
|
DISPATCH(COMBINE_SUBTRACT);
|
||||||
@@ -135,5 +135,6 @@ void combineImage(Image& a, const Image& b, ImageCombine combine) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawCombineImage(DC& dc, UInt x, UInt y, const Image& img, ImageCombine combine) {
|
void draw_combine_image(DC& dc, UInt x, UInt y, const Image& img, ImageCombine combine) {
|
||||||
|
// todo
|
||||||
}
|
}
|
||||||
+4
-4
@@ -41,7 +41,7 @@ void resample_and_clip(const Image& imgIn, Image& imgOut, wxRect rect);
|
|||||||
|
|
||||||
/// Rotates an image counter clockwise
|
/// Rotates an image counter clockwise
|
||||||
/// angle must be a multiple of 90, i.e. {0,90,180,270}
|
/// angle must be a multiple of 90, i.e. {0,90,180,270}
|
||||||
Image rotateImageBy(const Image& image, int angle);
|
Image rotate_image(const Image& image, int angle);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Blending
|
// ----------------------------------------------------------------------------- : Blending
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ void vblend(Image& img1, const Image& img2);
|
|||||||
* mask is used as a mask, white pixels are taken from img1, black pixels from img2
|
* mask is used as a mask, white pixels are taken from img1, black pixels from img2
|
||||||
* color channels are blended separatly
|
* color channels are blended separatly
|
||||||
*/
|
*/
|
||||||
void maskBlend(Image& img1, const Image& img2, const Image& mask);
|
void mask_blend(Image& img1, const Image& img2, const Image& mask);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Combining
|
// ----------------------------------------------------------------------------- : Combining
|
||||||
|
|
||||||
@@ -94,10 +94,10 @@ enum ImageCombine
|
|||||||
/// The results are stored in the image A.
|
/// The results are stored in the image A.
|
||||||
/// This image gets the alpha channel from B, it should then be
|
/// This image gets the alpha channel from B, it should then be
|
||||||
/// drawn onto the area where A originated.
|
/// drawn onto the area where A originated.
|
||||||
void combineImage(Image& a, const Image& b, ImageCombine combine);
|
void combine_image(Image& a, const Image& b, ImageCombine combine);
|
||||||
|
|
||||||
/// Draw an image to a DC using a combining function
|
/// Draw an image to a DC using a combining function
|
||||||
void drawCombineImage(DC& dc, UInt x, UInt y, const Image& img, ImageCombine combine);
|
void draw_combine_image(DC& dc, UInt x, UInt y, const Image& img, ImageCombine combine);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Utility
|
// ----------------------------------------------------------------------------- : Utility
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Solving
|
// ----------------------------------------------------------------------------- : Solving
|
||||||
|
|
||||||
UInt solveLinear(double a, double b, double* root) {
|
UInt solve_linear(double a, double b, double* root) {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
if (b == 0) {
|
if (b == 0) {
|
||||||
root[0] = 0;
|
root[0] = 0;
|
||||||
@@ -25,9 +25,9 @@ UInt solveLinear(double a, double b, double* root) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt solveQuadratic(double a, double b, double c, double* roots) {
|
UInt solve_quadratic(double a, double b, double c, double* roots) {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
return solveLinear(b, c, roots);
|
return solve_linear(b, c, roots);
|
||||||
} else {
|
} else {
|
||||||
double d = b*b - 4*a*c;
|
double d = b*b - 4*a*c;
|
||||||
if (d < 0) return 0;
|
if (d < 0) return 0;
|
||||||
@@ -37,11 +37,11 @@ UInt solveQuadratic(double a, double b, double c, double* roots) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt solveCubic(double a, double b, double c, double d, double* roots) {
|
UInt solve_cubic(double a, double b, double c, double d, double* roots) {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
return solveQuadratic(b, c, d, roots);
|
return solve_quadratic(b, c, d, roots);
|
||||||
} else {
|
} else {
|
||||||
return solveCubic(b/a, c/a, d/a, roots);
|
return solve_cubic(b/a, c/a, d/a, roots);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ UInt solveCubic(double a, double b, double c, double d, double* roots) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline T curt(T x) { return pow(x, 1.0 / 3); }
|
inline T curt(T x) { return pow(x, 1.0 / 3); }
|
||||||
|
|
||||||
UInt solveCubic(double a, double b, double c, double* roots) {
|
UInt solve_cubic(double a, double b, double c, double* roots) {
|
||||||
double p = b - a*a / 3;
|
double p = b - a*a / 3;
|
||||||
double q = c + (2 * a*a*a - 9 * a * b) / 27;
|
double q = c + (2 * a*a*a - 9 * a * b) / 27;
|
||||||
if (p == 0 && q == 0) {
|
if (p == 0 && q == 0) {
|
||||||
|
|||||||
@@ -21,23 +21,23 @@
|
|||||||
/// Solve a linear equation a x + b = 0
|
/// Solve a linear equation a x + b = 0
|
||||||
/** Returns the number of real roots, and the roots themselfs in the output parameter.
|
/** Returns the number of real roots, and the roots themselfs in the output parameter.
|
||||||
*/
|
*/
|
||||||
UInt solveLinear(double a, double b, double* root);
|
UInt solve_linear(double a, double b, double* root);
|
||||||
|
|
||||||
/// Solve a quadratic equation a x^2 + b x + c == 0
|
/// Solve a quadratic equation a x^2 + b x + c == 0
|
||||||
/** Returns the number of real roots, and the roots themselfs in the output parameter.
|
/** Returns the number of real roots, and the roots themselfs in the output parameter.
|
||||||
*/
|
*/
|
||||||
UInt solveQuadratic(double a, double b, double c, double* roots);
|
UInt solve_quadratic(double a, double b, double c, double* roots);
|
||||||
|
|
||||||
// Solve a cubic equation a x^3 + b x^2 + c x + d == 0
|
// Solve a cubic equation a x^3 + b x^2 + c x + d == 0
|
||||||
/** Returns the number of real roots, and the roots themselfs in the output parameter.
|
/** Returns the number of real roots, and the roots themselfs in the output parameter.
|
||||||
*/
|
*/
|
||||||
UInt solveCubic(double a, double b, double c, double d, double* roots);
|
UInt solve_cubic(double a, double b, double c, double d, double* roots);
|
||||||
|
|
||||||
// Solve a cubic equation x^3 + a x^2 + b x + c == 0
|
// Solve a cubic equation x^3 + a x^2 + b x + c == 0
|
||||||
/** Returns the number of real roots, and the roots themselfs in the output parameter.
|
/** Returns the number of real roots, and the roots themselfs in the output parameter.
|
||||||
* Based on http://en.wikipedia.org/wiki/Cubic_equation
|
* Based on http://en.wikipedia.org/wiki/Cubic_equation
|
||||||
*/
|
*/
|
||||||
UInt solveCubic(double a, double b, double c, double* roots);
|
UInt solve_cubic(double a, double b, double c, double* roots);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// Rotates an image
|
// Rotates an image
|
||||||
// 'Rotater' is a function object that knows how to 'rotate' a pixel coordinate
|
// 'Rotater' is a function object that knows how to 'rotate' a pixel coordinate
|
||||||
template <class Rotater>
|
template <class Rotater>
|
||||||
Image rotateImageImpl(Image img) {
|
Image rotate_image_impl(Image img) {
|
||||||
UInt width = img.GetWidth(), height = img.GetHeight();
|
UInt width = img.GetWidth(), height = img.GetHeight();
|
||||||
// initialize the return image
|
// initialize the return image
|
||||||
Image ret;
|
Image ret;
|
||||||
@@ -83,13 +83,13 @@ struct Rotate270 {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Interface
|
// ----------------------------------------------------------------------------- : Interface
|
||||||
|
|
||||||
Image rotateImageBy(const Image& image, int angle) {
|
Image rotate_image(const Image& image, int angle) {
|
||||||
if (angle == 90) {
|
if (angle == 90) {
|
||||||
return rotateImageImpl<Rotate90>(image);
|
return rotate_image_impl<Rotate90>(image);
|
||||||
} else if (angle == 180){
|
} else if (angle == 180){
|
||||||
return rotateImageImpl<Rotate180>(image);
|
return rotate_image_impl<Rotate180>(image);
|
||||||
} else if (angle == 270){
|
} else if (angle == 270){
|
||||||
return rotateImageImpl<Rotate270>(image);
|
return rotate_image_impl<Rotate270>(image);
|
||||||
} else{
|
} else{
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-40
@@ -26,8 +26,8 @@ DECLARE_TYPEOF_COLLECTION(SetWindowPanel*);
|
|||||||
|
|
||||||
SetWindow::SetWindow(Window* parent, const SetP& set)
|
SetWindow::SetWindow(Window* parent, const SetP& set)
|
||||||
: wxFrame(parent, wxID_ANY, _("Magic Set Editor"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
|
: wxFrame(parent, wxID_ANY, _("Magic Set Editor"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
|
||||||
, currentPanel(nullptr)
|
, current_panel(nullptr)
|
||||||
, findDialog(nullptr)
|
, find_dialog(nullptr)
|
||||||
{
|
{
|
||||||
SetIcon(wxIcon(_("ICON_APP")));
|
SetIcon(wxIcon(_("ICON_APP")));
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ SetWindow::SetWindow(Window* parent, const SetP& set)
|
|||||||
menuExport->Append(ID_FILE_EXPORT_IMAGE, _("Card &Image..."), _("Export the selected card to an image file"));
|
menuExport->Append(ID_FILE_EXPORT_IMAGE, _("Card &Image..."), _("Export the selected card to an image file"));
|
||||||
menuExport->Append(ID_FILE_EXPORT_IMAGES, _("All Card I&mages..."), _("Export images for all cards"));
|
menuExport->Append(ID_FILE_EXPORT_IMAGES, _("All Card I&mages..."), _("Export images for all cards"));
|
||||||
menuExport->Append(ID_FILE_EXPORT_APPR, _("&Apprentice..."), _("Export the set so it can be played with in Apprentice"));
|
menuExport->Append(ID_FILE_EXPORT_APPR, _("&Apprentice..."), _("Export the set so it can be played with in Apprentice"));
|
||||||
menuExport->Append(ID_FILE_EXPORT_MWS, _("Magic &Workstation..."), _("Export the set so it can be played with in Magic Workstation"));
|
menuExport->Append(ID_FILE_EXPORT_MWS, _("Magic &Workstation..."), _("Export the set so it can be played with in Magic Workstation"));
|
||||||
menuFile->Append(ID_FILE_EXPORT, _("&Export"), _("Export the set..."), menuExport);
|
menuFile->Append(ID_FILE_EXPORT, _("&Export"), _("Export the set..."), menuExport);
|
||||||
menuFile->AppendSeparator();
|
menuFile->AppendSeparator();
|
||||||
menuFile->Append(ID_FILE_INSPECT, _("Inspect Internal Data..."), _("Shows a the data in the set using a tree structure"));
|
menuFile->Append(ID_FILE_INSPECT, _("Inspect Internal Data..."), _("Shows a the data in the set using a tree structure"));
|
||||||
@@ -126,8 +126,8 @@ SetWindow::SetWindow(Window* parent, const SetP& set)
|
|||||||
|
|
||||||
// loose ends
|
// loose ends
|
||||||
tabBar->Realize();
|
tabBar->Realize();
|
||||||
SetSize(settings.setWindowWidth, settings.setWindowHeight);
|
SetSize(settings.set_window_width, settings.set_window_height);
|
||||||
if (settings.setWindowMaximized) {
|
if (settings.set_window_maximized) {
|
||||||
Maximize();
|
Maximize();
|
||||||
}
|
}
|
||||||
// SetWindows.push_back(&this); // register this window
|
// SetWindows.push_back(&this); // register this window
|
||||||
@@ -144,15 +144,15 @@ SetWindow::SetWindow(Window* parent, const SetP& set)
|
|||||||
SetWindow::~SetWindow() {
|
SetWindow::~SetWindow() {
|
||||||
// store window size in settings
|
// store window size in settings
|
||||||
wxSize s = GetSize();
|
wxSize s = GetSize();
|
||||||
settings.setWindowMaximized = IsMaximized();
|
settings.set_window_maximized = IsMaximized();
|
||||||
if (!IsMaximized()) {
|
if (!IsMaximized()) {
|
||||||
settings.setWindowWidth = s.GetWidth();
|
settings.set_window_width = s.GetWidth();
|
||||||
settings.setWindowHeight = s.GetHeight();
|
settings.set_window_height = s.GetHeight();
|
||||||
}
|
}
|
||||||
// destroy ui of selected panel
|
// destroy ui of selected panel
|
||||||
currentPanel->destroyUI(GetToolBar(), GetMenuBar());
|
current_panel->destroyUI(GetToolBar(), GetMenuBar());
|
||||||
// cleanup (see find stuff)
|
// cleanup (see find stuff)
|
||||||
delete findDialog;
|
delete find_dialog;
|
||||||
// remove from list of main windows
|
// remove from list of main windows
|
||||||
// SetWindows.erase(remove(SetWindows.begin(), SetWindows.end(), &this));
|
// SetWindows.erase(remove(SetWindows.begin(), SetWindows.end(), &this));
|
||||||
// stop updating
|
// stop updating
|
||||||
@@ -177,11 +177,11 @@ void SetWindow::addPanel(wxMenu* windowMenu, wxToolBar* tabBar, SetWindowPanel*
|
|||||||
|
|
||||||
void SetWindow::selectPanel(int id) {
|
void SetWindow::selectPanel(int id) {
|
||||||
SetWindowPanel* toSelect = panels.at(id - ID_WINDOW_MIN);
|
SetWindowPanel* toSelect = panels.at(id - ID_WINDOW_MIN);
|
||||||
if (currentPanel != toSelect) {
|
if (current_panel != toSelect) {
|
||||||
// destroy & create menus
|
// destroy & create menus
|
||||||
if (currentPanel) currentPanel->destroyUI(GetToolBar(), GetMenuBar());
|
if (current_panel) current_panel->destroyUI(GetToolBar(), GetMenuBar());
|
||||||
currentPanel = toSelect;
|
current_panel = toSelect;
|
||||||
currentPanel->initUI(GetToolBar(), GetMenuBar());
|
current_panel->initUI(GetToolBar(), GetMenuBar());
|
||||||
}
|
}
|
||||||
// show/hide panels and select tabs
|
// show/hide panels and select tabs
|
||||||
wxSizer* sizer = GetSizer();
|
wxSizer* sizer = GetSizer();
|
||||||
@@ -189,9 +189,9 @@ void SetWindow::selectPanel(int id) {
|
|||||||
wxMenuBar* menuBar = GetMenuBar();
|
wxMenuBar* menuBar = GetMenuBar();
|
||||||
int wid = ID_WINDOW_MIN;
|
int wid = ID_WINDOW_MIN;
|
||||||
FOR_EACH(p, panels) {
|
FOR_EACH(p, panels) {
|
||||||
sizer->Show (p, p == currentPanel);
|
sizer->Show (p, p == current_panel);
|
||||||
tabBar->ToggleTool(wid, p == currentPanel);
|
tabBar->ToggleTool(wid, p == current_panel);
|
||||||
menuBar->Check (wid, p == currentPanel);
|
menuBar->Check (wid, p == current_panel);
|
||||||
++wid;
|
++wid;
|
||||||
}
|
}
|
||||||
// fix sizer stuff
|
// fix sizer stuff
|
||||||
@@ -322,7 +322,7 @@ void SetWindow::onUpdateUI(wxUpdateUIEvent& ev) {
|
|||||||
switch (ev.GetId()) {
|
switch (ev.GetId()) {
|
||||||
// file menu
|
// file menu
|
||||||
case ID_FILE_SAVE_AS: ev.Enable(!set->actions.atSavePoint() || set->needSaveAs()); break;
|
case ID_FILE_SAVE_AS: ev.Enable(!set->actions.atSavePoint() || set->needSaveAs()); break;
|
||||||
case ID_FILE_EXPORT_IMAGE: ev.Enable(!!currentPanel->selectedCard()); break;
|
case ID_FILE_EXPORT_IMAGE: ev.Enable(!!current_panel->selectedCard()); break;
|
||||||
case ID_FILE_EXPORT_APPR: ev.Enable(set->game->isMagic()); break;
|
case ID_FILE_EXPORT_APPR: ev.Enable(set->game->isMagic()); break;
|
||||||
case ID_FILE_EXPORT_MWS: ev.Enable(set->game->isMagic()); break;
|
case ID_FILE_EXPORT_MWS: ev.Enable(set->game->isMagic()); break;
|
||||||
/*case ID_FILE_INSPECT: {
|
/*case ID_FILE_INSPECT: {
|
||||||
@@ -346,15 +346,15 @@ void SetWindow::onUpdateUI(wxUpdateUIEvent& ev) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// copy & paste & find
|
// copy & paste & find
|
||||||
case ID_EDIT_CUT : ev.Enable(currentPanel->canCut()); break;
|
case ID_EDIT_CUT : ev.Enable(current_panel->canCut()); break;
|
||||||
case ID_EDIT_COPY : ev.Enable(currentPanel->canCopy()); break;
|
case ID_EDIT_COPY : ev.Enable(current_panel->canCopy()); break;
|
||||||
case ID_EDIT_PASTE : ev.Enable(currentPanel->canPaste()); break;
|
case ID_EDIT_PASTE : ev.Enable(current_panel->canPaste()); break;
|
||||||
case ID_EDIT_FIND : ev.Enable(currentPanel->canFind()); break;
|
case ID_EDIT_FIND : ev.Enable(current_panel->canFind()); break;
|
||||||
case ID_EDIT_FIND_NEXT : ev.Enable(currentPanel->canFind()); break;
|
case ID_EDIT_FIND_NEXT : ev.Enable(current_panel->canFind()); break;
|
||||||
case ID_EDIT_REPLACE : ev.Enable(currentPanel->canReplace()); break;
|
case ID_EDIT_REPLACE : ev.Enable(current_panel->canReplace()); break;
|
||||||
default:
|
default:
|
||||||
// items created by the panel, and cut/copy/paste and find/replace
|
// items created by the panel, and cut/copy/paste and find/replace
|
||||||
currentPanel->onUpdateUI(ev);
|
current_panel->onUpdateUI(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +401,7 @@ void SetWindow::onFileInspect(wxCommandEvent&) {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
void SetWindow::onFileExportImage(wxCommandEvent&) {
|
void SetWindow::onFileExportImage(wxCommandEvent&) {
|
||||||
CardP card = currentPanel->selectedCard();
|
CardP card = current_panel->selectedCard();
|
||||||
if (!card) return; // no card selected
|
if (!card) return; // no card selected
|
||||||
String name = wxFileSelector(_("Save image"), _(""), card->identification(), _(""),
|
String name = wxFileSelector(_("Save image"), _(""), card->identification(), _(""),
|
||||||
_("JPEG images (*.jpg)|*.jpg|Windows bitmaps (*.bmp)|*.bmp|PNG images (*.png)|*.png|GIF images (*.gif)|*.gif|TIFF images (*.tif)|*.tif"),
|
_("JPEG images (*.jpg)|*.jpg|Windows bitmaps (*.bmp)|*.bmp|PNG images (*.png)|*.png|GIF images (*.gif)|*.gif|TIFF images (*.tif)|*.tif"),
|
||||||
@@ -465,38 +465,38 @@ void SetWindow::onEditRedo(wxCommandEvent&) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetWindow::onEditCut (wxCommandEvent&) {
|
void SetWindow::onEditCut (wxCommandEvent&) {
|
||||||
currentPanel->doCut();
|
current_panel->doCut();
|
||||||
}
|
}
|
||||||
void SetWindow::onEditCopy (wxCommandEvent&) {
|
void SetWindow::onEditCopy (wxCommandEvent&) {
|
||||||
currentPanel->doCopy();
|
current_panel->doCopy();
|
||||||
}
|
}
|
||||||
void SetWindow::onEditPaste(wxCommandEvent&) {
|
void SetWindow::onEditPaste(wxCommandEvent&) {
|
||||||
currentPanel->doPaste();
|
current_panel->doPaste();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWindow::onEditFind(wxCommandEvent&) {
|
void SetWindow::onEditFind(wxCommandEvent&) {
|
||||||
delete findDialog;
|
delete find_dialog;
|
||||||
findDialog = new wxFindReplaceDialog(this, &findData, _("Find"));
|
find_dialog = new wxFindReplaceDialog(this, &find_data, _("Find"));
|
||||||
findDialog->Show();
|
find_dialog->Show();
|
||||||
}
|
}
|
||||||
void SetWindow::onEditFindNext(wxCommandEvent&) {
|
void SetWindow::onEditFindNext(wxCommandEvent&) {
|
||||||
currentPanel->doFind(findData);
|
current_panel->doFind(find_data);
|
||||||
}
|
}
|
||||||
void SetWindow::onEditReplace(wxCommandEvent&) {
|
void SetWindow::onEditReplace(wxCommandEvent&) {
|
||||||
delete findDialog;
|
delete find_dialog;
|
||||||
findDialog = new wxFindReplaceDialog(this, &findData, _("Replace"), wxFR_REPLACEDIALOG);
|
find_dialog = new wxFindReplaceDialog(this, &find_data, _("Replace"), wxFR_REPLACEDIALOG);
|
||||||
findDialog->Show();
|
find_dialog->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// find events
|
// find events
|
||||||
void SetWindow::onFind (wxFindDialogEvent&) {
|
void SetWindow::onFind (wxFindDialogEvent&) {
|
||||||
currentPanel->doFind(findData);
|
current_panel->doFind(find_data);
|
||||||
}
|
}
|
||||||
void SetWindow::onFindNext (wxFindDialogEvent&) {
|
void SetWindow::onFindNext (wxFindDialogEvent&) {
|
||||||
currentPanel->doFind(findData);
|
current_panel->doFind(find_data);
|
||||||
}
|
}
|
||||||
void SetWindow::onReplace (wxFindDialogEvent&) {
|
void SetWindow::onReplace (wxFindDialogEvent&) {
|
||||||
currentPanel->doReplace(findData);
|
current_panel->doReplace(find_data);
|
||||||
}
|
}
|
||||||
void SetWindow::onReplaceAll(wxFindDialogEvent&) {
|
void SetWindow::onReplaceAll(wxFindDialogEvent&) {
|
||||||
// todo
|
// todo
|
||||||
@@ -541,7 +541,7 @@ void SetWindow::onHelpAbout(wxCommandEvent&) {
|
|||||||
// ----------------------------------------------------------------------------- : Window events - menu - for child panel
|
// ----------------------------------------------------------------------------- : Window events - menu - for child panel
|
||||||
|
|
||||||
void SetWindow::onChildMenu(wxCommandEvent& ev) {
|
void SetWindow::onChildMenu(wxCommandEvent& ev) {
|
||||||
currentPanel->onCommand(ev.GetId());
|
current_panel->onCommand(ev.GetId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Event table
|
// ----------------------------------------------------------------------------- : Event table
|
||||||
|
|||||||
@@ -41,14 +41,14 @@ class SetWindow : public wxFrame, public SetView {
|
|||||||
|
|
||||||
// gui items
|
// gui items
|
||||||
vector<SetWindowPanel*> panels; ///< All panels on this window
|
vector<SetWindowPanel*> panels; ///< All panels on this window
|
||||||
SetWindowPanel* currentPanel;
|
SetWindowPanel* current_panel;
|
||||||
|
|
||||||
/// Number of items in the recent sets list
|
/// Number of items in the recent sets list
|
||||||
size_t numberOfRecentSets;
|
size_t number_of_recentSets;
|
||||||
|
|
||||||
// data for find/replace
|
// data for find/replace
|
||||||
wxDialog* findDialog;
|
wxDialog* find_dialog;
|
||||||
wxFindReplaceData findData;
|
wxFindReplaceData find_data;
|
||||||
|
|
||||||
// --------------------------------------------------- : Panel managment
|
// --------------------------------------------------- : Panel managment
|
||||||
|
|
||||||
|
|||||||
+29
-29
@@ -35,7 +35,7 @@ void SymbolControl::switchEditor(const SymbolEditorBaseP& e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SymbolControl::onChangeSymbol() {
|
void SymbolControl::onChangeSymbol() {
|
||||||
selectedParts.clear();
|
selected_parts.clear();
|
||||||
switchEditor(new_shared2<SymbolSelectEditor>(this, false));
|
switchEditor(new_shared2<SymbolSelectEditor>(this, false));
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
}
|
}
|
||||||
@@ -49,14 +49,14 @@ void SymbolControl::onModeChange(wxCommandEvent& ev) {
|
|||||||
switchEditor(new_shared2<SymbolSelectEditor>(this, true));
|
switchEditor(new_shared2<SymbolSelectEditor>(this, true));
|
||||||
break;
|
break;
|
||||||
case ID_MODE_POINTS:
|
case ID_MODE_POINTS:
|
||||||
if (selectedParts.size() == 1) {
|
if (selected_parts.size() == 1) {
|
||||||
singleSelection = *selectedParts.begin();
|
single_selection = *selected_parts.begin();
|
||||||
switchEditor(new_shared2<SymbolPointEditor>(this, singleSelection));
|
switchEditor(new_shared2<SymbolPointEditor>(this, single_selection));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_MODE_SHAPES:
|
case ID_MODE_SHAPES:
|
||||||
if (!selectedParts.empty()) {
|
if (!selected_parts.empty()) {
|
||||||
selectedParts.clear();
|
selected_parts.clear();
|
||||||
signalSelectionChange();
|
signalSelectionChange();
|
||||||
}
|
}
|
||||||
switchEditor(new_shared1<SymbolBasicShapeEditor>(this));
|
switchEditor(new_shared1<SymbolBasicShapeEditor>(this));
|
||||||
@@ -78,26 +78,26 @@ void SymbolControl::onUpdateSelection() {
|
|||||||
switch(editor->modeToolId()) {
|
switch(editor->modeToolId()) {
|
||||||
case ID_MODE_POINTS:
|
case ID_MODE_POINTS:
|
||||||
// can only select a single part!
|
// can only select a single part!
|
||||||
if (selectedParts.size() > 1) {
|
if (selected_parts.size() > 1) {
|
||||||
SymbolPartP part = *selectedParts.begin();
|
SymbolPartP part = *selected_parts.begin();
|
||||||
selectedParts.clear();
|
selected_parts.clear();
|
||||||
selectedParts.insert(part);
|
selected_parts.insert(part);
|
||||||
signalSelectionChange();
|
signalSelectionChange();
|
||||||
} else if (selectedParts.empty()) {
|
} else if (selected_parts.empty()) {
|
||||||
selectedParts.insert(singleSelection);
|
selected_parts.insert(single_selection);
|
||||||
signalSelectionChange();
|
signalSelectionChange();
|
||||||
}
|
}
|
||||||
if (singleSelection != *selectedParts.begin()) {
|
if (single_selection != *selected_parts.begin()) {
|
||||||
// begin editing another part
|
// begin editing another part
|
||||||
singleSelection = *selectedParts.begin();
|
single_selection = *selected_parts.begin();
|
||||||
editor = new_shared2<SymbolPointEditor>(this, singleSelection);
|
editor = new_shared2<SymbolPointEditor>(this, single_selection);
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_MODE_SHAPES:
|
case ID_MODE_SHAPES:
|
||||||
if (!selectedParts.empty()) {
|
if (!selected_parts.empty()) {
|
||||||
// there can't be a selection
|
// there can't be a selection
|
||||||
selectedParts.clear();
|
selected_parts.clear();
|
||||||
signalSelectionChange();
|
signalSelectionChange();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -108,15 +108,15 @@ void SymbolControl::onUpdateSelection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SymbolControl::selectPart(const SymbolPartP& part) {
|
void SymbolControl::selectPart(const SymbolPartP& part) {
|
||||||
selectedParts.clear();
|
selected_parts.clear();
|
||||||
selectedParts.insert(part);
|
selected_parts.insert(part);
|
||||||
switchEditor(new_shared2<SymbolSelectEditor>(this, false));
|
switchEditor(new_shared2<SymbolSelectEditor>(this, false));
|
||||||
signalSelectionChange();
|
signalSelectionChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolControl::activatePart(const SymbolPartP& part) {
|
void SymbolControl::activatePart(const SymbolPartP& part) {
|
||||||
selectedParts.clear();
|
selected_parts.clear();
|
||||||
selectedParts.insert(part);
|
selected_parts.insert(part);
|
||||||
switchEditor(new_shared2<SymbolPointEditor>(this, part));
|
switchEditor(new_shared2<SymbolPointEditor>(this, part));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,34 +154,34 @@ void SymbolControl::onPaint(wxPaintEvent& e) {
|
|||||||
void SymbolControl::onLeftDown(wxMouseEvent& ev) {
|
void SymbolControl::onLeftDown(wxMouseEvent& ev) {
|
||||||
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
||||||
if (editor) editor->onLeftDown(pos, ev);
|
if (editor) editor->onLeftDown(pos, ev);
|
||||||
lastPos = pos;
|
last_pos = pos;
|
||||||
ev.Skip(); // for focus
|
ev.Skip(); // for focus
|
||||||
}
|
}
|
||||||
void SymbolControl::onLeftUp(wxMouseEvent& ev) {
|
void SymbolControl::onLeftUp(wxMouseEvent& ev) {
|
||||||
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
||||||
if (editor) editor->onLeftUp(pos, ev);
|
if (editor) editor->onLeftUp(pos, ev);
|
||||||
lastPos = pos;
|
last_pos = pos;
|
||||||
}
|
}
|
||||||
void SymbolControl::onLeftDClick(wxMouseEvent& ev) {
|
void SymbolControl::onLeftDClick(wxMouseEvent& ev) {
|
||||||
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
||||||
if (editor) editor->onLeftDClick(pos, ev);
|
if (editor) editor->onLeftDClick(pos, ev);
|
||||||
lastPos = pos;
|
last_pos = pos;
|
||||||
}
|
}
|
||||||
void SymbolControl::onRightDown(wxMouseEvent& ev) {
|
void SymbolControl::onRightDown(wxMouseEvent& ev) {
|
||||||
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
||||||
if (editor) editor->onRightDown(pos, ev);
|
if (editor) editor->onRightDown(pos, ev);
|
||||||
lastPos = pos;
|
last_pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolControl::onMotion(wxMouseEvent& ev) {
|
void SymbolControl::onMotion(wxMouseEvent& ev) {
|
||||||
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
Vector2D pos = rotation.trInv(RealPoint(ev.GetX(), ev.GetY()));
|
||||||
// Dragging something?
|
// Dragging something?
|
||||||
if (ev.LeftIsDown()) {
|
if (ev.LeftIsDown()) {
|
||||||
if (editor) editor->onMouseDrag(lastPos, pos, ev);
|
if (editor) editor->onMouseDrag(last_pos, pos, ev);
|
||||||
} else {
|
} else {
|
||||||
if (editor) editor->onMouseMove(lastPos, pos, ev);
|
if (editor) editor->onMouseMove(last_pos, pos, ev);
|
||||||
}
|
}
|
||||||
lastPos = pos;
|
last_pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key events, just forward
|
// Key events, just forward
|
||||||
@@ -207,7 +207,7 @@ void SymbolControl::onUpdateUI(wxUpdateUIEvent& ev) {
|
|||||||
ev.Check(editor->modeToolId() == ev.GetId());
|
ev.Check(editor->modeToolId() == ev.GetId());
|
||||||
if (ev.GetId() == ID_MODE_POINTS) {
|
if (ev.GetId() == ID_MODE_POINTS) {
|
||||||
// can only edit points when a single part is selected <TODO?>
|
// can only edit points when a single part is selected <TODO?>
|
||||||
ev.Enable(selectedParts.size() == 1);
|
ev.Enable(selected_parts.size() == 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_MODE_PAINT:
|
case ID_MODE_PAINT:
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ class SymbolControl : public wxControl, public SymbolViewer {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// What parts are selected
|
/// What parts are selected
|
||||||
set<SymbolPartP> selectedParts;
|
set<SymbolPartP> selected_parts;
|
||||||
SymbolPartP singleSelection;
|
SymbolPartP single_selection;
|
||||||
|
|
||||||
/// Parent window
|
/// Parent window
|
||||||
SymbolWindow* parent;
|
SymbolWindow* parent;
|
||||||
@@ -82,7 +82,7 @@ class SymbolControl : public wxControl, public SymbolViewer {
|
|||||||
SymbolEditorBaseP editor;
|
SymbolEditorBaseP editor;
|
||||||
|
|
||||||
/// Last mouse position
|
/// Last mouse position
|
||||||
Vector2D lastPos;
|
Vector2D last_pos;
|
||||||
|
|
||||||
// --------------------------------------------------- : Events
|
// --------------------------------------------------- : Events
|
||||||
|
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ SymbolPartList::SymbolPartList(Window* parent, int id, SymbolP symbol)
|
|||||||
// Create image list
|
// Create image list
|
||||||
wxImageList* images = new wxImageList(16,16);
|
wxImageList* images = new wxImageList(16,16);
|
||||||
// NOTE: this is based on the order of the SymbolPartCombine enum!
|
// NOTE: this is based on the order of the SymbolPartCombine enum!
|
||||||
images->Add(loadResourceImage(_("COMBINE_OR")));
|
images->Add(load_resource_image(_("COMBINE_OR")));
|
||||||
images->Add(loadResourceImage(_("COMBINE_SUB")));
|
images->Add(load_resource_image(_("COMBINE_SUB")));
|
||||||
images->Add(loadResourceImage(_("COMBINE_AND")));
|
images->Add(load_resource_image(_("COMBINE_AND")));
|
||||||
images->Add(loadResourceImage(_("COMBINE_XOR")));
|
images->Add(load_resource_image(_("COMBINE_XOR")));
|
||||||
images->Add(loadResourceImage(_("COMBINE_OVER")));
|
images->Add(load_resource_image(_("COMBINE_OVER")));
|
||||||
images->Add(loadResourceImage(_("COMBINE_BORDER")));
|
images->Add(load_resource_image(_("COMBINE_BORDER")));
|
||||||
AssignImageList(images, wxIMAGE_LIST_SMALL);
|
AssignImageList(images, wxIMAGE_LIST_SMALL);
|
||||||
// create columns
|
// create columns
|
||||||
InsertColumn(0, _("Name"));
|
InsertColumn(0, _("Name"));
|
||||||
@@ -74,7 +74,7 @@ void SymbolPartList::selectItem(long item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPartList::getSelectedParts(set<SymbolPartP>& sel) {
|
void SymbolPartList::getselected_parts(set<SymbolPartP>& sel) {
|
||||||
sel.clear();
|
sel.clear();
|
||||||
long count = GetItemCount();
|
long count = GetItemCount();
|
||||||
for (long i = 0 ; i < count ; ++ i) {
|
for (long i = 0 ; i < count ; ++ i) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class SymbolPartList : public wxListCtrl, public SymbolView {
|
|||||||
inline SymbolPartP getSelection() const { return getPart(selected); }
|
inline SymbolPartP getSelection() const { return getPart(selected); }
|
||||||
|
|
||||||
/// Get a set of selected parts
|
/// Get a set of selected parts
|
||||||
void getSelectedParts(set<SymbolPartP>& sel);
|
void getselected_parts(set<SymbolPartP>& sel);
|
||||||
/// Select the specified parts, and nothing else
|
/// Select the specified parts, and nothing else
|
||||||
void selectParts(const set<SymbolPartP>& sel);
|
void selectParts(const set<SymbolPartP>& sel);
|
||||||
|
|
||||||
|
|||||||
@@ -50,13 +50,13 @@ void SymbolPointEditor::draw(DC& dc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPointEditor::drawHoveredLine(DC& dc) {
|
void SymbolPointEditor::drawHoveredLine(DC& dc) {
|
||||||
BezierCurve c(*hoverLine1, *hoverLine2);
|
BezierCurve c(*hover_line_1, *hover_line_2);
|
||||||
wxPoint prevPoint = control.rotation.tr(hoverLine1->pos);
|
wxPoint prevPoint = control.rotation.tr(hover_line_1->pos);
|
||||||
for(int i = 1 ; i <= 100 ; ++i) {
|
for(int i = 1 ; i <= 100 ; ++i) {
|
||||||
// Draw 100 segments of the curve
|
// Draw 100 segments of the curve
|
||||||
double t = double(i)/100.0f;
|
double t = double(i)/100.0f;
|
||||||
wxPoint curPoint = control.rotation.tr(c.pointAt(t));
|
wxPoint curPoint = control.rotation.tr(c.pointAt(t));
|
||||||
double selectPercent = 1.0 - 1.2 * sqrt(fabs(hoverLineT-t)); // amount to color
|
double selectPercent = 1.0 - 1.2 * sqrt(fabs(hover_line_t-t)); // amount to color
|
||||||
if (selectPercent > 0) {
|
if (selectPercent > 0) {
|
||||||
// gradient color
|
// gradient color
|
||||||
Color color(
|
Color color(
|
||||||
@@ -87,7 +87,7 @@ void SymbolPointEditor::drawHandles(DC& dc) {
|
|||||||
void SymbolPointEditor::drawNewPoint(DC& dc) {
|
void SymbolPointEditor::drawNewPoint(DC& dc) {
|
||||||
dc.SetPen(*wxGREEN_PEN);
|
dc.SetPen(*wxGREEN_PEN);
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
wxPoint p = control.rotation.tr(newPoint);
|
wxPoint p = control.rotation.tr(new_point);
|
||||||
drawHandleBox(dc, p.x, p.y, true);
|
drawHandleBox(dc, p.x, p.y, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,16 +98,16 @@ void SymbolPointEditor::drawControlPoint(DC& dc, const ControlPoint& p, bool dra
|
|||||||
if (drawHandleBefore || drawHandleAfter) {
|
if (drawHandleBefore || drawHandleAfter) {
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
// Before handle
|
// Before handle
|
||||||
if (drawHandleBefore && p.segmentBefore == SEGMENT_CURVE) {
|
if (drawHandleBefore && p.segment_before == SEGMENT_CURVE) {
|
||||||
wxPoint p1 = control.rotation.tr(p.pos + p.deltaBefore);
|
wxPoint p1 = control.rotation.tr(p.pos + p.delta_before);
|
||||||
dc.SetPen(handlePen(PEN_LINE, p.lock));
|
dc.SetPen(handlePen(PEN_LINE, p.lock));
|
||||||
dc.DrawLine(p0.x, p0.y, p1.x, p1.y);
|
dc.DrawLine(p0.x, p0.y, p1.x, p1.y);
|
||||||
dc.SetPen(handlePen(handleHovered(p, HANDLE_BEFORE) ? PEN_HOVER : PEN_NORMAL, p.lock));
|
dc.SetPen(handlePen(handleHovered(p, HANDLE_BEFORE) ? PEN_HOVER : PEN_NORMAL, p.lock));
|
||||||
drawHandleCircle(dc, p1.x, p1.y);
|
drawHandleCircle(dc, p1.x, p1.y);
|
||||||
}
|
}
|
||||||
// After handle
|
// After handle
|
||||||
if (drawHandleAfter && p.segmentAfter == SEGMENT_CURVE) {
|
if (drawHandleAfter && p.segment_after == SEGMENT_CURVE) {
|
||||||
wxPoint p1 = control.rotation.tr(p.pos + p.deltaAfter);
|
wxPoint p1 = control.rotation.tr(p.pos + p.delta_after);
|
||||||
dc.SetPen(handlePen(PEN_LINE, p.lock));
|
dc.SetPen(handlePen(PEN_LINE, p.lock));
|
||||||
dc.DrawLine(p0.x, p0.y, p1.x, p1.y);
|
dc.DrawLine(p0.x, p0.y, p1.x, p1.y);
|
||||||
dc.SetPen(handlePen(handleHovered(p, HANDLE_AFTER) ? PEN_HOVER : PEN_NORMAL, p.lock));
|
dc.SetPen(handlePen(handleHovered(p, HANDLE_AFTER) ? PEN_HOVER : PEN_NORMAL, p.lock));
|
||||||
@@ -186,9 +186,9 @@ void SymbolPointEditor::onUpdateUI(wxUpdateUIEvent& ev) {
|
|||||||
break;
|
break;
|
||||||
case ID_LOCK_FREE: case ID_LOCK_DIR: case ID_LOCK_SIZE:
|
case ID_LOCK_FREE: case ID_LOCK_DIR: case ID_LOCK_SIZE:
|
||||||
enabled = selection == SELECTED_POINTS &&
|
enabled = selection == SELECTED_POINTS &&
|
||||||
selectedPoints.size() == 1 &&
|
selected_points.size() == 1 &&
|
||||||
(*selectedPoints.begin())->segmentBefore == SEGMENT_CURVE &&
|
(*selected_points.begin())->segment_before == SEGMENT_CURVE &&
|
||||||
(*selectedPoints.begin())->segmentAfter == SEGMENT_CURVE;
|
(*selected_points.begin())->segment_after == SEGMENT_CURVE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ev.Enable(false); // we don't know this item
|
ev.Enable(false); // we don't know this item
|
||||||
@@ -198,10 +198,10 @@ void SymbolPointEditor::onUpdateUI(wxUpdateUIEvent& ev) {
|
|||||||
if (enabled) {
|
if (enabled) {
|
||||||
switch (ev.GetId()) {
|
switch (ev.GetId()) {
|
||||||
case ID_SEGMENT_LINE: case ID_SEGMENT_CURVE:
|
case ID_SEGMENT_LINE: case ID_SEGMENT_CURVE:
|
||||||
checked = selectedLine1->segmentAfter == ev.GetId() - ID_SEGMENT;
|
checked = selected_line1->segment_after == ev.GetId() - ID_SEGMENT;
|
||||||
break;
|
break;
|
||||||
case ID_LOCK_FREE: case ID_LOCK_DIR: case ID_LOCK_SIZE:
|
case ID_LOCK_FREE: case ID_LOCK_DIR: case ID_LOCK_SIZE:
|
||||||
checked = (*selectedPoints.begin())->lock == ev.GetId() - ID_LOCK;
|
checked = (*selected_points.begin())->lock == ev.GetId() - ID_LOCK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,17 +248,17 @@ void SymbolPointEditor::onLeftDClick(const Vector2D& pos, wxMouseEvent& ev) {
|
|||||||
findHoveredItem(pos, false);
|
findHoveredItem(pos, false);
|
||||||
if (hovering == SELECTED_NEW_POINT) {
|
if (hovering == SELECTED_NEW_POINT) {
|
||||||
// Add point
|
// Add point
|
||||||
ControlPointAddAction* act = new ControlPointAddAction(part, hoverLine1Idx, hoverLineT);
|
ControlPointAddAction* act = new ControlPointAddAction(part, hover_line_1_idx, hover_line_t);
|
||||||
getSymbol()->actions.add(act);
|
getSymbol()->actions.add(act);
|
||||||
// select the new point
|
// select the new point
|
||||||
selectPoint(act->getNewPoint(), false);
|
selectPoint(act->getNewPoint(), false);
|
||||||
selection = SELECTED_POINTS;
|
selection = SELECTED_POINTS;
|
||||||
} else if (hovering == SELECTED_HANDLE && hoverHandle.handle == HANDLE_MAIN) { //%%%%%%% ||/&&
|
} else if (hovering == SELECTED_HANDLE && hover_handle.handle == HANDLE_MAIN) { //%%%%%%% ||/&&
|
||||||
// Delete point
|
// Delete point
|
||||||
selectedPoints.clear();
|
selected_points.clear();
|
||||||
selectPoint(hoverHandle.point, false);
|
selectPoint(hover_handle.point, false);
|
||||||
getSymbol()->actions.add(controlPointRemoveAction(part, selectedPoints));
|
getSymbol()->actions.add(controlPointRemoveAction(part, selected_points));
|
||||||
selectedPoints.clear();
|
selected_points.clear();
|
||||||
selection = SELECTED_NONE;
|
selection = SELECTED_NONE;
|
||||||
}
|
}
|
||||||
// refresh
|
// refresh
|
||||||
@@ -278,27 +278,27 @@ void SymbolPointEditor::onMouseDrag(const Vector2D& from, const Vector2D& to, wx
|
|||||||
// Drag the curve
|
// Drag the curve
|
||||||
if (controlPointMoveAction) controlPointMoveAction = 0;
|
if (controlPointMoveAction) controlPointMoveAction = 0;
|
||||||
if (!curveDragAction) {
|
if (!curveDragAction) {
|
||||||
curveDragAction = new CurveDragAction(selectedLine1, selectedLine2);
|
curveDragAction = new CurveDragAction(selected_line1, selected_line2);
|
||||||
getSymbol()->actions.add(curveDragAction);
|
getSymbol()->actions.add(curveDragAction);
|
||||||
}
|
}
|
||||||
curveDragAction->move(delta, selectedLineT);
|
curveDragAction->move(delta, selected_line_t);
|
||||||
control.Refresh(false);
|
control.Refresh(false);
|
||||||
} else if (selection == SELECTED_POINTS || selection == SELECTED_LINE) {
|
} else if (selection == SELECTED_POINTS || selection == SELECTED_LINE) {
|
||||||
// Move all selected points
|
// Move all selected points
|
||||||
if (curveDragAction) curveDragAction = 0;
|
if (curveDragAction) curveDragAction = 0;
|
||||||
if (!controlPointMoveAction) {
|
if (!controlPointMoveAction) {
|
||||||
// create action we can add this movement to
|
// create action we can add this movement to
|
||||||
controlPointMoveAction = new ControlPointMoveAction(selectedPoints);
|
controlPointMoveAction = new ControlPointMoveAction(selected_points);
|
||||||
getSymbol()->actions.add(controlPointMoveAction);
|
getSymbol()->actions.add(controlPointMoveAction);
|
||||||
}
|
}
|
||||||
controlPointMoveAction->constrain = ev.ControlDown(); // ctrl constrains
|
controlPointMoveAction->constrain = ev.ControlDown(); // ctrl constrains
|
||||||
controlPointMoveAction->move(delta);
|
controlPointMoveAction->move(delta);
|
||||||
newPoint += delta;
|
new_point += delta;
|
||||||
control.Refresh(false);
|
control.Refresh(false);
|
||||||
} else if (selection == SELECTED_HANDLE) {
|
} else if (selection == SELECTED_HANDLE) {
|
||||||
// Move the selected handle
|
// Move the selected handle
|
||||||
if (!handleMoveAction) {
|
if (!handleMoveAction) {
|
||||||
handleMoveAction = new HandleMoveAction(selectedHandle);
|
handleMoveAction = new HandleMoveAction(selected_handle);
|
||||||
getSymbol()->actions.add(handleMoveAction);
|
getSymbol()->actions.add(handleMoveAction);
|
||||||
}
|
}
|
||||||
handleMoveAction->constrain = ev.ControlDown(); // ctrl constrains
|
handleMoveAction->constrain = ev.ControlDown(); // ctrl constrains
|
||||||
@@ -352,21 +352,21 @@ bool SymbolPointEditor::isEditing() {
|
|||||||
|
|
||||||
void SymbolPointEditor::selectNothing() {
|
void SymbolPointEditor::selectNothing() {
|
||||||
selection = SELECTED_NONE;
|
selection = SELECTED_NONE;
|
||||||
selectedPoints.clear();
|
selected_points.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPointEditor::selectPoint(const ControlPointP& point, bool toggle) {
|
void SymbolPointEditor::selectPoint(const ControlPointP& point, bool toggle) {
|
||||||
set<ControlPointP>::iterator inSet = selectedPoints.find(point);
|
set<ControlPointP>::iterator inSet = selected_points.find(point);
|
||||||
if (toggle) {
|
if (toggle) {
|
||||||
if (inSet == selectedPoints.end()) {
|
if (inSet == selected_points.end()) {
|
||||||
selectedPoints.insert(point);
|
selected_points.insert(point);
|
||||||
} else {
|
} else {
|
||||||
selectedPoints.erase(inSet);
|
selected_points.erase(inSet);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (inSet == selectedPoints.end()) {
|
if (inSet == selected_points.end()) {
|
||||||
selectedPoints.clear();
|
selected_points.clear();
|
||||||
selectedPoints.insert(point);
|
selected_points.insert(point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -377,26 +377,26 @@ void SymbolPointEditor::selectHandle(const SelectedHandle& h, const wxMouseEvent
|
|||||||
selectPoint(h.point, keystate.ShiftDown());
|
selectPoint(h.point, keystate.ShiftDown());
|
||||||
} else {
|
} else {
|
||||||
selection = SELECTED_HANDLE;
|
selection = SELECTED_HANDLE;
|
||||||
selectedHandle = h;
|
selected_handle = h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPointEditor::selectLine(const wxMouseEvent& keystate) {
|
void SymbolPointEditor::selectLine(const wxMouseEvent& keystate) {
|
||||||
selection = SELECTED_LINE;
|
selection = SELECTED_LINE;
|
||||||
selectedLine1 = hoverLine1;
|
selected_line1 = hover_line_1;
|
||||||
selectedLine2 = hoverLine2;
|
selected_line2 = hover_line_2;
|
||||||
selectedLineT = hoverLineT;
|
selected_line_t = hover_line_t;
|
||||||
if (!keystate.ShiftDown()) selectedPoints.clear();
|
if (!keystate.ShiftDown()) selected_points.clear();
|
||||||
selectPoint(selectedLine1, true);
|
selectPoint(selected_line1, true);
|
||||||
selectPoint(selectedLine2, true);
|
selectPoint(selected_line2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SymbolPointEditor::pointSelected(const ControlPointP& pnt) {
|
bool SymbolPointEditor::pointSelected(const ControlPointP& pnt) {
|
||||||
return selectedPoints.find(pnt) != selectedPoints.end();
|
return selected_points.find(pnt) != selected_points.end();
|
||||||
}
|
}
|
||||||
bool SymbolPointEditor::pointSelected(const ControlPoint& pnt) {
|
bool SymbolPointEditor::pointSelected(const ControlPoint& pnt) {
|
||||||
FOR_EACH(s, selectedPoints) {
|
FOR_EACH(s, selected_points) {
|
||||||
if (s.get() == &pnt) return true;
|
if (s.get() == &pnt) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -410,10 +410,10 @@ bool SymbolPointEditor::pointHovered(const ControlPoint& pnt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SymbolPointEditor::handleHovered(const ControlPointP& pnt, WhichHandle wh) {
|
bool SymbolPointEditor::handleHovered(const ControlPointP& pnt, WhichHandle wh) {
|
||||||
return hovering == SELECTED_HANDLE && hoverHandle.point == pnt && hoverHandle.handle == wh;
|
return hovering == SELECTED_HANDLE && hover_handle.point == pnt && hover_handle.handle == wh;
|
||||||
}
|
}
|
||||||
bool SymbolPointEditor::handleHovered(const ControlPoint& pnt, WhichHandle wh) {
|
bool SymbolPointEditor::handleHovered(const ControlPoint& pnt, WhichHandle wh) {
|
||||||
return hovering == SELECTED_HANDLE && hoverHandle.point && hoverHandle.point.get() == &pnt && hoverHandle.handle == wh;
|
return hovering == SELECTED_HANDLE && hover_handle.point && hover_handle.point.get() == &pnt && hover_handle.handle == wh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -426,24 +426,24 @@ void SymbolPointEditor::resetActions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPointEditor::deleteSelection() {
|
void SymbolPointEditor::deleteSelection() {
|
||||||
if (!selectedPoints.empty()) {
|
if (!selected_points.empty()) {
|
||||||
getSymbol()->actions.add(controlPointRemoveAction(part, selectedPoints));
|
getSymbol()->actions.add(controlPointRemoveAction(part, selected_points));
|
||||||
selectedPoints.clear();
|
selected_points.clear();
|
||||||
resetActions();
|
resetActions();
|
||||||
control.Refresh(false);
|
control.Refresh(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPointEditor::onChangeSegment(SegmentMode mode) {
|
void SymbolPointEditor::onChangeSegment(SegmentMode mode) {
|
||||||
assert(selectedLine1);
|
assert(selected_line1);
|
||||||
assert(selectedLine2);
|
assert(selected_line2);
|
||||||
if (selectedLine1->segmentAfter == mode) return;
|
if (selected_line1->segment_after == mode) return;
|
||||||
getSymbol()->actions.add(new SegmentModeAction(selectedLine1, selectedLine2, mode));
|
getSymbol()->actions.add(new SegmentModeAction(selected_line1, selected_line2, mode));
|
||||||
control.Refresh(false);
|
control.Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolPointEditor::onChangeLock(LockMode mode) {
|
void SymbolPointEditor::onChangeLock(LockMode mode) {
|
||||||
getSymbol()->actions.add(new LockModeAction(*selectedPoints.begin(), mode));
|
getSymbol()->actions.add(new LockModeAction(*selected_points.begin(), mode));
|
||||||
control.Refresh(false);
|
control.Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,9 +452,9 @@ void SymbolPointEditor::onChangeLock(LockMode mode) {
|
|||||||
|
|
||||||
void SymbolPointEditor::findHoveredItem(const Vector2D& pos, bool altDown) {
|
void SymbolPointEditor::findHoveredItem(const Vector2D& pos, bool altDown) {
|
||||||
// is there a point currently under the cursor?
|
// is there a point currently under the cursor?
|
||||||
hoverHandle = findHandle(pos);
|
hover_handle = findHandle(pos);
|
||||||
// change cursor and statusbar if point is under it
|
// change cursor and statusbar if point is under it
|
||||||
if (hoverHandle.handle) {
|
if (hover_handle.handle) {
|
||||||
hovering = SELECTED_HANDLE;
|
hovering = SELECTED_HANDLE;
|
||||||
control.SetCursor(pointMove);
|
control.SetCursor(pointMove);
|
||||||
SetStatusText(_("Click and drag to move control point"));
|
SetStatusText(_("Click and drag to move control point"));
|
||||||
@@ -483,11 +483,11 @@ bool SymbolPointEditor::checkPosOnCurve(const Vector2D& pos) {
|
|||||||
size_t size = part->points.size();
|
size_t size = part->points.size();
|
||||||
for(int i = 0 ; (size_t)i < size ; ++i) {
|
for(int i = 0 ; (size_t)i < size ; ++i) {
|
||||||
// Curve between these lines
|
// Curve between these lines
|
||||||
hoverLine1 = part->getPoint(i);
|
hover_line_1 = part->getPoint(i);
|
||||||
hoverLine2 = part->getPoint(i + 1);
|
hover_line_2 = part->getPoint(i + 1);
|
||||||
if (posOnSegment(pos, range, *hoverLine1, *hoverLine2, newPoint, hoverLineT)) {
|
if (pos_on_segment(pos, range, *hover_line_1, *hover_line_2, new_point, hover_line_t)) {
|
||||||
// mouse is on this line
|
// mouse is on this line
|
||||||
hoverLine1Idx = i;
|
hover_line_1_idx = i;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -510,13 +510,13 @@ SelectedHandle SymbolPointEditor::findHandle(const Vector2D& pos) {
|
|||||||
bool sel = pointSelected(p);
|
bool sel = pointSelected(p);
|
||||||
bool before = sel || pointSelected(part->getPoint(i-1)); // are the handles visible?
|
bool before = sel || pointSelected(part->getPoint(i-1)); // are the handles visible?
|
||||||
bool after = sel || pointSelected(part->getPoint(i+1));
|
bool after = sel || pointSelected(part->getPoint(i+1));
|
||||||
if (before && p->segmentBefore == SEGMENT_CURVE) {
|
if (before && p->segment_before == SEGMENT_CURVE) {
|
||||||
if (inRange(p->pos + p->deltaBefore, pos, range)) {
|
if (inRange(p->pos + p->delta_before, pos, range)) {
|
||||||
return SelectedHandle(p, HANDLE_BEFORE);
|
return SelectedHandle(p, HANDLE_BEFORE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (after && p->segmentAfter == SEGMENT_CURVE) {
|
if (after && p->segment_after == SEGMENT_CURVE) {
|
||||||
if (inRange(p->pos + p->deltaAfter, pos, range)) {
|
if (inRange(p->pos + p->delta_after, pos, range)) {
|
||||||
return SelectedHandle(p, HANDLE_AFTER);
|
return SelectedHandle(p, HANDLE_AFTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,23 +99,23 @@ class SymbolPointEditor : public SymbolEditorBase {
|
|||||||
};
|
};
|
||||||
Selection selection;
|
Selection selection;
|
||||||
// points
|
// points
|
||||||
set<ControlPointP> selectedPoints;
|
set<ControlPointP> selected_points;
|
||||||
// handle
|
// handle
|
||||||
SelectedHandle selectedHandle;
|
SelectedHandle selected_handle;
|
||||||
// line
|
// line
|
||||||
ControlPointP selectedLine1, selectedLine2; // selected the line between these points
|
ControlPointP selected_line1, selected_line2; // selected the line between these points
|
||||||
double selectedLineT; // time on the line of the selection
|
double selected_line_t; // time on the line of the selection
|
||||||
|
|
||||||
// Mouse feedback
|
// Mouse feedback
|
||||||
Selection hovering;
|
Selection hovering;
|
||||||
// handle
|
// handle
|
||||||
SelectedHandle hoverHandle; // the handle currently under the cursor
|
SelectedHandle hover_handle; // the handle currently under the cursor
|
||||||
// new point
|
// new point
|
||||||
Vector2D newPoint;
|
Vector2D new_point;
|
||||||
// line
|
// line
|
||||||
ControlPointP hoverLine1, hoverLine2; // hovering on the line between these points
|
ControlPointP hover_line_1, hover_line_2; // hovering on the line between these points
|
||||||
double hoverLineT;
|
double hover_line_t;
|
||||||
int hoverLine1Idx; // index of hoverLine1 in the list of points
|
int hover_line_1_idx; // index of hover_line_1 in the list of points
|
||||||
|
|
||||||
// Gui stock
|
// Gui stock
|
||||||
wxBitmap background;
|
wxBitmap background;
|
||||||
|
|||||||
@@ -25,15 +25,15 @@ SymbolSelectEditor::SymbolSelectEditor(SymbolControl* control, bool rotate)
|
|||||||
, cursorShearY(_("CUR_SHEAR_Y"), wxBITMAP_TYPE_CUR_RESOURCE)
|
, cursorShearY(_("CUR_SHEAR_Y"), wxBITMAP_TYPE_CUR_RESOURCE)
|
||||||
{
|
{
|
||||||
// Load resource images
|
// Load resource images
|
||||||
Image rot = loadResourceImage(_("HANDLE_ROTATE"));
|
Image rot = load_resource_image(_("HANDLE_ROTATE"));
|
||||||
handleRotateTL = wxBitmap(rot);
|
handleRotateTL = wxBitmap(rot);
|
||||||
handleRotateTR = wxBitmap(rotateImageBy(rot,90));
|
handleRotateTR = wxBitmap(rotate_image(rot,90));
|
||||||
handleRotateBR = wxBitmap(rotateImageBy(rot,180));
|
handleRotateBR = wxBitmap(rotate_image(rot,180));
|
||||||
handleRotateBL = wxBitmap(rotateImageBy(rot,270));
|
handleRotateBL = wxBitmap(rotate_image(rot,270));
|
||||||
Image shear = loadResourceImage(_("HANDLE_SHEAR_X"));
|
Image shear = load_resource_image(_("HANDLE_SHEAR_X"));
|
||||||
handleShearX = wxBitmap(shear);
|
handleShearX = wxBitmap(shear);
|
||||||
handleShearY = wxBitmap(rotateImageBy(shear,90));
|
handleShearY = wxBitmap(rotate_image(shear,90));
|
||||||
handleCenter = wxBitmap(loadResourceImage(_("HANDLE_CENTER")));
|
handleCenter = wxBitmap(load_resource_image(_("HANDLE_CENTER")));
|
||||||
// Make sure all parts have updated bounds
|
// Make sure all parts have updated bounds
|
||||||
FOR_EACH(p, getSymbol()->parts) {
|
FOR_EACH(p, getSymbol()->parts) {
|
||||||
p->calculateBounds();
|
p->calculateBounds();
|
||||||
@@ -45,7 +45,7 @@ SymbolSelectEditor::SymbolSelectEditor(SymbolControl* control, bool rotate)
|
|||||||
|
|
||||||
void SymbolSelectEditor::draw(DC& dc) {
|
void SymbolSelectEditor::draw(DC& dc) {
|
||||||
// highlight selected parts
|
// highlight selected parts
|
||||||
FOR_EACH(p, control.selectedParts) {
|
FOR_EACH(p, control.selected_parts) {
|
||||||
control.highlightPart(dc, *p, HIGHLIGHT_INTERIOR);
|
control.highlightPart(dc, *p, HIGHLIGHT_INTERIOR);
|
||||||
}
|
}
|
||||||
// highlight the part under the cursor
|
// highlight the part under the cursor
|
||||||
@@ -57,7 +57,7 @@ void SymbolSelectEditor::draw(DC& dc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SymbolSelectEditor::drawHandles(DC& dc) {
|
void SymbolSelectEditor::drawHandles(DC& dc) {
|
||||||
if (control.selectedParts.empty()) return;
|
if (control.selected_parts.empty()) return;
|
||||||
if (rotateAction) return; // not when rotating
|
if (rotateAction) return; // not when rotating
|
||||||
updateBoundingBox();
|
updateBoundingBox();
|
||||||
// Draw handles on all sides
|
// Draw handles on all sides
|
||||||
@@ -107,12 +107,12 @@ void SymbolSelectEditor::drawRotationCenter(DC& dc, const Vector2D& pos) {
|
|||||||
|
|
||||||
void SymbolSelectEditor::initUI(wxToolBar* tb, wxMenuBar* mb) {
|
void SymbolSelectEditor::initUI(wxToolBar* tb, wxMenuBar* mb) {
|
||||||
tb->AddSeparator();
|
tb->AddSeparator();
|
||||||
tb->AddTool(ID_PART_MERGE, _("Merge"), loadResourceImage(_("COMBINE_OR")), wxNullBitmap, wxITEM_CHECK, _("Merge with shapes below"), _("Merges this shape with those below it"));
|
tb->AddTool(ID_PART_MERGE, _("Merge"), load_resource_image(_("COMBINE_OR")), wxNullBitmap, wxITEM_CHECK, _("Merge with shapes below"), _("Merges this shape with those below it"));
|
||||||
tb->AddTool(ID_PART_SUBTRACT, _("Subtract"), loadResourceImage(_("COMBINE_SUB_DARK")), wxNullBitmap, wxITEM_CHECK, _("Subtract from shapes below"), _("Subtracts this shape from shapes below it, leaves only the area in that shape that is not in this shape"));
|
tb->AddTool(ID_PART_SUBTRACT, _("Subtract"), load_resource_image(_("COMBINE_SUB_DARK")), wxNullBitmap, wxITEM_CHECK, _("Subtract from shapes below"), _("Subtracts this shape from shapes below it, leaves only the area in that shape that is not in this shape"));
|
||||||
tb->AddTool(ID_PART_INTERSECTION, _("Intersect"), loadResourceImage(_("COMBINE_AND_DARK")), wxNullBitmap, wxITEM_CHECK, _("Intersect with shapes below"), _("Intersects this shape with shapes below it, leaves only the area in both shapes"));
|
tb->AddTool(ID_PART_INTERSECTION, _("Intersect"), load_resource_image(_("COMBINE_AND_DARK")), wxNullBitmap, wxITEM_CHECK, _("Intersect with shapes below"), _("Intersects this shape with shapes below it, leaves only the area in both shapes"));
|
||||||
// note: difference doesn't work (yet)
|
// note: difference doesn't work (yet)
|
||||||
tb->AddTool(ID_PART_OVERLAP, _("Overlap"), loadResourceImage(_("COMBINE_OVER")), wxNullBitmap, wxITEM_CHECK, _("Place above other shapes"), _("Place this shape, and its border above shapes below it"));
|
tb->AddTool(ID_PART_OVERLAP, _("Overlap"), load_resource_image(_("COMBINE_OVER")), wxNullBitmap, wxITEM_CHECK, _("Place above other shapes"), _("Place this shape, and its border above shapes below it"));
|
||||||
tb->AddTool(ID_PART_BORDER, _("Border"), loadResourceImage(_("COMBINE_BORDER")), wxNullBitmap, wxITEM_CHECK, _("Draw as a border"), _("Draws this shape as a border"));
|
tb->AddTool(ID_PART_BORDER, _("Border"), load_resource_image(_("COMBINE_BORDER")), wxNullBitmap, wxITEM_CHECK, _("Draw as a border"), _("Draws this shape as a border"));
|
||||||
tb->Realize();
|
tb->Realize();
|
||||||
}
|
}
|
||||||
void SymbolSelectEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
|
void SymbolSelectEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
|
||||||
@@ -127,13 +127,13 @@ void SymbolSelectEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
|
|||||||
|
|
||||||
void SymbolSelectEditor::onUpdateUI(wxUpdateUIEvent& ev) {
|
void SymbolSelectEditor::onUpdateUI(wxUpdateUIEvent& ev) {
|
||||||
if (ev.GetId() >= ID_PART && ev.GetId() < ID_PART_MAX) {
|
if (ev.GetId() >= ID_PART && ev.GetId() < ID_PART_MAX) {
|
||||||
if (control.selectedParts.empty()) {
|
if (control.selected_parts.empty()) {
|
||||||
ev.Check(false);
|
ev.Check(false);
|
||||||
ev.Enable(false);
|
ev.Enable(false);
|
||||||
} else {
|
} else {
|
||||||
ev.Enable(true);
|
ev.Enable(true);
|
||||||
bool check = true;
|
bool check = true;
|
||||||
FOR_EACH(p, control.selectedParts) {
|
FOR_EACH(p, control.selected_parts) {
|
||||||
if (p->combine != ev.GetId() - ID_PART) {
|
if (p->combine != ev.GetId() - ID_PART) {
|
||||||
check = false;
|
check = false;
|
||||||
break;
|
break;
|
||||||
@@ -142,7 +142,7 @@ void SymbolSelectEditor::onUpdateUI(wxUpdateUIEvent& ev) {
|
|||||||
ev.Check(check);
|
ev.Check(check);
|
||||||
}
|
}
|
||||||
} else if (ev.GetId() == ID_EDIT_DUPLICATE) {
|
} else if (ev.GetId() == ID_EDIT_DUPLICATE) {
|
||||||
ev.Enable(!control.selectedParts.empty());
|
ev.Enable(!control.selected_parts.empty());
|
||||||
} else {
|
} else {
|
||||||
ev.Enable(false); // we don't know about this item
|
ev.Enable(false); // we don't know about this item
|
||||||
}
|
}
|
||||||
@@ -152,14 +152,14 @@ void SymbolSelectEditor::onCommand(int id) {
|
|||||||
if (id >= ID_PART && id < ID_PART_MAX) {
|
if (id >= ID_PART && id < ID_PART_MAX) {
|
||||||
// change combine mode
|
// change combine mode
|
||||||
getSymbol()->actions.add(new CombiningModeAction(
|
getSymbol()->actions.add(new CombiningModeAction(
|
||||||
control.selectedParts,
|
control.selected_parts,
|
||||||
static_cast<SymbolPartCombine>(id - ID_PART)
|
static_cast<SymbolPartCombine>(id - ID_PART)
|
||||||
));
|
));
|
||||||
control.Refresh(false);
|
control.Refresh(false);
|
||||||
} else if (id == ID_EDIT_DUPLICATE && !isEditing()) {
|
} else if (id == ID_EDIT_DUPLICATE && !isEditing()) {
|
||||||
// duplicate selection, not when dragging
|
// duplicate selection, not when dragging
|
||||||
DuplicateSymbolPartsAction* action = new DuplicateSymbolPartsAction(
|
DuplicateSymbolPartsAction* action = new DuplicateSymbolPartsAction(
|
||||||
*getSymbol(), control.selectedParts
|
*getSymbol(), control.selected_parts
|
||||||
);
|
);
|
||||||
getSymbol()->actions.add(action);
|
getSymbol()->actions.add(action);
|
||||||
control.Refresh(false);
|
control.Refresh(false);
|
||||||
@@ -189,26 +189,26 @@ void SymbolSelectEditor::onLeftUp (const Vector2D& pos, wxMouseEvent& ev) {
|
|||||||
if (part) {
|
if (part) {
|
||||||
if (ev.ShiftDown()) {
|
if (ev.ShiftDown()) {
|
||||||
// toggle selection
|
// toggle selection
|
||||||
set<SymbolPartP>::iterator it = control.selectedParts.find(part);
|
set<SymbolPartP>::iterator it = control.selected_parts.find(part);
|
||||||
if (it != control.selectedParts.end()) {
|
if (it != control.selected_parts.end()) {
|
||||||
control.selectedParts.erase(it);
|
control.selected_parts.erase(it);
|
||||||
} else {
|
} else {
|
||||||
control.selectedParts.insert(part);
|
control.selected_parts.insert(part);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (control.selectedParts.find(part) != control.selectedParts.end()) {
|
if (control.selected_parts.find(part) != control.selected_parts.end()) {
|
||||||
// already selected, don't change selection
|
// already selected, don't change selection
|
||||||
// instead switch between rotate and resize mode
|
// instead switch between rotate and resize mode
|
||||||
rotate = !rotate;
|
rotate = !rotate;
|
||||||
} else {
|
} else {
|
||||||
// select the part under the cursor
|
// select the part under the cursor
|
||||||
control.selectedParts.clear();
|
control.selected_parts.clear();
|
||||||
control.selectedParts.insert(part);
|
control.selected_parts.insert(part);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!ev.ShiftDown()) {
|
} else if (!ev.ShiftDown()) {
|
||||||
// select nothing
|
// select nothing
|
||||||
control.selectedParts.clear();
|
control.selected_parts.clear();
|
||||||
}
|
}
|
||||||
// selection has changed
|
// selection has changed
|
||||||
updateBoundingBox();
|
updateBoundingBox();
|
||||||
@@ -230,20 +230,20 @@ void SymbolSelectEditor::onMouseMove (const Vector2D& from, const Vector2D& to,
|
|||||||
highlightPart = findPart(to);
|
highlightPart = findPart(to);
|
||||||
// are we on a handle?
|
// are we on a handle?
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
if (!control.selectedParts.empty() && onAnyHandle(to, &dx, &dy)) {
|
if (!control.selected_parts.empty() && onAnyHandle(to, &dx, &dy)) {
|
||||||
// we are on a handle, don't highlight
|
// we are on a handle, don't highlight
|
||||||
highlightPart = SymbolPartP();
|
highlightPart = SymbolPartP();
|
||||||
if (rotate) {
|
if (rotate) {
|
||||||
// shear or rotating?
|
// shear or rotating?
|
||||||
if (dx == 0 || dy == 0) {
|
if (dx == 0 || dy == 0) {
|
||||||
SetStatusText(String(_("Drag to shear selected shape")) + (control.selectedParts.size() > 1 ? _("s") : _("")));
|
SetStatusText(String(_("Drag to shear selected shape")) + (control.selected_parts.size() > 1 ? _("s") : _("")));
|
||||||
control.SetCursor(dx == 0 ? cursorShearX : cursorShearY);
|
control.SetCursor(dx == 0 ? cursorShearX : cursorShearY);
|
||||||
} else {
|
} else {
|
||||||
SetStatusText(String(_("Drag to rotate selected shape")) + (control.selectedParts.size() > 1 ? _("s") : _("")) + _(", Ctrl constrains angle to multiples of 15 degrees"));
|
SetStatusText(String(_("Drag to rotate selected shape")) + (control.selected_parts.size() > 1 ? _("s") : _("")) + _(", Ctrl constrains angle to multiples of 15 degrees"));
|
||||||
control.SetCursor(cursorRotate);
|
control.SetCursor(cursorRotate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SetStatusText(String(_("Drag to resize selected shape")) + (control.selectedParts.size() > 1 ? _("s") : _("")) + _(", Ctrl constrains size"));
|
SetStatusText(String(_("Drag to resize selected shape")) + (control.selected_parts.size() > 1 ? _("s") : _("")) + _(", Ctrl constrains size"));
|
||||||
// what cursor to use?
|
// what cursor to use?
|
||||||
if (dx == dy) control.SetCursor(wxCURSOR_SIZENWSE);
|
if (dx == dy) control.SetCursor(wxCURSOR_SIZENWSE);
|
||||||
else if (dx == -dy) control.SetCursor(wxCURSOR_SIZENESW);
|
else if (dx == -dy) control.SetCursor(wxCURSOR_SIZENESW);
|
||||||
@@ -262,7 +262,7 @@ void SymbolSelectEditor::onMouseMove (const Vector2D& from, const Vector2D& to,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SymbolSelectEditor::onMouseDrag (const Vector2D& from, const Vector2D& to, wxMouseEvent& ev) {
|
void SymbolSelectEditor::onMouseDrag (const Vector2D& from, const Vector2D& to, wxMouseEvent& ev) {
|
||||||
if (control.selectedParts.empty()) return;
|
if (control.selected_parts.empty()) return;
|
||||||
if (!isEditing()) {
|
if (!isEditing()) {
|
||||||
// we don't have an action yet, determine what to do
|
// we don't have an action yet, determine what to do
|
||||||
// note: base it on the from position, which is the position where dragging started
|
// note: base it on the from position, which is the position where dragging started
|
||||||
@@ -270,22 +270,22 @@ void SymbolSelectEditor::onMouseDrag (const Vector2D& from, const Vector2D& to,
|
|||||||
if (rotate) {
|
if (rotate) {
|
||||||
if (scaleX == 0 || scaleY == 0) {
|
if (scaleX == 0 || scaleY == 0) {
|
||||||
// shear, center/fixed point on the opposite side
|
// shear, center/fixed point on the opposite side
|
||||||
shearAction = new SymbolPartShearAction(control.selectedParts, handlePos(-scaleX, -scaleY));
|
shearAction = new SymbolPartShearAction(control.selected_parts, handlePos(-scaleX, -scaleY));
|
||||||
getSymbol()->actions.add(shearAction);
|
getSymbol()->actions.add(shearAction);
|
||||||
} else {
|
} else {
|
||||||
// rotate
|
// rotate
|
||||||
rotateAction = new SymbolPartRotateAction(control.selectedParts, center);
|
rotateAction = new SymbolPartRotateAction(control.selected_parts, center);
|
||||||
getSymbol()->actions.add(rotateAction);
|
getSymbol()->actions.add(rotateAction);
|
||||||
startAngle = angleTo(to);
|
startAngle = angleTo(to);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// we are on a handle; start scaling
|
// we are on a handle; start scaling
|
||||||
scaleAction = new SymbolPartScaleAction(control.selectedParts, scaleX, scaleY);
|
scaleAction = new SymbolPartScaleAction(control.selected_parts, scaleX, scaleY);
|
||||||
getSymbol()->actions.add(scaleAction);
|
getSymbol()->actions.add(scaleAction);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// move
|
// move
|
||||||
moveAction = new SymbolPartMoveAction(control.selectedParts);
|
moveAction = new SymbolPartMoveAction(control.selected_parts);
|
||||||
getSymbol()->actions.add(moveAction);
|
getSymbol()->actions.add(moveAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,8 +345,8 @@ void SymbolSelectEditor::onKeyChange (wxKeyEvent& ev) {
|
|||||||
void SymbolSelectEditor::onChar(wxKeyEvent& ev) {
|
void SymbolSelectEditor::onChar(wxKeyEvent& ev) {
|
||||||
if (ev.GetKeyCode() == WXK_DELETE) {
|
if (ev.GetKeyCode() == WXK_DELETE) {
|
||||||
// delete selected parts
|
// delete selected parts
|
||||||
getSymbol()->actions.add(new RemoveSymbolPartsAction(*getSymbol(), control.selectedParts));
|
getSymbol()->actions.add(new RemoveSymbolPartsAction(*getSymbol(), control.selected_parts));
|
||||||
control.selectedParts.clear();
|
control.selected_parts.clear();
|
||||||
resetActions();
|
resetActions();
|
||||||
control.Refresh(false);
|
control.Refresh(false);
|
||||||
} else {
|
} else {
|
||||||
@@ -395,7 +395,7 @@ double SymbolSelectEditor::angleTo(const Vector2D& pos) {
|
|||||||
|
|
||||||
SymbolPartP SymbolSelectEditor::findPart(const Vector2D& pos) {
|
SymbolPartP SymbolSelectEditor::findPart(const Vector2D& pos) {
|
||||||
FOR_EACH(p, getSymbol()->parts) {
|
FOR_EACH(p, getSymbol()->parts) {
|
||||||
if (pointInPart(pos, *p)) return p;
|
if (point_in_part(pos, *p)) return p;
|
||||||
}
|
}
|
||||||
return SymbolPartP();
|
return SymbolPartP();
|
||||||
}
|
}
|
||||||
@@ -404,18 +404,18 @@ void SymbolSelectEditor::updateBoundingBox() {
|
|||||||
// Find min and max coordinates
|
// Find min and max coordinates
|
||||||
minV = Vector2D::infinity();
|
minV = Vector2D::infinity();
|
||||||
maxV = -Vector2D::infinity();
|
maxV = -Vector2D::infinity();
|
||||||
FOR_EACH(p, control.selectedParts) {
|
FOR_EACH(p, control.selected_parts) {
|
||||||
minV = piecewise_min(minV, p->minPos);
|
minV = piecewise_min(minV, p->min_pos);
|
||||||
maxV = piecewise_max(maxV, p->maxPos);
|
maxV = piecewise_max(maxV, p->max_pos);
|
||||||
}
|
}
|
||||||
// Find rotation center
|
// Find rotation center
|
||||||
center = Vector2D(0,0);
|
center = Vector2D(0,0);
|
||||||
FOR_EACH(p, control.selectedParts) {
|
FOR_EACH(p, control.selected_parts) {
|
||||||
Vector2D size = p->maxPos - p->minPos;
|
Vector2D size = p->max_pos - p->min_pos;
|
||||||
size = size.mul(p->rotationCenter);
|
size = size.mul(p->rotation_center);
|
||||||
center += p->minPos + size;
|
center += p->min_pos + size;
|
||||||
}
|
}
|
||||||
center /= control.selectedParts.size();
|
center /= control.selected_parts.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolSelectEditor::resetActions() {
|
void SymbolSelectEditor::resetActions() {
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class SymbolSelectEditor : public SymbolEditorBase {
|
|||||||
/// Find the first part at the given position
|
/// Find the first part at the given position
|
||||||
SymbolPartP findPart(const Vector2D& pos);
|
SymbolPartP findPart(const Vector2D& pos);
|
||||||
|
|
||||||
/// Update minV and maxV to be the bounding box of the selectedParts
|
/// Update minV and maxV to be the bounding box of the selected_parts
|
||||||
/// Updates center to be the rotation center of the parts
|
/// Updates center to be the rotation center of the parts
|
||||||
void updateBoundingBox();
|
void updateBoundingBox();
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolPart& part, HighlightStyle
|
|||||||
vector<wxPoint> points;
|
vector<wxPoint> points;
|
||||||
size_t size = part.points.size();
|
size_t size = part.points.size();
|
||||||
for(size_t i = 0 ; i < size ; ++i) {
|
for(size_t i = 0 ; i < size ; ++i) {
|
||||||
segmentSubdivide(*part.getPoint((int)i), *part.getPoint((int)i+1), rotation, points);
|
segment_subdivide(*part.getPoint((int)i), *part.getPoint((int)i+1), rotation, points);
|
||||||
}
|
}
|
||||||
// draw
|
// draw
|
||||||
if (style == HIGHLIGHT_BORDER) {
|
if (style == HIGHLIGHT_BORDER) {
|
||||||
@@ -165,7 +165,7 @@ void SymbolViewer::drawSymbolPart(const SymbolPart& part, DC* border, DC* interi
|
|||||||
vector<wxPoint> points;
|
vector<wxPoint> points;
|
||||||
size_t size = part.points.size();
|
size_t size = part.points.size();
|
||||||
for(size_t i = 0 ; i < size ; ++i) {
|
for(size_t i = 0 ; i < size ; ++i) {
|
||||||
segmentSubdivide(*part.getPoint((int)i), *part.getPoint((int)i+1), rotation, points);
|
segment_subdivide(*part.getPoint((int)i), *part.getPoint((int)i+1), rotation, points);
|
||||||
}
|
}
|
||||||
// draw border
|
// draw border
|
||||||
if (border) {
|
if (border) {
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ void SymbolWindow::onUpdateUI(wxUpdateUIEvent& ev) {
|
|||||||
void SymbolWindow::onSelectFromList(wxListEvent& ev) {
|
void SymbolWindow::onSelectFromList(wxListEvent& ev) {
|
||||||
if (inSelectionEvent) return ;
|
if (inSelectionEvent) return ;
|
||||||
inSelectionEvent = true;
|
inSelectionEvent = true;
|
||||||
parts->getSelectedParts(control->selectedParts);
|
parts->getselected_parts(control->selected_parts);
|
||||||
control->onUpdateSelection();
|
control->onUpdateSelection();
|
||||||
inSelectionEvent = false;
|
inSelectionEvent = false;
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ void SymbolWindow::onActivateFromList(wxListEvent& ev) {
|
|||||||
void SymbolWindow::onSelectFromControl() {
|
void SymbolWindow::onSelectFromControl() {
|
||||||
if (inSelectionEvent) return ;
|
if (inSelectionEvent) return ;
|
||||||
inSelectionEvent = true;
|
inSelectionEvent = true;
|
||||||
parts->selectParts(control->selectedParts);
|
parts->selectParts(control->selected_parts);
|
||||||
inSelectionEvent = false;
|
inSelectionEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ void clearDC(DC& dc, const wxBrush& brush) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Image related
|
// ----------------------------------------------------------------------------- : Image related
|
||||||
|
|
||||||
Image loadResourceImage(String name) {
|
Image load_resource_image(String name) {
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
// Load resource
|
// Load resource
|
||||||
// based on wxLoadUserResource
|
// based on wxLoadUserResource
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ void clearDC(DC& dc, const wxBrush& brush = *wxBLACK_BRUSH);
|
|||||||
// ----------------------------------------------------------------------------- : Resource related
|
// ----------------------------------------------------------------------------- : Resource related
|
||||||
|
|
||||||
/// Load an image from a resource
|
/// Load an image from a resource
|
||||||
Image loadResourceImage(String name);
|
Image load_resource_image(String name);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -161,7 +161,7 @@
|
|||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;UNICODE;_UNICODE;wxUSE_UNICODE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;UNICODE;_UNICODE;wxUSE_UNICODE"
|
||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="3"
|
||||||
BufferSecurityCheck="TRUE"
|
BufferSecurityCheck="TRUE"
|
||||||
RuntimeTypeInfo="TRUE"
|
RuntimeTypeInfo="TRUE"
|
||||||
UsePrecompiledHeader="2"
|
UsePrecompiledHeader="2"
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ class TokenIterator {
|
|||||||
private:
|
private:
|
||||||
String input;
|
String input;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
vector<Token> buffer; // buffer of unread tokens, front() = current
|
vector<Token> buffer; // buffer of unread tokens, front() = current
|
||||||
stack<bool> openBraces; // braces we entered, true if the brace was from a smart string escape
|
stack<bool> open_braces; // braces we entered, true if the brace was from a smart string escape
|
||||||
/// Read the next token, and add it to the buffer
|
/// Read the next token, and add it to the buffer
|
||||||
void addToken();
|
void addToken();
|
||||||
/// Read the next token which is a string (after the opening ")
|
/// Read the next token which is a string (after the opening ")
|
||||||
@@ -125,7 +125,7 @@ void TokenIterator::addToken() {
|
|||||||
// name
|
// name
|
||||||
size_t start = pos - 1;
|
size_t start = pos - 1;
|
||||||
while (pos < input.size() && isAlnum_(input.GetChar(pos))) ++pos;
|
while (pos < input.size() && isAlnum_(input.GetChar(pos))) ++pos;
|
||||||
Token t = {TOK_NAME, cannocialNameForm(input.substr(start, pos-start)) }; // convert name to cannocial form
|
Token t = {TOK_NAME, cannocial_name_form(input.substr(start, pos-start)) }; // convert name to cannocial form
|
||||||
buffer.push_back(t);
|
buffer.push_back(t);
|
||||||
} else if (isDigit(c)) {
|
} else if (isDigit(c)) {
|
||||||
// number
|
// number
|
||||||
@@ -151,21 +151,21 @@ void TokenIterator::addToken() {
|
|||||||
} else if (c==_('"')) {
|
} else if (c==_('"')) {
|
||||||
// string
|
// string
|
||||||
addStringToken();
|
addStringToken();
|
||||||
} else if (c == _('}') && !openBraces.empty() && openBraces.top()) {
|
} else if (c == _('}') && !open_braces.empty() && open_braces.top()) {
|
||||||
// closing smart string, resume to string parsing
|
// closing smart string, resume to string parsing
|
||||||
// "a{e}b" --> "a" "{ e }" "b"
|
// "a{e}b" --> "a" "{ e }" "b"
|
||||||
openBraces.pop();
|
open_braces.pop();
|
||||||
Token t2 = {TOK_RPAREN, _("}\"")};
|
Token t2 = {TOK_RPAREN, _("}\"")};
|
||||||
buffer.push_back(t2);
|
buffer.push_back(t2);
|
||||||
addStringToken();
|
addStringToken();
|
||||||
} else if (isLparen(c)) {
|
} else if (isLparen(c)) {
|
||||||
// paranthesis/brace
|
// paranthesis/brace
|
||||||
openBraces.push(false);
|
open_braces.push(false);
|
||||||
Token t = { TOK_LPAREN, String(1,c) };
|
Token t = { TOK_LPAREN, String(1,c) };
|
||||||
buffer.push_back(t);
|
buffer.push_back(t);
|
||||||
} else if (isRparen(c)) {
|
} else if (isRparen(c)) {
|
||||||
// paranthesis/brace
|
// paranthesis/brace
|
||||||
if (!openBraces.empty()) openBraces.pop();
|
if (!open_braces.empty()) open_braces.pop();
|
||||||
Token t = { TOK_RPAREN, String(1,c) };
|
Token t = { TOK_RPAREN, String(1,c) };
|
||||||
buffer.push_back(t);
|
buffer.push_back(t);
|
||||||
} else if(c==_('#')) {
|
} else if(c==_('#')) {
|
||||||
@@ -197,7 +197,7 @@ void TokenIterator::addStringToken() {
|
|||||||
// smart string
|
// smart string
|
||||||
// "a{e}b" --> "a" "{ e }" "b"
|
// "a{e}b" --> "a" "{ e }" "b"
|
||||||
buffer.push_back(t);
|
buffer.push_back(t);
|
||||||
openBraces.push(true);
|
open_braces.push(true);
|
||||||
Token t2 = {TOK_LPAREN, _("\"{")};
|
Token t2 = {TOK_LPAREN, _("\"{")};
|
||||||
buffer.push_back(t2);
|
buffer.push_back(t2);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+22
-22
@@ -16,77 +16,77 @@ DECLARE_TYPEOF_COLLECTION(Action*);
|
|||||||
DECLARE_TYPEOF_COLLECTION(ActionListener*);
|
DECLARE_TYPEOF_COLLECTION(ActionListener*);
|
||||||
|
|
||||||
ActionStack::ActionStack()
|
ActionStack::ActionStack()
|
||||||
: savePoint(nullptr)
|
: save_point(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ActionStack::~ActionStack() {
|
ActionStack::~ActionStack() {
|
||||||
// we own the actions, delete them
|
// we own the actions, delete them
|
||||||
FOR_EACH(a, undoActions) delete a;
|
FOR_EACH(a, undo_actions) delete a;
|
||||||
FOR_EACH(a, redoActions) delete a;
|
FOR_EACH(a, redo_actions) delete a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionStack::add(Action* action, bool allowMerge) {
|
void ActionStack::add(Action* action, bool allow_merge) {
|
||||||
if (!action) return; // no action
|
if (!action) return; // no action
|
||||||
action->perform(false); // TODO: delete action if perform throws
|
action->perform(false); // TODO: delete action if perform throws
|
||||||
redoActions.clear();
|
redo_actions.clear();
|
||||||
tellListeners(*action);
|
tellListeners(*action);
|
||||||
// try to merge?
|
// try to merge?
|
||||||
if (allowMerge && !undoActions.empty() && undoActions.back()->merge(action)) {
|
if (allow_merge && !undo_actions.empty() && undo_actions.back()->merge(action)) {
|
||||||
// merged with top undo action
|
// merged with top undo action
|
||||||
delete action;
|
delete action;
|
||||||
} else {
|
} else {
|
||||||
undoActions.push_back(action);
|
undo_actions.push_back(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionStack::undo() {
|
void ActionStack::undo() {
|
||||||
assert(canUndo());
|
assert(canUndo());
|
||||||
Action* action = undoActions.back();
|
Action* action = undo_actions.back();
|
||||||
action->perform(true);
|
action->perform(true);
|
||||||
// move to redo stack
|
// move to redo stack
|
||||||
undoActions.pop_back();
|
undo_actions.pop_back();
|
||||||
redoActions.push_back(action);
|
redo_actions.push_back(action);
|
||||||
}
|
}
|
||||||
void ActionStack::redo() {
|
void ActionStack::redo() {
|
||||||
assert(canRedo());
|
assert(canRedo());
|
||||||
Action* action = redoActions.back();
|
Action* action = redo_actions.back();
|
||||||
action->perform(false);
|
action->perform(false);
|
||||||
// move to undo stack
|
// move to undo stack
|
||||||
redoActions.pop_back();
|
redo_actions.pop_back();
|
||||||
undoActions.push_back(action);
|
undo_actions.push_back(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ActionStack::canUndo() const {
|
bool ActionStack::canUndo() const {
|
||||||
return !undoActions.empty();
|
return !undo_actions.empty();
|
||||||
}
|
}
|
||||||
bool ActionStack::canRedo() const {
|
bool ActionStack::canRedo() const {
|
||||||
return !redoActions.empty();
|
return !redo_actions.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
String ActionStack::undoName() const {
|
String ActionStack::undoName() const {
|
||||||
if (canUndo()) {
|
if (canUndo()) {
|
||||||
return _("Undo ") + capitalize(undoActions.back()->getName(true));
|
return _("Undo ") + capitalize(undo_actions.back()->getName(true));
|
||||||
} else {
|
} else {
|
||||||
return _("Undo");
|
return _("Undo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String ActionStack::redoName() const {
|
String ActionStack::redoName() const {
|
||||||
if (canRedo()) {
|
if (canRedo()) {
|
||||||
return _("Redo ") + capitalize(redoActions.back()->getName(false));
|
return _("Redo ") + capitalize(redo_actions.back()->getName(false));
|
||||||
} else {
|
} else {
|
||||||
return _("Redo");
|
return _("Redo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ActionStack::atSavePoint() const {
|
bool ActionStack::atSavePoint() const {
|
||||||
return (undoActions.empty() && savePoint == nullptr)
|
return (undo_actions.empty() && save_point == nullptr)
|
||||||
|| (undoActions.back() == savePoint);
|
|| (undo_actions.back() == save_point);
|
||||||
}
|
}
|
||||||
void ActionStack::setSavePoint() {
|
void ActionStack::setSavePoint() {
|
||||||
if (undoActions.empty()) {
|
if (undo_actions.empty()) {
|
||||||
savePoint = nullptr;
|
save_point = nullptr;
|
||||||
} else {
|
} else {
|
||||||
savePoint = undoActions.back();
|
save_point = undo_actions.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,17 +23,17 @@ class Action {
|
|||||||
virtual ~Action() {};
|
virtual ~Action() {};
|
||||||
|
|
||||||
/// Name of the action, for use in strings like "Undo <name>"
|
/// Name of the action, for use in strings like "Undo <name>"
|
||||||
virtual String getName(bool toUndo) const = 0;
|
virtual String getName(bool to_undo) const = 0;
|
||||||
|
|
||||||
/// Perform the action
|
/// Perform the action
|
||||||
/** @param toUndo if true, undo the action instead of doing it
|
/** @param to_undo if true, undo the action instead of doing it
|
||||||
*
|
*
|
||||||
* Must be implemented in derived class.
|
* Must be implemented in derived class.
|
||||||
*
|
*
|
||||||
* Perform will only ever be called alternatingly with toUndo = true/false,
|
* Perform will only ever be called alternatingly with to_undo = true/false,
|
||||||
* the first time with toUndo = false
|
* the first time with to_undo = false
|
||||||
*/
|
*/
|
||||||
virtual void perform(bool toUndo) = 0;
|
virtual void perform(bool to_undo) = 0;
|
||||||
|
|
||||||
/// Try to merge another action to the end of this action.
|
/// Try to merge another action to the end of this action.
|
||||||
/** Either: return false and do nothing
|
/** Either: return false and do nothing
|
||||||
@@ -103,12 +103,12 @@ class ActionStack {
|
|||||||
private:
|
private:
|
||||||
/// Actions to be undone
|
/// Actions to be undone
|
||||||
/// Owns the action objects!
|
/// Owns the action objects!
|
||||||
vector<Action*> undoActions;
|
vector<Action*> undo_actions;
|
||||||
/// Actions to be redone
|
/// Actions to be redone
|
||||||
/// Owns the action objects!
|
/// Owns the action objects!
|
||||||
vector<Action*> redoActions;
|
vector<Action*> redo_actions;
|
||||||
/// Point at which the file was saved, corresponds to the top of the undo stack at that point
|
/// Point at which the file was saved, corresponds to the top of the undo stack at that point
|
||||||
Action* savePoint;
|
Action* save_point;
|
||||||
/// Objects that are listening to actions
|
/// Objects that are listening to actions
|
||||||
vector<ActionListener*> listeners;
|
vector<ActionListener*> listeners;
|
||||||
};
|
};
|
||||||
|
|||||||
+23
-23
@@ -13,19 +13,19 @@
|
|||||||
// ----------------------------------------------------------------------------- : Reader
|
// ----------------------------------------------------------------------------- : Reader
|
||||||
|
|
||||||
Reader::Reader(const InputStreamP& input, String filename)
|
Reader::Reader(const InputStreamP& input, String filename)
|
||||||
: input(input), filename(filename), lineNumber(0)
|
: input(input), filename(filename), line_number(0)
|
||||||
, indent(0), expectedIndent(0), justOpened(false)
|
, indent(0), expected_indent(0), just_opened(false)
|
||||||
, stream(*input)
|
, stream(*input)
|
||||||
{
|
{
|
||||||
moveNext();
|
moveNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Reader::enterBlock(const Char* name) {
|
bool Reader::enterBlock(const Char* name) {
|
||||||
if (justOpened) moveNext(); // on the key of the parent block, first move inside it
|
if (just_opened) moveNext(); // on the key of the parent block, first move inside it
|
||||||
if (indent != expectedIndent) return false; // not enough indentation
|
if (indent != expected_indent) return false; // not enough indentation
|
||||||
if (name == key) {
|
if (name == key) {
|
||||||
justOpened = true;
|
just_opened = true;
|
||||||
expectedIndent += 1; // the indent inside the block must be at least this much
|
expected_indent += 1; // the indent inside the block must be at least this much
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -33,21 +33,21 @@ bool Reader::enterBlock(const Char* name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reader::exitBlock() {
|
void Reader::exitBlock() {
|
||||||
assert(expectedIndent > 0);
|
assert(expected_indent > 0);
|
||||||
expectedIndent -= 1;
|
expected_indent -= 1;
|
||||||
multiLineStr.clear();
|
multi_line_str.clear();
|
||||||
if (justOpened) moveNext(); // leave this key
|
if (just_opened) moveNext(); // leave this key
|
||||||
// Dump the remainder of the block
|
// Dump the remainder of the block
|
||||||
// TODO: issue warnings?
|
// TODO: issue warnings?
|
||||||
while (indent > expectedIndent) {
|
while (indent > expected_indent) {
|
||||||
moveNext();
|
moveNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reader::moveNext() {
|
void Reader::moveNext() {
|
||||||
justOpened = false;
|
just_opened = false;
|
||||||
key.clear();
|
key.clear();
|
||||||
multiLineStr.clear();
|
multi_line_str.clear();
|
||||||
indent = -1; // if no line is read it never has the expected indentation
|
indent = -1; // if no line is read it never has the expected indentation
|
||||||
// repeat until we have a good line
|
// repeat until we have a good line
|
||||||
while (key.empty() && !input->Eof()) {
|
while (key.empty() && !input->Eof()) {
|
||||||
@@ -55,7 +55,7 @@ void Reader::moveNext() {
|
|||||||
}
|
}
|
||||||
// did we reach the end of the file?
|
// did we reach the end of the file?
|
||||||
if (key.empty() && input->Eof()) {
|
if (key.empty() && input->Eof()) {
|
||||||
lineNumber += 1;
|
line_number += 1;
|
||||||
indent = -1;
|
indent = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,10 +70,10 @@ void Reader::readLine() {
|
|||||||
}
|
}
|
||||||
// read key / value
|
// read key / value
|
||||||
size_t pos = line.find_first_of(_(':'), indent);
|
size_t pos = line.find_first_of(_(':'), indent);
|
||||||
key = trim(line.substr(indent, pos - indent));
|
key = cannocial_name_form(trim(line.substr(indent, pos - indent)));
|
||||||
value = pos == String::npos ? _("") : trimLeft(line.substr(pos+1));
|
value = pos == String::npos ? _("") : trim_left(line.substr(pos+1));
|
||||||
// we read a line
|
// we read a line
|
||||||
lineNumber += 1;
|
line_number += 1;
|
||||||
// was it a comment?
|
// was it a comment?
|
||||||
if (!key.empty() && key.GetChar(0) == _('#')) {
|
if (!key.empty() && key.GetChar(0) == _('#')) {
|
||||||
key.clear();
|
key.clear();
|
||||||
@@ -83,25 +83,25 @@ void Reader::readLine() {
|
|||||||
// ----------------------------------------------------------------------------- : Handling basic types
|
// ----------------------------------------------------------------------------- : Handling basic types
|
||||||
|
|
||||||
template <> void Reader::handle(String& s) {
|
template <> void Reader::handle(String& s) {
|
||||||
if (!multiLineStr.empty()) {
|
if (!multi_line_str.empty()) {
|
||||||
s = multiLineStr;
|
s = multi_line_str;
|
||||||
} else if (value.empty()) {
|
} else if (value.empty()) {
|
||||||
// a multiline string
|
// a multiline string
|
||||||
bool first = true;
|
bool first = true;
|
||||||
// read all lines that are indented enough
|
// read all lines that are indented enough
|
||||||
readLine();
|
readLine();
|
||||||
while (indent >= expectedIndent) {
|
while (indent >= expected_indent) {
|
||||||
if (!first) value += '\n';
|
if (!first) value += '\n';
|
||||||
first = false;
|
first = false;
|
||||||
multiLineStr += line.substr(expectedIndent); // strip expected indent
|
multi_line_str += line.substr(expected_indent); // strip expected indent
|
||||||
readLine();
|
readLine();
|
||||||
}
|
}
|
||||||
// moveNext(), but without emptying multiLineStr
|
// moveNext(), but without emptying multiLineStr
|
||||||
justOpened = false;
|
just_opened = false;
|
||||||
while (key.empty() && !input->Eof()) {
|
while (key.empty() && !input->Eof()) {
|
||||||
readLine();
|
readLine();
|
||||||
}
|
}
|
||||||
s = multiLineStr;
|
s = multi_line_str;
|
||||||
} else {
|
} else {
|
||||||
s = value;
|
s = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,18 +64,18 @@ class Reader {
|
|||||||
/// The key and value of the last line we read
|
/// The key and value of the last line we read
|
||||||
String key, value;
|
String key, value;
|
||||||
/// A string spanning multiple lines
|
/// A string spanning multiple lines
|
||||||
String multiLineStr;
|
String multi_line_str;
|
||||||
/// Indentation of the last line we read
|
/// Indentation of the last line we read
|
||||||
int indent;
|
int indent;
|
||||||
/// Indentation of the block we are in
|
/// Indentation of the block we are in
|
||||||
int expectedIndent;
|
int expected_indent;
|
||||||
/// Did we just open a block (i.e. not read any more lines of it)?
|
/// Did we just open a block (i.e. not read any more lines of it)?
|
||||||
bool justOpened;
|
bool just_opened;
|
||||||
|
|
||||||
/// Filename for error messages
|
/// Filename for error messages
|
||||||
String filename;
|
String filename;
|
||||||
/// Line number for error messages
|
/// Line number for error messages
|
||||||
UInt lineNumber;
|
UInt line_number;
|
||||||
/// Input stream we are reading from
|
/// Input stream we are reading from
|
||||||
InputStreamP input;
|
InputStreamP input;
|
||||||
/// Text stream wrapping the input stream
|
/// Text stream wrapping the input stream
|
||||||
|
|||||||
+10
-8
@@ -16,7 +16,7 @@ Writer::Writer(const OutputStreamP& output)
|
|||||||
: output(output)
|
: output(output)
|
||||||
, stream(*output)
|
, stream(*output)
|
||||||
, indentation(0)
|
, indentation(0)
|
||||||
, justOpened(false)
|
, just_opened(false)
|
||||||
{
|
{
|
||||||
stream.WriteString(BYTE_ORDER_MARK);
|
stream.WriteString(BYTE_ORDER_MARK);
|
||||||
}
|
}
|
||||||
@@ -24,25 +24,27 @@ Writer::Writer(const OutputStreamP& output)
|
|||||||
|
|
||||||
void Writer::enterBlock(const Char* name) {
|
void Writer::enterBlock(const Char* name) {
|
||||||
// indenting into a sub-block?
|
// indenting into a sub-block?
|
||||||
if (justOpened) {
|
if (just_opened) {
|
||||||
writeKey();
|
writeKey();
|
||||||
stream.WriteString(_(":\n"));
|
stream.WriteString(_(":\n"));
|
||||||
}
|
}
|
||||||
// don't write the key yet
|
// don't write the key yet
|
||||||
indentation += 1;
|
indentation += 1;
|
||||||
openedKey = name;
|
opened_key = name;
|
||||||
justOpened = true;
|
just_opened = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::exitBlock() {
|
void Writer::exitBlock() {
|
||||||
assert(indentation > 0);
|
assert(indentation > 0);
|
||||||
indentation -= 1;
|
indentation -= 1;
|
||||||
justOpened = false;
|
just_opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::writeKey() {
|
void Writer::writeKey() {
|
||||||
writeIndentation();
|
writeIndentation();
|
||||||
writeUTF8(stream, openedKey);
|
// Use ' ' instead of '_' because it is more human readable
|
||||||
|
FOR_EACH(c, opened_key) if (c == _('_')) c = _(' ');
|
||||||
|
writeUTF8(stream, opened_key);
|
||||||
}
|
}
|
||||||
void Writer::writeIndentation() {
|
void Writer::writeIndentation() {
|
||||||
for(int i = 1 ; i < indentation ; ++i) {
|
for(int i = 1 ; i < indentation ; ++i) {
|
||||||
@@ -53,7 +55,7 @@ void Writer::writeIndentation() {
|
|||||||
// ----------------------------------------------------------------------------- : Handling basic types
|
// ----------------------------------------------------------------------------- : Handling basic types
|
||||||
|
|
||||||
void Writer::handle(const String& value) {
|
void Writer::handle(const String& value) {
|
||||||
if (!justOpened) {
|
if (!just_opened) {
|
||||||
throw InternalError(_("Can only write a value in a key that was just opened"));
|
throw InternalError(_("Can only write a value in a key that was just opened"));
|
||||||
}
|
}
|
||||||
// write indentation and key
|
// write indentation and key
|
||||||
@@ -86,7 +88,7 @@ void Writer::handle(const String& value) {
|
|||||||
writeUTF8(stream, value);
|
writeUTF8(stream, value);
|
||||||
}
|
}
|
||||||
stream.PutChar(_('\n'));
|
stream.PutChar(_('\n'));
|
||||||
justOpened = false;
|
just_opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> void Writer::handle(const int& value) {
|
template <> void Writer::handle(const int& value) {
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ class Writer {
|
|||||||
/// Indentation of the current block
|
/// Indentation of the current block
|
||||||
int indentation;
|
int indentation;
|
||||||
/// Did we just open a block (i.e. not written any lines of it)?
|
/// Did we just open a block (i.e. not written any lines of it)?
|
||||||
bool justOpened;
|
bool just_opened;
|
||||||
/// Last key opened
|
/// Last key opened
|
||||||
String openedKey;
|
String opened_key;
|
||||||
|
|
||||||
/// Output stream we are writing to
|
/// Output stream we are writing to
|
||||||
OutputStreamP output;
|
OutputStreamP output;
|
||||||
@@ -69,7 +69,7 @@ class Writer {
|
|||||||
/// Leave the block we are in
|
/// Leave the block we are in
|
||||||
void exitBlock();
|
void exitBlock();
|
||||||
|
|
||||||
/// Write the openedKey and the required indentation
|
/// Write the opened_key and the required indentation
|
||||||
void writeKey();
|
void writeKey();
|
||||||
/// Output some taps to represent the indentation level
|
/// Output some taps to represent the indentation level
|
||||||
void writeIndentation();
|
void writeIndentation();
|
||||||
|
|||||||
+20
-3
@@ -52,7 +52,7 @@ String trim(const String& s){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String trimLeft(const String& s) {
|
String trim_left(const String& s) {
|
||||||
size_t start = s.find_first_not_of(_(' '));
|
size_t start = s.find_first_not_of(_(' '));
|
||||||
if (start == String::npos) {
|
if (start == String::npos) {
|
||||||
return String();
|
return String();
|
||||||
@@ -63,7 +63,7 @@ String trimLeft(const String& s) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Words
|
// ----------------------------------------------------------------------------- : Words
|
||||||
|
|
||||||
String lastWord(const String& s) {
|
String last_word(const String& s) {
|
||||||
size_t endLastWord = s.find_last_not_of(_(' '));
|
size_t endLastWord = s.find_last_not_of(_(' '));
|
||||||
size_t startLastWord = s.find_last_of( _(' '), endLastWord);
|
size_t startLastWord = s.find_last_of( _(' '), endLastWord);
|
||||||
if (endLastWord == String::npos) {
|
if (endLastWord == String::npos) {
|
||||||
@@ -75,7 +75,7 @@ String lastWord(const String& s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String stripLastWord(const String& s) {
|
String strip_last_word(const String& s) {
|
||||||
size_t endLastWord = s.find_last_not_of(_(' '));
|
size_t endLastWord = s.find_last_not_of(_(' '));
|
||||||
size_t startLastWord = s.find_last_of(_(' '), endLastWord);
|
size_t startLastWord = s.find_last_of(_(' '), endLastWord);
|
||||||
if (endLastWord == String::npos || startLastWord == String::npos) {
|
if (endLastWord == String::npos || startLastWord == String::npos) {
|
||||||
@@ -116,3 +116,20 @@ String capitalize(const String& s) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String cannocial_name_form(const String& str) {
|
||||||
|
String ret;
|
||||||
|
ret.reserve(str.size());
|
||||||
|
bool leading = true;
|
||||||
|
FOR_EACH_CONST(c, str) {
|
||||||
|
if ((c == _('_') || c == _(' ')) && !leading) {
|
||||||
|
ret += _('_');
|
||||||
|
} else if (isAlnum(c)) {
|
||||||
|
ret += toLower(c);
|
||||||
|
leading = false;
|
||||||
|
} else {
|
||||||
|
// ignore non alpha numeric
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
+15
-13
@@ -52,9 +52,9 @@ typedef IF_UNICODE(wchar_t, char) Char;
|
|||||||
String decodeUTF8BOM(const String& s);
|
String decodeUTF8BOM(const String& s);
|
||||||
|
|
||||||
/// UTF8 Byte order mark for writing at the start of files
|
/// UTF8 Byte order mark for writing at the start of files
|
||||||
/** In non-unicode builds it is UTF8 encoded \xFEFF
|
/** In non-unicode builds it is UTF8 encoded \xFEFF.
|
||||||
* In unicode builds it is a normal \xFEFF
|
* In unicode builds it is a normal \xFEFF.
|
||||||
*/
|
*/
|
||||||
const Char BYTE_ORDER_MARK[] = IF_UNICODE(L"\xFEFF", "\xEF\xBB\xBF");
|
const Char BYTE_ORDER_MARK[] = IF_UNICODE(L"\xFEFF", "\xEF\xBB\xBF");
|
||||||
|
|
||||||
/// Writes a string to an output stream, encoded as UTF8
|
/// Writes a string to an output stream, encoded as UTF8
|
||||||
@@ -79,30 +79,32 @@ inline Char toLower(Char c) { return IF_UNICODE( towlower(c) , tolower(c) ); }
|
|||||||
String trim(const String&);
|
String trim(const String&);
|
||||||
|
|
||||||
/// Remove whitespace from the start of a string
|
/// Remove whitespace from the start of a string
|
||||||
String trimLeft(const String&);
|
String trim_left(const String&);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Words
|
// ----------------------------------------------------------------------------- : Words
|
||||||
|
|
||||||
/// Returns the last word in a string
|
/// Returns the last word in a string
|
||||||
String lastWord(const String&);
|
String last_word(const String&);
|
||||||
|
|
||||||
/// Remove the last word from a string, leaves whitespace before that word
|
/// Remove the last word from a string, leaves whitespace before that word
|
||||||
String stripLastWord(const String&);
|
String strip_last_word(const String&);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Caseing
|
// ----------------------------------------------------------------------------- : Caseing
|
||||||
|
|
||||||
/// Make each word in a string start with an upper case character.
|
/// Make each word in a string start with an upper case character.
|
||||||
/// for use in menus
|
/** for use in menus */
|
||||||
String capitalize(const String&);
|
String capitalize(const String&);
|
||||||
|
|
||||||
/// Make the first word in a string start with an upper case character.
|
/// Make the first word in a string start with an upper case character.
|
||||||
/// for use in dialogs
|
/** for use in dialogs */
|
||||||
String capitalizeSentence(const String&);
|
String capitalize_sentence(const String&);
|
||||||
|
|
||||||
/// Convert a field name to cannocial form: lower case and ' ' instead of '_'
|
/// Convert a field name to cannocial form
|
||||||
/// non alphanumeric characters are ignored
|
/** - lower case and '_' instead of ' '.
|
||||||
/// "camalCase" is converted to words "camel case"
|
* - non alphanumeric characters are droped
|
||||||
String cannocialNameForm(const String&);
|
* - "camalCase" is converted to words "camel case" (TODO)
|
||||||
|
*/
|
||||||
|
String cannocial_name_form(const String&);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#ifndef HEADER_UTIL_VERSION
|
||||||
|
#define HEADER_UTIL_VERSION
|
||||||
|
|
||||||
|
/** @file util/version.hpp
|
||||||
|
*
|
||||||
|
* @brief Utility functions related to version numbers.
|
||||||
|
* This header also stores the MSE version number.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <util/prec.hpp>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Version datatype
|
||||||
|
|
||||||
|
/// A version number
|
||||||
|
struct Version {
|
||||||
|
public:
|
||||||
|
Version() : version(0) {}
|
||||||
|
Version(UInt version) : version(version) {}
|
||||||
|
|
||||||
|
bool operator < (Version v) { return version < v.versionSuffix; }
|
||||||
|
|
||||||
|
/// Convert a version number to a string
|
||||||
|
String toString();
|
||||||
|
|
||||||
|
/// Convert a string to a version number
|
||||||
|
static Version fromString(UInt version);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UInt version; ///< Version number encoded as aabbcc, where a=major, b=minor, c=revision
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Versions
|
||||||
|
|
||||||
|
/// The verwsion number of MSE
|
||||||
|
const Version app_version = 000300; // 0.3.0
|
||||||
|
const Char* version_suffix = _(" (beta)");
|
||||||
|
|
||||||
|
/// File version, usually the same as program version,
|
||||||
|
/** When no files are changed the file version is not incremented
|
||||||
|
* Changes:
|
||||||
|
* 0.2.0 : start of version numbering practice
|
||||||
|
* 0.2.2 : _("include file")
|
||||||
|
* 0.2.6 : fix in settings loading
|
||||||
|
* 0.2.7 : new tag system, different style of close tags
|
||||||
|
* 0.3.0 : port of code to C++
|
||||||
|
*/
|
||||||
|
const Version file_version = 000300; // 0.3.0
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
#endif
|
||||||
@@ -214,7 +214,7 @@ COLLABORATION_GRAPH = NO
|
|||||||
GROUP_GRAPHS = YES
|
GROUP_GRAPHS = YES
|
||||||
UML_LOOK = NO
|
UML_LOOK = NO
|
||||||
TEMPLATE_RELATIONS = YES
|
TEMPLATE_RELATIONS = YES
|
||||||
INCLUDE_GRAPH = YES
|
INCLUDE_GRAPH = NO
|
||||||
INCLUDED_BY_GRAPH = YES
|
INCLUDED_BY_GRAPH = YES
|
||||||
CALL_GRAPH = NO
|
CALL_GRAPH = NO
|
||||||
CALLER_GRAPH = NO
|
CALLER_GRAPH = NO
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/** @page coding_conventions Coding conventions
|
||||||
|
|
||||||
|
MSE uses the following coding style:
|
||||||
|
@code
|
||||||
|
/// Doxygen documentation
|
||||||
|
class ClassName {
|
||||||
|
public:
|
||||||
|
void someMemberFunction();
|
||||||
|
private:
|
||||||
|
int some_member; ///< postfix doxygen documentation
|
||||||
|
};
|
||||||
|
|
||||||
|
void a_global_function();
|
||||||
|
|
||||||
|
enum MyEnumeration
|
||||||
|
{ MY_SOMETHING
|
||||||
|
, MY_SOMETHING_ELSE
|
||||||
|
};
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The rules are:
|
||||||
|
- Classes use CaptializationForEachWord
|
||||||
|
- Member functions use camelCase
|
||||||
|
- Data members and globals use lower_case_with_underscores
|
||||||
|
- Constants (enumeration values) and macros are UPPER_CASE_WITH_UNDERSCORES
|
||||||
|
|
||||||
|
The exceptions to this are:
|
||||||
|
- wxWidgets functions, which LookLikeThis
|
||||||
|
- wxWidget classes, which look like wxSomeClass
|
||||||
|
- C++ standard library and boost, lower_case for everything
|
||||||
|
- Person names, in particular deCasteljau
|
||||||
|
- Class names in function names, in particular clearDC
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
+25
-106
@@ -1,21 +1,35 @@
|
|||||||
/** \mainpage
|
/** @mainpage
|
||||||
|
|
||||||
This is the documentation of the Magic Set Editor (MSE) source code, automatically generated using doxygen.
|
This is the documentation of the Magic Set Editor (MSE) source code, automatically generated using doxygen.
|
||||||
|
|
||||||
<h2>Structure</h2>
|
Before starting with the source code, you should take a look at the following:
|
||||||
|
- \subpage structure "Structure of the MSE source code"
|
||||||
|
- \subpage dependencies "Libraries and dependencies"
|
||||||
|
- \subpage coding_conventions "Coding conventions"
|
||||||
|
- \subpage tricks "Tricks used by MSE"
|
||||||
|
|
||||||
|
|
||||||
|
@page structure Structure of the MSE source code
|
||||||
|
|
||||||
The MSE source code is subdivided into several directories, with the following meaning:
|
The MSE source code is subdivided into several directories, with the following meaning:
|
||||||
- util: Utility functions and classes, stuff that would work equally well in another project
|
- <tt>util</tt>: Utility functions and classes, stuff that would work equally well in another project
|
||||||
- gfx: Graphics related functions, again mostly independent of MSE.
|
- <tt>util/io</tt>: Classes related to input and output
|
||||||
This directory contains algorithms for image blending, scaling, and bezier curve functions.
|
- <tt>gfx</tt>: Graphics related functions, again mostly independent of MSE.
|
||||||
- data: Data structures, like sets, cards, symbols, etc.
|
This directory contains algorithms for image blending, scaling, and bezier curve functions.
|
||||||
These data structures are documented in the <a href="http://magicseteditor.sourceforge.net/extending">'Extending MSE'</a> section of the official documentation.
|
- <tt>data</tt>: Data structures, like sets, cards, symbols, etc.
|
||||||
- data/action: Actions that can be applied to those data structures.
|
These data structures are documented in the <a href="http://magicseteditor.sourceforge.net/extending">'Extending MSE'</a> section of the official documentation.
|
||||||
- gui: Graphical User Interface
|
- <tt>data/action</tt>: Actions that can be applied to those data structures.
|
||||||
- resource: Resource files used (icons, cursors, etc.)
|
- <tt>data/field</tt>: Data types for fields, values and styles. One source file per type.
|
||||||
|
- <tt>data/format</tt>: File formats and import/export stuff.
|
||||||
|
- <tt>script</tt>: The scripting system.
|
||||||
|
- <tt>gui</tt>: Graphical User Interface
|
||||||
|
- <tt>set</tt>: SetWindow related
|
||||||
|
- <tt>symbol</tt>: SymbolWindow related
|
||||||
|
- <tt>resource</tt>: Resource files used (icons, cursors, etc.)
|
||||||
|
|
||||||
|
See <a href="dirs.html">the directory list</a> for details.
|
||||||
|
|
||||||
<h2>Libraries/dependencies</h2>
|
@page dependencies Libraries and dependencies
|
||||||
|
|
||||||
MSE depends on the following libraries:
|
MSE depends on the following libraries:
|
||||||
- <a href="http://wxwidgets.org">wxWidgets</a> for the GUI.
|
- <a href="http://wxwidgets.org">wxWidgets</a> for the GUI.
|
||||||
@@ -25,99 +39,4 @@ Additional tools (not needed for building MSE) also depend on:
|
|||||||
- <a href="http://doxygen.org">doxygen</a> for generating the documentation.
|
- <a href="http://doxygen.org">doxygen</a> for generating the documentation.
|
||||||
- Perl for small utility scripts
|
- Perl for small utility scripts
|
||||||
|
|
||||||
|
|
||||||
<h2>Coding style</h2>
|
|
||||||
|
|
||||||
MSE uses the following coding style:
|
|
||||||
@code
|
|
||||||
class ClassName {
|
|
||||||
public:
|
|
||||||
void someFunction();
|
|
||||||
private:
|
|
||||||
int someMember;
|
|
||||||
};
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
The exception to this rule are wxWidgets functions, which LookLikeThis; and classes, which look like wxSomeClass.
|
|
||||||
As well as standard library functions.
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Macro and template tricks</h2>
|
|
||||||
|
|
||||||
The source code uses several macro/preprocessor and template tricks to make the code more readable.
|
|
||||||
|
|
||||||
<h3>Smart pointers</h3>
|
|
||||||
|
|
||||||
MSE makes extensive use of boost::shared_ptr. To make the code more readable there are typedefs for these pointer types, using a suffix P.
|
|
||||||
These are defined using a macro:
|
|
||||||
@code
|
|
||||||
DECLARE_POINTER_TYPE(MyClass);
|
|
||||||
MyClassP someObject; // the same as boost::shared_ptr<MyClass> someObject
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
To create new shared_ptrs the function new_shared# can be used (where # is the number of arguments):
|
|
||||||
@code
|
|
||||||
MyClassP someObject;
|
|
||||||
someObject = new_shared2<MyClass>(arg1, arg2);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Implemented in: util/smart_ptr.hpp
|
|
||||||
|
|
||||||
<h3>Iterating</h3>
|
|
||||||
|
|
||||||
To iterate over containers the FOR_EACH macro is used:
|
|
||||||
@code
|
|
||||||
vector<CardP> cards;
|
|
||||||
FOR_EACH(card, cards) {
|
|
||||||
doSomething(card);
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
Is equivalent to:
|
|
||||||
@code
|
|
||||||
vector<CardP> cards;
|
|
||||||
for(vector<CardP>::iterator it = cards.begin() ; it != cards.end() ; ++it) {
|
|
||||||
CardP& card = *it;
|
|
||||||
doSomething(card);
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
The iterators are completely hidden!
|
|
||||||
There are several veriations to this macro, for using const iterators (FOR_EACH_CONST), iterating in reverse (FOR_EACH_REVERSE),
|
|
||||||
for iterating over two collections in parallel (FOR_EACH_2), and for getting access to the iterator (FOR_EACH_IT).
|
|
||||||
|
|
||||||
Each of these macros require that the collection type has been declared using:
|
|
||||||
@code
|
|
||||||
DECLARE_COLLECTION_TYPE(CardP);
|
|
||||||
@endcode
|
|
||||||
This allows the calling of TYPEOF(cards) to evaluate to vector<CardP>.
|
|
||||||
|
|
||||||
Implemented in: util/for_each.hpp
|
|
||||||
|
|
||||||
<h3>Reflection</h3>
|
|
||||||
|
|
||||||
The io (input/output) system is based on reflection.
|
|
||||||
For a class to support reflection the following must be declared:
|
|
||||||
@code
|
|
||||||
class SomeClass {
|
|
||||||
int member1, member2;
|
|
||||||
DECLARE_REFLECTION();
|
|
||||||
};
|
|
||||||
@endcode
|
|
||||||
Then in a source file the members of the class have to be specified:
|
|
||||||
@code
|
|
||||||
IMPLEMENT_REFLECTION(SomeClass) {
|
|
||||||
REFLECT(member1);
|
|
||||||
REFLECT_N("another_name", member2);
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Simlairly for enumerations (a declaration is not necessary):
|
|
||||||
@code
|
|
||||||
IMPLEMENT_REFLECTION_ENUM(MyEnum) {
|
|
||||||
VALUE(value_of_enum_1); // the default value
|
|
||||||
VALUE(value_of_enum_2);
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Implemented in: util/reflect.hpp
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/** @page tricks Macro and template tricks
|
||||||
|
|
||||||
|
The source code uses several macro/preprocessor and template tricks to make the code more readable.
|
||||||
|
|
||||||
|
<h2>Smart pointers</h2>
|
||||||
|
|
||||||
|
MSE makes extensive use of boost::shared_ptr. To make the code more readable there are typedefs for these pointer types, using a suffix P.
|
||||||
|
These are defined using a macro:
|
||||||
|
@code
|
||||||
|
DECLARE_POINTER_TYPE(MyClass);
|
||||||
|
MyClassP someObject; // the same as boost::shared_ptr<MyClass> someObject
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
To create new shared_ptrs the function new_shared# can be used (where # is the number of arguments):
|
||||||
|
@code
|
||||||
|
MyClassP someObject;
|
||||||
|
someObject = new_shared2<MyClass>(arg1, arg2);
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Implemented in: util/smart_ptr.hpp
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Iterating</h2>
|
||||||
|
|
||||||
|
To iterate over containers the FOR_EACH macro is used:
|
||||||
|
@code
|
||||||
|
vector<CardP> cards;
|
||||||
|
FOR_EACH(card, cards) {
|
||||||
|
doSomething(card);
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
Is equivalent to:
|
||||||
|
@code
|
||||||
|
vector<CardP> cards;
|
||||||
|
for(vector<CardP>::iterator it = cards.begin() ; it != cards.end() ; ++it) {
|
||||||
|
CardP& card = *it;
|
||||||
|
doSomething(card);
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
The iterators are completely hidden!
|
||||||
|
There are several veriations to this macro, for using const iterators (FOR_EACH_CONST), iterating in reverse (FOR_EACH_REVERSE),
|
||||||
|
for iterating over two collections in parallel (FOR_EACH_2), and for getting access to the iterator (FOR_EACH_IT).
|
||||||
|
|
||||||
|
Each of these macros require that the collection type has been declared using:
|
||||||
|
@code
|
||||||
|
DECLARE_COLLECTION_TYPE(CardP);
|
||||||
|
@endcode
|
||||||
|
This allows the calling of TYPEOF(cards) to evaluate to vector<CardP>.
|
||||||
|
|
||||||
|
Implemented in: util/for_each.hpp
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Reflection</h2>
|
||||||
|
|
||||||
|
The io (input/output) system is based on reflection.
|
||||||
|
For a class to support reflection the following must be declared:
|
||||||
|
@code
|
||||||
|
class SomeClass {
|
||||||
|
int member1, member2;
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
@endcode
|
||||||
|
Then in a source file the members of the class have to be specified:
|
||||||
|
@code
|
||||||
|
IMPLEMENT_REFLECTION(SomeClass) {
|
||||||
|
REFLECT(member1);
|
||||||
|
REFLECT_N("another_name", member2);
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Simlairly for enumerations (a declaration is not necessary):
|
||||||
|
@code
|
||||||
|
IMPLEMENT_REFLECTION_ENUM(MyEnum) {
|
||||||
|
VALUE_N("value1", MY_VALUE1); // the first is the default value
|
||||||
|
VALUE_N("value2", MY_VALUE2);
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Reflection is used by the following classes:
|
||||||
|
- Reader
|
||||||
|
- Writer
|
||||||
|
- GetMember
|
||||||
|
|
||||||
|
Implemented in: util/reflect.hpp
|
||||||
|
|
||||||
|
*/
|
||||||
Reference in New Issue
Block a user