Changed all resources to .png files;

Added 'snap to grid' to symbol editor

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@207 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2007-02-16 00:07:14 +00:00
parent 4e88ff8cf0
commit 0c66191ab3
101 changed files with 317 additions and 126 deletions
+29 -7
View File
@@ -18,8 +18,16 @@ DECLARE_TYPEOF_COLLECTION(ControlPointP);
SymbolPartMoveAction::SymbolPartMoveAction(const set<SymbolPartP>& parts)
: parts(parts)
, min_pos(Vector2D::infinity()), max_pos(-Vector2D::infinity())
, constrain(false)
{}
, snap(0)
{
// Determine min/max_pos
FOR_EACH(p,parts) {
min_pos = piecewise_min(min_pos, p->min_pos);
max_pos = piecewise_max(max_pos, p->max_pos);
}
}
String SymbolPartMoveAction::getName(bool to_undo) const {
return parts.size() == 1 ? _("Move shape") : _("Move shapes");
@@ -39,9 +47,10 @@ void SymbolPartMoveAction::perform(bool to_undo) {
void SymbolPartMoveAction::move(const Vector2D& deltaDelta) {
delta += deltaDelta;
// Move each point by deltaDelta, possibly constrained
Vector2D d = constrainVector(delta, constrain);
// Determine actual delta, possibly constrained and snapped
Vector2D d = constrain_snap_vector_offset(min_pos, max_pos, delta, constrain, snap);
Vector2D dd = d - moved;
// Move each point by d
FOR_EACH(p, parts) {
p->min_pos += dd;
p->max_pos += dd;
@@ -114,7 +123,8 @@ void SymbolPartRotateAction::rotateBy(double deltaAngle) {
SymbolPartShearAction::SymbolPartShearAction(const set<SymbolPartP>& parts, const Vector2D& center)
: SymbolPartMatrixAction(parts, center)
, constrain(false)
// , constrain(false)
, snap(0)
{}
String SymbolPartShearAction::getName(bool to_undo) const {
@@ -130,12 +140,14 @@ void SymbolPartShearAction::perform(bool to_undo) {
// <1 -x> /
// <-y 1> / (1 - xy)
// we have: xy = 0 => (1 - xy) = 1
shearBy(-shear);
shearBy(-moved);
}
void SymbolPartShearAction::move(const Vector2D& deltaShear) {
shear += deltaShear;
shearBy(deltaShear);
Vector2D d = snap_vector(shear - moved, snap);
shearBy(d);
moved += d;
}
void SymbolPartShearAction::shearBy(const Vector2D& shear) {
@@ -154,6 +166,7 @@ SymbolPartScaleAction::SymbolPartScaleAction(const set<SymbolPartP>& parts, int
: parts(parts)
, scaleX(scaleX), scaleY(scaleY)
, constrain(false)
, snap(0)
{
// Find min and max coordinates
oldMin = Vector2D::infinity();
@@ -191,10 +204,19 @@ void SymbolPartScaleAction::update() {
// the size after the move
newMin = newRealMin; newSize = newRealSize;
if (constrain && scaleX != 0 && scaleY != 0) {
// TODO : snapping
Vector2D scale = newSize.div(tmpSize);
scale = constrainVector(scale, true, true);
scale = constrain_vector(scale, true, true);
newSize = tmpSize.mul(scale);
newMin += (newRealSize - newSize).mul(Vector2D(scaleX == -1 ? 1 : 0, scaleY == -1 ? 1 : 0));
} else if (snap >= 0) {
if (scaleX + scaleY < 0) {
newMin = snap_vector(newMin, snap);
newSize += newRealMin - newMin;
} else {
Vector2D newMax = snap_vector(newMin + newSize, snap);
newSize = newMax - newMin;
}
}
// now move all points
transformAll();
+7 -2
View File
@@ -43,8 +43,10 @@ class SymbolPartMoveAction : public SymbolPartAction {
set<SymbolPartP> parts; ///< Parts to move
Vector2D delta; ///< How much to move
Vector2D moved; ///< How much has been moved
Vector2D min_pos, max_pos; ///< Bounding box of the thing we are moving
public:
bool constrain; ///< Constrain movement?
int snap; ///< Snap to grid?
};
// ----------------------------------------------------------------------------- : Rotating symbol parts
@@ -101,9 +103,11 @@ class SymbolPartShearAction : public SymbolPartMatrixAction {
private:
Vector2D shear; ///< Shearing, shear.x == 0 || shear.y == 0
Vector2D moved;
void shearBy(const Vector2D& shear);
public:
bool constrain; ///< Constrain movement?
// bool constrain; ///< Constrain movement?
int snap; ///< Snap to grid?
};
@@ -135,7 +139,8 @@ class SymbolPartScaleAction : public SymbolPartAction {
return (v - oldMin).div(oldSize).mul(newSize) + newMin;
}
public:
bool constrain; ///< Constrain movement?
bool constrain; ///< Constrain movement?
int snap; ///< Snap to grid?
};
// ----------------------------------------------------------------------------- : Change combine mode
+57 -13
View File
@@ -16,12 +16,12 @@ DECLARE_TYPEOF_COLLECTION(ControlPointP);
inline double sgn(double v) { return v > 0 ? 1 : -1; }
Vector2D constrainVector(const Vector2D& v, bool constrain, bool onlyDiagonal) {
Vector2D constrain_vector(const Vector2D& v, bool constrain, bool only_diagonal) {
if (!constrain) return v;
double ax = fabs(v.x), ay = fabs(v.y);
if (ax * 2 < ay && !onlyDiagonal) {
if (ax * 2 < ay && !only_diagonal) {
return Vector2D(0, v.y); // vertical
} else if(ay * 2 < ax && !onlyDiagonal) {
} else if(ay * 2 < ax && !only_diagonal) {
return Vector2D(v.x, 0); // horizontal
} else {
return Vector2D( // diagonal
@@ -31,11 +31,62 @@ Vector2D constrainVector(const Vector2D& v, bool constrain, bool onlyDiagonal) {
}
}
inline double snap(double x, int steps) {
return steps <= 0 ? x : floor(x * steps + 0.5) / steps;
}
Vector2D snap_vector(const Vector2D& v, int steps) {
return Vector2D(snap(v.x, steps), snap(v.y, steps));
}
Vector2D constrain_snap_vector(const Vector2D& v, const Vector2D& d, bool constrain, int steps) {
if (!constrain) return snap_vector(v+d, steps);
double ax = fabs(d.x), ay = fabs(d.y);
if (ax * 2 < ay) {
return Vector2D(v.x, snap(d.y + v.y, steps)); // vertical
} else if(ay * 2 < ax) {
return Vector2D(snap(d.x + v.x, steps), v.y); // horizontal
} else {
double dc = (ax + ay) / 2; // delta in both directions
double dxs = snap(v.x + dc, steps) - v.x; // snapped to x
double dys = snap(v.y + dc, steps) - v.y; // snapped to y
if (fabs(dxs-dc) < fabs(dys-dc)) {
// take the one that is closest to the unsnaped delta
return Vector2D(v.x + sgn(d.x) * dxs, v.y + sgn(d.y) * dxs);
} else {
return Vector2D(v.x + sgn(d.x) * dys, v.y + sgn(d.y) * dys);
}
}
}
Vector2D constrain_snap_vector_offset(const Vector2D& off1, const Vector2D& d, bool constrain, int steps) {
return constrain_snap_vector(off1, d, constrain, steps) - off1;
}
// calculate constrained delta for the given offset, store in output if it is better
void constrain_snap_vector_offset_(const Vector2D& off, const Vector2D& d, bool constrain, int steps, Vector2D& best, double& best_length) {
Vector2D d2 = constrain_snap_vector_offset(off, d, constrain, steps);
double l2 = d2.lengthSqr();
if (l2 < best_length) {
best_length = l2;
best = d2;
}
}
Vector2D constrain_snap_vector_offset(const Vector2D& off1, const Vector2D& off2, const Vector2D& d, bool constrain, int steps) {
Vector2D dd; double l = numeric_limits<double>::infinity();
constrain_snap_vector_offset_(off1, d, constrain, steps, dd, l);
constrain_snap_vector_offset_(off2, d, constrain, steps, dd, l);
constrain_snap_vector_offset_(Vector2D(off1.x,off2.y), d, constrain, steps, dd, l);
constrain_snap_vector_offset_(Vector2D(off2.x,off1.y), d, constrain, steps, dd, l);
return dd;
}
// ----------------------------------------------------------------------------- : Move control point
ControlPointMoveAction::ControlPointMoveAction(const set<ControlPointP>& points)
: points(points)
, constrain(false)
, snap(0)
{
oldValues.reserve(points.size());
FOR_EACH(p, points) {
@@ -48,13 +99,6 @@ String ControlPointMoveAction::getName(bool to_undo) const {
}
void ControlPointMoveAction::perform(bool to_undo) {
/*
set<ControlPointP>::const_iterator it = points.begin();
vector<Vector2D> ::iterator it2 = oldValues.begin();
for( ; it != points.end() && it2 != oldValues.end() ; ++it, ++it2) {
swap<Vector2D>((*it)->pos, *it2);
}
*/
FOR_EACH_2(p,points, op,oldValues) {
swap(p->pos, op);
}
@@ -63,11 +107,10 @@ void ControlPointMoveAction::perform(bool to_undo) {
void ControlPointMoveAction::move (const Vector2D& deltaDelta) {
delta += deltaDelta;
// Move each point by delta, possibly constrained
Vector2D d = constrainVector(delta, constrain);
set<ControlPointP>::const_iterator it = points.begin();
vector<Vector2D> ::iterator it2 = oldValues.begin();
for( ; it != points.end() && it2 != oldValues.end() ; ++it, ++it2) {
(*it)->pos = (*it2) + d;
(*it)->pos = constrain_snap_vector(*it2, delta, constrain, snap);
}
}
@@ -79,6 +122,7 @@ HandleMoveAction::HandleMoveAction(const SelectedHandle& handle)
, old_handle(handle.getHandle())
, old_other (handle.getOther())
, constrain(false)
, snap(0)
{}
String HandleMoveAction::getName(bool to_undo) const {
@@ -92,7 +136,7 @@ void HandleMoveAction::perform(bool to_undo) {
void HandleMoveAction::move(const Vector2D& deltaDelta) {
delta += deltaDelta;
handle.getHandle() = constrainVector(old_handle + delta, constrain);
handle.getHandle() = constrain_snap_vector_offset(handle.point->pos, old_handle + delta, constrain, snap);
handle.getOther() = old_other;
handle.onUpdateHandle();
}
+21 -3
View File
@@ -20,9 +20,25 @@
// ----------------------------------------------------------------------------- : Utility
/// Constrain a vector to be horizontal, vertical or diagonal
/// If constraint==false does nothing
Vector2D constrainVector(const Vector2D& v, bool constrain = true, bool onlyDiagonal = false);
/// Constrain a vector to be horizontal, vertical or diagonal.
/** If constraint==false does nothing
*/
Vector2D constrain_vector(const Vector2D& v, bool constrain = true, bool only_diagonal = false);
/// Snap a vector to the grid with the given number of steps per unit interval.
/** If spacing==0 does not snap. */
Vector2D snap_vector(const Vector2D& v, int steps);
/// Add a delta to a vector
/** Possibly constrain the delta, and snap to result to grid
*/
Vector2D constrain_snap_vector(const Vector2D& v, const Vector2D& d, bool constrain, int steps);
/// Constrain a vector a vector, and snap to an offset grid
Vector2D constrain_snap_vector_offset(const Vector2D& off1, const Vector2D& d, bool constrain, int steps);
/// Constrain a vector a vector, and snap to two possible offset grids
/** Takes the closest snap */
Vector2D constrain_snap_vector_offset(const Vector2D& off1, const Vector2D& off2, const Vector2D& d, bool constrain, int steps);
// ----------------------------------------------------------------------------- : Move control point
@@ -43,6 +59,7 @@ class ControlPointMoveAction : public Action {
Vector2D delta; ///< Amount we moved
public:
bool constrain; ///< Constrain movement?
int snap; ///< Snap to grid?
};
// ----------------------------------------------------------------------------- : Move handle
@@ -65,6 +82,7 @@ class HandleMoveAction : public Action {
Vector2D delta; ///< Amount we moved
public:
bool constrain; ///< Constrain movement?
int snap; ///< Snap to grid?
};
// ----------------------------------------------------------------------------- : Segment mode
+5 -1
View File
@@ -220,6 +220,10 @@ SymbolP import_symbol(Image& img) {
if (is_mse1_symbol(img)) {
Image img2 = img.GetSubImage(wxRect(20,0,40,40));
symbol = image_to_symbol(img2);
} else if (img.GetWidth() > 100 || img.GetHeight() > 100) {
// 100x100 ought to be enough, we trow out most afterwards data anyway
Image resampled = img.Rescale(100,100);
symbol = image_to_symbol(resampled);
} else {
symbol = image_to_symbol(img);
}
@@ -387,7 +391,7 @@ void remove_point(SymbolPart& part, int i);
* stop when the cost becomes too high
*/
void remove_points(SymbolPart& part) {
const double treshold = 0.002; // maximum cost
const double treshold = 0.0002; // maximum cost
while (true) {
// Find the point with the lowest cost of removal
int best = -1;
+6
View File
@@ -88,6 +88,9 @@ Settings::Settings()
, set_window_width (790)
, set_window_height (300)
, card_notes_height (40)
, symbol_grid_size (30)
, symbol_grid (true)
, symbol_grid_snap (false)
, updates_url (_("http://magicseteditor.sourceforge.net/updates"))
, check_updates (CHECK_IF_CONNECTED)
, website_url (_("http://magicseteditor.sourceforge.net/"))
@@ -155,6 +158,9 @@ IMPLEMENT_REFLECTION(Settings) {
REFLECT(set_window_width);
REFLECT(set_window_height);
REFLECT(card_notes_height);
REFLECT(symbol_grid_size);
REFLECT(symbol_grid);
REFLECT(symbol_grid_snap);
REFLECT(default_game);
REFLECT(apprentice_location);
REFLECT(updates_url);
+5
View File
@@ -100,6 +100,11 @@ class Settings {
UInt set_window_height;
UInt card_notes_height;
// --------------------------------------------------- : Symbol editor
UInt symbol_grid_size;
bool symbol_grid;
bool symbol_grid_snap;
// --------------------------------------------------- : Default pacakge selections
String default_game;