Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
magicseteditor
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
magicseteditor
Commits
a56a8454
Commit
a56a8454
authored
Jul 08, 2007
by
twanvl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New symbol part list control that shows previews and has a built in editor
parent
767efcdb
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
838 additions
and
325 deletions
+838
-325
src/data/action/symbol.cpp
src/data/action/symbol.cpp
+118
-70
src/data/action/symbol.hpp
src/data/action/symbol.hpp
+30
-17
src/data/action/symbol_part.cpp
src/data/action/symbol_part.cpp
+2
-2
src/data/format/image_to_symbol.cpp
src/data/format/image_to_symbol.cpp
+6
-6
src/data/symbol.cpp
src/data/symbol.cpp
+18
-0
src/data/symbol.hpp
src/data/symbol.hpp
+13
-8
src/gfx/bezier.cpp
src/gfx/bezier.cpp
+1
-1
src/gui/symbol/basic_shape_editor.cpp
src/gui/symbol/basic_shape_editor.cpp
+10
-3
src/gui/symbol/basic_shape_editor.hpp
src/gui/symbol/basic_shape_editor.hpp
+1
-1
src/gui/symbol/control.cpp
src/gui/symbol/control.cpp
+6
-6
src/gui/symbol/control.hpp
src/gui/symbol/control.hpp
+2
-1
src/gui/symbol/part_list.cpp
src/gui/symbol/part_list.cpp
+401
-93
src/gui/symbol/part_list.hpp
src/gui/symbol/part_list.hpp
+58
-39
src/gui/symbol/select_editor.cpp
src/gui/symbol/select_editor.cpp
+53
-35
src/gui/symbol/window.cpp
src/gui/symbol/window.cpp
+13
-10
src/gui/symbol/window.hpp
src/gui/symbol/window.hpp
+3
-2
src/main.cpp
src/main.cpp
+4
-0
src/render/symbol/filter.cpp
src/render/symbol/filter.cpp
+23
-0
src/render/symbol/filter.hpp
src/render/symbol/filter.hpp
+6
-5
src/render/symbol/viewer.cpp
src/render/symbol/viewer.cpp
+14
-6
src/render/symbol/viewer.hpp
src/render/symbol/viewer.hpp
+5
-3
src/resource/msw/mse.rc
src/resource/msw/mse.rc
+14
-0
src/resource/msw/tool/group.png
src/resource/msw/tool/group.png
+0
-0
src/resource/msw/tool/mode_symmetry.png
src/resource/msw/tool/mode_symmetry.png
+0
-0
src/resource/msw/tool/ungroup.png
src/resource/msw/tool/ungroup.png
+0
-0
src/util/real_point.hpp
src/util/real_point.hpp
+8
-1
src/util/vector2d.hpp
src/util/vector2d.hpp
+28
-16
src/util/window_id.hpp
src/util/window_id.hpp
+1
-0
No files found.
src/data/action/symbol.cpp
View file @
a56a8454
This diff is collapsed.
Click to expand it.
src/data/action/symbol.hpp
View file @
a56a8454
...
...
@@ -20,16 +20,24 @@
// ----------------------------------------------------------------------------- : Transform symbol part
/// Anything that changes
a part
/// Anything that changes
one or more parts
class
SymbolPartAction
:
public
Action
{};
/// Anything that changes a set of parts
class
SymbolPartsAction
:
public
SymbolPartAction
{
public:
SymbolPartsAction
(
const
set
<
SymbolPartP
>&
parts
);
const
set
<
SymbolPartP
>
parts
;
///< Affected parts
};
/// Anything that changes a part as displayed in the part list
class
SymbolPartListAction
:
public
SymbolPartAction
{};
// ----------------------------------------------------------------------------- : Moving symbol parts
/// Move some symbol parts
class
SymbolPartMoveAction
:
public
SymbolPartAction
{
class
SymbolPartMoveAction
:
public
SymbolPart
s
Action
{
public:
SymbolPartMoveAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
delta
=
Vector2D
());
...
...
@@ -40,10 +48,11 @@ class SymbolPartMoveAction : public SymbolPartAction {
void
move
(
const
Vector2D
&
delta
);
private:
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
void
movePart
(
SymbolPart
&
part
);
///< Move a single part
public:
bool
constrain
;
///< Constrain movement?
int
snap
;
///< Snap to grid?
...
...
@@ -52,7 +61,7 @@ class SymbolPartMoveAction : public SymbolPartAction {
// ----------------------------------------------------------------------------- : Rotating symbol parts
/// Transforming symbol parts using a matrix
class
SymbolPartMatrixAction
:
public
SymbolPartAction
{
class
SymbolPartMatrixAction
:
public
SymbolPart
s
Action
{
public:
SymbolPartMatrixAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
center
);
...
...
@@ -61,10 +70,10 @@ class SymbolPartMatrixAction : public SymbolPartAction {
protected:
/// Perform the transformation using the given matrix
void
transform
(
const
Vector2D
&
mx
,
const
Vector2D
&
my
);
void
transform
(
const
Matrix2D
&
m
);
void
transform
(
SymbolPart
&
part
,
const
Matrix2D
&
m
);
set
<
SymbolPartP
>
parts
;
///< Parts to transform
Vector2D
center
;
///< Center to transform around
Vector2D
center
;
///< Center to transform around
};
/// Rotate some symbol parts
...
...
@@ -114,7 +123,7 @@ class SymbolPartShearAction : public SymbolPartMatrixAction {
// ----------------------------------------------------------------------------- : Scaling symbol parts
/// Scale some symbol parts
class
SymbolPartScaleAction
:
public
SymbolPartAction
{
class
SymbolPartScaleAction
:
public
SymbolPart
s
Action
{
public:
SymbolPartScaleAction
(
const
set
<
SymbolPartP
>&
parts
,
int
scaleX
,
int
scaleY
);
...
...
@@ -127,13 +136,13 @@ class SymbolPartScaleAction : public SymbolPartAction {
void
update
();
private:
set
<
SymbolPartP
>
parts
;
///< Parts to scale
Vector2D
old_min
,
old_size
;
///< the original pos/size
Vector2D
new_real_min
,
new_real_size
;
///< the target pos/sizevoid shearBy(const Vector2D& shear)
Vector2D
new_min
,
new_size
;
///< the target pos/size after applying constrains
int
scaleX
,
scaleY
;
///< to what corner are we attached?
/// Transform everything in the parts
void
transformAll
();
void
transformPart
(
SymbolPart
&
);
/// Transform a single vector
inline
Vector2D
transform
(
const
Vector2D
&
v
);
public:
...
...
@@ -144,7 +153,7 @@ class SymbolPartScaleAction : public SymbolPartAction {
// ----------------------------------------------------------------------------- : Change combine mode
/// Change the name of a symbol part
class
CombiningModeAction
:
public
SymbolPart
List
Action
{
class
CombiningModeAction
:
public
SymbolPart
s
Action
{
public:
// All parts must be SymbolParts
CombiningModeAction
(
const
set
<
SymbolPartP
>&
parts
,
SymbolShapeCombine
mode
);
...
...
@@ -153,22 +162,26 @@ class CombiningModeAction : public SymbolPartListAction {
virtual
void
perform
(
bool
to_undo
);
private:
void
add
(
const
SymbolPartP
&
,
SymbolShapeCombine
mode
);
vector
<
pair
<
SymbolShapeP
,
SymbolShapeCombine
>
>
parts
;
///< Affected parts with new combining modes
};
// ----------------------------------------------------------------------------- : Change name
/// Change the name of a symbol part
class
SymbolPartNameAction
:
public
SymbolPart
List
Action
{
class
SymbolPartNameAction
:
public
SymbolPartAction
{
public:
SymbolPartNameAction
(
const
SymbolPartP
&
part
,
const
String
&
name
);
SymbolPartNameAction
(
const
SymbolPartP
&
part
,
const
String
&
name
,
size_t
old_cursor
,
size_t
new_cursor
);
virtual
String
getName
(
bool
to_undo
)
const
;
virtual
void
perform
(
bool
to_undo
);
virtual
bool
merge
(
const
Action
&
action
);
p
rivate
:
p
ublic
:
SymbolPartP
part
;
///< Affected part
String
part_name
;
///< New name
size_t
old_cursor
;
///< Cursor position
size_t
new_cursor
;
///< Cursor position
};
// ----------------------------------------------------------------------------- : Add symbol part
...
...
@@ -224,18 +237,18 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction {
// ----------------------------------------------------------------------------- : Reorder symbol parts
/// Change the position of a part in a symbol, by
swapping two parts
.
/// Change the position of a part in a symbol, by
moving a part
.
class
ReorderSymbolPartsAction
:
public
SymbolPartListAction
{
public:
ReorderSymbolPartsAction
(
Symbol
&
symbol
,
size_t
part_id1
,
size_t
part_id2
);
ReorderSymbolPartsAction
(
Symbol
&
symbol
,
size_t
old_position
,
size_t
new_position
);
virtual
String
getName
(
bool
to_undo
)
const
;
virtual
void
perform
(
bool
to_undo
);
private:
Symbol
&
symbol
;
///< Symbol to swap the parts in
Symbol
&
symbol
;
///< Symbol to swap the parts in
public:
size_t
part_id1
,
part_id2
;
///< Indices of parts to swap
size_t
old_position
,
new_position
;
///< Positions to move from and to
};
...
...
src/data/action/symbol_part.cpp
View file @
a56a8454
...
...
@@ -349,8 +349,8 @@ SinglePointRemoveAction::SinglePointRemoveAction(const SymbolShapeP& shape, UInt
Vector2D
p
=
c
.
pointAt
(
t
);
Vector2D
distP
=
point
->
pos
-
p
;
// adjust handle sizes
point1
.
other
.
delta_after
*=
ssqrt
(
d
istP
.
dot
(
point1
.
other
.
delta_after
)
/
point1
.
other
.
delta_after
.
lengthSqr
())
+
1
;
point2
.
other
.
delta_before
*=
ssqrt
(
d
istP
.
dot
(
point2
.
other
.
delta_before
)
/
point2
.
other
.
delta_before
.
lengthSqr
())
+
1
;
point1
.
other
.
delta_after
*=
ssqrt
(
d
ot
(
distP
,
point1
.
other
.
delta_after
)
/
point1
.
other
.
delta_after
.
lengthSqr
())
+
1
;
point2
.
other
.
delta_before
*=
ssqrt
(
d
ot
(
distP
,
point2
.
other
.
delta_before
)
/
point2
.
other
.
delta_before
.
lengthSqr
())
+
1
;
// unlock if needed
if
(
point1
.
other
.
lock
==
LOCK_SIZE
)
point1
.
other
.
lock
=
LOCK_DIR
;
...
...
src/data/format/image_to_symbol.cpp
View file @
a56a8454
...
...
@@ -245,7 +245,7 @@ void mark_corners(SymbolShape& shape) {
Vector2D
after
=
.6
*
shape
.
getPoint
(
i
+
1
)
->
pos
+
.2
*
shape
.
getPoint
(
i
+
2
)
->
pos
+
.1
*
shape
.
getPoint
(
i
+
3
)
->
pos
+
.1
*
shape
.
getPoint
(
i
+
4
)
->
pos
;
before
=
(
before
-
current
.
pos
).
normalized
();
after
=
(
after
-
current
.
pos
).
normalized
();
if
(
before
.
dot
(
after
)
>=
-
0.25
f
)
{
if
(
dot
(
before
,
after
)
>=
-
0.25
f
)
{
// corner
current
.
lock
=
LOCK_FREE
;
}
else
{
...
...
@@ -285,8 +285,8 @@ void merge_corners(SymbolShape& shape) {
for
(
int
j
=
0
;
j
<
4
;
++
j
)
{
Vector2D
a_
=
(
shape
.
getPoint
(
i
-
j
-
1
)
->
pos
-
prev
.
pos
).
normalized
();
Vector2D
b_
=
(
shape
.
getPoint
(
i
+
j
)
->
pos
-
cur
.
pos
).
normalized
();
double
a_dot
=
a_
.
dot
(
ab
);
double
b_dot
=
-
b_
.
dot
(
ab
);
double
a_dot
=
dot
(
a_
,
ab
);
double
b_dot
=
-
dot
(
b_
,
ab
);
if
(
a_dot
<
min_a_dot
)
{
min_a_dot
=
a_dot
;
a
=
a_
;
...
...
@@ -300,8 +300,8 @@ void merge_corners(SymbolShape& shape) {
// t a + ab = u b, solve for t,u
// Gives us:
// t = ab cross b / b cross a
double
tden
=
max
(
0.00000001
,
b
.
cross
(
a
));
double
t
=
ab
.
cross
(
b
)
/
tden
;
double
tden
=
max
(
0.00000001
,
cross
(
b
,
a
));
double
t
=
cross
(
ab
,
b
)
/
tden
;
// do these tangent lines intersect, and not too far away?
// if so, then the intersection point is the merged point
if
(
t
>=
0
&&
t
<
20.0
)
{
...
...
@@ -358,7 +358,7 @@ void straighten(SymbolShape& shape) {
Vector2D
bb
=
next
.
delta_before
.
normalized
();
// if the area beneath the polygon formed by the handles is small
// then it is a straight line
double
cpDot
=
abs
(
aa
.
cross
(
ab
))
+
abs
(
bb
.
cross
(
ab
));
double
cpDot
=
abs
(
cross
(
aa
,
ab
))
+
abs
(
cross
(
bb
,
ab
));
if
(
cpDot
<
treshold
)
{
cur
.
segment_after
=
next
.
segment_before
=
SEGMENT_LINE
;
cur
.
delta_after
=
next
.
delta_before
=
Vector2D
();
...
...
src/data/symbol.cpp
View file @
a56a8454
...
...
@@ -94,6 +94,11 @@ Vector2D& ControlPoint::getOther(WhichHandle wh) {
// ----------------------------------------------------------------------------- : SymbolPart
void
SymbolPart
::
calculateBounds
()
{
min_pos
=
Vector2D
::
infinity
();
max_pos
=
-
Vector2D
::
infinity
();
}
IMPLEMENT_REFLECTION
(
SymbolPart
)
{
REFLECT_IF_NOT_READING
{
String
type
=
typeName
();
...
...
@@ -235,6 +240,19 @@ SymbolPartP SymbolGroup::clone() const {
return
part
;
}
void
SymbolGroup
::
calculateBounds
()
{
FOR_EACH
(
p
,
parts
)
p
->
calculateBounds
();
calculateBoundsNonRec
();
}
void
SymbolGroup
::
calculateBoundsNonRec
()
{
min_pos
=
Vector2D
::
infinity
();
max_pos
=
-
Vector2D
::
infinity
();
FOR_EACH
(
p
,
parts
)
{
min_pos
=
piecewise_min
(
min_pos
,
p
->
min_pos
);
max_pos
=
piecewise_max
(
max_pos
,
p
->
max_pos
);
}
}
IMPLEMENT_REFLECTION
(
SymbolGroup
)
{
REFLECT_BASE
(
SymbolPart
);
REFLECT
(
parts
);
...
...
src/data/symbol.hpp
View file @
a56a8454
...
...
@@ -112,6 +112,9 @@ class SymbolPart : public IntrusivePtrVirtualBase {
public:
/// Name/label for this part
String
name
;
/// Position and size of the part.
/** this is the smallest axis aligned bounding box that fits around the part */
Vector2D
min_pos
,
max_pos
;
/// Type of this part
virtual
String
typeName
()
const
=
0
;
...
...
@@ -130,6 +133,9 @@ class SymbolPart : public IntrusivePtrVirtualBase {
virtual
SymbolGroup
*
isSymbolGroup
()
{
return
nullptr
;
}
virtual
const
SymbolGroup
*
isSymbolGroup
()
const
{
return
nullptr
;
}
/// Calculate the position and size of the part (min_pos and max_pos)
virtual
void
calculateBounds
();
DECLARE_REFLECTION_VIRTUAL
();
};
...
...
@@ -162,9 +168,6 @@ class SymbolShape : public SymbolPart {
SymbolShapeCombine
combine
;
// Center of rotation, relative to the part, when the part is scaled to [0..1]
Vector2D
rotation_center
;
/// Position and size of the part
/// this is the smallest axis aligned bounding box that fits around the part
Vector2D
min_pos
,
max_pos
;
SymbolShape
();
...
...
@@ -183,7 +186,7 @@ class SymbolShape : public SymbolPart {
void
enforceConstraints
();
/// Calculate the position and size of the part
void
calculateBounds
();
v
irtual
v
oid
calculateBounds
();
DECLARE_REFLECTION
();
};
...
...
@@ -221,7 +224,7 @@ class SymbolSymmetry : public SymbolPart {
/// A group of symbol parts
class
SymbolGroup
:
public
SymbolPart
{
public:
vector
<
SymbolPartP
>
parts
;
///< The parts in this group
vector
<
SymbolPartP
>
parts
;
///< The parts in this group
, first item is on top
virtual
String
typeName
()
const
;
virtual
SymbolPartP
clone
()
const
;
...
...
@@ -229,16 +232,18 @@ class SymbolGroup : public SymbolPart {
virtual
SymbolGroup
*
isSymbolGroup
()
{
return
this
;
}
virtual
const
SymbolGroup
*
isSymbolGroup
()
const
{
return
this
;
}
virtual
void
calculateBounds
();
/// re-calculate the bounds, but not of the contained parts
void
calculateBoundsNonRec
();
DECLARE_REFLECTION
();
};
// ----------------------------------------------------------------------------- : Symbol
/// An editable symbol, consists of any number of SymbolParts
class
Symbol
:
public
IntrusivePtrBase
<
Symbol
>
{
class
Symbol
:
public
SymbolGroup
{
public:
/// The parts of this symbol, first item is on top
vector
<
SymbolPartP
>
parts
;
/// Actions performed on this symbol and the parts in it
ActionStack
actions
;
...
...
src/gfx/bezier.cpp
View file @
a56a8454
...
...
@@ -203,7 +203,7 @@ bool pos_on_line(const Vector2D& pos, double range, const Vector2D& p1, const Ve
Vector2D
p21
=
p2
-
p1
;
double
p21len
=
p21
.
lengthSqr
();
if
(
p21len
<
0.00001
)
return
false
;
// line is too short
t
=
p21
.
dot
(
pos
-
p1
)
/
p21len
;
// 'time' on line p1->p2
t
=
dot
(
p21
,
pos
-
p1
)
/
p21len
;
// 'time' on line p1->p2
if
(
t
<
0
||
t
>
1
)
return
false
;
// outside segment
pOut
=
p1
+
p21
*
t
;
// point on line
Vector2D
dist
=
pOut
-
pos
;
// distance to line
...
...
src/gui/symbol/basic_shape_editor.cpp
View file @
a56a8454
...
...
@@ -9,7 +9,9 @@
#include <gui/symbol/basic_shape_editor.hpp>
#include <gui/util.hpp>
#include <util/window_id.hpp>
#include <data/settings.hpp>
#include <data/action/symbol.hpp>
#include <data/action/symbol_part.hpp>
#include <wx/spinctrl.h>
// ----------------------------------------------------------------------------- : SymbolBasicShapeEditor
...
...
@@ -108,7 +110,7 @@ void SymbolBasicShapeEditor::onMouseDrag (const Vector2D& from, const Vector2D&
// Resize the object
if
(
drawing
)
{
end
=
to
;
makeShape
(
start
,
end
,
ev
.
ControlDown
(),
ev
.
ShiftDown
());
makeShape
(
start
,
end
,
ev
.
ControlDown
(),
settings
.
symbol_grid_snap
,
ev
.
ShiftDown
());
control
.
Refresh
(
false
);
}
}
...
...
@@ -119,7 +121,7 @@ void SymbolBasicShapeEditor::onKeyChange(wxKeyEvent& ev) {
if
(
drawing
)
{
if
(
ev
.
GetKeyCode
()
==
WXK_CONTROL
||
ev
.
GetKeyCode
()
==
WXK_SHIFT
)
{
// changed constrains
makeShape
(
start
,
end
,
ev
.
ControlDown
(),
ev
.
ShiftDown
());
makeShape
(
start
,
end
,
ev
.
ControlDown
(),
settings
.
symbol_grid_snap
,
ev
.
ShiftDown
());
control
.
Refresh
(
false
);
}
else
if
(
ev
.
GetKeyCode
()
==
WXK_ESCAPE
)
{
// cancel drawing
...
...
@@ -156,7 +158,12 @@ inline double sgn(double d) {
return
d
<
0
?
-
1
:
1
;
}
void
SymbolBasicShapeEditor
::
makeShape
(
const
Vector2D
&
a
,
const
Vector2D
&
b
,
bool
constrained
,
bool
centered
)
{
void
SymbolBasicShapeEditor
::
makeShape
(
Vector2D
a
,
Vector2D
b
,
bool
constrained
,
bool
snap
,
bool
centered
)
{
// snap
if
(
snap
)
{
a
=
snap_vector
(
a
,
settings
.
symbol_grid_size
);
b
=
snap_vector
(
b
,
settings
.
symbol_grid_size
);
}
// constrain
Vector2D
size
=
b
-
a
;
if
(
constrained
)
{
...
...
src/gui/symbol/basic_shape_editor.hpp
View file @
a56a8454
...
...
@@ -63,7 +63,7 @@ class SymbolBasicShapeEditor : public SymbolEditorBase {
/** when centered: a = center, b-a = radius
* otherwise: a = top left, b = bottom right
*/
void
makeShape
(
const
Vector2D
&
a
,
const
Vector2D
&
b
,
bool
constrained
,
bool
centered
);
void
makeShape
(
Vector2D
a
,
Vector2D
b
,
bool
constrained
,
bool
snap
,
bool
centered
);
/// Make the shape, centered in c, with radius r
void
makeCenteredShape
(
const
Vector2D
&
c
,
Vector2D
r
,
bool
constrained
);
...
...
src/gui/symbol/control.cpp
View file @
a56a8454
...
...
@@ -162,20 +162,20 @@ void SymbolControl::draw(DC& dc) {
SymbolViewer
::
draw
(
dc
);
// draw grid
if
(
settings
.
symbol_grid
)
{
wxSize
s
=
dc
.
GetSize
();
double
lines
=
settings
.
symbol_grid_size
;
double
end
=
rotation
.
trS
(
1
);
for
(
int
i
=
0
;
i
<=
lines
;
++
i
)
{
int
x
=
(
int
)
floor
(
rotation
.
trS
(
i
/
lines
-
0.0001
));
//dc.SetPen(Color(0, i%5 == 0 ? 64 : 31, 0));
//dc.SetPen(Color(i%5 == 0 ? 64 : 31, 0, 0));
dc
.
SetLogicalFunction
(
wxAND
);
dc
.
SetPen
(
i
%
5
==
0
?
Color
(
191
,
255
,
191
)
:
Color
(
191
,
255
,
191
));
dc
.
DrawLine
(
x
,
0
,
x
,
s
.
y
);
dc
.
DrawLine
(
0
,
x
,
s
.
x
,
x
);
dc
.
DrawLine
(
x
,
0
,
x
,
end
);
dc
.
DrawLine
(
0
,
x
,
end
,
x
);
dc
.
SetLogicalFunction
(
wxOR
);
dc
.
SetPen
(
i
%
5
==
0
?
Color
(
0
,
63
,
0
)
:
Color
(
0
,
31
,
0
));
dc
.
DrawLine
(
x
,
0
,
x
,
s
.
y
);
dc
.
DrawLine
(
0
,
x
,
s
.
x
,
x
);
dc
.
DrawLine
(
x
,
0
,
x
,
end
);
dc
.
DrawLine
(
0
,
x
,
end
,
x
);
}
dc
.
SetLogicalFunction
(
wxCOPY
);
}
...
...
@@ -251,7 +251,7 @@ void SymbolControl::onUpdateUI(wxUpdateUIEvent& ev) {
ev
.
Check
(
editor
->
modeToolId
()
==
ev
.
GetId
());
if
(
ev
.
GetId
()
==
ID_MODE_POINTS
)
{
// can only edit points when a single part is selected <TODO?>
ev
.
Enable
(
selected_parts
.
size
()
==
1
);
ev
.
Enable
(
selected_parts
.
size
()
==
1
&&
(
*
selected_parts
.
begin
())
->
isSymbolShape
()
);
}
break
;
case
ID_MODE_PAINT
:
...
...
src/gui/symbol/control.hpp
View file @
a56a8454
...
...
@@ -72,7 +72,8 @@ class SymbolControl : public wxControl, public SymbolViewer {
public:
/// What parts are selected?
set
<
SymbolPartP
>
selected_parts
;
SymbolShapeP
selected_shape
;
// if there is a single selection
SymbolPartP
highlight_part
;
///< part the mouse cursor is over
SymbolShapeP
selected_shape
;
///< if there is a single selection
/// Parent window
SymbolWindow
*
parent
;
...
...
src/gui/symbol/part_list.cpp
View file @
a56a8454
This diff is collapsed.
Click to expand it.
src/gui/symbol/part_list.hpp
View file @
a56a8454
...
...
@@ -11,61 +11,80 @@
#include <util/prec.hpp>
#include <data/symbol.hpp>
#include <wx/listctrl.h>
// ----------------------------------------------------------------------------- : Events
DECLARE_EVENT_TYPE
(
EVENT_PART_SELECT
,
<
not
used
>
)
DECLARE_EVENT_TYPE
(
EVENT_PART_ACTIVATE
,
<
not
used
>
)
/// Handle EVENT_PART_SELECT events
#define EVT_PART_SELECT( id, handler) EVT_COMMAND(id, EVENT_PART_SELECT, handler)
/// Handle EVENT_PART_ACTIVATE events
#define EVT_PART_ACTIVATE(id, handler) EVT_COMMAND(id, EVENT_PART_ACTIVATE, handler)
// ----------------------------------------------------------------------------- : SymbolPartList
// A list view of parts of a symbol
class
SymbolPartList
:
public
wxListCtrl
,
public
SymbolView
{
class
SymbolPartList
:
public
wxScrolledWindow
,
public
SymbolView
{
public:
SymbolPartList
(
Window
*
parent
,
int
id
,
SymbolP
symbol
=
SymbolP
());
/// Update the list
void
update
();
/// Is there a selection?
inline
bool
hasSelection
()
const
{
return
selected
!=
-
1
;
}
/// Return the last part that was selected
/** @pre hasSelection()
*/
inline
SymbolPartP
getSelection
()
const
{
return
getPart
(
selected
);
}
/// Get a set of selected parts
void
getSelectedParts
(
set
<
SymbolPartP
>&
sel
);
/// Select the specified parts, and nothing else
void
selectParts
(
const
set
<
SymbolPartP
>&
sel
);
SymbolPartList
(
Window
*
parent
,
int
id
,
set
<
SymbolPartP
>&
selection
,
SymbolP
symbol
=
SymbolP
());
/// Another symbol is being viewed
void
onChangeSymbol
();
virtual
void
onChangeSymbol
();
/// Event handler for changes to the symbol
virtual
void
onAction
(
const
Action
&
a
,
bool
undone
);
virtual
void
onAction
(
const
Action
&
,
bool
);
protected:
/// Get the text of an item
virtual
String
OnGetItemText
(
long
item
,
long
col
)
const
;
/// Get the icon of an item
virtual
int
OnGetItemImage
(
long
item
)
const
;
/// Update the control
void
update
();
/// Update only a subset of the parts
void
updateParts
(
const
set
<
SymbolPartP
>&
parts
);
protected:
virtual
wxSize
DoGetBestSize
()
const
;
private:
/// The selected item, or -1 if there is no selection
long
selected
;
set
<
SymbolPartP
>&
selection
;
///< Store selection here
/// Get a part from the symbol
SymbolPartP
getPart
(
long
item
)
const
;
SymbolPartP
mouse_down_on
;
int
drop_position
;
int
number_of_items
;
/// Select an item, also in the list control
/// Deselects all other items
void
selectItem
(
long
item
);
SymbolPartP
typing_in
;
size_t
cursor
;
wxImageList
state_icons
;
struct
Preview
{
Preview
()
:
up_to_date
(
false
),
image
(
25
,
25
)
{}
bool
up_to_date
;
Image
image
;
};
Preview
symbol_preview
;
///< Preview of the whole symbol
vector
<
Preview
>
part_previews
;
static
const
int
ITEM_HEIGHT
=
25
;
// --------------------------------------------------- : Event handling
DECLARE_EVENT_TABLE
();
void
onSelect
(
wxListEvent
&
ev
);
void
onDeselect
(
wxListEvent
&
ev
);
void
onLabelEdit
(
wxListEvent
&
ev
);
void
onSize
(
wxSizeEvent
&
ev
);
void
onDrag
(
wxMouseEvent
&
ev
);
void
onLeftDown
(
wxMouseEvent
&
ev
);
void
onLeftDClick
(
wxMouseEvent
&
ev
);
void
onLeftUp
(
wxMouseEvent
&
ev
);
void
onMotion
(
wxMouseEvent
&
ev
);
void
onChar
(
wxKeyEvent
&
ev
);
void
onPaint
(
wxPaintEvent
&
);
void
onSize
(
wxSizeEvent
&
);
void
OnDraw
(
DC
&
dc
);
void
sendEvent
(
int
type
);
void
drawItem
(
DC
&
dc
,
int
x
,
int
&
i
,
bool
parent_active
,
const
SymbolPartP
&
part
);
const
Image
&
itemPreview
(
int
i
,
const
SymbolPartP
&
part
);
const
Image
&
symbolPreview
();
void
updatePart
(
const
set
<
SymbolPartP
>&
parts
,
int
&
i
,
bool
parent_updated
,
const
SymbolPartP
&
part
);
SymbolPartP
findItem
(
int
i
)
const
;
static
SymbolPartP
findItem
(
int
&
i
,
const
SymbolPartP
&
part
);
static
int
childCount
(
const
SymbolPartP
&
part
);
void
updateCaret
(
DC
&
dc
,
int
x
,
int
y
,
int
h
,
const
SymbolPartP
&
part
);
};
// ----------------------------------------------------------------------------- : EOF
...
...
src/gui/symbol/select_editor.cpp
View file @
a56a8454
...
...
@@ -37,11 +37,7 @@ SymbolSelectEditor::SymbolSelectEditor(SymbolControl* control, bool rotate)
handleShearY
=
wxBitmap
(
rotate_image
(
shear
,
90
));
handleCenter
=
wxBitmap
(
load_resource_image
(
_
(
"handle_center"
)));
// Make sure all parts have updated bounds
FOR_EACH
(
p
,
getSymbol
()
->
parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
s
->
calculateBounds
();
}
}
getSymbol
()
->
calculateBounds
();
resetActions
();
}
...
...
@@ -132,24 +128,32 @@ void SymbolSelectEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
void
SymbolSelectEditor
::
onUpdateUI
(
wxUpdateUIEvent
&
ev
)
{
if
(
ev
.
GetId
()
>=
ID_SYMBOL_COMBINE
&&
ev
.
GetId
()
<
ID_SYMBOL_COMBINE_MAX
)
{
if
(
control
.
selected_parts
.
empty
())
{
ev
.
Check
(
false
);
ev
.
Enable
(
false
);
}
else
{
ev
.
Enable
(
true
);
bool
check
=
true
;
FOR_EACH
(
p
,
control
.
selected_parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
if
(
s
->
combine
!=
ev
.
GetId
()
-
ID_SYMBOL_COMBINE
)
{
check
=
false
;
break
;
}
}
// disable when symmetries are selected?
}
ev
.
Check
(
check
);
bool
enable
=
false
;
bool
check
=
true
;
FOR_EACH
(
p
,
control
.
selected_parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
enable
=
true
;
if
(
s
->
combine
!=
ev
.
GetId
()
-
ID_SYMBOL_COMBINE
)
{
check
=
false
;
break
;
}
}
// disable when symmetries are selected?
}
ev
.
Enable
(
enable
);
ev
.
Check
(
enable
&&
check
);
}
else
if
(
ev
.
GetId
()
==
ID_EDIT_DUPLICATE
)
{
ev
.
Enable
(
!
control
.
selected_parts
.
empty
());
}
else
if
(
ev
.
GetId
()
==
ID_EDIT_GROUP
)
{
ev
.
Enable
(
control
.
selected_parts
.
size
()
>=
2
);
}
else
if
(
ev
.
GetId
()
==
ID_EDIT_UNGROUP
)
{
// is a group selected
FOR_EACH
(
p
,
control
.
selected_parts
)
{
if
(
p
->
isSymbolGroup
())
{
ev
.
Enable
(
true
);
return
;
}
}
ev
.
Enable
(
false
);
}
else
{
ev
.
Enable
(
false
);
// we don't know about this item
}
...
...
@@ -165,10 +169,15 @@ void SymbolSelectEditor::onCommand(int id) {
control
.
Refresh
(
false
);
}
else
if
(
id
==
ID_EDIT_DUPLICATE
&&
!
isEditing
())
{
// duplicate selection, not when dragging
DuplicateSymbolPartsAction
*
action
=
new
DuplicateSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
);
getSymbol
()
->
actions
.
add
(
action
);
getSymbol
()
->
actions
.
add
(
new
DuplicateSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
control
.
Refresh
(
false
);
}
else
if
(
id
==
ID_EDIT_GROUP
&&
!
isEditing
())
{
// group selection, not when dragging
getSymbol
()
->
actions
.
add
(
new
GroupSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
control
.
Refresh
(
false
);
}
else
if
(
id
==
ID_EDIT_UNGROUP
&&
!
isEditing
())
{
// ungroup selection, not when dragging
getSymbol
()
->
actions
.
add
(
new
UngroupSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
control
.
Refresh
(
false
);
}
}
...
...
@@ -383,6 +392,7 @@ void SymbolSelectEditor::onChar(wxKeyEvent& ev) {
if
(
ev
.
GetKeyCode
()
==
WXK_DELETE
)
{
// delete selected parts
getSymbol
()
->
actions
.
add
(
new
RemoveSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
if
(
control
.
selected_parts
.
find
(
highlightPart
)
!=
control
.
selected_parts
.
end
())
highlightPart
=
SymbolPartP
();
// deleted it
control
.
selected_parts
.
clear
();
resetActions
();
control
.
Refresh
(
false
);
...
...
@@ -441,15 +451,25 @@ double SymbolSelectEditor::angleTo(const Vector2D& pos) {
}
SymbolPartP
find_part
(
const
SymbolPartP
&
part
,
const
Vector2D
&
pos
)
{
if
(
SymbolShape
*
s
=
part
->
isSymbolShape
())
{
if
(
point_in_shape
(
pos
,
*
s
))
return
part
;
}
else
if
(
SymbolSymmetry
*
s
=
part
->
isSymbolSymmetry
())
{
// TODO
}
else
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
if
(
find_part
(
p
,
pos
))
return
part
;
}
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
return
SymbolPartP
();
}
SymbolPartP
SymbolSelectEditor
::
findPart
(
const
Vector2D
&
pos
)
{
FOR_EACH
(
p
,
getSymbol
()
->
parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
if
(
point_in_shape
(
pos
,
*
s
))
return
p
;
}
else
if
(
SymbolSymmetry
*
s
=
p
->
isSymbolSymmetry
())
{
// TODO
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
SymbolPartP
found
=
find_part
(
p
,
pos
);
if
(
found
)
return
found
;
}
return
SymbolPartP
();
}
...
...
@@ -459,10 +479,8 @@ void SymbolSelectEditor::updateBoundingBox() {
minV
=
Vector2D
::
infinity
();
maxV
=
-
Vector2D
::
infinity
();
FOR_EACH
(
p
,
control
.
selected_parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
minV
=
piecewise_min
(
minV
,
s
->
min_pos
);
maxV
=
piecewise_max
(
maxV
,
s
->
max_pos
);
}
minV
=
piecewise_min
(
minV
,
p
->
min_pos
);
maxV
=
piecewise_max
(
maxV
,
p
->
max_pos
);
}
/* // Find rotation center
center = Vector2D(0,0);
...
...
src/gui/symbol/window.cpp
View file @
a56a8454
...
...
@@ -74,6 +74,9 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
menuEdit
->
Append
(
ID_EDIT_UNDO
,
_
(
"undo"
),
_MENU_1_
(
"undo"
,
wxEmptyString
),
_HELP_
(
"undo"
));
menuEdit
->
Append
(
ID_EDIT_REDO
,
_
(
"redo"
),
_MENU_1_
(
"redo"
,
wxEmptyString
),
_HELP_
(
"redo"
));
menuEdit
->
AppendSeparator
();
menuEdit
->
Append
(
ID_EDIT_GROUP
,
_
(
"group"
),
_MENU_
(
"group"
),
_HELP_
(
"group"
));
menuEdit
->
Append
(
ID_EDIT_UNGROUP
,
_
(
"ungroup"
),
_MENU_
(
"ungroup"
),
_HELP_
(
"ungroup"
));
menuEdit
->
AppendSeparator
();
menuEdit
->
Append
(
ID_EDIT_DUPLICATE
,
_
(
"duplicate"
),
_MENU_
(
"duplicate"
),
_HELP_
(
"duplicate"
));
menuBar
->
Append
(
menuEdit
,
_MENU_
(
"edit"
));
...
...
@@ -82,6 +85,7 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
menuTool
->
Append
(
ID_MODE_ROTATE
,
_
(
"mode_rotate"
),
_MENU_
(
"rotate"
),
_HELP_
(
"rotate"
),
wxITEM_CHECK
);
menuTool
->
Append
(
ID_MODE_POINTS
,
_
(
"mode_curve"
),
_MENU_
(
"points"
),
_HELP_
(
"points"
),
wxITEM_CHECK
);
menuTool
->
Append
(
ID_MODE_SHAPES
,
_
(
"circle"
),
_MENU_
(
"basic shapes"
),
_HELP_
(
"basic shapes"
),
wxITEM_CHECK
);
menuTool
->
Append
(
ID_MODE_SYMMETRY
,
_
(
"mode_symmetry"
),
_MENU_
(
"symmetry"
),
_HELP_
(
"symmetry"
),
wxITEM_CHECK
);
menuTool
->
Append
(
ID_MODE_PAINT
,
_
(
"mode_paint"
),
_MENU_
(
"paint"
),
_HELP_
(
"paint"
),
wxITEM_CHECK
);
menuBar
->
Append
(
menuTool
,
_MENU_
(
"tool"
));
...
...
@@ -118,11 +122,11 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
// Controls
control
=
new
SymbolControl
(
this
,
ID_CONTROL
,
symbol
);
parts
=
new
SymbolPartList
(
this
,
ID_PART_LIST
,
symbol
);
parts
=
new
SymbolPartList
(
this
,
ID_PART_LIST
,
control
->
selected_parts
,
symbol
);
// Lay out
wxSizer
*
es
=
new
wxBoxSizer
(
wxHORIZONTAL
);
es
->
Add
(
em
,
0
,
wxEXPAND
|
wxTOP
|
wxBOTTOM
|
wxALIGN_CENTER
,
1
);
es
->
Add
(
em
,
1
,
wxEXPAND
|
wxTOP
|
wxBOTTOM
|
wxALIGN_CENTER
,
1
);
emp
->
SetSizer
(
es
);
wxSizer
*
s
=
new
wxBoxSizer
(
wxHORIZONTAL
);
...
...
@@ -246,21 +250,21 @@ void SymbolWindow::onUpdateUI(wxUpdateUIEvent& ev) {
}
void
SymbolWindow
::
onSelectFromList
(
wx
List
Event
&
ev
)
{
void
SymbolWindow
::
onSelectFromList
(
wx
Command
Event
&
ev
)
{
if
(
inSelectionEvent
)
return
;
inSelectionEvent
=
true
;
parts
->
getSelectedParts
(
control
->
selected_parts
);
control
->
onUpdateSelection
();
inSelectionEvent
=
false
;
}
void
SymbolWindow
::
onActivateFromList
(
wxListEvent
&
ev
)
{
control
->
activatePart
(
control
->
getSymbol
()
->
parts
.
at
(
ev
.
GetIndex
()));
void
SymbolWindow
::
onActivateFromList
(
wxCommandEvent
&
ev
)
{
//% control->activatePart(control->getSymbol()->parts.at(ev.GetIndex()));
// TODO
}
void
SymbolWindow
::
onSelectFromControl
()
{
if
(
inSelectionEvent
)
return
;
inSelectionEvent
=
true
;
parts
->
selectParts
(
control
->
selected_parts
);
parts
->
Refresh
(
false
);
inSelectionEvent
=
false
;
}
...
...
@@ -280,7 +284,6 @@ BEGIN_EVENT_TABLE(SymbolWindow, wxFrame)
EVT_TOOL_RANGE
(
ID_CHILD_MIN
,
ID_CHILD_MAX
,
SymbolWindow
::
onExtraTool
)
EVT_UPDATE_UI
(
wxID_ANY
,
SymbolWindow
::
onUpdateUI
)
EVT_LIST_ITEM_SELECTED
(
ID_PART_LIST
,
SymbolWindow
::
onSelectFromList
)
EVT_LIST_ITEM_DESELECTED
(
ID_PART_LIST
,
SymbolWindow
::
onSelectFromList
)
EVT_LIST_ITEM_ACTIVATED
(
ID_PART_LIST
,
SymbolWindow
::
onActivateFromList
)
EVT_PART_SELECT
(
ID_PART_LIST
,
SymbolWindow
::
onSelectFromList
)
EVT_PART_ACTIVATE
(
ID_PART_LIST
,
SymbolWindow
::
onActivateFromList
)
END_EVENT_TABLE
()
src/gui/symbol/window.hpp
View file @
a56a8454
...
...
@@ -14,6 +14,7 @@
#include <wx/listctrl.h>
class
SymbolControl
;
//%%class SymbolPartList;
class
SymbolPartList
;
DECLARE_POINTER_TYPE
(
SymbolValue
);
DECLARE_POINTER_TYPE
(
Set
);
...
...
@@ -62,9 +63,9 @@ class SymbolWindow : public Frame {
void
onUpdateUI
(
wxUpdateUIEvent
&
);
/// Changing selected parts in the list
void
onSelectFromList
(
wx
List
Event
&
ev
);
void
onSelectFromList
(
wx
Command
Event
&
ev
);
/// Activating a part: open the point editor
void
onActivateFromList
(
wx
List
Event
&
ev
);
void
onActivateFromList
(
wx
Command
Event
&
ev
);
bool
inSelectionEvent
;
///< Prevent recursion in onSelect...
...
...
src/main.cpp
View file @
a56a8454
...
...
@@ -96,6 +96,10 @@ bool MSE::OnInit() {
// Installer; install it
Installer
::
installFrom
(
argv
[
1
],
true
);
return
false
;
}
else
if
(
arg
==
_
(
"--symbol-editor"
))
{
Window
*
wnd
=
new
SymbolWindow
(
nullptr
);
wnd
->
Show
();
return
true
;
}
else
if
(
arg
==
_
(
"--create-installer"
))
{
// create an installer
Installer
inst
;
...
...
src/render/symbol/filter.cpp
View file @
a56a8454
...
...
@@ -12,6 +12,29 @@
#include <util/error.hpp>
#include <script/value.hpp> // for some strange reason the profile build needs this :(
// ----------------------------------------------------------------------------- : Color
template
<>
void
GetDefaultMember
::
handle
(
const
AColor
&
col
)
{
handle
((
const
Color
&
)
col
);
}
template
<>
void
Reader
::
handle
(
AColor
&
col
)
{
UInt
r
,
g
,
b
,
a
;
if
(
wxSscanf
(
getValue
().
c_str
(),
_
(
"rgb(%u,%u,%u)"
),
&
r
,
&
g
,
&
b
))
{
col
.
Set
(
r
,
g
,
b
);
col
.
alpha
=
255
;
}
else
if
(
wxSscanf
(
getValue
().
c_str
(),
_
(
"rgba(%u,%u,%u,%u)"
),
&
r
,
&
g
,
&
b
,
&
a
))
{
col
.
Set
(
r
,
g
,
b
);
col
.
alpha
=
a
;
}
}
template
<>
void
Writer
::
handle
(
const
AColor
&
col
)
{
if
(
col
.
alpha
==
255
)
{
handle
(
String
::
Format
(
_
(
"rgb(%u,%u,%u)"
),
col
.
Red
(),
col
.
Green
(),
col
.
Blue
()));
}
else
{
handle
(
String
::
Format
(
_
(
"rgba(%u,%u,%u,%u)"
),
col
.
Red
(),
col
.
Green
(),
col
.
Blue
(),
col
.
alpha
));
}
}
// ----------------------------------------------------------------------------- : Symbol filtering
void
filter_symbol
(
Image
&
symbol
,
const
SymbolFilter
&
filter
)
{
...
...
src/render/symbol/filter.hpp
View file @
a56a8454
...
...
@@ -20,9 +20,10 @@ class SymbolFilter;
/// Color with alpha channel
class
AColor
:
public
Color
{
public:
int
alpha
;
///< The alpha value, in the range [0..255]
inline
AColor
(
int
r
,
int
g
,
int
b
,
int
a
=
255
)
:
Color
(
r
,
g
,
b
),
alpha
(
a
)
{}
inline
AColor
(
const
Color
&
color
,
int
a
=
255
)
:
Color
(
color
),
alpha
(
a
)
{}
Byte
alpha
;
///< The alpha value, in the range [0..255]
inline
AColor
()
:
alpha
(
0
)
{}
inline
AColor
(
Byte
r
,
Byte
g
,
Byte
b
,
Byte
a
=
255
)
:
Color
(
r
,
g
,
b
),
alpha
(
a
)
{}
inline
AColor
(
const
Color
&
color
,
Byte
a
=
255
)
:
Color
(
color
),
alpha
(
a
)
{}
};
// ----------------------------------------------------------------------------- : Symbol filtering
...
...
@@ -69,14 +70,14 @@ intrusive_ptr<SymbolFilter> read_new<SymbolFilter>(Reader& reader);
class
SolidFillSymbolFilter
:
public
SymbolFilter
{
public:
inline
SolidFillSymbolFilter
()
{}
inline
SolidFillSymbolFilter
(
Color
fill_color
,
Color
border_color
)
inline
SolidFillSymbolFilter
(
const
AColor
&
fill_color
,
const
AColor
&
border_color
)
:
fill_color
(
fill_color
),
border_color
(
border_color
)
{}
virtual
AColor
color
(
double
x
,
double
y
,
SymbolSet
point
)
const
;
virtual
String
fillType
()
const
;
virtual
bool
operator
==
(
const
SymbolFilter
&
that
)
const
;
private:
Color
fill_color
,
border_color
;
A
Color
fill_color
,
border_color
;
DECLARE_REFLECTION
();
};
...
...
src/render/symbol/viewer.cpp
View file @
a56a8454
...
...
@@ -72,10 +72,8 @@ void SymbolViewer::draw(DC& dc) {
}
}
}
// Draw all parts, in reverse order (bottom to top)
FOR_EACH_REVERSE
(
p
,
symbol
->
parts
)
{
combineSymbolPart
(
dc
,
*
p
,
paintedSomething
,
buffersFilled
,
borderDC
,
interiorDC
);
}
// Draw all parts
combineSymbolPart
(
dc
,
*
symbol
,
paintedSomething
,
buffersFilled
,
borderDC
,
interiorDC
);
// Output the final parts from the buffer
if
(
buffersFilled
)
{
...
...
@@ -118,7 +116,8 @@ void SymbolViewer::combineSymbolPart(DC& dc, const SymbolPart& part, bool& paint
}
else
if
(
const
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
// symmetry, already handled above
}
else
if
(
const
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
FOR_EACH_CONST
(
p
,
g
->
parts
)
{
// Draw all parts, in reverse order (bottom to top)
FOR_EACH_CONST_REVERSE
(
p
,
g
->
parts
)
{
combineSymbolPart
(
dc
,
*
p
,
paintedSomething
,
buffersFilled
,
borderDC
,
interiorDC
);
}
}
...
...
@@ -147,6 +146,10 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolShape& shape, HighlightStyl
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
SetPen
(
wxPen
(
Color
(
255
,
0
,
0
),
2
));
dc
.
DrawPolygon
((
int
)
points
.
size
(),
&
points
[
0
]);
}
else
if
(
style
==
HIGHLIGHT_BORDER_DOT
)
{
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
SetPen
(
wxPen
(
Color
(
255
,
0
,
0
),
1
,
wxDOT
));
dc
.
DrawPolygon
((
int
)
points
.
size
(),
&
points
[
0
]);
}
else
{
dc
.
SetLogicalFunction
(
wxOR
);
dc
.
SetBrush
(
Color
(
0
,
0
,
64
));
...
...
@@ -164,8 +167,13 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolSymmetry& sym) {
// TODO
}
void
SymbolViewer
::
highlightPart
(
DC
&
dc
,
const
SymbolGroup
&
group
,
HighlightStyle
style
)
{
if
(
style
==
HIGHLIGHT_BORDER
)
{
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
SetPen
(
wxPen
(
Color
(
255
,
0
,
0
),
2
));
dc
.
DrawRectangle
(
rotation
.
tr
(
RealRect
(
group
.
min_pos
,
RealSize
(
group
.
max_pos
-
group
.
min_pos
))));
}
FOR_EACH_CONST
(
part
,
group
.
parts
)
{
highlightPart
(
dc
,
*
part
,
style
);
highlightPart
(
dc
,
*
part
,
(
HighlightStyle
)(
style
|
HIGHLIGHT_LESS
)
);
}
}
...
...
src/render/symbol/viewer.hpp
View file @
a56a8454
...
...
@@ -21,9 +21,11 @@ Image render_symbol(const SymbolP& symbol, double border_radius = 0.05, int size
// ----------------------------------------------------------------------------- : Symbol Viewer
enum
HighlightStyle
{
HIGHLIGHT_BORDER
,
HIGHLIGHT_INTERIOR
enum
HighlightStyle
{
HIGHLIGHT_BORDER
=
0x01
,
HIGHLIGHT_INTERIOR
=
0x02
,
HIGHLIGHT_LESS
=
0x10
,
HIGHLIGHT_BORDER_DOT
=
HIGHLIGHT_BORDER
|
HIGHLIGHT_LESS
};
/// Class that knows how to draw a symbol
...
...
src/resource/msw/mse.rc
View file @
a56a8454
...
...
@@ -87,10 +87,13 @@ tool/mode_select IMAGE "tool/mode_select.png"
tool/mode_rotate IMAGE "tool/mode_rotate.png"
tool/mode_curve IMAGE "tool/mode_curve.png"
tool/mode_paint IMAGE "tool/mode_paint.png"
tool/mode_symmetry IMAGE "tool/mode_symmetry.png"
tool/apply IMAGE "tool/apply.png"
tool/duplicate IMAGE "tool/duplicate.png"
tool/grid IMAGE "tool/grid.png"
tool/grid_snap IMAGE "tool/grid_snap.png"
tool/group IMAGE "tool/group.png"
tool/ungroup IMAGE "tool/ungroup.png"
combine_or IMAGE "../common/combine_or.png"
combine_sub IMAGE "../common/combine_sub.png"
...
...
@@ -102,6 +105,17 @@ combine_over IMAGE "../common/combine_over.png"
combine_border IMAGE "../common/combine_border.png"
symmetry_rotation IMAGE "../common/symmetry_rotation.png"
symmetry_reflection IMAGE "../common/symmetry_reflection.png"
symbol_group IMAGE "../common/symbol_group.png"
icon_combine_merge IMAGE "../common/icon_combine_merge.png"
icon_combine_subtract IMAGE "../common/icon_combine_subtract.png"
icon_combine_intersection IMAGE "../common/icon_combine_intersection.png"
icon_combine_difference IMAGE "../common/icon_combine_difference.png"
icon_combine_overlap IMAGE "../common/icon_combine_overlap.png"
icon_combine_border IMAGE "../common/icon_combine_border.png"
icon_symmetry_rotation IMAGE "../common/icon_symmetry_rotation.png"
icon_symmetry_reflection IMAGE "../common/icon_symmetry_reflection.png"
icon_symbol_group IMAGE "../common/icon_symbol_group.png"
handle_rotate IMAGE "../common/handle_rotate.png"
handle_shear_x IMAGE "../common/handle_shear_x.png"
...
...
src/resource/msw/tool/group.png
0 → 100644
View file @
a56a8454
149 Bytes
src/resource/msw/tool/mode_symmetry.png
0 → 100644
View file @
a56a8454
146 Bytes
src/resource/msw/tool/ungroup.png
0 → 100644
View file @
a56a8454
148 Bytes
src/util/real_point.hpp
View file @
a56a8454
...
...
@@ -37,7 +37,14 @@ class RealSize {
:
width
(
w
),
height
(
h
)
{}
inline
RealSize
(
wxSize
s
)
:
width
(
s
.
GetWidth
()),
height
(
s
.
GetHeight
())
:
width
(
s
.
x
),
height
(
s
.
y
)
{}
inline
explicit
RealSize
(
const
Vector2D
&
v
)
:
width
(
v
.
x
),
height
(
v
.
y
)
{}
/// size of an image
inline
explicit
RealSize
(
const
wxImage
&
img
)
:
width
(
img
.
GetWidth
()),
height
(
img
.
GetHeight
())
{}
/// Negation of a size, negates both components
...
...
src/util/vector2d.hpp
View file @
a56a8454
...
...
@@ -74,15 +74,6 @@ class Vector2D {
x
/=
r
;
y
/=
r
;
}
/// Inner product with another vector
inline
double
dot
(
Vector2D
p2
)
const
{
return
(
x
*
p2
.
x
)
+
(
y
*
p2
.
y
);
}
/// Outer product with another vector
inline
double
cross
(
Vector2D
p2
)
const
{
return
(
x
*
p2
.
y
)
-
(
y
*
p2
.
x
);
}
/// Piecewise multiplication
inline
Vector2D
mul
(
Vector2D
p2
)
{
return
Vector2D
(
x
*
p2
.
x
,
y
*
p2
.
y
);
...
...
@@ -91,12 +82,7 @@ class Vector2D {
inline
Vector2D
div
(
Vector2D
p2
)
{
return
Vector2D
(
x
/
p2
.
x
,
y
/
p2
.
y
);
}
/// Apply a 'matrix' to this vector
inline
Vector2D
mul
(
Vector2D
mx
,
Vector2D
my
)
{
return
Vector2D
(
dot
(
mx
),
dot
(
my
));
}
/// Returns the square of the length of this vector
inline
double
lengthSqr
()
const
{
return
x
*
x
+
y
*
y
;
...
...
@@ -106,7 +92,7 @@ class Vector2D {
return
sqrt
(
lengthSqr
());
}
/// Returns a normalized version of this vector
/
// i.e. length() == 1
/
** i.e. length() == 1 */
inline
Vector2D
normalized
()
const
{
return
*
this
/
length
();
}
...
...
@@ -122,6 +108,15 @@ class Vector2D {
}
};
/// Inner product of two vectors
inline
double
dot
(
const
Vector2D
&
a
,
const
Vector2D
&
b
)
{
return
(
a
.
x
*
b
.
x
)
+
(
a
.
y
*
b
.
y
);
}
/// Length of the outer product of two vectors
inline
double
cross
(
const
Vector2D
&
a
,
const
Vector2D
&
b
)
{
return
(
a
.
x
*
b
.
y
)
-
(
a
.
y
*
b
.
x
);
}
/// Piecewise minimum
inline
Vector2D
piecewise_min
(
const
Vector2D
&
a
,
const
Vector2D
&
b
)
{
return
Vector2D
(
...
...
@@ -140,6 +135,23 @@ inline Vector2D piecewise_max(const Vector2D& a, const Vector2D& b) {
inline
Vector2D
operator
*
(
double
a
,
const
Vector2D
&
b
)
{
return
b
*
a
;
}
// ----------------------------------------------------------------------------- : Matrix2D
/// A two dimensional transformation matrix, simply two vectors
class
Matrix2D
{
public:
Vector2D
mx
,
my
;
inline
Matrix2D
()
{}
inline
Matrix2D
(
const
Vector2D
&
mx
,
const
Vector2D
&
my
)
:
mx
(
mx
),
my
(
my
)
{}
inline
Matrix2D
(
double
a
,
double
b
,
double
c
,
double
d
)
:
mx
(
a
,
b
),
my
(
c
,
d
)
{}
};
/// vector-matrix product
inline
Vector2D
operator
*
(
const
Vector2D
&
a
,
const
Matrix2D
&
m
)
{
return
Vector2D
(
dot
(
a
,
m
.
mx
),
dot
(
a
,
m
.
my
));
}
// ----------------------------------------------------------------------------- : EOF
#endif
src/util/window_id.hpp
View file @
a56a8454
...
...
@@ -76,6 +76,7 @@ enum MenuID {
,
ID_MODE_ROTATE
,
ID_MODE_POINTS
,
ID_MODE_SHAPES
,
ID_MODE_SYMMETRY
,
ID_MODE_PAINT
,
ID_MODE_MAX
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment