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
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
...
@@ -18,13 +18,17 @@ DECLARE_TYPEOF_COLLECTION(ControlPointP);
...
@@ -18,13 +18,17 @@ DECLARE_TYPEOF_COLLECTION(ControlPointP);
// ----------------------------------------------------------------------------- : Utility
// ----------------------------------------------------------------------------- : Utility
String
action_name_for
(
const
set
<
SymbolPartP
>&
parts
,
const
String
&
action
)
{
String
action_name_for
(
const
set
<
SymbolPartP
>&
parts
,
const
String
&
action
)
{
return
format_string
(
action
,
parts
.
size
()
==
1
?
_TYPE_
(
"shape"
)
:
_TYPE_
(
"shapes"
));
return
format_string
(
action
,
parts
.
size
()
==
1
?
(
*
parts
.
begin
())
->
name
:
_TYPE_
(
"shapes"
));
}
}
SymbolPartsAction
::
SymbolPartsAction
(
const
set
<
SymbolPartP
>&
parts
)
:
parts
(
parts
)
{}
// ----------------------------------------------------------------------------- : Moving symbol parts
// ----------------------------------------------------------------------------- : Moving symbol parts
SymbolPartMoveAction
::
SymbolPartMoveAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
delta
)
SymbolPartMoveAction
::
SymbolPartMoveAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
delta
)
:
parts
(
parts
)
:
SymbolPartsAction
(
parts
)
,
delta
(
delta
),
moved
(
-
delta
)
,
delta
(
delta
),
moved
(
-
delta
)
,
min_pos
(
Vector2D
::
infinity
()),
max_pos
(
-
Vector2D
::
infinity
())
,
min_pos
(
Vector2D
::
infinity
()),
max_pos
(
-
Vector2D
::
infinity
())
,
constrain
(
false
)
,
constrain
(
false
)
...
@@ -32,10 +36,8 @@ SymbolPartMoveAction::SymbolPartMoveAction(const set<SymbolPartP>& parts, const
...
@@ -32,10 +36,8 @@ SymbolPartMoveAction::SymbolPartMoveAction(const set<SymbolPartP>& parts, const
{
{
// Determine min/max_pos
// Determine min/max_pos
FOR_EACH
(
p
,
parts
)
{
FOR_EACH
(
p
,
parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
min_pos
=
piecewise_min
(
min_pos
,
p
->
min_pos
);
min_pos
=
piecewise_min
(
min_pos
,
s
->
min_pos
);
max_pos
=
piecewise_max
(
max_pos
,
p
->
max_pos
);
max_pos
=
piecewise_max
(
max_pos
,
s
->
max_pos
);
}
}
}
}
}
...
@@ -46,20 +48,28 @@ String SymbolPartMoveAction::getName(bool to_undo) const {
...
@@ -46,20 +48,28 @@ String SymbolPartMoveAction::getName(bool to_undo) const {
void
SymbolPartMoveAction
::
perform
(
bool
to_undo
)
{
void
SymbolPartMoveAction
::
perform
(
bool
to_undo
)
{
// move the points back
// move the points back
FOR_EACH
(
p
,
parts
)
{
FOR_EACH
(
p
,
parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
movePart
(
*
p
);
s
->
min_pos
-=
moved
;
s
->
max_pos
-=
moved
;
FOR_EACH
(
pnt
,
s
->
points
)
{
pnt
->
pos
-=
moved
;
}
}
else
if
(
SymbolSymmetry
*
s
=
p
->
isSymbolSymmetry
())
{
s
->
center
-=
moved
;
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
}
}
moved
=
-
moved
;
moved
=
-
moved
;
}
}
void
SymbolPartMoveAction
::
movePart
(
SymbolPart
&
part
)
{
if
(
SymbolShape
*
s
=
part
.
isSymbolShape
())
{
s
->
min_pos
-=
moved
;
s
->
max_pos
-=
moved
;
FOR_EACH
(
pnt
,
s
->
points
)
{
pnt
->
pos
-=
moved
;
}
}
else
if
(
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
s
->
center
-=
moved
;
}
else
if
(
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
movePart
(
*
p
);
}
g
->
calculateBoundsNonRec
();
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
}
void
SymbolPartMoveAction
::
move
(
const
Vector2D
&
deltaDelta
)
{
void
SymbolPartMoveAction
::
move
(
const
Vector2D
&
deltaDelta
)
{
delta
+=
deltaDelta
;
delta
+=
deltaDelta
;
...
@@ -75,26 +85,34 @@ void SymbolPartMoveAction::move(const Vector2D& deltaDelta) {
...
@@ -75,26 +85,34 @@ void SymbolPartMoveAction::move(const Vector2D& deltaDelta) {
// ----------------------------------------------------------------------------- : Rotating symbol parts
// ----------------------------------------------------------------------------- : Rotating symbol parts
SymbolPartMatrixAction
::
SymbolPartMatrixAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
center
)
SymbolPartMatrixAction
::
SymbolPartMatrixAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
center
)
:
parts
(
parts
)
:
SymbolPartsAction
(
parts
)
,
center
(
center
)
,
center
(
center
)
{}
{}
void
SymbolPartMatrixAction
::
transform
(
const
Vector2D
&
mx
,
const
Vector2D
&
my
)
{
void
SymbolPartMatrixAction
::
transform
(
const
Matrix2D
&
m
)
{
// Transform each p
oin
t
// Transform each p
ar
t
FOR_EACH
(
p
,
parts
)
{
FOR_EACH
(
p
,
parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
transform
(
*
p
,
m
);
FOR_EACH
(
pnt
,
s
->
points
)
{
}
pnt
->
pos
=
(
pnt
->
pos
-
center
).
mul
(
mx
,
my
)
+
center
;
}
pnt
->
delta_before
=
pnt
->
delta_before
.
mul
(
mx
,
my
);
void
SymbolPartMatrixAction
::
transform
(
SymbolPart
&
part
,
const
Matrix2D
&
m
)
{
pnt
->
delta_after
=
pnt
->
delta_after
.
mul
(
mx
,
my
);
if
(
SymbolShape
*
s
=
part
.
isSymbolShape
())
{
}
FOR_EACH
(
pnt
,
s
->
points
)
{
// bounds change after transforming
pnt
->
pos
=
((
pnt
->
pos
-
center
)
*
m
)
+
center
;
s
->
calculateBounds
();
pnt
->
delta_before
=
pnt
->
delta_before
*
m
;
}
else
if
(
SymbolSymmetry
*
s
=
p
->
isSymbolSymmetry
())
{
pnt
->
delta_after
=
pnt
->
delta_after
*
m
;
s
->
handle
=
s
->
handle
.
mul
(
mx
,
my
);
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
}
// bounds change after transforming
s
->
calculateBounds
();
}
else
if
(
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
s
->
handle
=
s
->
handle
*
m
;
}
else
if
(
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
transform
(
*
p
,
m
);
}
g
->
calculateBoundsNonRec
();
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
}
}
}
...
@@ -130,8 +148,8 @@ void SymbolPartRotateAction::rotateTo(double newAngle) {
...
@@ -130,8 +148,8 @@ void SymbolPartRotateAction::rotateTo(double newAngle) {
void
SymbolPartRotateAction
::
rotateBy
(
double
deltaAngle
)
{
void
SymbolPartRotateAction
::
rotateBy
(
double
deltaAngle
)
{
// Rotation 'matrix'
// Rotation 'matrix'
transform
(
transform
(
Vector2D
(
cos
(
deltaAngle
),
-
sin
(
deltaAngle
)),
Matrix2D
(
cos
(
deltaAngle
),
-
sin
(
deltaAngle
)
Vector2D
(
sin
(
deltaAngle
),
cos
(
deltaAngle
))
,
sin
(
deltaAngle
),
cos
(
deltaAngle
))
);
);
}
}
...
@@ -170,8 +188,8 @@ void SymbolPartShearAction::move(const Vector2D& deltaShear) {
...
@@ -170,8 +188,8 @@ void SymbolPartShearAction::move(const Vector2D& deltaShear) {
void
SymbolPartShearAction
::
shearBy
(
const
Vector2D
&
shear
)
{
void
SymbolPartShearAction
::
shearBy
(
const
Vector2D
&
shear
)
{
// Shear 'matrix'
// Shear 'matrix'
transform
(
transform
(
Vector2D
(
1
,
shear
.
x
),
Matrix2D
(
1
,
shear
.
x
Vector2D
(
shear
.
y
,
1
)
,
shear
.
y
,
1
)
);
);
}
}
...
@@ -180,7 +198,7 @@ void SymbolPartShearAction::shearBy(const Vector2D& shear) {
...
@@ -180,7 +198,7 @@ void SymbolPartShearAction::shearBy(const Vector2D& shear) {
SymbolPartScaleAction
::
SymbolPartScaleAction
(
const
set
<
SymbolPartP
>&
parts
,
int
scaleX
,
int
scaleY
)
SymbolPartScaleAction
::
SymbolPartScaleAction
(
const
set
<
SymbolPartP
>&
parts
,
int
scaleX
,
int
scaleY
)
:
parts
(
parts
)
:
SymbolPartsAction
(
parts
)
,
scaleX
(
scaleX
),
scaleY
(
scaleY
)
,
scaleX
(
scaleX
),
scaleY
(
scaleY
)
,
constrain
(
false
)
,
constrain
(
false
)
,
snap
(
0
)
,
snap
(
0
)
...
@@ -189,10 +207,8 @@ SymbolPartScaleAction::SymbolPartScaleAction(const set<SymbolPartP>& parts, int
...
@@ -189,10 +207,8 @@ SymbolPartScaleAction::SymbolPartScaleAction(const set<SymbolPartP>& parts, int
old_min
=
Vector2D
(
1e6
,
1e6
);
old_min
=
Vector2D
(
1e6
,
1e6
);
Vector2D
old_max
(
-
1e6
,
-
1e6
);
Vector2D
old_max
(
-
1e6
,
-
1e6
);
FOR_EACH
(
p
,
parts
)
{
FOR_EACH
(
p
,
parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
old_min
=
piecewise_min
(
old_min
,
p
->
min_pos
);
old_min
=
piecewise_min
(
old_min
,
s
->
min_pos
);
old_max
=
piecewise_max
(
old_max
,
p
->
max_pos
);
old_max
=
piecewise_max
(
old_max
,
s
->
max_pos
);
}
}
}
// new == old
// new == old
new_min
=
new_real_min
=
old_min
;
new_min
=
new_real_min
=
old_min
;
...
@@ -244,26 +260,34 @@ void SymbolPartScaleAction::update() {
...
@@ -244,26 +260,34 @@ void SymbolPartScaleAction::update() {
}
}
void
SymbolPartScaleAction
::
transformAll
()
{
void
SymbolPartScaleAction
::
transformAll
()
{
Vector2D
scale
=
new_size
.
div
(
old_size
);
FOR_EACH
(
p
,
parts
)
{
FOR_EACH
(
p
,
parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
transformPart
(
*
p
);
s
->
min_pos
=
transform
(
s
->
min_pos
);
}
s
->
max_pos
=
transform
(
s
->
max_pos
);
}
// make sure that max >= min
void
SymbolPartScaleAction
::
transformPart
(
SymbolPart
&
part
)
{
if
(
s
->
min_pos
.
x
>
s
->
max_pos
.
x
)
swap
(
s
->
min_pos
.
x
,
s
->
max_pos
.
x
);
if
(
SymbolShape
*
s
=
part
.
isSymbolShape
())
{
if
(
s
->
min_pos
.
y
>
s
->
max_pos
.
y
)
swap
(
s
->
min_pos
.
y
,
s
->
max_pos
.
y
);
Vector2D
scale
=
new_size
.
div
(
old_size
);
// scale all points
s
->
min_pos
=
transform
(
s
->
min_pos
);
FOR_EACH
(
pnt
,
s
->
points
)
{
s
->
max_pos
=
transform
(
s
->
max_pos
);
pnt
->
pos
=
transform
(
pnt
->
pos
);
// make sure that max >= min
// also scale handles
if
(
s
->
min_pos
.
x
>
s
->
max_pos
.
x
)
swap
(
s
->
min_pos
.
x
,
s
->
max_pos
.
x
);
pnt
->
delta_before
=
pnt
->
delta_before
.
mul
(
scale
);
if
(
s
->
min_pos
.
y
>
s
->
max_pos
.
y
)
swap
(
s
->
min_pos
.
y
,
s
->
max_pos
.
y
);
pnt
->
delta_after
=
pnt
->
delta_after
.
mul
(
scale
);
// scale all points
}
FOR_EACH
(
pnt
,
s
->
points
)
{
}
else
if
(
SymbolSymmetry
*
s
=
p
->
isSymbolSymmetry
())
{
pnt
->
pos
=
transform
(
pnt
->
pos
);
throw
"TODO"
;
// also scale handles
}
else
{
pnt
->
delta_before
=
pnt
->
delta_before
.
mul
(
scale
);
throw
InternalError
(
_
(
"Invalid symbol part type"
));
pnt
->
delta_after
=
pnt
->
delta_after
.
mul
(
scale
);
}
}
else
if
(
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
throw
"TODO"
;
}
else
if
(
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
transformPart
(
*
p
);
}
}
g
->
calculateBoundsNonRec
();
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
}
}
}
...
@@ -274,11 +298,18 @@ Vector2D SymbolPartScaleAction::transform(const Vector2D& v) {
...
@@ -274,11 +298,18 @@ Vector2D SymbolPartScaleAction::transform(const Vector2D& v) {
// ----------------------------------------------------------------------------- : Change combine mode
// ----------------------------------------------------------------------------- : Change combine mode
CombiningModeAction
::
CombiningModeAction
(
const
set
<
SymbolPartP
>&
parts
,
SymbolShapeCombine
mode
)
{
CombiningModeAction
::
CombiningModeAction
(
const
set
<
SymbolPartP
>&
parts
,
SymbolShapeCombine
mode
)
:
SymbolPartsAction
(
parts
)
{
FOR_EACH
(
p
,
parts
)
{
FOR_EACH
(
p
,
parts
)
{
if
(
p
->
isSymbolShape
())
{
add
(
p
,
mode
);
this
->
parts
.
push_back
(
make_pair
(
static_pointer_cast
<
SymbolShape
>
(
p
),
mode
));
}
}
}
void
CombiningModeAction
::
add
(
const
SymbolPartP
&
part
,
SymbolShapeCombine
mode
)
{
if
(
part
->
isSymbolShape
())
{
this
->
parts
.
push_back
(
make_pair
(
static_pointer_cast
<
SymbolShape
>
(
part
),
mode
));
}
else
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
add
(
p
,
mode
);
}
}
}
}
...
@@ -294,16 +325,28 @@ void CombiningModeAction::perform(bool to_undo) {
...
@@ -294,16 +325,28 @@ void CombiningModeAction::perform(bool to_undo) {
// ----------------------------------------------------------------------------- : Change name
// ----------------------------------------------------------------------------- : Change name
SymbolPartNameAction
::
SymbolPartNameAction
(
const
SymbolPartP
&
part
,
const
String
&
name
)
SymbolPartNameAction
::
SymbolPartNameAction
(
const
SymbolPartP
&
part
,
const
String
&
name
,
size_t
old_cursor
,
size_t
new_cursor
)
:
part
(
part
),
part_name
(
name
)
:
part
(
part
),
part_name
(
name
)
,
new_cursor
(
old_cursor
),
old_cursor
(
new_cursor
)
// will be swapped
{}
{}
String
SymbolPartNameAction
::
getName
(
bool
to_undo
)
const
{
String
SymbolPartNameAction
::
getName
(
bool
to_undo
)
const
{
return
_ACTION_
(
"change shape name"
);
return
_ACTION_
(
"change shape name"
);
}
}
bool
SymbolPartNameAction
::
merge
(
const
Action
&
action
)
{
TYPE_CASE
(
action
,
SymbolPartNameAction
)
{
if
(
action
.
part
==
part
)
{
// adjacent actions on the same part, discard the other one,
// because it only keeps an intermediate value
return
true
;
}
}
return
false
;
}
void
SymbolPartNameAction
::
perform
(
bool
to_undo
)
{
void
SymbolPartNameAction
::
perform
(
bool
to_undo
)
{
swap
(
part
->
name
,
part_name
);
swap
(
part
->
name
,
part_name
);
swap
(
old_cursor
,
new_cursor
);
}
}
// ----------------------------------------------------------------------------- : Add symbol part
// ----------------------------------------------------------------------------- : Add symbol part
...
@@ -313,7 +356,7 @@ AddSymbolPartAction::AddSymbolPartAction(Symbol& symbol, const SymbolPartP& part
...
@@ -313,7 +356,7 @@ AddSymbolPartAction::AddSymbolPartAction(Symbol& symbol, const SymbolPartP& part
{}
{}
String
AddSymbolPartAction
::
getName
(
bool
to_undo
)
const
{
String
AddSymbolPartAction
::
getName
(
bool
to_undo
)
const
{
return
format_string
(
_ACTION_
(
"add"
),
part
->
name
);
return
format_string
(
_ACTION_
(
"add
part
"
),
part
->
name
);
}
}
void
AddSymbolPartAction
::
perform
(
bool
to_undo
)
{
void
AddSymbolPartAction
::
perform
(
bool
to_undo
)
{
...
@@ -407,8 +450,8 @@ void DuplicateSymbolPartsAction::getParts(set<SymbolPartP>& parts) {
...
@@ -407,8 +450,8 @@ void DuplicateSymbolPartsAction::getParts(set<SymbolPartP>& parts) {
// ----------------------------------------------------------------------------- : Reorder symbol parts
// ----------------------------------------------------------------------------- : Reorder symbol parts
ReorderSymbolPartsAction
::
ReorderSymbolPartsAction
(
Symbol
&
symbol
,
size_t
part_id1
,
size_t
part_id2
)
ReorderSymbolPartsAction
::
ReorderSymbolPartsAction
(
Symbol
&
symbol
,
size_t
old_position
,
size_t
new_position
)
:
symbol
(
symbol
),
part_id1
(
part_id1
),
part_id2
(
part_id2
)
:
symbol
(
symbol
),
old_position
(
old_position
),
new_position
(
new_position
)
{}
{}
String
ReorderSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
String
ReorderSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
...
@@ -416,9 +459,12 @@ String ReorderSymbolPartsAction::getName(bool to_undo) const {
...
@@ -416,9 +459,12 @@ String ReorderSymbolPartsAction::getName(bool to_undo) const {
}
}
void
ReorderSymbolPartsAction
::
perform
(
bool
to_undo
)
{
void
ReorderSymbolPartsAction
::
perform
(
bool
to_undo
)
{
assert
(
part_id1
<
symbol
.
parts
.
size
());
assert
(
old_position
<
symbol
.
parts
.
size
());
assert
(
part_id2
<
symbol
.
parts
.
size
());
assert
(
new_position
<
symbol
.
parts
.
size
());
swap
(
symbol
.
parts
[
part_id1
],
symbol
.
parts
[
part_id2
]);
SymbolPartP
part
=
symbol
.
parts
.
at
(
old_position
);
symbol
.
parts
.
erase
(
symbol
.
parts
.
begin
()
+
old_position
);
symbol
.
parts
.
insert
(
symbol
.
parts
.
begin
()
+
new_position
,
part
);
swap
(
old_position
,
new_position
);
}
}
// ----------------------------------------------------------------------------- : Group symbol parts
// ----------------------------------------------------------------------------- : Group symbol parts
...
@@ -439,6 +485,7 @@ GroupSymbolPartsAction::GroupSymbolPartsAction(Symbol& symbol, const set<SymbolP
...
@@ -439,6 +485,7 @@ GroupSymbolPartsAction::GroupSymbolPartsAction(Symbol& symbol, const set<SymbolP
group
->
name
=
_
(
"Group"
);
group
->
name
=
_
(
"Group"
);
FOR_EACH
(
p
,
symbol
.
parts
)
{
FOR_EACH
(
p
,
symbol
.
parts
)
{
if
(
parts
.
find
(
p
)
!=
parts
.
end
())
{
if
(
parts
.
find
(
p
)
!=
parts
.
end
())
{
// add to group instead
group
->
parts
.
push_back
(
p
);
group
->
parts
.
push_back
(
p
);
if
(
!
done
)
{
if
(
!
done
)
{
done
=
true
;
done
=
true
;
...
@@ -449,6 +496,7 @@ GroupSymbolPartsAction::GroupSymbolPartsAction(Symbol& symbol, const set<SymbolP
...
@@ -449,6 +496,7 @@ GroupSymbolPartsAction::GroupSymbolPartsAction(Symbol& symbol, const set<SymbolP
old_part_list
.
push_back
(
p
);
old_part_list
.
push_back
(
p
);
}
}
}
}
group
->
calculateBounds
();
}
}
String
GroupSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
String
GroupSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
return
_ACTION_
(
"group parts"
);
return
_ACTION_
(
"group parts"
);
...
...
src/data/action/symbol.hpp
View file @
a56a8454
...
@@ -20,16 +20,24 @@
...
@@ -20,16 +20,24 @@
// ----------------------------------------------------------------------------- : Transform symbol part
// ----------------------------------------------------------------------------- : Transform symbol part
/// Anything that changes
a part
/// Anything that changes
one or more parts
class
SymbolPartAction
:
public
Action
{};
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
/// Anything that changes a part as displayed in the part list
class
SymbolPartListAction
:
public
SymbolPartAction
{};
class
SymbolPartListAction
:
public
SymbolPartAction
{};
// ----------------------------------------------------------------------------- : Moving symbol parts
// ----------------------------------------------------------------------------- : Moving symbol parts
/// Move some symbol parts
/// Move some symbol parts
class
SymbolPartMoveAction
:
public
SymbolPartAction
{
class
SymbolPartMoveAction
:
public
SymbolPart
s
Action
{
public:
public:
SymbolPartMoveAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
delta
=
Vector2D
());
SymbolPartMoveAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
delta
=
Vector2D
());
...
@@ -40,10 +48,11 @@ class SymbolPartMoveAction : public SymbolPartAction {
...
@@ -40,10 +48,11 @@ class SymbolPartMoveAction : public SymbolPartAction {
void
move
(
const
Vector2D
&
delta
);
void
move
(
const
Vector2D
&
delta
);
private:
private:
set
<
SymbolPartP
>
parts
;
///< Parts to move
Vector2D
delta
;
///< How much to move
Vector2D
delta
;
///< How much to move
Vector2D
moved
;
///< How much has been moved
Vector2D
moved
;
///< How much has been moved
Vector2D
min_pos
,
max_pos
;
///< Bounding box of the thing we are moving
Vector2D
min_pos
,
max_pos
;
///< Bounding box of the thing we are moving
void
movePart
(
SymbolPart
&
part
);
///< Move a single part
public:
public:
bool
constrain
;
///< Constrain movement?
bool
constrain
;
///< Constrain movement?
int
snap
;
///< Snap to grid?
int
snap
;
///< Snap to grid?
...
@@ -52,7 +61,7 @@ class SymbolPartMoveAction : public SymbolPartAction {
...
@@ -52,7 +61,7 @@ class SymbolPartMoveAction : public SymbolPartAction {
// ----------------------------------------------------------------------------- : Rotating symbol parts
// ----------------------------------------------------------------------------- : Rotating symbol parts
/// Transforming symbol parts using a matrix
/// Transforming symbol parts using a matrix
class
SymbolPartMatrixAction
:
public
SymbolPartAction
{
class
SymbolPartMatrixAction
:
public
SymbolPart
s
Action
{
public:
public:
SymbolPartMatrixAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
center
);
SymbolPartMatrixAction
(
const
set
<
SymbolPartP
>&
parts
,
const
Vector2D
&
center
);
...
@@ -61,10 +70,10 @@ class SymbolPartMatrixAction : public SymbolPartAction {
...
@@ -61,10 +70,10 @@ class SymbolPartMatrixAction : public SymbolPartAction {
protected:
protected:
/// Perform the transformation using the given matrix
/// 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
/// Rotate some symbol parts
...
@@ -114,7 +123,7 @@ class SymbolPartShearAction : public SymbolPartMatrixAction {
...
@@ -114,7 +123,7 @@ class SymbolPartShearAction : public SymbolPartMatrixAction {
// ----------------------------------------------------------------------------- : Scaling symbol parts
// ----------------------------------------------------------------------------- : Scaling symbol parts
/// Scale some symbol parts
/// Scale some symbol parts
class
SymbolPartScaleAction
:
public
SymbolPartAction
{
class
SymbolPartScaleAction
:
public
SymbolPart
s
Action
{
public:
public:
SymbolPartScaleAction
(
const
set
<
SymbolPartP
>&
parts
,
int
scaleX
,
int
scaleY
);
SymbolPartScaleAction
(
const
set
<
SymbolPartP
>&
parts
,
int
scaleX
,
int
scaleY
);
...
@@ -127,13 +136,13 @@ class SymbolPartScaleAction : public SymbolPartAction {
...
@@ -127,13 +136,13 @@ class SymbolPartScaleAction : public SymbolPartAction {
void
update
();
void
update
();
private:
private:
set
<
SymbolPartP
>
parts
;
///< Parts to scale
Vector2D
old_min
,
old_size
;
///< the original pos/size
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_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
Vector2D
new_min
,
new_size
;
///< the target pos/size after applying constrains
int
scaleX
,
scaleY
;
///< to what corner are we attached?
int
scaleX
,
scaleY
;
///< to what corner are we attached?
/// Transform everything in the parts
/// Transform everything in the parts
void
transformAll
();
void
transformAll
();
void
transformPart
(
SymbolPart
&
);
/// Transform a single vector
/// Transform a single vector
inline
Vector2D
transform
(
const
Vector2D
&
v
);
inline
Vector2D
transform
(
const
Vector2D
&
v
);
public:
public:
...
@@ -144,7 +153,7 @@ class SymbolPartScaleAction : public SymbolPartAction {
...
@@ -144,7 +153,7 @@ class SymbolPartScaleAction : public SymbolPartAction {
// ----------------------------------------------------------------------------- : Change combine mode
// ----------------------------------------------------------------------------- : Change combine mode
/// Change the name of a symbol part
/// Change the name of a symbol part
class
CombiningModeAction
:
public
SymbolPart
List
Action
{
class
CombiningModeAction
:
public
SymbolPart
s
Action
{
public:
public:
// All parts must be SymbolParts
// All parts must be SymbolParts
CombiningModeAction
(
const
set
<
SymbolPartP
>&
parts
,
SymbolShapeCombine
mode
);
CombiningModeAction
(
const
set
<
SymbolPartP
>&
parts
,
SymbolShapeCombine
mode
);
...
@@ -153,22 +162,26 @@ class CombiningModeAction : public SymbolPartListAction {
...
@@ -153,22 +162,26 @@ class CombiningModeAction : public SymbolPartListAction {
virtual
void
perform
(
bool
to_undo
);
virtual
void
perform
(
bool
to_undo
);
private:
private:
void
add
(
const
SymbolPartP
&
,
SymbolShapeCombine
mode
);
vector
<
pair
<
SymbolShapeP
,
SymbolShapeCombine
>
>
parts
;
///< Affected parts with new combining modes
vector
<
pair
<
SymbolShapeP
,
SymbolShapeCombine
>
>
parts
;
///< Affected parts with new combining modes
};
};
// ----------------------------------------------------------------------------- : Change name
// ----------------------------------------------------------------------------- : Change name
/// Change the name of a symbol part
/// Change the name of a symbol part
class
SymbolPartNameAction
:
public
SymbolPart
List
Action
{
class
SymbolPartNameAction
:
public
SymbolPartAction
{
public:
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
String
getName
(
bool
to_undo
)
const
;
virtual
void
perform
(
bool
to_undo
);
virtual
void
perform
(
bool
to_undo
);
virtual
bool
merge
(
const
Action
&
action
);
p
rivate
:
p
ublic
:
SymbolPartP
part
;
///< Affected part
SymbolPartP
part
;
///< Affected part
String
part_name
;
///< New name
String
part_name
;
///< New name
size_t
old_cursor
;
///< Cursor position
size_t
new_cursor
;
///< Cursor position
};
};
// ----------------------------------------------------------------------------- : Add symbol part
// ----------------------------------------------------------------------------- : Add symbol part
...
@@ -224,18 +237,18 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction {
...
@@ -224,18 +237,18 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction {
// ----------------------------------------------------------------------------- : Reorder symbol parts
// ----------------------------------------------------------------------------- : 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
{
class
ReorderSymbolPartsAction
:
public
SymbolPartListAction
{
public:
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
String
getName
(
bool
to_undo
)
const
;
virtual
void
perform
(
bool
to_undo
);
virtual
void
perform
(
bool
to_undo
);
private:
private:
Symbol
&
symbol
;
///< Symbol to swap the parts in
Symbol
&
symbol
;
///< Symbol to swap the parts in
public:
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
...
@@ -349,8 +349,8 @@ SinglePointRemoveAction::SinglePointRemoveAction(const SymbolShapeP& shape, UInt
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
.
delta_after
*=
ssqrt
(
d
istP
.
dot
(
point1
.
other
.
delta_after
)
/
point1
.
other
.
delta_after
.
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
istP
.
dot
(
point2
.
other
.
delta_before
)
/
point2
.
other
.
delta_before
.
lengthSqr
())
+
1
;
point2
.
other
.
delta_before
*=
ssqrt
(
d
ot
(
distP
,
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
;
...
...
src/data/format/image_to_symbol.cpp
View file @
a56a8454
...
@@ -245,7 +245,7 @@ void mark_corners(SymbolShape& shape) {
...
@@ -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
;
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
();
before
=
(
before
-
current
.
pos
).
normalized
();
after
=
(
after
-
current
.
pos
).
normalized
();
after
=
(
after
-
current
.
pos
).
normalized
();
if
(
before
.
dot
(
after
)
>=
-
0.25
f
)
{
if
(
dot
(
before
,
after
)
>=
-
0.25
f
)
{
// corner
// corner
current
.
lock
=
LOCK_FREE
;
current
.
lock
=
LOCK_FREE
;
}
else
{
}
else
{
...
@@ -285,8 +285,8 @@ void merge_corners(SymbolShape& shape) {
...
@@ -285,8 +285,8 @@ void merge_corners(SymbolShape& shape) {
for
(
int
j
=
0
;
j
<
4
;
++
j
)
{
for
(
int
j
=
0
;
j
<
4
;
++
j
)
{
Vector2D
a_
=
(
shape
.
getPoint
(
i
-
j
-
1
)
->
pos
-
prev
.
pos
).
normalized
();
Vector2D
a_
=
(
shape
.
getPoint
(
i
-
j
-
1
)
->
pos
-
prev
.
pos
).
normalized
();
Vector2D
b_
=
(
shape
.
getPoint
(
i
+
j
)
->
pos
-
cur
.
pos
).
normalized
();
Vector2D
b_
=
(
shape
.
getPoint
(
i
+
j
)
->
pos
-
cur
.
pos
).
normalized
();
double
a_dot
=
a_
.
dot
(
ab
);
double
a_dot
=
dot
(
a_
,
ab
);
double
b_dot
=
-
b_
.
dot
(
ab
);
double
b_dot
=
-
dot
(
b_
,
ab
);
if
(
a_dot
<
min_a_dot
)
{
if
(
a_dot
<
min_a_dot
)
{
min_a_dot
=
a_dot
;
min_a_dot
=
a_dot
;
a
=
a_
;
a
=
a_
;
...
@@ -300,8 +300,8 @@ void merge_corners(SymbolShape& shape) {
...
@@ -300,8 +300,8 @@ void merge_corners(SymbolShape& shape) {
// t a + ab = u b, solve for t,u
// t a + ab = u b, solve for t,u
// Gives us:
// Gives us:
// t = ab cross b / b cross a
// t = ab cross b / b cross a
double
tden
=
max
(
0.00000001
,
b
.
cross
(
a
));
double
tden
=
max
(
0.00000001
,
cross
(
b
,
a
));
double
t
=
ab
.
cross
(
b
)
/
tden
;
double
t
=
cross
(
ab
,
b
)
/
tden
;
// do these tangent lines intersect, and not too far away?
// do these tangent lines intersect, and not too far away?
// if so, then the intersection point is the merged point
// if so, then the intersection point is the merged point
if
(
t
>=
0
&&
t
<
20.0
)
{
if
(
t
>=
0
&&
t
<
20.0
)
{
...
@@ -358,7 +358,7 @@ void straighten(SymbolShape& shape) {
...
@@ -358,7 +358,7 @@ void straighten(SymbolShape& shape) {
Vector2D
bb
=
next
.
delta_before
.
normalized
();
Vector2D
bb
=
next
.
delta_before
.
normalized
();
// if the area beneath the polygon formed by the handles is small
// if the area beneath the polygon formed by the handles is small
// then it is a straight line
// 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
)
{
if
(
cpDot
<
treshold
)
{
cur
.
segment_after
=
next
.
segment_before
=
SEGMENT_LINE
;
cur
.
segment_after
=
next
.
segment_before
=
SEGMENT_LINE
;
cur
.
delta_after
=
next
.
delta_before
=
Vector2D
();
cur
.
delta_after
=
next
.
delta_before
=
Vector2D
();
...
...
src/data/symbol.cpp
View file @
a56a8454
...
@@ -94,6 +94,11 @@ Vector2D& ControlPoint::getOther(WhichHandle wh) {
...
@@ -94,6 +94,11 @@ Vector2D& ControlPoint::getOther(WhichHandle wh) {
// ----------------------------------------------------------------------------- : SymbolPart
// ----------------------------------------------------------------------------- : SymbolPart
void
SymbolPart
::
calculateBounds
()
{
min_pos
=
Vector2D
::
infinity
();
max_pos
=
-
Vector2D
::
infinity
();
}
IMPLEMENT_REFLECTION
(
SymbolPart
)
{
IMPLEMENT_REFLECTION
(
SymbolPart
)
{
REFLECT_IF_NOT_READING
{
REFLECT_IF_NOT_READING
{
String
type
=
typeName
();
String
type
=
typeName
();
...
@@ -235,6 +240,19 @@ SymbolPartP SymbolGroup::clone() const {
...
@@ -235,6 +240,19 @@ SymbolPartP SymbolGroup::clone() const {
return
part
;
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
)
{
IMPLEMENT_REFLECTION
(
SymbolGroup
)
{
REFLECT_BASE
(
SymbolPart
);
REFLECT_BASE
(
SymbolPart
);
REFLECT
(
parts
);
REFLECT
(
parts
);
...
...
src/data/symbol.hpp
View file @
a56a8454
...
@@ -112,6 +112,9 @@ class SymbolPart : public IntrusivePtrVirtualBase {
...
@@ -112,6 +112,9 @@ class SymbolPart : public IntrusivePtrVirtualBase {
public:
public:
/// Name/label for this part
/// Name/label for this part
String
name
;
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
/// Type of this part
virtual
String
typeName
()
const
=
0
;
virtual
String
typeName
()
const
=
0
;
...
@@ -130,6 +133,9 @@ class SymbolPart : public IntrusivePtrVirtualBase {
...
@@ -130,6 +133,9 @@ class SymbolPart : public IntrusivePtrVirtualBase {
virtual
SymbolGroup
*
isSymbolGroup
()
{
return
nullptr
;
}
virtual
SymbolGroup
*
isSymbolGroup
()
{
return
nullptr
;
}
virtual
const
SymbolGroup
*
isSymbolGroup
()
const
{
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
();
DECLARE_REFLECTION_VIRTUAL
();
};
};
...
@@ -162,9 +168,6 @@ class SymbolShape : public SymbolPart {
...
@@ -162,9 +168,6 @@ class SymbolShape : public SymbolPart {
SymbolShapeCombine
combine
;
SymbolShapeCombine
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
rotation_center
;
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
();
SymbolShape
();
...
@@ -183,7 +186,7 @@ class SymbolShape : public SymbolPart {
...
@@ -183,7 +186,7 @@ class SymbolShape : public SymbolPart {
void
enforceConstraints
();
void
enforceConstraints
();
/// Calculate the position and size of the part
/// Calculate the position and size of the part
void
calculateBounds
();
v
irtual
v
oid
calculateBounds
();
DECLARE_REFLECTION
();
DECLARE_REFLECTION
();
};
};
...
@@ -221,7 +224,7 @@ class SymbolSymmetry : public SymbolPart {
...
@@ -221,7 +224,7 @@ class SymbolSymmetry : public SymbolPart {
/// A group of symbol parts
/// A group of symbol parts
class
SymbolGroup
:
public
SymbolPart
{
class
SymbolGroup
:
public
SymbolPart
{
public:
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
String
typeName
()
const
;
virtual
SymbolPartP
clone
()
const
;
virtual
SymbolPartP
clone
()
const
;
...
@@ -229,16 +232,18 @@ class SymbolGroup : public SymbolPart {
...
@@ -229,16 +232,18 @@ class SymbolGroup : public SymbolPart {
virtual
SymbolGroup
*
isSymbolGroup
()
{
return
this
;
}
virtual
SymbolGroup
*
isSymbolGroup
()
{
return
this
;
}
virtual
const
SymbolGroup
*
isSymbolGroup
()
const
{
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
();
DECLARE_REFLECTION
();
};
};
// ----------------------------------------------------------------------------- : Symbol
// ----------------------------------------------------------------------------- : Symbol
/// An editable symbol, consists of any number of SymbolParts
/// An editable symbol, consists of any number of SymbolParts
class
Symbol
:
public
IntrusivePtrBase
<
Symbol
>
{
class
Symbol
:
public
SymbolGroup
{
public:
public:
/// The parts of this symbol, first item is on top
vector
<
SymbolPartP
>
parts
;
/// Actions performed on this symbol and the parts in it
/// Actions performed on this symbol and the parts in it
ActionStack
actions
;
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
...
@@ -203,7 +203,7 @@ bool pos_on_line(const Vector2D& pos, double range, const Vector2D& p1, const Ve
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
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
if
(
t
<
0
||
t
>
1
)
return
false
;
// outside segment
pOut
=
p1
+
p21
*
t
;
// point on line
pOut
=
p1
+
p21
*
t
;
// point on line
Vector2D
dist
=
pOut
-
pos
;
// distance to line
Vector2D
dist
=
pOut
-
pos
;
// distance to line
...
...
src/gui/symbol/basic_shape_editor.cpp
View file @
a56a8454
...
@@ -9,7 +9,9 @@
...
@@ -9,7 +9,9 @@
#include <gui/symbol/basic_shape_editor.hpp>
#include <gui/symbol/basic_shape_editor.hpp>
#include <gui/util.hpp>
#include <gui/util.hpp>
#include <util/window_id.hpp>
#include <util/window_id.hpp>
#include <data/settings.hpp>
#include <data/action/symbol.hpp>
#include <data/action/symbol.hpp>
#include <data/action/symbol_part.hpp>
#include <wx/spinctrl.h>
#include <wx/spinctrl.h>
// ----------------------------------------------------------------------------- : SymbolBasicShapeEditor
// ----------------------------------------------------------------------------- : SymbolBasicShapeEditor
...
@@ -108,7 +110,7 @@ void SymbolBasicShapeEditor::onMouseDrag (const Vector2D& from, const Vector2D&
...
@@ -108,7 +110,7 @@ void SymbolBasicShapeEditor::onMouseDrag (const Vector2D& from, const Vector2D&
// Resize the object
// Resize the object
if
(
drawing
)
{
if
(
drawing
)
{
end
=
to
;
end
=
to
;
makeShape
(
start
,
end
,
ev
.
ControlDown
(),
ev
.
ShiftDown
());
makeShape
(
start
,
end
,
ev
.
ControlDown
(),
settings
.
symbol_grid_snap
,
ev
.
ShiftDown
());
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
}
}
}
}
...
@@ -119,7 +121,7 @@ void SymbolBasicShapeEditor::onKeyChange(wxKeyEvent& ev) {
...
@@ -119,7 +121,7 @@ void SymbolBasicShapeEditor::onKeyChange(wxKeyEvent& ev) {
if
(
drawing
)
{
if
(
drawing
)
{
if
(
ev
.
GetKeyCode
()
==
WXK_CONTROL
||
ev
.
GetKeyCode
()
==
WXK_SHIFT
)
{
if
(
ev
.
GetKeyCode
()
==
WXK_CONTROL
||
ev
.
GetKeyCode
()
==
WXK_SHIFT
)
{
// changed constrains
// changed constrains
makeShape
(
start
,
end
,
ev
.
ControlDown
(),
ev
.
ShiftDown
());
makeShape
(
start
,
end
,
ev
.
ControlDown
(),
settings
.
symbol_grid_snap
,
ev
.
ShiftDown
());
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
}
else
if
(
ev
.
GetKeyCode
()
==
WXK_ESCAPE
)
{
}
else
if
(
ev
.
GetKeyCode
()
==
WXK_ESCAPE
)
{
// cancel drawing
// cancel drawing
...
@@ -156,7 +158,12 @@ inline double sgn(double d) {
...
@@ -156,7 +158,12 @@ inline double sgn(double d) {
return
d
<
0
?
-
1
:
1
;
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
// constrain
Vector2D
size
=
b
-
a
;
Vector2D
size
=
b
-
a
;
if
(
constrained
)
{
if
(
constrained
)
{
...
...
src/gui/symbol/basic_shape_editor.hpp
View file @
a56a8454
...
@@ -63,7 +63,7 @@ class SymbolBasicShapeEditor : public SymbolEditorBase {
...
@@ -63,7 +63,7 @@ class SymbolBasicShapeEditor : public SymbolEditorBase {
/** when centered: a = center, b-a = radius
/** when centered: a = center, b-a = radius
* otherwise: a = top left, b = bottom right
* 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
/// Make the shape, centered in c, with radius r
void
makeCenteredShape
(
const
Vector2D
&
c
,
Vector2D
r
,
bool
constrained
);
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) {
...
@@ -162,20 +162,20 @@ void SymbolControl::draw(DC& dc) {
SymbolViewer
::
draw
(
dc
);
SymbolViewer
::
draw
(
dc
);
// draw grid
// draw grid
if
(
settings
.
symbol_grid
)
{
if
(
settings
.
symbol_grid
)
{
wxSize
s
=
dc
.
GetSize
();
double
lines
=
settings
.
symbol_grid_size
;
double
lines
=
settings
.
symbol_grid_size
;
double
end
=
rotation
.
trS
(
1
);
for
(
int
i
=
0
;
i
<=
lines
;
++
i
)
{
for
(
int
i
=
0
;
i
<=
lines
;
++
i
)
{
int
x
=
(
int
)
floor
(
rotation
.
trS
(
i
/
lines
-
0.0001
));
int
x
=
(
int
)
floor
(
rotation
.
trS
(
i
/
lines
-
0.0001
));
//dc.SetPen(Color(0, i%5 == 0 ? 64 : 31, 0));
//dc.SetPen(Color(0, i%5 == 0 ? 64 : 31, 0));
//dc.SetPen(Color(i%5 == 0 ? 64 : 31, 0, 0));
//dc.SetPen(Color(i%5 == 0 ? 64 : 31, 0, 0));
dc
.
SetLogicalFunction
(
wxAND
);
dc
.
SetLogicalFunction
(
wxAND
);
dc
.
SetPen
(
i
%
5
==
0
?
Color
(
191
,
255
,
191
)
:
Color
(
191
,
255
,
191
));
dc
.
SetPen
(
i
%
5
==
0
?
Color
(
191
,
255
,
191
)
:
Color
(
191
,
255
,
191
));
dc
.
DrawLine
(
x
,
0
,
x
,
s
.
y
);
dc
.
DrawLine
(
x
,
0
,
x
,
end
);
dc
.
DrawLine
(
0
,
x
,
s
.
x
,
x
);
dc
.
DrawLine
(
0
,
x
,
end
,
x
);
dc
.
SetLogicalFunction
(
wxOR
);
dc
.
SetLogicalFunction
(
wxOR
);
dc
.
SetPen
(
i
%
5
==
0
?
Color
(
0
,
63
,
0
)
:
Color
(
0
,
31
,
0
));
dc
.
SetPen
(
i
%
5
==
0
?
Color
(
0
,
63
,
0
)
:
Color
(
0
,
31
,
0
));
dc
.
DrawLine
(
x
,
0
,
x
,
s
.
y
);
dc
.
DrawLine
(
x
,
0
,
x
,
end
);
dc
.
DrawLine
(
0
,
x
,
s
.
x
,
x
);
dc
.
DrawLine
(
0
,
x
,
end
,
x
);
}
}
dc
.
SetLogicalFunction
(
wxCOPY
);
dc
.
SetLogicalFunction
(
wxCOPY
);
}
}
...
@@ -251,7 +251,7 @@ void SymbolControl::onUpdateUI(wxUpdateUIEvent& ev) {
...
@@ -251,7 +251,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
(
selected_parts
.
size
()
==
1
);
ev
.
Enable
(
selected_parts
.
size
()
==
1
&&
(
*
selected_parts
.
begin
())
->
isSymbolShape
()
);
}
}
break
;
break
;
case
ID_MODE_PAINT
:
case
ID_MODE_PAINT
:
...
...
src/gui/symbol/control.hpp
View file @
a56a8454
...
@@ -72,7 +72,8 @@ class SymbolControl : public wxControl, public SymbolViewer {
...
@@ -72,7 +72,8 @@ class SymbolControl : public wxControl, public SymbolViewer {
public:
public:
/// What parts are selected?
/// What parts are selected?
set
<
SymbolPartP
>
selected_parts
;
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
/// Parent window
SymbolWindow
*
parent
;
SymbolWindow
*
parent
;
...
...
src/gui/symbol/part_list.cpp
View file @
a56a8454
...
@@ -9,147 +9,455 @@
...
@@ -9,147 +9,455 @@
#include <gui/symbol/part_list.hpp>
#include <gui/symbol/part_list.hpp>
#include <gui/util.hpp>
#include <gui/util.hpp>
#include <data/action/symbol.hpp>
#include <data/action/symbol.hpp>
#include <wx/imaglist.h>
#include <gfx/gfx.hpp>
#include <render/symbol/filter.hpp>
#include <wx/dcbuffer.h>
#include <wx/caret.h>
// ----------------------------------------------------------------------------- : Constructor
DECLARE_TYPEOF_COLLECTION
(
SymbolPartP
);
SymbolPartList
::
SymbolPartList
(
Window
*
parent
,
int
id
,
SymbolP
symbol
)
// ----------------------------------------------------------------------------- : Events
:
wxListCtrl
(
parent
,
id
,
wxDefaultPosition
,
wxDefaultSize
,
wxLC_REPORT
|
wxLC_NO_HEADER
|
wxLC_VIRTUAL
|
wxLC_EDIT_LABELS
)
DEFINE_EVENT_TYPE
(
EVENT_PART_SELECT
);
DEFINE_EVENT_TYPE
(
EVENT_PART_ACTIVATE
);
// ----------------------------------------------------------------------------- : SymbolPartList
SymbolPartList
::
SymbolPartList
(
Window
*
parent
,
int
id
,
set
<
SymbolPartP
>&
selection
,
SymbolP
symbol
)
:
wxScrolledWindow
(
parent
,
id
,
wxDefaultPosition
,
wxDefaultSize
,
wxSUNKEN_BORDER
|
wxVSCROLL
)
,
selection
(
selection
)
,
state_icons
(
9
,
8
)
{
{
// Create image list
wxImageList
*
images
=
new
wxImageList
(
16
,
16
);
// NOTE: this is based on the order of the SymbolShapeCombine and SymbolSymmetryType enums!
// NOTE: this is based on the order of the SymbolShapeCombine and SymbolSymmetryType enums!
images
->
Add
(
load_resource_image
(
_
(
"combine_or"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_merge"
)));
images
->
Add
(
load_resource_image
(
_
(
"combine_sub"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_subtract"
)));
images
->
Add
(
load_resource_image
(
_
(
"combine_and"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_intersection"
)));
images
->
Add
(
load_resource_image
(
_
(
"combine_xor"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_difference"
)));
images
->
Add
(
load_resource_image
(
_
(
"combine_over"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_overlap"
)));
images
->
Add
(
load_resource_image
(
_
(
"combine_border"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_border"
)));
images
->
Add
(
load_resource_image
(
_
(
"symmetry_rotation"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_symmetry_rotation"
)));
images
->
Add
(
load_resource_image
(
_
(
"symmetry_reflection"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_symmetry_reflection"
)));
AssignImageList
(
images
,
wxIMAGE_LIST_SMALL
);
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_symbol_group"
)));
// create columns
InsertColumn
(
0
,
_
(
"Name"
));
// view symbol
// view symbol
setSymbol
(
symbol
);
setSymbol
(
symbol
);
}
}
// ----------------------------------------------------------------------------- : View events
void
SymbolPartList
::
onChangeSymbol
()
{
void
SymbolPartList
::
onChangeSymbol
()
{
typing_in
=
SymbolPartP
();
cursor
=
0
;
update
();
update
();
}
}
void
SymbolPartList
::
onAction
(
const
Action
&
action
,
bool
undone
)
{
void
SymbolPartList
::
onAction
(
const
Action
&
action
,
bool
undone
)
{
TYPE_CASE
(
action
,
ReorderSymbolPartsAction
)
{
TYPE_CASE
(
action
,
SymbolPartNameAction
)
{
if
(
selected
==
(
long
)
action
.
part_id1
)
{
if
(
typing_in
==
action
.
part
)
{
selectItem
((
long
)
action
.
part_id2
);
cursor
=
action
.
new_cursor
;
}
else
if
(
selected
==
(
long
)
action
.
part_id2
)
{
selectItem
((
long
)
action
.
part_id1
);
}
}
Refresh
(
false
);
if
(
true
)
return
;
}
}
TYPE_CASE_
(
action
,
SymbolPartListAction
)
{
TYPE_CASE_
(
action
,
SymbolPartListAction
)
{
update
();
update
();
return
;
}
TYPE_CASE
(
action
,
SymbolPartsAction
)
{
symbol_preview
.
up_to_date
=
false
;
updateParts
(
action
.
parts
);
if
(
true
)
return
;
}
TYPE_CASE_
(
action
,
SymbolPartAction
)
{
symbol_preview
.
up_to_date
=
false
;
// some part changed, but we don't know which one, assume it is the selection
updateParts
(
selection
);
return
;
}
}
}
}
// ----------------------------------------------------------------------------- : Other
wxSize
SymbolPartList
::
DoGetBestSize
()
const
{
wxSize
ws
=
GetSize
(),
cs
=
GetClientSize
();
const
int
w
=
110
;
const
int
h
=
ITEM_HEIGHT
;
return
wxSize
(
w
,
h
)
+
ws
-
cs
;
}
String
SymbolPartList
::
OnGetItemText
(
long
item
,
long
col
)
const
{
void
SymbolPartList
::
update
()
{
assert
(
col
==
0
);
// count items
return
getPart
(
item
)
->
name
;
number_of_items
=
childCount
(
symbol
);
SetVirtualSize
(
110
,
number_of_items
*
(
ITEM_HEIGHT
+
1
));
// invalidate previews
symbol_preview
.
up_to_date
=
false
;
for
(
size_t
i
=
0
;
i
<
part_previews
.
size
()
;
++
i
)
{
part_previews
[
i
].
up_to_date
=
false
;
}
// refresh
Refresh
(
false
);
}
void
SymbolPartList
::
updateParts
(
const
set
<
SymbolPartP
>&
parts
)
{
symbol_preview
.
up_to_date
=
false
;
int
i
=
0
;
FOR_EACH
(
p
,
symbol
->
parts
)
{
updatePart
(
parts
,
i
,
false
,
p
);
}
// refresh
Refresh
(
false
);
}
}
int
SymbolPartList
::
OnGetItemImage
(
long
item
)
const
{
void
SymbolPartList
::
updatePart
(
const
set
<
SymbolPartP
>&
parts
,
int
&
i
,
bool
parent_updated
,
const
SymbolPartP
&
part
)
{
return
getPart
(
item
)
->
icon
();
bool
update
=
parent_updated
||
parts
.
find
(
part
)
!=
parts
.
end
();
if
(
update
)
{
part_previews
[
i
].
up_to_date
=
false
;
}
++
i
;
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
updatePart
(
parts
,
i
,
update
,
p
);
}
}
}
}
SymbolPartP
SymbolPartList
::
getPart
(
long
item
)
const
{
// ----------------------------------------------------------------------------- : Events
return
symbol
->
parts
.
at
(
item
);
void
SymbolPartList
::
onLeftDown
(
wxMouseEvent
&
ev
)
{
// find item under cursor
if
(
ev
.
GetX
()
<
0
||
ev
.
GetX
()
>=
GetClientSize
().
x
)
return
;
SymbolPartP
part
=
findItem
(
ev
.
GetY
()
/
(
ITEM_HEIGHT
+
1
));
if
(
part
)
{
// toggle/select
if
(
!
ev
.
ShiftDown
())
{
selection
.
clear
();
}
if
(
selection
.
find
(
part
)
!=
selection
.
end
())
{
selection
.
erase
(
part
);
}
else
{
selection
.
insert
(
part
);
}
if
(
!
ev
.
ShiftDown
())
{
// drag item
mouse_down_on
=
part
;
drop_position
=
-
1
;
CaptureMouse
();
}
sendEvent
(
EVENT_PART_SELECT
);
Refresh
(
false
);
}
ev
.
Skip
();
// for focus
}
}
void
SymbolPartList
::
selectItem
(
long
item
)
{
void
SymbolPartList
::
onLeftUp
(
wxMouseEvent
&
ev
)
{
selected
=
(
long
)
item
;
if
(
HasCapture
())
ReleaseMouse
();
long
count
=
GetItemCount
();
if
(
mouse_down_on
&&
drop_position
!=
-
1
)
{
for
(
long
i
=
0
;
i
<
count
;
++
i
)
{
// move part
SetItemState
(
i
,
i
==
selected
?
wxLIST_STATE_SELECTED
|
wxLIST_STATE_FOCUSED
:
0
,
// find old position
wxLIST_STATE_SELECTED
|
wxLIST_STATE_FOCUSED
);
vector
<
SymbolPartP
>::
const_iterator
it
=
find
(
symbol
->
parts
.
begin
(),
symbol
->
parts
.
end
(),
mouse_down_on
);
mouse_down_on
=
SymbolPartP
();
if
(
it
==
symbol
->
parts
.
end
())
{
Refresh
(
false
);
return
;
}
size_t
old_position
=
it
-
symbol
->
parts
.
begin
();
// find new position
size_t
new_position
;
SymbolPartP
drop_before
=
findItem
(
drop_position
);
it
=
find
(
symbol
->
parts
.
begin
(),
symbol
->
parts
.
end
(),
drop_before
);
if
(
it
==
symbol
->
parts
.
end
())
{
new_position
=
number_of_items
-
1
;
}
else
{
new_position
=
it
-
symbol
->
parts
.
begin
();
if
(
old_position
<
new_position
)
new_position
-=
1
;
}
// move part
if
(
old_position
!=
new_position
)
{
symbol
->
actions
.
add
(
new
ReorderSymbolPartsAction
(
*
symbol
,
old_position
,
new_position
));
}
else
{
Refresh
(
false
);
}
}
else
{
mouse_down_on
=
SymbolPartP
();
}
}
}
}
void
SymbolPartList
::
onMotion
(
wxMouseEvent
&
ev
)
{
if
(
mouse_down_on
)
{
int
new_drop_position
=
(
ev
.
GetY
()
+
ITEM_HEIGHT
/
2
)
/
(
ITEM_HEIGHT
+
1
);
if
(
new_drop_position
<
0
||
new_drop_position
>
number_of_items
)
new_drop_position
=
-
1
;
// TODO: make sure it is not in a group
if
(
drop_position
!=
new_drop_position
)
{
drop_position
=
new_drop_position
;
Refresh
(
false
);
}
}
}
void
SymbolPartList
::
onLeftDClick
(
wxMouseEvent
&
ev
)
{
// double click = activate
sendEvent
(
EVENT_PART_ACTIVATE
);
}
void
SymbolPartList
::
getSelectedParts
(
set
<
SymbolPartP
>&
sel
)
{
void
SymbolPartList
::
onChar
(
wxKeyEvent
&
ev
)
{
sel
.
clear
();
if
(
typing_in
)
{
long
count
=
GetItemCount
();
// Typing in name
for
(
long
i
=
0
;
i
<
count
;
++
i
)
{
String
new_name
=
typing_in
->
name
;
bool
selected
=
GetItemState
(
i
,
wxLIST_STATE_SELECTED
);
switch
(
ev
.
GetKeyCode
())
{
if
(
selected
)
sel
.
insert
(
symbol
->
parts
.
at
(
i
));
case
WXK_HOME
:
if
(
cursor
!=
0
)
{
cursor
=
0
;
Refresh
(
false
);
// TODO: without refresh
}
break
;
case
WXK_END
:
if
(
cursor
!=
typing_in
->
name
.
size
())
{
cursor
=
typing_in
->
name
.
size
();
Refresh
(
false
);
}
break
;
case
WXK_LEFT
:
if
(
cursor
>
0
)
{
--
cursor
;
Refresh
(
false
);
}
break
;
case
WXK_RIGHT
:
if
(
cursor
<
typing_in
->
name
.
size
())
{
++
cursor
;
Refresh
(
false
);
}
break
;
case
WXK_BACK
:
if
(
cursor
>
0
&&
cursor
<=
typing_in
->
name
.
size
())
{
String
new_name
=
typing_in
->
name
;
new_name
.
erase
(
cursor
-
1
,
1
);
symbol
->
actions
.
add
(
new
SymbolPartNameAction
(
typing_in
,
new_name
,
cursor
,
cursor
-
1
));
}
break
;
case
WXK_DELETE
:
if
(
cursor
<
typing_in
->
name
.
size
())
{
String
new_name
=
typing_in
->
name
;
new_name
.
erase
(
cursor
,
1
);
symbol
->
actions
.
add
(
new
SymbolPartNameAction
(
typing_in
,
new_name
,
cursor
,
cursor
));
}
break
;
default:
// See gui/value/text.cpp
#ifdef __WXMSW__
if
(
ev
.
GetKeyCode
()
>=
_
(
' '
)
&&
ev
.
GetKeyCode
()
==
(
int
)
ev
.
GetRawKeyCode
())
{
#else
if
(
ev
.
GetKeyCode
()
>=
_
(
' '
)
/*&& ev.GetKeyCode() == (int)ev.GetRawKeyCode()*/
)
{
#endif
#ifdef UNICODE
Char
key
=
ev
.
GetUnicodeKey
();
#else
Char
key
=
(
Char
)
ev
.
GetKeyCode
();
#endif
String
new_name
=
typing_in
->
name
;
new_name
.
insert
(
cursor
,
1
,
key
);
symbol
->
actions
.
add
(
new
SymbolPartNameAction
(
typing_in
,
new_name
,
cursor
,
cursor
+
1
));
}
}
}
}
// Move up/down?
}
}
void
SymbolPartList
::
selectParts
(
const
set
<
SymbolPartP
>&
sel
)
{
void
SymbolPartList
::
onSize
(
wxSizeEvent
&
)
{
long
count
=
GetItemCount
();
Refresh
(
false
);
for
(
long
i
=
0
;
i
<
count
;
++
i
)
{
// is that part selected?
bool
selected
=
sel
.
find
(
symbol
->
parts
.
at
(
i
))
!=
sel
.
end
();
SetItemState
(
i
,
selected
?
wxLIST_STATE_SELECTED
:
0
,
wxLIST_STATE_SELECTED
);
}
}
}
void
SymbolPartList
::
update
()
{
void
SymbolPartList
::
sendEvent
(
int
type
)
{
if
(
symbol
->
parts
.
empty
())
{
wxCommandEvent
ev
(
type
,
GetId
());
// deleting all items requires a full refresh on win32
ProcessEvent
(
ev
);
SetItemCount
(
0
);
}
Refresh
(
true
);
// ----------------------------------------------------------------------------- : Items
SymbolPartP
SymbolPartList
::
findItem
(
int
i
)
const
{
FOR_EACH
(
p
,
symbol
->
parts
)
{
SymbolPartP
f
=
findItem
(
i
,
p
);
if
(
f
)
return
f
;
}
return
SymbolPartP
();
}
SymbolPartP
SymbolPartList
::
findItem
(
int
&
i
,
const
SymbolPartP
&
part
)
{
if
(
i
<
0
)
return
SymbolPartP
();
if
(
i
==
0
)
return
part
;
i
-=
1
;
// sub item?
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
if
(
findItem
(
i
,
p
))
return
part
;
}
}
return
SymbolPartP
();
}
int
SymbolPartList
::
childCount
(
const
SymbolPartP
&
part
)
{
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
int
count
=
0
;
FOR_EACH
(
p
,
g
->
parts
)
count
+=
1
+
childCount
(
p
);
return
count
;
}
else
{
}
else
{
SetItemCount
((
long
)
symbol
->
parts
.
size
()
);
return
0
;
Refresh
(
false
);
}
}
}
}
// ----------------------------------------------------------------------------- : Event handling
// ----------------------------------------------------------------------------- : Text editor
// ----------------------------------------------------------------------------- : Drawing
void
SymbolPartList
::
onSelect
(
wxListEvent
&
ev
)
{
void
SymbolPartList
::
onPaint
(
wxPaintEvent
&
)
{
selected
=
ev
.
GetIndex
();
wxBufferedPaintDC
dc
(
this
);
ev
.
Skip
();
DoPrepareDC
(
dc
);
OnDraw
(
dc
);
}
}
void
SymbolPartList
::
onDeselect
(
wxListEvent
&
ev
)
{
void
SymbolPartList
::
OnDraw
(
DC
&
dc
)
{
selected
=
-
1
;
// init
ev
.
Skip
();
dc
.
SetFont
(
*
wxNORMAL_FONT
);
// clear background
wxSize
size
=
GetClientSize
();
dc
.
SetPen
(
*
wxTRANSPARENT_PEN
);
dc
.
SetBrush
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
));
dc
.
DrawRectangle
(
0
,
0
,
size
.
x
,
size
.
y
);
// items
int
i
=
0
;
FOR_EACH
(
p
,
symbol
->
parts
)
{
drawItem
(
dc
,
0
,
i
,
false
,
p
);
}
// drag/drop indicator
if
(
mouse_down_on
&&
drop_position
!=
-
1
)
{
dc
.
SetPen
(
wxPen
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
),
3
));
int
y
=
drop_position
*
(
ITEM_HEIGHT
+
1
)
-
1
;
dc
.
DrawLine
(
0
,
y
,
size
.
x
,
y
);
dc
.
DrawLine
(
0
,
y
-
3
,
0
,
y
+
3
);
dc
.
DrawLine
(
size
.
x
-
1
,
y
-
3
,
size
.
x
-
1
,
y
+
3
);
}
// hide caret
if
(
selection
.
size
()
!=
1
)
{
typing_in
=
SymbolPartP
();
wxCaret
*
caret
=
GetCaret
();
if
(
caret
)
caret
->
Hide
();
}
}
}
void
SymbolPartList
::
onLabelEdit
(
wxListEvent
&
ev
){
void
SymbolPartList
::
drawItem
(
DC
&
dc
,
int
x
,
int
&
i
,
bool
parent_active
,
const
SymbolPartP
&
part
)
{
symbol
->
actions
.
add
(
wxSize
size
=
GetClientSize
();
new
SymbolPartNameAction
(
getPart
(
ev
.
GetIndex
()),
ev
.
GetLabel
())
int
w
=
size
.
x
-
x
;
);
int
y
=
i
*
(
ITEM_HEIGHT
+
1
);
// draw item : highlight
Color
background
;
dc
.
SetPen
(
*
wxTRANSPARENT_PEN
);
bool
active
=
selection
.
find
(
part
)
!=
selection
.
end
();
if
(
active
)
{
background
=
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_HIGHLIGHT
);
dc
.
SetBrush
(
background
);
dc
.
DrawRectangle
(
x
,
y
,
w
,
ITEM_HEIGHT
);
dc
.
SetTextForeground
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_HIGHLIGHTTEXT
));
}
else
if
(
parent_active
)
{
background
=
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_HIGHLIGHT
);
dc
.
SetTextForeground
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
));
}
else
{
background
=
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
);
dc
.
SetTextForeground
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
));
}
// draw item : name
int
h
=
dc
.
GetCharHeight
();
dc
.
DrawText
(
part
->
name
,
ITEM_HEIGHT
+
x
+
3
,
y
+
(
ITEM_HEIGHT
-
h
)
/
2
);
// draw item : icon
dc
.
SetBrush
(
lerp
(
background
,
wxColour
(
0
,
128
,
0
),
0.7
));
dc
.
DrawRectangle
(
x
,
y
,
ITEM_HEIGHT
,
ITEM_HEIGHT
);
dc
.
DrawBitmap
(
symbolPreview
(),
x
,
y
);
dc
.
DrawBitmap
(
itemPreview
(
i
,
part
),
x
,
y
);
// draw item : border
wxPen
line_pen
=
lerp
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
),
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
),
0.5
);
dc
.
SetPen
(
line_pen
);
dc
.
DrawLine
(
x
+
ITEM_HEIGHT
,
y
,
x
+
ITEM_HEIGHT
,
y
+
ITEM_HEIGHT
+
1
);
// line after image
dc
.
DrawLine
(
x
,
y
+
ITEM_HEIGHT
,
size
.
x
,
y
+
ITEM_HEIGHT
);
// line below
// update caret
if
(
selection
.
size
()
==
1
&&
active
)
{
updateCaret
(
dc
,
x
+
ITEM_HEIGHT
+
3
,
y
+
(
ITEM_HEIGHT
-
h
)
/
2
,
h
,
part
);
}
// move down
i
+=
1
;
// draw more?
if
(
SymbolShape
*
s
=
part
->
isSymbolShape
())
{
// combine state
state_icons
.
Draw
(
s
->
combine
,
dc
,
size
.
x
-
10
,
y
+
1
);
}
else
if
(
SymbolSymmetry
*
s
=
part
->
isSymbolSymmetry
())
{
// kind of symmetry
state_icons
.
Draw
(
s
->
kind
,
dc
,
size
.
x
-
10
,
y
+
1
);
// TODO: show clip mode?
}
else
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
state_icons
.
Draw
(
SYMMETRY_REFLECTION
+
1
,
dc
,
size
.
x
-
10
,
y
+
1
);
FOR_EACH
(
p
,
g
->
parts
)
drawItem
(
dc
,
x
+
5
,
i
,
active
||
parent_active
,
p
);
// draw bar on the left
int
new_y
=
i
*
(
ITEM_HEIGHT
+
1
);
y
+=
ITEM_HEIGHT
+
1
;
if
(
y
!=
new_y
)
{
dc
.
SetPen
(
line_pen
);
dc
.
SetBrush
(
background
);
dc
.
DrawRectangle
(
x
-
1
,
y
-
1
,
5
+
1
,
new_y
-
y
+
1
);
}
}
else
{
throw
"Unknown symbol part type"
;
}
}
}
void
SymbolPartList
::
onSize
(
wxSizeEvent
&
ev
)
{
const
Image
&
SymbolPartList
::
itemPreview
(
int
i
,
const
SymbolPartP
&
part
)
{
wxSize
s
=
GetClientSize
();
if
((
size_t
)
i
>=
part_previews
.
size
())
part_previews
.
resize
(
i
+
1
);
SetColumnWidth
(
0
,
s
.
GetWidth
()
-
2
);
Preview
&
p
=
part_previews
[
i
];
if
(
!
p
.
up_to_date
)
{
SolidFillSymbolFilter
filter
(
*
wxBLACK
,
Color
(
255
,
128
,
128
));
// temporary symbol
SymbolP
sym
(
new
Symbol
);
sym
->
parts
.
push_back
(
part
);
Image
img
;
if
(
SymbolShape
*
s
=
part
->
isSymbolShape
())
{
if
(
s
->
combine
==
SYMBOL_COMBINE_SUBTRACT
)
{
// temporarily render using subtract instead, otherwise we don't see anything
s
->
combine
=
SYMBOL_COMBINE_BORDER
;
img
=
render_symbol
(
sym
,
filter
,
0.08
,
ITEM_HEIGHT
*
4
);
s
->
combine
=
SYMBOL_COMBINE_SUBTRACT
;
}
else
{
img
=
render_symbol
(
sym
,
filter
,
0.08
,
ITEM_HEIGHT
*
4
);
}
}
else
{
img
=
render_symbol
(
sym
,
filter
,
0.08
,
ITEM_HEIGHT
*
4
);
}
resample
(
img
,
p
.
image
);
p
.
up_to_date
=
true
;
}
return
p
.
image
;
}
const
Image
&
SymbolPartList
::
symbolPreview
()
{
if
(
!
symbol_preview
.
up_to_date
)
{
SolidFillSymbolFilter
filter
(
AColor
(
0
,
0
,
0
,
40
),
AColor
(
255
,
255
,
255
,
40
));
Image
img
=
render_symbol
(
symbol
,
filter
,
0.06
,
ITEM_HEIGHT
*
4
);
resample
(
img
,
symbol_preview
.
image
);
symbol_preview
.
up_to_date
=
true
;
}
return
symbol_preview
.
image
;
}
}
void
SymbolPartList
::
onDrag
(
wxMouseEvent
&
ev
)
{
void
SymbolPartList
::
updateCaret
(
DC
&
dc
,
int
x
,
int
y
,
int
h
,
const
SymbolPartP
&
part
)
{
if
(
!
ev
.
Dragging
()
||
selected
==
-
1
)
return
;
// make caret
// reorder the list of parts
wxCaret
*
caret
=
GetCaret
();
int
flags
;
if
(
!
caret
)
{
long
item
=
HitTest
(
ev
.
GetPosition
(),
flags
);
caret
=
new
wxCaret
(
this
,
1
,
h
);
if
(
flags
&
wxLIST_HITTEST_ONITEM
)
{
SetCaret
(
caret
);
if
(
item
>
0
)
EnsureVisible
(
item
-
1
);
}
if
(
item
<
GetItemCount
()
-
1
)
EnsureVisible
(
item
+
1
);
// move caret
if
(
item
!=
selected
)
{
if
(
typing_in
!=
part
)
{
// swap the two items
typing_in
=
part
;
symbol
->
actions
.
add
(
new
ReorderSymbolPartsAction
(
*
symbol
,
item
,
selected
));
cursor
=
typing_in
->
name
.
size
();
selectItem
(
item
);
// deselect all other items, to prevent 'lassoing' them
}
}
}
cursor
=
min
(
cursor
,
typing_in
->
name
.
size
());
int
w
;
dc
.
GetTextExtent
(
typing_in
->
name
.
substr
(
0
,
cursor
),
&
w
,
nullptr
);
caret
->
Move
(
x
+
w
,
y
);
if
(
!
caret
->
IsVisible
())
caret
->
Show
();
}
}
// ----------------------------------------------------------------------------- : Event table
// ----------------------------------------------------------------------------- : Event table
BEGIN_EVENT_TABLE
(
SymbolPartList
,
wxListCtrl
)
BEGIN_EVENT_TABLE
(
SymbolPartList
,
wxScrolledWindow
)
EVT_LIST_ITEM_SELECTED
(
wxID_ANY
,
SymbolPartList
::
onSelect
)
EVT_LEFT_DOWN
(
SymbolPartList
::
onLeftDown
)
EVT_LIST_ITEM_DESELECTED
(
wxID_ANY
,
SymbolPartList
::
onDeselect
)
EVT_LEFT_DCLICK
(
SymbolPartList
::
onLeftDClick
)
EVT_LIST_END_LABEL_EDIT
(
wxID_ANY
,
SymbolPartList
::
onLabelEdit
)
EVT_LEFT_UP
(
SymbolPartList
::
onLeftUp
)
EVT_SIZE
(
SymbolPartList
::
onSize
)
EVT_MOTION
(
SymbolPartList
::
onMotion
)
EVT_MOTION
(
SymbolPartList
::
onDrag
)
EVT_CHAR
(
SymbolPartList
::
onChar
)
EVT_PAINT
(
SymbolPartList
::
onPaint
)
EVT_SIZE
(
SymbolPartList
::
onSize
)
END_EVENT_TABLE
()
END_EVENT_TABLE
()
src/gui/symbol/part_list.hpp
View file @
a56a8454
...
@@ -11,61 +11,80 @@
...
@@ -11,61 +11,80 @@
#include <util/prec.hpp>
#include <util/prec.hpp>
#include <data/symbol.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
// ----------------------------------------------------------------------------- : SymbolPartList
// A list view of parts of a symbol
class
SymbolPartList
:
public
wxScrolledWindow
,
public
SymbolView
{
class
SymbolPartList
:
public
wxListCtrl
,
public
SymbolView
{
public:
public:
SymbolPartList
(
Window
*
parent
,
int
id
,
SymbolP
symbol
=
SymbolP
());
SymbolPartList
(
Window
*
parent
,
int
id
,
set
<
SymbolPartP
>&
selection
,
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
);
/// Another symbol is being viewed
/// Another symbol is being viewed
void
onChangeSymbol
();
virtual
void
onChangeSymbol
();
/// Event handler for changes to the symbol
/// Event handler for changes to the symbol
virtual
void
onAction
(
const
Action
&
a
,
bool
undone
);
virtual
void
onAction
(
const
Action
&
,
bool
);
protected:
/// Update the control
/// Get the text of an item
void
update
();
virtual
String
OnGetItemText
(
long
item
,
long
col
)
const
;
/// Update only a subset of the parts
/// Get the icon of an item
void
updateParts
(
const
set
<
SymbolPartP
>&
parts
);
virtual
int
OnGetItemImage
(
long
item
)
const
;
protected:
virtual
wxSize
DoGetBestSize
()
const
;
private:
private:
/// The selected item, or -1 if there is no selection
set
<
SymbolPartP
>&
selection
;
///< Store selection here
long
selected
;
/// Get a part from the symbol
SymbolPartP
mouse_down_on
;
SymbolPartP
getPart
(
long
item
)
const
;
int
drop_position
;
int
number_of_items
;
/// Select an item, also in the list control
SymbolPartP
typing_in
;
/// Deselects all other items
size_t
cursor
;
void
selectItem
(
long
item
);
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
// --------------------------------------------------- : Event handling
DECLARE_EVENT_TABLE
();
DECLARE_EVENT_TABLE
();
void
onSelect
(
wxListEvent
&
ev
);
void
onLeftDown
(
wxMouseEvent
&
ev
);
void
onDeselect
(
wxListEvent
&
ev
);
void
onLeftDClick
(
wxMouseEvent
&
ev
);
void
onLabelEdit
(
wxListEvent
&
ev
);
void
onLeftUp
(
wxMouseEvent
&
ev
);
void
onSize
(
wxSizeEvent
&
ev
);
void
onMotion
(
wxMouseEvent
&
ev
);
void
onDrag
(
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
// ----------------------------------------------------------------------------- : EOF
...
...
src/gui/symbol/select_editor.cpp
View file @
a56a8454
...
@@ -37,11 +37,7 @@ SymbolSelectEditor::SymbolSelectEditor(SymbolControl* control, bool rotate)
...
@@ -37,11 +37,7 @@ SymbolSelectEditor::SymbolSelectEditor(SymbolControl* control, bool rotate)
handleShearY
=
wxBitmap
(
rotate_image
(
shear
,
90
));
handleShearY
=
wxBitmap
(
rotate_image
(
shear
,
90
));
handleCenter
=
wxBitmap
(
load_resource_image
(
_
(
"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
)
{
getSymbol
()
->
calculateBounds
();
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
s
->
calculateBounds
();
}
}
resetActions
();
resetActions
();
}
}
...
@@ -132,24 +128,32 @@ void SymbolSelectEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
...
@@ -132,24 +128,32 @@ void SymbolSelectEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
void
SymbolSelectEditor
::
onUpdateUI
(
wxUpdateUIEvent
&
ev
)
{
void
SymbolSelectEditor
::
onUpdateUI
(
wxUpdateUIEvent
&
ev
)
{
if
(
ev
.
GetId
()
>=
ID_SYMBOL_COMBINE
&&
ev
.
GetId
()
<
ID_SYMBOL_COMBINE_MAX
)
{
if
(
ev
.
GetId
()
>=
ID_SYMBOL_COMBINE
&&
ev
.
GetId
()
<
ID_SYMBOL_COMBINE_MAX
)
{
if
(
control
.
selected_parts
.
empty
())
{
bool
enable
=
false
;
ev
.
Check
(
false
);
bool
check
=
true
;
ev
.
Enable
(
false
);
FOR_EACH
(
p
,
control
.
selected_parts
)
{
}
else
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
ev
.
Enable
(
true
);
enable
=
true
;
bool
check
=
true
;
if
(
s
->
combine
!=
ev
.
GetId
()
-
ID_SYMBOL_COMBINE
)
{
FOR_EACH
(
p
,
control
.
selected_parts
)
{
check
=
false
;
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
break
;
if
(
s
->
combine
!=
ev
.
GetId
()
-
ID_SYMBOL_COMBINE
)
{
}
check
=
false
;
}
// disable when symmetries are selected?
break
;
}
}
// disable when symmetries are selected?
}
ev
.
Check
(
check
);
}
}
ev
.
Enable
(
enable
);
ev
.
Check
(
enable
&&
check
);
}
else
if
(
ev
.
GetId
()
==
ID_EDIT_DUPLICATE
)
{
}
else
if
(
ev
.
GetId
()
==
ID_EDIT_DUPLICATE
)
{
ev
.
Enable
(
!
control
.
selected_parts
.
empty
());
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
{
}
else
{
ev
.
Enable
(
false
);
// we don't know about this item
ev
.
Enable
(
false
);
// we don't know about this item
}
}
...
@@ -165,10 +169,15 @@ void SymbolSelectEditor::onCommand(int id) {
...
@@ -165,10 +169,15 @@ void SymbolSelectEditor::onCommand(int id) {
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
(
getSymbol
()
->
actions
.
add
(
new
DuplicateSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
*
getSymbol
(),
control
.
selected_parts
control
.
Refresh
(
false
);
);
}
else
if
(
id
==
ID_EDIT_GROUP
&&
!
isEditing
())
{
getSymbol
()
->
actions
.
add
(
action
);
// 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
);
control
.
Refresh
(
false
);
}
}
}
}
...
@@ -383,6 +392,7 @@ void SymbolSelectEditor::onChar(wxKeyEvent& ev) {
...
@@ -383,6 +392,7 @@ 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
.
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
();
control
.
selected_parts
.
clear
();
resetActions
();
resetActions
();
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
...
@@ -441,15 +451,25 @@ double SymbolSelectEditor::angleTo(const Vector2D& pos) {
...
@@ -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
)
{
SymbolPartP
SymbolSelectEditor
::
findPart
(
const
Vector2D
&
pos
)
{
FOR_EACH
(
p
,
getSymbol
()
->
parts
)
{
FOR_EACH
(
p
,
getSymbol
()
->
parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
SymbolPartP
found
=
find_part
(
p
,
pos
);
if
(
point_in_shape
(
pos
,
*
s
))
return
p
;
if
(
found
)
return
found
;
}
else
if
(
SymbolSymmetry
*
s
=
p
->
isSymbolSymmetry
())
{
// TODO
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
}
}
return
SymbolPartP
();
return
SymbolPartP
();
}
}
...
@@ -459,10 +479,8 @@ void SymbolSelectEditor::updateBoundingBox() {
...
@@ -459,10 +479,8 @@ void SymbolSelectEditor::updateBoundingBox() {
minV
=
Vector2D
::
infinity
();
minV
=
Vector2D
::
infinity
();
maxV
=
-
Vector2D
::
infinity
();
maxV
=
-
Vector2D
::
infinity
();
FOR_EACH
(
p
,
control
.
selected_parts
)
{
FOR_EACH
(
p
,
control
.
selected_parts
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
minV
=
piecewise_min
(
minV
,
p
->
min_pos
);
minV
=
piecewise_min
(
minV
,
s
->
min_pos
);
maxV
=
piecewise_max
(
maxV
,
p
->
max_pos
);
maxV
=
piecewise_max
(
maxV
,
s
->
max_pos
);
}
}
}
/* // Find rotation center
/* // Find rotation center
center = Vector2D(0,0);
center = Vector2D(0,0);
...
...
src/gui/symbol/window.cpp
View file @
a56a8454
...
@@ -74,6 +74,9 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
...
@@ -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_UNDO
,
_
(
"undo"
),
_MENU_1_
(
"undo"
,
wxEmptyString
),
_HELP_
(
"undo"
));
menuEdit
->
Append
(
ID_EDIT_REDO
,
_
(
"redo"
),
_MENU_1_
(
"redo"
,
wxEmptyString
),
_HELP_
(
"redo"
));
menuEdit
->
Append
(
ID_EDIT_REDO
,
_
(
"redo"
),
_MENU_1_
(
"redo"
,
wxEmptyString
),
_HELP_
(
"redo"
));
menuEdit
->
AppendSeparator
();
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"
));
menuEdit
->
Append
(
ID_EDIT_DUPLICATE
,
_
(
"duplicate"
),
_MENU_
(
"duplicate"
),
_HELP_
(
"duplicate"
));
menuBar
->
Append
(
menuEdit
,
_MENU_
(
"edit"
));
menuBar
->
Append
(
menuEdit
,
_MENU_
(
"edit"
));
...
@@ -82,6 +85,7 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
...
@@ -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_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_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_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
);
menuTool
->
Append
(
ID_MODE_PAINT
,
_
(
"mode_paint"
),
_MENU_
(
"paint"
),
_HELP_
(
"paint"
),
wxITEM_CHECK
);
menuBar
->
Append
(
menuTool
,
_MENU_
(
"tool"
));
menuBar
->
Append
(
menuTool
,
_MENU_
(
"tool"
));
...
@@ -118,11 +122,11 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
...
@@ -118,11 +122,11 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
// Controls
// Controls
control
=
new
SymbolControl
(
this
,
ID_CONTROL
,
symbol
);
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
// Lay out
wxSizer
*
es
=
new
wxBoxSizer
(
wxHORIZONTAL
);
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
);
emp
->
SetSizer
(
es
);
wxSizer
*
s
=
new
wxBoxSizer
(
wxHORIZONTAL
);
wxSizer
*
s
=
new
wxBoxSizer
(
wxHORIZONTAL
);
...
@@ -246,21 +250,21 @@ void SymbolWindow::onUpdateUI(wxUpdateUIEvent& ev) {
...
@@ -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
;
if
(
inSelectionEvent
)
return
;
inSelectionEvent
=
true
;
inSelectionEvent
=
true
;
parts
->
getSelectedParts
(
control
->
selected_parts
);
control
->
onUpdateSelection
();
control
->
onUpdateSelection
();
inSelectionEvent
=
false
;
inSelectionEvent
=
false
;
}
}
void
SymbolWindow
::
onActivateFromList
(
wxListEvent
&
ev
)
{
void
SymbolWindow
::
onActivateFromList
(
wxCommandEvent
&
ev
)
{
control
->
activatePart
(
control
->
getSymbol
()
->
parts
.
at
(
ev
.
GetIndex
()));
//% control->activatePart(control->getSymbol()->parts.at(ev.GetIndex()));
// TODO
}
}
void
SymbolWindow
::
onSelectFromControl
()
{
void
SymbolWindow
::
onSelectFromControl
()
{
if
(
inSelectionEvent
)
return
;
if
(
inSelectionEvent
)
return
;
inSelectionEvent
=
true
;
inSelectionEvent
=
true
;
parts
->
selectParts
(
control
->
selected_parts
);
parts
->
Refresh
(
false
);
inSelectionEvent
=
false
;
inSelectionEvent
=
false
;
}
}
...
@@ -280,7 +284,6 @@ BEGIN_EVENT_TABLE(SymbolWindow, wxFrame)
...
@@ -280,7 +284,6 @@ BEGIN_EVENT_TABLE(SymbolWindow, wxFrame)
EVT_TOOL_RANGE
(
ID_CHILD_MIN
,
ID_CHILD_MAX
,
SymbolWindow
::
onExtraTool
)
EVT_TOOL_RANGE
(
ID_CHILD_MIN
,
ID_CHILD_MAX
,
SymbolWindow
::
onExtraTool
)
EVT_UPDATE_UI
(
wxID_ANY
,
SymbolWindow
::
onUpdateUI
)
EVT_UPDATE_UI
(
wxID_ANY
,
SymbolWindow
::
onUpdateUI
)
EVT_LIST_ITEM_SELECTED
(
ID_PART_LIST
,
SymbolWindow
::
onSelectFromList
)
EVT_PART_SELECT
(
ID_PART_LIST
,
SymbolWindow
::
onSelectFromList
)
EVT_LIST_ITEM_DESELECTED
(
ID_PART_LIST
,
SymbolWindow
::
onSelectFromList
)
EVT_PART_ACTIVATE
(
ID_PART_LIST
,
SymbolWindow
::
onActivateFromList
)
EVT_LIST_ITEM_ACTIVATED
(
ID_PART_LIST
,
SymbolWindow
::
onActivateFromList
)
END_EVENT_TABLE
()
END_EVENT_TABLE
()
src/gui/symbol/window.hpp
View file @
a56a8454
...
@@ -14,6 +14,7 @@
...
@@ -14,6 +14,7 @@
#include <wx/listctrl.h>
#include <wx/listctrl.h>
class
SymbolControl
;
class
SymbolControl
;
//%%class SymbolPartList;
class
SymbolPartList
;
class
SymbolPartList
;
DECLARE_POINTER_TYPE
(
SymbolValue
);
DECLARE_POINTER_TYPE
(
SymbolValue
);
DECLARE_POINTER_TYPE
(
Set
);
DECLARE_POINTER_TYPE
(
Set
);
...
@@ -62,9 +63,9 @@ class SymbolWindow : public Frame {
...
@@ -62,9 +63,9 @@ class SymbolWindow : public Frame {
void
onUpdateUI
(
wxUpdateUIEvent
&
);
void
onUpdateUI
(
wxUpdateUIEvent
&
);
/// Changing selected parts in the list
/// 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
/// 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...
bool
inSelectionEvent
;
///< Prevent recursion in onSelect...
...
...
src/main.cpp
View file @
a56a8454
...
@@ -96,6 +96,10 @@ bool MSE::OnInit() {
...
@@ -96,6 +96,10 @@ bool MSE::OnInit() {
// Installer; install it
// Installer; install it
Installer
::
installFrom
(
argv
[
1
],
true
);
Installer
::
installFrom
(
argv
[
1
],
true
);
return
false
;
return
false
;
}
else
if
(
arg
==
_
(
"--symbol-editor"
))
{
Window
*
wnd
=
new
SymbolWindow
(
nullptr
);
wnd
->
Show
();
return
true
;
}
else
if
(
arg
==
_
(
"--create-installer"
))
{
}
else
if
(
arg
==
_
(
"--create-installer"
))
{
// create an installer
// create an installer
Installer
inst
;
Installer
inst
;
...
...
src/render/symbol/filter.cpp
View file @
a56a8454
...
@@ -12,6 +12,29 @@
...
@@ -12,6 +12,29 @@
#include <util/error.hpp>
#include <util/error.hpp>
#include <script/value.hpp> // for some strange reason the profile build needs this :(
#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
// ----------------------------------------------------------------------------- : Symbol filtering
void
filter_symbol
(
Image
&
symbol
,
const
SymbolFilter
&
filter
)
{
void
filter_symbol
(
Image
&
symbol
,
const
SymbolFilter
&
filter
)
{
...
...
src/render/symbol/filter.hpp
View file @
a56a8454
...
@@ -20,9 +20,10 @@ class SymbolFilter;
...
@@ -20,9 +20,10 @@ class SymbolFilter;
/// Color with alpha channel
/// Color with alpha channel
class
AColor
:
public
Color
{
class
AColor
:
public
Color
{
public:
public:
int
alpha
;
///< The alpha value, in the range [0..255]
Byte
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
()
:
alpha
(
0
)
{}
inline
AColor
(
const
Color
&
color
,
int
a
=
255
)
:
Color
(
color
),
alpha
(
a
)
{}
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
// ----------------------------------------------------------------------------- : Symbol filtering
...
@@ -69,14 +70,14 @@ intrusive_ptr<SymbolFilter> read_new<SymbolFilter>(Reader& reader);
...
@@ -69,14 +70,14 @@ intrusive_ptr<SymbolFilter> read_new<SymbolFilter>(Reader& reader);
class
SolidFillSymbolFilter
:
public
SymbolFilter
{
class
SolidFillSymbolFilter
:
public
SymbolFilter
{
public:
public:
inline
SolidFillSymbolFilter
()
{}
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
)
:
fill_color
(
fill_color
),
border_color
(
border_color
)
{}
{}
virtual
AColor
color
(
double
x
,
double
y
,
SymbolSet
point
)
const
;
virtual
AColor
color
(
double
x
,
double
y
,
SymbolSet
point
)
const
;
virtual
String
fillType
()
const
;
virtual
String
fillType
()
const
;
virtual
bool
operator
==
(
const
SymbolFilter
&
that
)
const
;
virtual
bool
operator
==
(
const
SymbolFilter
&
that
)
const
;
private:
private:
Color
fill_color
,
border_color
;
A
Color
fill_color
,
border_color
;
DECLARE_REFLECTION
();
DECLARE_REFLECTION
();
};
};
...
...
src/render/symbol/viewer.cpp
View file @
a56a8454
...
@@ -72,10 +72,8 @@ void SymbolViewer::draw(DC& dc) {
...
@@ -72,10 +72,8 @@ void SymbolViewer::draw(DC& dc) {
}
}
}
}
}
}
// Draw all parts, in reverse order (bottom to top)
// Draw all parts
FOR_EACH_REVERSE
(
p
,
symbol
->
parts
)
{
combineSymbolPart
(
dc
,
*
symbol
,
paintedSomething
,
buffersFilled
,
borderDC
,
interiorDC
);
combineSymbolPart
(
dc
,
*
p
,
paintedSomething
,
buffersFilled
,
borderDC
,
interiorDC
);
}
// Output the final parts from the buffer
// Output the final parts from the buffer
if
(
buffersFilled
)
{
if
(
buffersFilled
)
{
...
@@ -118,7 +116,8 @@ void SymbolViewer::combineSymbolPart(DC& dc, const SymbolPart& part, bool& paint
...
@@ -118,7 +116,8 @@ void SymbolViewer::combineSymbolPart(DC& dc, const SymbolPart& part, bool& paint
}
else
if
(
const
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
}
else
if
(
const
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
// symmetry, already handled above
// symmetry, already handled above
}
else
if
(
const
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
}
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
);
combineSymbolPart
(
dc
,
*
p
,
paintedSomething
,
buffersFilled
,
borderDC
,
interiorDC
);
}
}
}
}
...
@@ -147,6 +146,10 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolShape& shape, HighlightStyl
...
@@ -147,6 +146,10 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolShape& shape, HighlightStyl
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
SetPen
(
wxPen
(
Color
(
255
,
0
,
0
),
2
));
dc
.
SetPen
(
wxPen
(
Color
(
255
,
0
,
0
),
2
));
dc
.
DrawPolygon
((
int
)
points
.
size
(),
&
points
[
0
]);
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
{
}
else
{
dc
.
SetLogicalFunction
(
wxOR
);
dc
.
SetLogicalFunction
(
wxOR
);
dc
.
SetBrush
(
Color
(
0
,
0
,
64
));
dc
.
SetBrush
(
Color
(
0
,
0
,
64
));
...
@@ -164,8 +167,13 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolSymmetry& sym) {
...
@@ -164,8 +167,13 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolSymmetry& sym) {
// TODO
// TODO
}
}
void
SymbolViewer
::
highlightPart
(
DC
&
dc
,
const
SymbolGroup
&
group
,
HighlightStyle
style
)
{
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
)
{
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
...
@@ -21,9 +21,11 @@ Image render_symbol(const SymbolP& symbol, double border_radius = 0.05, int size
// ----------------------------------------------------------------------------- : Symbol Viewer
// ----------------------------------------------------------------------------- : Symbol Viewer
enum
HighlightStyle
{
enum
HighlightStyle
HIGHLIGHT_BORDER
,
{
HIGHLIGHT_BORDER
=
0x01
HIGHLIGHT_INTERIOR
,
HIGHLIGHT_INTERIOR
=
0x02
,
HIGHLIGHT_LESS
=
0x10
,
HIGHLIGHT_BORDER_DOT
=
HIGHLIGHT_BORDER
|
HIGHLIGHT_LESS
};
};
/// Class that knows how to draw a symbol
/// 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"
...
@@ -87,10 +87,13 @@ tool/mode_select IMAGE "tool/mode_select.png"
tool/mode_rotate IMAGE "tool/mode_rotate.png"
tool/mode_rotate IMAGE "tool/mode_rotate.png"
tool/mode_curve IMAGE "tool/mode_curve.png"
tool/mode_curve IMAGE "tool/mode_curve.png"
tool/mode_paint IMAGE "tool/mode_paint.png"
tool/mode_paint IMAGE "tool/mode_paint.png"
tool/mode_symmetry IMAGE "tool/mode_symmetry.png"
tool/apply IMAGE "tool/apply.png"
tool/apply IMAGE "tool/apply.png"
tool/duplicate IMAGE "tool/duplicate.png"
tool/duplicate IMAGE "tool/duplicate.png"
tool/grid IMAGE "tool/grid.png"
tool/grid IMAGE "tool/grid.png"
tool/grid_snap IMAGE "tool/grid_snap.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_or IMAGE "../common/combine_or.png"
combine_sub IMAGE "../common/combine_sub.png"
combine_sub IMAGE "../common/combine_sub.png"
...
@@ -102,6 +105,17 @@ combine_over IMAGE "../common/combine_over.png"
...
@@ -102,6 +105,17 @@ combine_over IMAGE "../common/combine_over.png"
combine_border IMAGE "../common/combine_border.png"
combine_border IMAGE "../common/combine_border.png"
symmetry_rotation IMAGE "../common/symmetry_rotation.png"
symmetry_rotation IMAGE "../common/symmetry_rotation.png"
symmetry_reflection IMAGE "../common/symmetry_reflection.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_rotate IMAGE "../common/handle_rotate.png"
handle_shear_x IMAGE "../common/handle_shear_x.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 {
...
@@ -37,7 +37,14 @@ class RealSize {
:
width
(
w
),
height
(
h
)
:
width
(
w
),
height
(
h
)
{}
{}
inline
RealSize
(
wxSize
s
)
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
/// Negation of a size, negates both components
...
...
src/util/vector2d.hpp
View file @
a56a8454
...
@@ -74,15 +74,6 @@ class Vector2D {
...
@@ -74,15 +74,6 @@ class Vector2D {
x
/=
r
;
y
/=
r
;
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
/// Piecewise multiplication
inline
Vector2D
mul
(
Vector2D
p2
)
{
inline
Vector2D
mul
(
Vector2D
p2
)
{
return
Vector2D
(
x
*
p2
.
x
,
y
*
p2
.
y
);
return
Vector2D
(
x
*
p2
.
x
,
y
*
p2
.
y
);
...
@@ -91,12 +82,7 @@ class Vector2D {
...
@@ -91,12 +82,7 @@ class Vector2D {
inline
Vector2D
div
(
Vector2D
p2
)
{
inline
Vector2D
div
(
Vector2D
p2
)
{
return
Vector2D
(
x
/
p2
.
x
,
y
/
p2
.
y
);
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
/// Returns the square of the length of this vector
inline
double
lengthSqr
()
const
{
inline
double
lengthSqr
()
const
{
return
x
*
x
+
y
*
y
;
return
x
*
x
+
y
*
y
;
...
@@ -106,7 +92,7 @@ class Vector2D {
...
@@ -106,7 +92,7 @@ class Vector2D {
return
sqrt
(
lengthSqr
());
return
sqrt
(
lengthSqr
());
}
}
/// Returns a normalized version of this vector
/// Returns a normalized version of this vector
/
// i.e. length() == 1
/
** i.e. length() == 1 */
inline
Vector2D
normalized
()
const
{
inline
Vector2D
normalized
()
const
{
return
*
this
/
length
();
return
*
this
/
length
();
}
}
...
@@ -122,6 +108,15 @@ class Vector2D {
...
@@ -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
/// Piecewise minimum
inline
Vector2D
piecewise_min
(
const
Vector2D
&
a
,
const
Vector2D
&
b
)
{
inline
Vector2D
piecewise_min
(
const
Vector2D
&
a
,
const
Vector2D
&
b
)
{
return
Vector2D
(
return
Vector2D
(
...
@@ -140,6 +135,23 @@ inline Vector2D piecewise_max(const Vector2D& a, const Vector2D& b) {
...
@@ -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
;
}
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
// ----------------------------------------------------------------------------- : EOF
#endif
#endif
src/util/window_id.hpp
View file @
a56a8454
...
@@ -76,6 +76,7 @@ enum MenuID {
...
@@ -76,6 +76,7 @@ enum MenuID {
,
ID_MODE_ROTATE
,
ID_MODE_ROTATE
,
ID_MODE_POINTS
,
ID_MODE_POINTS
,
ID_MODE_SHAPES
,
ID_MODE_SHAPES
,
ID_MODE_SYMMETRY
,
ID_MODE_PAINT
,
ID_MODE_PAINT
,
ID_MODE_MAX
,
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