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
67c0e51f
Commit
67c0e51f
authored
Jul 09, 2007
by
twanvl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Symbol editor now has constraints on selection, but part list allows selection inside groups.
Added logical 'xor' operator for scripting.
parent
b4d89e6a
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
519 additions
and
287 deletions
+519
-287
src/data/action/symbol.cpp
src/data/action/symbol.cpp
+49
-19
src/data/action/symbol.hpp
src/data/action/symbol.hpp
+23
-7
src/data/symbol.cpp
src/data/symbol.cpp
+22
-11
src/data/symbol.hpp
src/data/symbol.hpp
+30
-22
src/gui/symbol/basic_shape_editor.cpp
src/gui/symbol/basic_shape_editor.cpp
+3
-1
src/gui/symbol/control.cpp
src/gui/symbol/control.cpp
+19
-24
src/gui/symbol/control.hpp
src/gui/symbol/control.hpp
+4
-3
src/gui/symbol/part_list.cpp
src/gui/symbol/part_list.cpp
+180
-101
src/gui/symbol/part_list.hpp
src/gui/symbol/part_list.hpp
+23
-7
src/gui/symbol/select_editor.cpp
src/gui/symbol/select_editor.cpp
+58
-79
src/gui/symbol/select_editor.hpp
src/gui/symbol/select_editor.hpp
+11
-3
src/gui/symbol/window.cpp
src/gui/symbol/window.cpp
+55
-9
src/mse.vcproj
src/mse.vcproj
+12
-0
src/render/symbol/viewer.cpp
src/render/symbol/viewer.cpp
+19
-1
src/script/context.cpp
src/script/context.cpp
+1
-0
src/script/parser.cpp
src/script/parser.cpp
+1
-0
src/script/script.cpp
src/script/script.cpp
+1
-0
src/script/script.hpp
src/script/script.hpp
+1
-0
src/util/window_id.hpp
src/util/window_id.hpp
+7
-0
No files found.
src/data/action/symbol.cpp
View file @
67c0e51f
...
@@ -105,6 +105,7 @@ void SymbolPartMatrixAction::transform(SymbolPart& part, const Matrix2D& m) {
...
@@ -105,6 +105,7 @@ void SymbolPartMatrixAction::transform(SymbolPart& part, const Matrix2D& m) {
// bounds change after transforming
// bounds change after transforming
s
->
calculateBounds
();
s
->
calculateBounds
();
}
else
if
(
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
}
else
if
(
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
s
->
center
=
(
s
->
center
-
center
)
*
m
+
center
;
s
->
handle
=
s
->
handle
*
m
;
s
->
handle
=
s
->
handle
*
m
;
}
else
if
(
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
}
else
if
(
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
FOR_EACH
(
p
,
g
->
parts
)
{
...
@@ -280,7 +281,8 @@ void SymbolPartScaleAction::transformPart(SymbolPart& part) {
...
@@ -280,7 +281,8 @@ void SymbolPartScaleAction::transformPart(SymbolPart& part) {
pnt
->
delta_after
=
pnt
->
delta_after
.
mul
(
scale
);
pnt
->
delta_after
=
pnt
->
delta_after
.
mul
(
scale
);
}
}
}
else
if
(
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
}
else
if
(
SymbolSymmetry
*
s
=
part
.
isSymbolSymmetry
())
{
throw
"TODO"
;
transform
(
s
->
center
);
s
->
handle
.
mul
(
new_size
.
div
(
old_size
));
}
else
if
(
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
}
else
if
(
SymbolGroup
*
g
=
part
.
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
FOR_EACH
(
p
,
g
->
parts
)
{
transformPart
(
*
p
);
transformPart
(
*
p
);
...
@@ -450,8 +452,9 @@ void DuplicateSymbolPartsAction::getParts(set<SymbolPartP>& parts) {
...
@@ -450,8 +452,9 @@ void DuplicateSymbolPartsAction::getParts(set<SymbolPartP>& parts) {
// ----------------------------------------------------------------------------- : Reorder symbol parts
// ----------------------------------------------------------------------------- : Reorder symbol parts
ReorderSymbolPartsAction
::
ReorderSymbolPartsAction
(
Symbol
&
symbol
,
size_t
old_position
,
size_t
new_position
)
ReorderSymbolPartsAction
::
ReorderSymbolPartsAction
(
SymbolGroup
&
old_parent
,
size_t
old_position
,
SymbolGroup
&
new_parent
,
size_t
new_position
)
:
symbol
(
symbol
),
old_position
(
old_position
),
new_position
(
new_position
)
:
old_parent
(
&
old_parent
),
new_parent
(
&
new_parent
)
,
old_position
(
old_position
),
new_position
(
new_position
)
{}
{}
String
ReorderSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
String
ReorderSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
...
@@ -459,31 +462,58 @@ String ReorderSymbolPartsAction::getName(bool to_undo) const {
...
@@ -459,31 +462,58 @@ String ReorderSymbolPartsAction::getName(bool to_undo) const {
}
}
void
ReorderSymbolPartsAction
::
perform
(
bool
to_undo
)
{
void
ReorderSymbolPartsAction
::
perform
(
bool
to_undo
)
{
assert
(
old_position
<
symbol
.
parts
.
size
());
// remove from old
assert
(
new_position
<
symbol
.
parts
.
size
());
assert
(
old_position
<
old_parent
->
parts
.
size
());
SymbolPartP
part
=
symbol
.
parts
.
at
(
old_position
);
SymbolPartP
part
=
old_parent
->
parts
.
at
(
old_position
);
symbol
.
parts
.
erase
(
symbol
.
parts
.
begin
()
+
old_position
);
old_parent
->
parts
.
erase
(
old_parent
->
parts
.
begin
()
+
old_position
);
symbol
.
parts
.
insert
(
symbol
.
parts
.
begin
()
+
new_position
,
part
);
// add to new
assert
(
new_position
<=
new_parent
->
parts
.
size
());
new_parent
->
parts
.
insert
(
new_parent
->
parts
.
begin
()
+
new_position
,
part
);
// next time the other way around
swap
(
old_parent
,
new_parent
);
swap
(
old_position
,
new_position
);
swap
(
old_position
,
new_position
);
}
}
UngroupReorderSymbolPartsAction
::
UngroupReorderSymbolPartsAction
(
SymbolGroup
&
group_parent
,
size_t
group_pos
,
SymbolGroup
&
target_parent
,
size_t
target_pos
)
:
group_parent
(
group_parent
),
group_pos
(
group_pos
)
,
target_parent
(
target_parent
),
target_pos
(
target_pos
)
{
group
=
dynamic_pointer_cast
<
SymbolGroup
>
(
group_parent
.
parts
.
at
(
group_pos
));
assert
(
group
);
}
String
UngroupReorderSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
return
_ACTION_
(
"reorder parts"
);
}
void
UngroupReorderSymbolPartsAction
::
perform
(
bool
to_undo
)
{
if
(
!
to_undo
)
{
group_parent
.
parts
.
erase
(
group_parent
.
parts
.
begin
()
+
group_pos
);
target_parent
.
parts
.
insert
(
target_parent
.
parts
.
begin
()
+
target_pos
,
group
->
parts
.
begin
(),
group
->
parts
.
end
());
}
else
{
target_parent
.
parts
.
erase
(
target_parent
.
parts
.
begin
()
+
target_pos
,
target_parent
.
parts
.
begin
()
+
target_pos
+
group
->
parts
.
size
());
group_parent
.
parts
.
insert
(
group_parent
.
parts
.
begin
()
+
group_pos
,
group
);
}
}
// ----------------------------------------------------------------------------- : Group symbol parts
// ----------------------------------------------------------------------------- : Group symbol parts
GroupSymbolPartsActionBase
::
GroupSymbolPartsActionBase
(
Symbol
&
symbol
)
GroupSymbolPartsActionBase
::
GroupSymbolPartsActionBase
(
Symbol
Group
&
root
)
:
symbol
(
symbol
)
:
root
(
root
)
{}
{}
void
GroupSymbolPartsActionBase
::
perform
(
bool
to_undo
)
{
void
GroupSymbolPartsActionBase
::
perform
(
bool
to_undo
)
{
swap
(
symbol
.
parts
,
old_part_list
);
swap
(
root
.
parts
,
old_part_list
);
}
}
GroupSymbolPartsAction
::
GroupSymbolPartsAction
(
Symbol
&
symbol
,
const
set
<
SymbolPartP
>&
parts
)
GroupSymbolPartsAction
::
GroupSymbolPartsAction
(
Symbol
Group
&
root
,
const
set
<
SymbolPartP
>&
parts
,
const
SymbolGroupP
&
group
)
:
GroupSymbolPartsActionBase
(
symbol
)
:
GroupSymbolPartsActionBase
(
root
)
{
{
// group parts in the old parts list
// group parts in the old parts list
bool
done
=
false
;
bool
done
=
false
;
SymbolGroupP
group
(
new
SymbolGroup
);
FOR_EACH
(
p
,
root
.
parts
)
{
group
->
name
=
_
(
"Group"
);
assert
(
p
!=
group
);
FOR_EACH
(
p
,
symbol
.
parts
)
{
if
(
parts
.
find
(
p
)
!=
parts
.
end
())
{
if
(
parts
.
find
(
p
)
!=
parts
.
end
())
{
// add to group instead
// add to group instead
group
->
parts
.
push_back
(
p
);
group
->
parts
.
push_back
(
p
);
...
@@ -502,11 +532,11 @@ String GroupSymbolPartsAction::getName(bool to_undo) const {
...
@@ -502,11 +532,11 @@ String GroupSymbolPartsAction::getName(bool to_undo) const {
return
_ACTION_
(
"group parts"
);
return
_ACTION_
(
"group parts"
);
}
}
UngroupSymbolPartsAction
::
UngroupSymbolPartsAction
(
Symbol
&
symbol
,
const
set
<
SymbolPartP
>&
parts
)
UngroupSymbolPartsAction
::
UngroupSymbolPartsAction
(
Symbol
Group
&
root
,
const
set
<
SymbolPartP
>&
parts
)
:
GroupSymbolPartsActionBase
(
symbol
)
:
GroupSymbolPartsActionBase
(
root
)
{
{
// break up the parts in the old parts list
// break up the parts in the old parts list
FOR_EACH
(
p
,
symbol
.
parts
)
{
FOR_EACH
(
p
,
root
.
parts
)
{
if
(
parts
.
find
(
p
)
!=
parts
.
end
()
&&
p
->
isSymbolGroup
())
{
if
(
parts
.
find
(
p
)
!=
parts
.
end
()
&&
p
->
isSymbolGroup
())
{
// break up the group
// break up the group
SymbolGroup
*
g
=
p
->
isSymbolGroup
();
SymbolGroup
*
g
=
p
->
isSymbolGroup
();
...
...
src/data/action/symbol.hpp
View file @
67c0e51f
...
@@ -240,36 +240,52 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction {
...
@@ -240,36 +240,52 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction {
/// Change the position of a part in a symbol, by moving a part.
/// 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
old_position
,
size_t
new_position
);
ReorderSymbolPartsAction
(
Symbol
Group
&
old_parent
,
size_t
old_position
,
SymbolGroup
&
new_parent
,
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
Group
*
old_parent
,
*
new_parent
;
///< Parents to move from and to
public:
public:
size_t
old_position
,
new_position
;
///< Positions to move from and to
size_t
old_position
,
new_position
;
///< Positions to move from and to
};
};
/// Break up a single group, and put its contents at a specific position
class
UngroupReorderSymbolPartsAction
:
public
SymbolPartListAction
{
public:
/// Remove all the given groups
UngroupReorderSymbolPartsAction
(
SymbolGroup
&
group_parent
,
size_t
group_pos
,
SymbolGroup
&
target_parent
,
size_t
target_pos
);
virtual
String
getName
(
bool
to_undo
)
const
;
virtual
void
perform
(
bool
to_undo
);
private:
SymbolGroup
&
group_parent
;
size_t
group_pos
;
SymbolGroupP
group
;
///< Group to destroy
SymbolGroup
&
target_parent
;
size_t
target_pos
;
};
// ----------------------------------------------------------------------------- : Group symbol parts
// ----------------------------------------------------------------------------- : Group symbol parts
/// Group multiple symbol parts together
/// Group multiple symbol parts together
class
GroupSymbolPartsActionBase
:
public
SymbolPartListAction
{
class
GroupSymbolPartsActionBase
:
public
SymbolPartListAction
{
public:
public:
GroupSymbolPartsActionBase
(
Symbol
&
symbol
);
GroupSymbolPartsActionBase
(
Symbol
Group
&
root
);
virtual
void
perform
(
bool
to_undo
);
virtual
void
perform
(
bool
to_undo
);
protected:
protected:
Symbol
&
symbol
;
///< Symbol
to group stuff in
Symbol
Group
&
root
;
///< Symbol or group
to group stuff in
vector
<
SymbolPartP
>
old_part_list
;
///< Old part list of the symbol
vector
<
SymbolPartP
>
old_part_list
;
///< Old part list of the symbol
};
};
/// Group multiple symbol parts together
/// Group multiple symbol parts together
class
GroupSymbolPartsAction
:
public
GroupSymbolPartsActionBase
{
class
GroupSymbolPartsAction
:
public
GroupSymbolPartsActionBase
{
public:
public:
GroupSymbolPartsAction
(
Symbol
&
symbol
,
const
set
<
SymbolPartP
>&
parts
);
GroupSymbolPartsAction
(
Symbol
Group
&
root
,
const
set
<
SymbolPartP
>&
parts
,
const
SymbolGroupP
&
group
);
virtual
String
getName
(
bool
to_undo
)
const
;
virtual
String
getName
(
bool
to_undo
)
const
;
};
};
...
@@ -277,11 +293,11 @@ class GroupSymbolPartsAction : public GroupSymbolPartsActionBase {
...
@@ -277,11 +293,11 @@ class GroupSymbolPartsAction : public GroupSymbolPartsActionBase {
/// Break up one or more SymbolGroups
/// Break up one or more SymbolGroups
class
UngroupSymbolPartsAction
:
public
GroupSymbolPartsActionBase
{
class
UngroupSymbolPartsAction
:
public
GroupSymbolPartsActionBase
{
public:
public:
UngroupSymbolPartsAction
(
Symbol
&
symbol
,
const
set
<
SymbolPartP
>&
groups
);
/// Remove all the given groups
UngroupSymbolPartsAction
(
SymbolGroup
&
root
,
const
set
<
SymbolPartP
>&
groups
);
virtual
String
getName
(
bool
to_undo
)
const
;
virtual
String
getName
(
bool
to_undo
)
const
;
};
};
// ----------------------------------------------------------------------------- : EOF
// ----------------------------------------------------------------------------- : EOF
#endif
#endif
src/data/symbol.cpp
View file @
67c0e51f
...
@@ -204,7 +204,12 @@ String SymbolSymmetry::typeName() const {
...
@@ -204,7 +204,12 @@ String SymbolSymmetry::typeName() const {
}
}
SymbolPartP
SymbolSymmetry
::
clone
()
const
{
SymbolPartP
SymbolSymmetry
::
clone
()
const
{
return
new_intrusive1
<
SymbolSymmetry
>
(
*
this
);
SymbolSymmetryP
part
(
new
SymbolSymmetry
(
*
this
));
// also clone the parts inside
FOR_EACH
(
p
,
part
->
parts
)
{
p
=
p
->
clone
();
}
return
part
;
}
}
IMPLEMENT_REFLECTION
(
SymbolSymmetry
)
{
IMPLEMENT_REFLECTION
(
SymbolSymmetry
)
{
...
@@ -213,20 +218,16 @@ IMPLEMENT_REFLECTION(SymbolSymmetry) {
...
@@ -213,20 +218,16 @@ IMPLEMENT_REFLECTION(SymbolSymmetry) {
REFLECT
(
copies
);
REFLECT
(
copies
);
REFLECT
(
center
);
REFLECT
(
center
);
REFLECT
(
handle
);
REFLECT
(
handle
);
// Fixes after reading
REFLECT
(
parts
);
REFLECT_IF_READING
{
REFLECT_IF_READING
calculateBoundsNonRec
();
if
(
name
.
empty
())
{
if
(
kind
==
SYMMETRY_REFLECTION
)
{
name
=
_
(
"Mirror"
);
}
else
{
name
=
_
(
"Symmetry"
);
}
}
}
}
}
// ----------------------------------------------------------------------------- : SymbolGroup
// ----------------------------------------------------------------------------- : SymbolGroup
SymbolGroup
::
SymbolGroup
()
{
name
=
capitalize
(
_TYPE_
(
"group"
));
}
String
SymbolGroup
::
typeName
()
const
{
String
SymbolGroup
::
typeName
()
const
{
return
_
(
"group"
);
return
_
(
"group"
);
}
}
...
@@ -240,6 +241,14 @@ SymbolPartP SymbolGroup::clone() const {
...
@@ -240,6 +241,14 @@ SymbolPartP SymbolGroup::clone() const {
return
part
;
return
part
;
}
}
bool
SymbolGroup
::
isAncestor
(
const
SymbolPart
&
that
)
const
{
if
(
this
==
&
that
)
return
true
;
FOR_EACH_CONST
(
p
,
parts
)
{
if
(
p
->
isAncestor
(
that
))
return
true
;
}
return
false
;
}
void
SymbolGroup
::
calculateBounds
()
{
void
SymbolGroup
::
calculateBounds
()
{
FOR_EACH
(
p
,
parts
)
p
->
calculateBounds
();
FOR_EACH
(
p
,
parts
)
p
->
calculateBounds
();
calculateBoundsNonRec
();
calculateBoundsNonRec
();
...
@@ -256,12 +265,14 @@ void SymbolGroup::calculateBoundsNonRec() {
...
@@ -256,12 +265,14 @@ void SymbolGroup::calculateBoundsNonRec() {
IMPLEMENT_REFLECTION
(
SymbolGroup
)
{
IMPLEMENT_REFLECTION
(
SymbolGroup
)
{
REFLECT_BASE
(
SymbolPart
);
REFLECT_BASE
(
SymbolPart
);
REFLECT
(
parts
);
REFLECT
(
parts
);
REFLECT_IF_READING
calculateBoundsNonRec
();
}
}
// ----------------------------------------------------------------------------- : Symbol
// ----------------------------------------------------------------------------- : Symbol
IMPLEMENT_REFLECTION
(
Symbol
)
{
IMPLEMENT_REFLECTION
(
Symbol
)
{
REFLECT
(
parts
);
REFLECT
(
parts
);
REFLECT_IF_READING
calculateBoundsNonRec
();
}
}
// ----------------------------------------------------------------------------- : Default symbol
// ----------------------------------------------------------------------------- : Default symbol
...
...
src/data/symbol.hpp
View file @
67c0e51f
...
@@ -133,6 +133,10 @@ class SymbolPart : public IntrusivePtrVirtualBase {
...
@@ -133,6 +133,10 @@ 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
;
}
/// Does this part contain another?
/** also true if this==that*/
virtual
bool
isAncestor
(
const
SymbolPart
&
that
)
const
{
return
this
==
&
that
;
}
/// Calculate the position and size of the part (min_pos and max_pos)
/// Calculate the position and size of the part (min_pos and max_pos)
virtual
void
calculateBounds
();
virtual
void
calculateBounds
();
...
@@ -191,6 +195,30 @@ class SymbolShape : public SymbolPart {
...
@@ -191,6 +195,30 @@ class SymbolShape : public SymbolPart {
DECLARE_REFLECTION
();
DECLARE_REFLECTION
();
};
};
// ----------------------------------------------------------------------------- : SymbolGroup
/// A group of symbol parts
class
SymbolGroup
:
public
SymbolPart
{
public:
vector
<
SymbolPartP
>
parts
;
///< The parts in this group, first item is on top
SymbolGroup
();
virtual
String
typeName
()
const
;
virtual
SymbolPartP
clone
()
const
;
virtual
int
icon
()
const
{
return
SYMBOL_COMBINE_BORDER
+
3
;
}
virtual
SymbolGroup
*
isSymbolGroup
()
{
return
this
;
}
virtual
const
SymbolGroup
*
isSymbolGroup
()
const
{
return
this
;
}
virtual
bool
isAncestor
(
const
SymbolPart
&
that
)
const
;
virtual
void
calculateBounds
();
/// re-calculate the bounds, but not of the contained parts
void
calculateBoundsNonRec
();
DECLARE_REFLECTION
();
};
// ----------------------------------------------------------------------------- : SymbolSymmetry
// ----------------------------------------------------------------------------- : SymbolSymmetry
enum
SymbolSymmetryType
enum
SymbolSymmetryType
...
@@ -198,9 +226,9 @@ enum SymbolSymmetryType
...
@@ -198,9 +226,9 @@ enum SymbolSymmetryType
,
SYMMETRY_REFLECTION
,
SYMMETRY_REFLECTION
};
};
/// A mirror, reflecting
part of the symbol
/// A mirror, reflecting
the part of the symbol in the group
/** Can handle rotation symmetry with any number of reflections */
/** Can handle rotation symmetry with any number of reflections */
class
SymbolSymmetry
:
public
Symbol
Part
{
class
SymbolSymmetry
:
public
Symbol
Group
{
public:
public:
SymbolSymmetryType
kind
;
///< What kind of symmetry
SymbolSymmetryType
kind
;
///< What kind of symmetry
int
copies
;
///< How many times is the orignal reflected (including the original itself)
int
copies
;
///< How many times is the orignal reflected (including the original itself)
...
@@ -219,26 +247,6 @@ class SymbolSymmetry : public SymbolPart {
...
@@ -219,26 +247,6 @@ class SymbolSymmetry : public SymbolPart {
DECLARE_REFLECTION
();
DECLARE_REFLECTION
();
};
};
// ----------------------------------------------------------------------------- : SymbolGroup
/// A group of symbol parts
class
SymbolGroup
:
public
SymbolPart
{
public:
vector
<
SymbolPartP
>
parts
;
///< The parts in this group, first item is on top
virtual
String
typeName
()
const
;
virtual
SymbolPartP
clone
()
const
;
virtual
int
icon
()
const
{
return
SYMMETRY_REFLECTION
+
1
;
}
virtual
SymbolGroup
*
isSymbolGroup
()
{
return
this
;
}
virtual
const
SymbolGroup
*
isSymbolGroup
()
const
{
return
this
;
}
virtual
void
calculateBounds
();
/// re-calculate the bounds, but not of the contained parts
void
calculateBoundsNonRec
();
DECLARE_REFLECTION
();
};
// ----------------------------------------------------------------------------- : Symbol
// ----------------------------------------------------------------------------- : Symbol
/// An editable symbol, consists of any number of SymbolParts
/// An editable symbol, consists of any number of SymbolParts
...
...
src/gui/symbol/basic_shape_editor.cpp
View file @
67c0e51f
...
@@ -28,7 +28,7 @@ SymbolBasicShapeEditor::SymbolBasicShapeEditor(SymbolControl* control)
...
@@ -28,7 +28,7 @@ SymbolBasicShapeEditor::SymbolBasicShapeEditor(SymbolControl* control)
void
SymbolBasicShapeEditor
::
draw
(
DC
&
dc
)
{
void
SymbolBasicShapeEditor
::
draw
(
DC
&
dc
)
{
// highlight the part we are drawing
// highlight the part we are drawing
if
(
drawing
)
{
if
(
shape
)
{
control
.
highlightPart
(
dc
,
*
shape
,
HIGHLIGHT_BORDER
);
control
.
highlightPart
(
dc
,
*
shape
,
HIGHLIGHT_BORDER
);
}
}
}
}
...
@@ -64,6 +64,7 @@ void SymbolBasicShapeEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
...
@@ -64,6 +64,7 @@ void SymbolBasicShapeEditor::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
delete
sides
;
delete
sides
;
delete
sidesL
;
delete
sidesL
;
#endif
#endif
stopActions
();
// set status text
}
}
void
SymbolBasicShapeEditor
::
onUpdateUI
(
wxUpdateUIEvent
&
ev
)
{
void
SymbolBasicShapeEditor
::
onUpdateUI
(
wxUpdateUIEvent
&
ev
)
{
...
@@ -80,6 +81,7 @@ void SymbolBasicShapeEditor::onCommand(int id) {
...
@@ -80,6 +81,7 @@ void SymbolBasicShapeEditor::onCommand(int id) {
if
(
id
>=
ID_SHAPE
&&
id
<
ID_SHAPE_MAX
)
{
if
(
id
>=
ID_SHAPE
&&
id
<
ID_SHAPE_MAX
)
{
// change shape mode
// change shape mode
mode
=
id
;
mode
=
id
;
stopActions
();
}
}
}
}
...
...
src/gui/symbol/control.cpp
View file @
67c0e51f
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
#include <gui/symbol/select_editor.hpp>
#include <gui/symbol/select_editor.hpp>
#include <gui/symbol/point_editor.hpp>
#include <gui/symbol/point_editor.hpp>
#include <gui/symbol/basic_shape_editor.hpp>
#include <gui/symbol/basic_shape_editor.hpp>
#include <gui/symbol/symmetry_editor.hpp>
#include <gui/util.hpp>
#include <gui/util.hpp>
#include <data/action/symbol.hpp>
#include <data/action/symbol.hpp>
#include <data/settings.hpp>
#include <data/settings.hpp>
...
@@ -36,7 +37,7 @@ void SymbolControl::switchEditor(const SymbolEditorBaseP& e) {
...
@@ -36,7 +37,7 @@ void SymbolControl::switchEditor(const SymbolEditorBaseP& e) {
}
}
void
SymbolControl
::
onChangeSymbol
()
{
void
SymbolControl
::
onChangeSymbol
()
{
selected_parts
.
clear
(
);
selected_parts
.
setSymbol
(
symbol
);
switchEditor
(
new_intrusive2
<
SymbolSelectEditor
>
(
this
,
false
));
switchEditor
(
new_intrusive2
<
SymbolSelectEditor
>
(
this
,
false
));
Refresh
(
false
);
Refresh
(
false
);
}
}
...
@@ -51,7 +52,7 @@ void SymbolControl::onModeChange(wxCommandEvent& ev) {
...
@@ -51,7 +52,7 @@ void SymbolControl::onModeChange(wxCommandEvent& ev) {
break
;
break
;
case
ID_MODE_POINTS
:
case
ID_MODE_POINTS
:
if
(
selected_parts
.
size
()
==
1
)
{
if
(
selected_parts
.
size
()
==
1
)
{
selected_shape
=
dynamic_pointer_cast
<
SymbolShape
>
(
*
selected_parts
.
begin
()
);
selected_shape
=
selected_parts
.
getAShape
(
);
if
(
selected_shape
)
{
if
(
selected_shape
)
{
switchEditor
(
new_intrusive2
<
SymbolPointEditor
>
(
this
,
selected_shape
));
switchEditor
(
new_intrusive2
<
SymbolPointEditor
>
(
this
,
selected_shape
));
}
}
...
@@ -64,6 +65,9 @@ void SymbolControl::onModeChange(wxCommandEvent& ev) {
...
@@ -64,6 +65,9 @@ void SymbolControl::onModeChange(wxCommandEvent& ev) {
}
}
switchEditor
(
new_intrusive1
<
SymbolBasicShapeEditor
>
(
this
));
switchEditor
(
new_intrusive1
<
SymbolBasicShapeEditor
>
(
this
));
break
;
break
;
case
ID_MODE_SYMMETRY
:
switchEditor
(
new_intrusive1
<
SymbolSymmetryEditor
>
(
this
));
break
;
}
}
}
}
...
@@ -92,25 +96,17 @@ void SymbolControl::onUpdateSelection() {
...
@@ -92,25 +96,17 @@ void SymbolControl::onUpdateSelection() {
switch
(
editor
->
modeToolId
())
{
switch
(
editor
->
modeToolId
())
{
case
ID_MODE_POINTS
:
{
case
ID_MODE_POINTS
:
{
// can only select a single part!
// can only select a single part!
if
(
selected_parts
.
size
()
>
1
)
{
SymbolShapeP
shape
=
selected_parts
.
getAShape
();
// TODO: find a part that is a shape
SymbolPartP
part
=
*
selected_parts
.
begin
();
selected_parts
.
clear
();
selected_parts
.
insert
(
part
);
signalSelectionChange
();
}
else
if
(
selected_parts
.
empty
())
{
selected_parts
.
insert
(
selected_shape
);
signalSelectionChange
();
break
;
}
SymbolShapeP
shape
=
dynamic_pointer_cast
<
SymbolShape
>
(
*
selected_parts
.
begin
());
if
(
!
shape
)
{
if
(
!
shape
)
{
selected_parts
.
clear
();
if
(
selected_parts
.
select
(
selected_shape
))
{
selected_parts
.
insert
(
selected_shape
);
signalSelectionChange
();
signalSelectionChange
();
}
break
;
break
;
}
}
if
(
shape
!=
selected_shape
)
{
if
(
shape
!=
selected_shape
)
{
if
(
selected_parts
.
select
(
shape
))
{
signalSelectionChange
();
}
// begin editing another part
// begin editing another part
selected_shape
=
shape
;
selected_shape
=
shape
;
editor
=
new_intrusive2
<
SymbolPointEditor
>
(
this
,
selected_shape
);
editor
=
new_intrusive2
<
SymbolPointEditor
>
(
this
,
selected_shape
);
...
@@ -131,16 +127,14 @@ void SymbolControl::onUpdateSelection() {
...
@@ -131,16 +127,14 @@ void SymbolControl::onUpdateSelection() {
}
}
void
SymbolControl
::
selectPart
(
const
SymbolPartP
&
part
)
{
void
SymbolControl
::
selectPart
(
const
SymbolPartP
&
part
)
{
selected_parts
.
clear
();
selected_parts
.
select
(
part
);
selected_parts
.
insert
(
part
);
switchEditor
(
new_intrusive2
<
SymbolSelectEditor
>
(
this
,
false
));
switchEditor
(
new_intrusive2
<
SymbolSelectEditor
>
(
this
,
false
));
signalSelectionChange
();
signalSelectionChange
();
}
}
void
SymbolControl
::
activatePart
(
const
SymbolPartP
&
part
)
{
void
SymbolControl
::
activatePart
(
const
SymbolPartP
&
part
)
{
if
(
part
->
isSymbolShape
())
{
if
(
part
->
isSymbolShape
())
{
selected_parts
.
clear
();
selected_parts
.
select
(
part
);
selected_parts
.
insert
(
part
);
switchEditor
(
new_intrusive2
<
SymbolPointEditor
>
(
this
,
static_pointer_cast
<
SymbolShape
>
(
part
)));
switchEditor
(
new_intrusive2
<
SymbolPointEditor
>
(
this
,
static_pointer_cast
<
SymbolShape
>
(
part
)));
}
}
}
}
...
@@ -247,11 +241,12 @@ void SymbolControl::onSize(wxSizeEvent& ev) {
...
@@ -247,11 +241,12 @@ void SymbolControl::onSize(wxSizeEvent& ev) {
void
SymbolControl
::
onUpdateUI
(
wxUpdateUIEvent
&
ev
)
{
void
SymbolControl
::
onUpdateUI
(
wxUpdateUIEvent
&
ev
)
{
if
(
!
editor
)
return
;
if
(
!
editor
)
return
;
switch
(
ev
.
GetId
())
{
switch
(
ev
.
GetId
())
{
case
ID_MODE_SELECT
:
case
ID_MODE_ROTATE
:
case
ID_MODE_POINTS
:
case
ID_MODE_SHAPES
:
//case ID_MODE_PAINT:
case
ID_MODE_SELECT
:
case
ID_MODE_ROTATE
:
case
ID_MODE_POINTS
:
case
ID_MODE_SHAPES
:
case
ID_MODE_SYMMETRY
:
//case ID_MODE_PAINT:
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 s
ingle part is selected <TODO?>
// can only edit points when a s
hape is available
ev
.
Enable
(
selected_parts
.
size
()
==
1
&&
(
*
selected_parts
.
begin
())
->
isSymbol
Shape
());
ev
.
Enable
(
selected_parts
.
getA
Shape
());
}
}
break
;
break
;
case
ID_MODE_PAINT
:
case
ID_MODE_PAINT
:
...
...
src/gui/symbol/control.hpp
View file @
67c0e51f
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include <util/prec.hpp>
#include <util/prec.hpp>
#include <data/symbol.hpp>
#include <data/symbol.hpp>
#include <gui/symbol/selection.hpp>
#include <render/symbol/viewer.hpp>
#include <render/symbol/viewer.hpp>
class
SymbolWindow
;
class
SymbolWindow
;
...
@@ -71,7 +72,7 @@ class SymbolControl : public wxControl, public SymbolViewer {
...
@@ -71,7 +72,7 @@ class SymbolControl : public wxControl, public SymbolViewer {
public:
public:
/// What parts are selected?
/// What parts are selected?
set
<
SymbolPartP
>
selected_parts
;
SymbolPartsSelection
selected_parts
;
SymbolPartP
highlight_part
;
///< part the mouse cursor is over
SymbolPartP
highlight_part
;
///< part the mouse cursor is over
SymbolShapeP
selected_shape
;
///< if there is a single selection
SymbolShapeP
selected_shape
;
///< if there is a single selection
...
...
src/gui/symbol/part_list.cpp
View file @
67c0e51f
...
@@ -7,10 +7,12 @@
...
@@ -7,10 +7,12 @@
// ----------------------------------------------------------------------------- : Includes
// ----------------------------------------------------------------------------- : Includes
#include <gui/symbol/part_list.hpp>
#include <gui/symbol/part_list.hpp>
#include <gui/symbol/selection.hpp>
#include <gui/util.hpp>
#include <gui/util.hpp>
#include <data/action/symbol.hpp>
#include <data/action/symbol.hpp>
#include <gfx/gfx.hpp>
#include <gfx/gfx.hpp>
#include <render/symbol/filter.hpp>
#include <render/symbol/filter.hpp>
#include <util/error.hpp>
#include <wx/dcbuffer.h>
#include <wx/dcbuffer.h>
#include <wx/caret.h>
#include <wx/caret.h>
...
@@ -24,11 +26,12 @@ DEFINE_EVENT_TYPE(EVENT_PART_ACTIVATE);
...
@@ -24,11 +26,12 @@ DEFINE_EVENT_TYPE(EVENT_PART_ACTIVATE);
// ----------------------------------------------------------------------------- : SymbolPartList
// ----------------------------------------------------------------------------- : SymbolPartList
SymbolPartList
::
SymbolPartList
(
Window
*
parent
,
int
id
,
set
<
SymbolPartP
>
&
selection
,
SymbolP
symbol
)
SymbolPartList
::
SymbolPartList
(
Window
*
parent
,
int
id
,
SymbolPartsSelection
&
selection
,
SymbolP
symbol
)
:
wxScrolledWindow
(
parent
,
id
,
wxDefaultPosition
,
wxDefaultSize
,
wxSUNKEN_BORDER
|
wxVSCROLL
)
:
wxScrolledWindow
(
parent
,
id
,
wxDefaultPosition
,
wxDefaultSize
,
wxSUNKEN_BORDER
|
wxVSCROLL
)
,
selection
(
selection
)
,
selection
(
selection
)
,
state_icons
(
9
,
8
)
,
state_icons
(
9
,
8
)
{
{
SetScrollRate
(
0
,
ITEM_HEIGHT
+
1
);
// 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!
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_merge"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_merge"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_subtract"
)));
state_icons
.
Add
(
load_resource_image
(
_
(
"icon_combine_subtract"
)));
...
@@ -69,7 +72,7 @@ void SymbolPartList::onAction(const Action& action, bool undone) {
...
@@ -69,7 +72,7 @@ void SymbolPartList::onAction(const Action& action, bool undone) {
TYPE_CASE_
(
action
,
SymbolPartAction
)
{
TYPE_CASE_
(
action
,
SymbolPartAction
)
{
symbol_preview
.
up_to_date
=
false
;
symbol_preview
.
up_to_date
=
false
;
// some part changed, but we don't know which one, assume it is the selection
// some part changed, but we don't know which one, assume it is the selection
updateParts
(
selection
);
updateParts
(
selection
.
get
()
);
return
;
return
;
}
}
}
}
...
@@ -84,7 +87,7 @@ wxSize SymbolPartList::DoGetBestSize() const {
...
@@ -84,7 +87,7 @@ wxSize SymbolPartList::DoGetBestSize() const {
void
SymbolPartList
::
update
()
{
void
SymbolPartList
::
update
()
{
// count items
// count items
number_of_items
=
childCount
(
symbol
);
number_of_items
=
childCount
(
symbol
);
SetVirtualSize
(
110
,
number_of_items
*
(
ITEM_HEIGHT
+
1
));
SetVirtualSize
(
110
,
number_of_items
*
(
ITEM_HEIGHT
+
1
));
// invalidate previews
// invalidate previews
symbol_preview
.
up_to_date
=
false
;
symbol_preview
.
up_to_date
=
false
;
for
(
size_t
i
=
0
;
i
<
part_previews
.
size
()
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
part_previews
.
size
()
;
++
i
)
{
...
@@ -118,23 +121,19 @@ void SymbolPartList::updatePart(const set<SymbolPartP>& parts, int& i, bool pare
...
@@ -118,23 +121,19 @@ void SymbolPartList::updatePart(const set<SymbolPartP>& parts, int& i, bool pare
// ----------------------------------------------------------------------------- : Events
// ----------------------------------------------------------------------------- : Events
void
SymbolPartList
::
onLeftDown
(
wxMouseEvent
&
ev
)
{
void
SymbolPartList
::
onLeftDown
(
wxMouseEvent
&
ev
)
{
int
top
;
GetViewStart
(
0
,
&
top
);
// find item under cursor
// find item under cursor
if
(
ev
.
GetX
()
<
0
||
ev
.
GetX
()
>=
GetClientSize
().
x
)
return
;
if
(
ev
.
GetX
()
<
0
||
ev
.
GetX
()
>=
GetClientSize
().
x
)
return
;
SymbolPartP
part
=
findItem
(
ev
.
GetY
()
/
(
ITEM_HEIGHT
+
1
));
int
pos
=
top
+
ev
.
GetY
()
/
(
ITEM_HEIGHT
+
1
);
SymbolPartP
part
=
findItem
(
pos
,
ev
.
GetX
());
if
(
part
)
{
if
(
part
)
{
// toggle/select
// toggle/select
if
(
!
ev
.
ShiftDown
())
{
selection
.
select
(
part
,
ev
.
ShiftDown
()
?
SELECT_TOGGLE
:
SELECT_OVERRIDE
);
selection
.
clear
();
if
(
!
ev
.
ShiftDown
()
&&
selection
.
selected
(
part
))
{
}
if
(
selection
.
find
(
part
)
!=
selection
.
end
())
{
selection
.
erase
(
part
);
}
else
{
selection
.
insert
(
part
);
}
if
(
!
ev
.
ShiftDown
())
{
// drag item
// drag item
mouse_down_on
=
part
;
drag
=
part
;
drop_position
=
-
1
;
findParent
(
*
part
,
drag_parent
,
drag_position
);
drop_parent
=
SymbolGroupP
();
CaptureMouse
();
CaptureMouse
();
}
}
sendEvent
(
EVENT_PART_SELECT
);
sendEvent
(
EVENT_PART_SELECT
);
...
@@ -144,43 +143,65 @@ void SymbolPartList::onLeftDown(wxMouseEvent& ev) {
...
@@ -144,43 +143,65 @@ void SymbolPartList::onLeftDown(wxMouseEvent& ev) {
}
}
void
SymbolPartList
::
onLeftUp
(
wxMouseEvent
&
ev
)
{
void
SymbolPartList
::
onLeftUp
(
wxMouseEvent
&
ev
)
{
if
(
HasCapture
())
ReleaseMouse
();
if
(
HasCapture
())
ReleaseMouse
();
if
(
mouse_down_on
&&
drop_position
!=
-
1
)
{
if
(
drag_parent
&&
drop_parent
)
{
// move part
// move part
// find old position
if
(
drag_parent
==
drop_parent
&&
drag_position
<
drop_position
)
{
vector
<
SymbolPartP
>::
const_iterator
it
=
find
(
symbol
->
parts
.
begin
(),
symbol
->
parts
.
end
(),
mouse_down_on
);
drop_position
-=
1
;
// adjust for removal of the dragged part
mouse_down_on
=
SymbolPartP
();
if
(
it
==
symbol
->
parts
.
end
())
{
Refresh
(
false
);
return
;
}
}
size_t
old_position
=
it
-
symbol
->
parts
.
begin
();
// move part
// find new position
SymbolGroupP
par
=
drag_parent
;
drag_parent
=
SymbolGroupP
();
size_t
new_position
;
if
(
par
!=
drop_parent
||
drag_position
!=
drop_position
)
{
SymbolPartP
drop_before
=
findItem
(
drop_position
);
if
(
par
!=
drop_parent
&&
par
->
parts
.
size
()
==
1
&&
!
par
->
isSymbolSymmetry
())
{
it
=
find
(
symbol
->
parts
.
begin
(),
symbol
->
parts
.
end
(),
drop_before
);
// this leaves a group without elements, remove it
if
(
it
==
symbol
->
parts
.
end
())
{
findParent
(
*
par
,
par
,
drag_position
);
// parent of the group
new_position
=
number_of_items
-
1
;
symbol
->
actions
.
add
(
new
UngroupReorderSymbolPartsAction
(
*
par
,
drag_position
,
*
drop_parent
,
drop_position
))
;
}
else
{
}
else
{
new_position
=
it
-
symbol
->
parts
.
begin
();
symbol
->
actions
.
add
(
new
ReorderSymbolPartsAction
(
*
par
,
drag_position
,
*
drop_parent
,
drop_position
));
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
{
}
else
{
Refresh
(
false
);
Refresh
(
false
);
}
}
}
else
{
}
else
{
mouse_down_on
=
SymbolPart
P
();
drag_parent
=
SymbolGroup
P
();
}
}
}
}
void
SymbolPartList
::
onMotion
(
wxMouseEvent
&
ev
)
{
void
SymbolPartList
::
onMotion
(
wxMouseEvent
&
ev
)
{
if
(
mouse_down_on
)
{
int
top
;
GetViewStart
(
0
,
&
top
);
int
new_drop_position
=
(
ev
.
GetY
()
+
ITEM_HEIGHT
/
2
)
/
(
ITEM_HEIGHT
+
1
);
if
(
drag_parent
)
{
if
(
new_drop_position
<
0
||
new_drop_position
>
number_of_items
)
new_drop_position
=
-
1
;
int
pos
=
top
+
(
ev
.
GetY
()
+
ITEM_HEIGHT
/
2
)
/
(
ITEM_HEIGHT
+
1
);
// TODO: make sure it is not in a group
if
(
pos
<
0
)
pos
=
0
;
if
(
drop_position
!=
new_drop_position
)
{
if
(
pos
>=
number_of_items
)
pos
=
number_of_items
;
drop_position
=
new_drop_position
;
bool
before
=
ev
.
GetY
()
<
(
pos
-
top
)
*
(
ITEM_HEIGHT
+
1
);
// old stuff
SymbolGroupP
old_drop_parent
=
drop_parent
;
size_t
old_drop_position
=
drop_position
;
bool
old_drop_inside
=
drop_inside
;
// find drop target
drop_parent
=
SymbolGroupP
();
findDropTarget
(
symbol
,
pos
,
before
);
// the drop parent must be an ancestor or sibling of ancestor of the drag_parent
// i.e. the drop parent's parent must be an ancestor of drag_parent
if
(
drop_parent
)
{
drop_inside
=
!
drop_parent
->
isAncestor
(
*
drag_parent
);
while
(
drop_parent
!=
symbol
)
{
// is drop_parent a sibling of an ancestor of drag_parent?
SymbolGroupP
drop_parent_parent
;
size_t
drop_parent_position
;
findParent
(
*
drop_parent
,
drop_parent_parent
,
drop_parent_position
);
if
(
!
drop_parent_parent
->
isAncestor
(
*
drag_parent
))
{
// move up one level
drop_parent
=
drop_parent_parent
;
drop_position
=
drop_parent_position
;
}
else
{
break
;
}
}
if
(
drop_parent
==
symbol
)
{
drop_inside
=
false
;
}
}
// refresh?
if
(
drop_parent
!=
old_drop_parent
||
drop_position
!=
old_drop_position
||
drop_inside
!=
old_drop_inside
)
{
Refresh
(
false
);
Refresh
(
false
);
}
}
}
}
...
@@ -262,26 +283,76 @@ void SymbolPartList::sendEvent(int type) {
...
@@ -262,26 +283,76 @@ void SymbolPartList::sendEvent(int type) {
// ----------------------------------------------------------------------------- : Items
// ----------------------------------------------------------------------------- : Items
SymbolPartP
SymbolPartList
::
findItem
(
int
i
)
const
{
SymbolPartP
SymbolPartList
::
findItem
(
int
i
,
int
x
)
const
{
FOR_EACH
(
p
,
symbol
->
parts
)
{
FOR_EACH
(
p
,
symbol
->
parts
)
{
SymbolPartP
f
=
findItem
(
i
,
p
);
SymbolPartP
f
=
findItem
(
i
,
x
,
p
);
if
(
f
)
return
f
;
if
(
f
)
return
f
;
}
}
return
SymbolPartP
();
return
SymbolPartP
();
}
}
SymbolPartP
SymbolPartList
::
findItem
(
int
&
i
,
const
SymbolPartP
&
part
)
{
SymbolPartP
SymbolPartList
::
findItem
(
int
&
i
,
int
x
,
const
SymbolPartP
&
part
)
{
if
(
i
<
0
)
return
SymbolPartP
();
if
(
i
<
0
)
return
SymbolPartP
();
if
(
i
==
0
)
return
part
;
if
(
i
==
0
)
return
part
;
i
-=
1
;
i
-=
1
;
// sub item?
// sub item?
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
FOR_EACH
(
p
,
g
->
parts
)
{
if
(
findItem
(
i
,
p
))
return
part
;
SymbolPartP
f
=
findItem
(
i
,
x
-
5
,
p
);
if
(
f
)
return
x
<
5
?
part
:
f
;
// clicked on bar at the left of group?
}
}
}
}
return
SymbolPartP
();
return
SymbolPartP
();
}
}
void
SymbolPartList
::
findParent
(
const
SymbolPart
&
of
,
SymbolGroupP
&
parent_out
,
size_t
&
pos_out
)
{
if
(
!
findParent
(
of
,
symbol
,
parent_out
,
pos_out
))
{
throw
InternalError
(
_
(
"Symbol part without a parent"
));
}
}
bool
SymbolPartList
::
findParent
(
const
SymbolPart
&
of
,
const
SymbolGroupP
&
g
,
SymbolGroupP
&
parent_out
,
size_t
&
pos_out
)
{
if
(
!
g
)
return
false
;
for
(
size_t
i
=
0
;
i
<
g
->
parts
.
size
()
;
++
i
)
{
if
(
g
->
parts
[
i
].
get
()
==
&
of
)
{
parent_out
=
g
;
pos_out
=
i
;
return
true
;
}
if
(
findParent
(
of
,
dynamic_pointer_cast
<
SymbolGroup
>
(
g
->
parts
[
i
]),
parent_out
,
pos_out
))
return
true
;
}
return
false
;
}
bool
SymbolPartList
::
findDropTarget
(
const
SymbolPartP
&
parent
,
int
&
i
,
bool
before
)
{
if
(
parent
!=
symbol
)
--
i
;
if
(
SymbolGroup
*
g
=
parent
->
isSymbolGroup
())
{
size_t
pos
=
0
;
FOR_EACH
(
p
,
g
->
parts
)
{
if
(
i
<=
0
)
{
// drop before this part
drop_parent
=
static_pointer_cast
<
SymbolGroup
>
(
parent
);
drop_position
=
pos
;
return
true
;
}
if
(
p
==
drag
)
{
i
-=
childCount
(
p
)
+
1
;
// don't drop inside
}
else
{
if
(
findDropTarget
(
p
,
i
,
before
))
{
return
true
;
}
}
++
pos
;
}
if
(
i
<=
0
&&
(
parent
==
symbol
||
before
))
{
// drop at the end
drop_parent
=
static_pointer_cast
<
SymbolGroup
>
(
parent
);
drop_position
=
g
->
parts
.
size
();
return
true
;
}
}
return
false
;
}
int
SymbolPartList
::
childCount
(
const
SymbolPartP
&
part
)
{
int
SymbolPartList
::
childCount
(
const
SymbolPartP
&
part
)
{
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
int
count
=
0
;
int
count
=
0
;
...
@@ -292,9 +363,6 @@ int SymbolPartList::childCount(const SymbolPartP& part) {
...
@@ -292,9 +363,6 @@ int SymbolPartList::childCount(const SymbolPartP& part) {
}
}
}
}
// ----------------------------------------------------------------------------- : Text editor
// ----------------------------------------------------------------------------- : Drawing
// ----------------------------------------------------------------------------- : Drawing
...
@@ -307,23 +375,13 @@ void SymbolPartList::OnDraw(DC& dc) {
...
@@ -307,23 +375,13 @@ void SymbolPartList::OnDraw(DC& dc) {
// init
// init
dc
.
SetFont
(
*
wxNORMAL_FONT
);
dc
.
SetFont
(
*
wxNORMAL_FONT
);
// clear background
// clear background
wxSize
size
=
GetClientSize
(
);
wxSize
size
=
piecewise_max
(
GetVirtualSize
()
+
RealSize
(
0
,
ITEM_HEIGHT
+
1
),
GetClientSize
()
);
dc
.
SetPen
(
*
wxTRANSPARENT_PEN
);
dc
.
SetPen
(
*
wxTRANSPARENT_PEN
);
dc
.
SetBrush
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
));
dc
.
SetBrush
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
));
dc
.
DrawRectangle
(
0
,
0
,
size
.
x
,
size
.
y
);
dc
.
DrawRectangle
(
0
,
0
,
size
.
x
,
size
.
y
);
// items
// items
int
i
=
0
;
int
i
=
0
;
FOR_EACH
(
p
,
symbol
->
parts
)
{
drawItem
(
dc
,
0
,
i
,
false
,
symbol
);
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
// hide caret
if
(
selection
.
size
()
!=
1
)
{
if
(
selection
.
size
()
!=
1
)
{
typing_in
=
SymbolPartP
();
typing_in
=
SymbolPartP
();
...
@@ -339,7 +397,7 @@ void SymbolPartList::drawItem(DC& dc, int x, int& i, bool parent_active, const S
...
@@ -339,7 +397,7 @@ void SymbolPartList::drawItem(DC& dc, int x, int& i, bool parent_active, const S
// draw item : highlight
// draw item : highlight
Color
background
;
Color
background
;
dc
.
SetPen
(
*
wxTRANSPARENT_PEN
);
dc
.
SetPen
(
*
wxTRANSPARENT_PEN
);
bool
active
=
selection
.
find
(
part
)
!=
selection
.
end
(
);
bool
active
=
selection
.
selected
(
part
);
if
(
active
)
{
if
(
active
)
{
background
=
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_HIGHLIGHT
);
background
=
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_HIGHLIGHT
);
dc
.
SetBrush
(
background
);
dc
.
SetBrush
(
background
);
...
@@ -352,6 +410,9 @@ void SymbolPartList::drawItem(DC& dc, int x, int& i, bool parent_active, const S
...
@@ -352,6 +410,9 @@ void SymbolPartList::drawItem(DC& dc, int x, int& i, bool parent_active, const S
background
=
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
);
background
=
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
);
dc
.
SetTextForeground
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
));
dc
.
SetTextForeground
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
));
}
}
wxPen
line_pen
=
lerp
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
),
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
),
0.5
);
if
(
part
!=
symbol
)
{
// draw item : name
// draw item : name
int
h
=
dc
.
GetCharHeight
();
int
h
=
dc
.
GetCharHeight
();
dc
.
DrawText
(
part
->
name
,
ITEM_HEIGHT
+
x
+
3
,
y
+
(
ITEM_HEIGHT
-
h
)
/
2
);
dc
.
DrawText
(
part
->
name
,
ITEM_HEIGHT
+
x
+
3
,
y
+
(
ITEM_HEIGHT
-
h
)
/
2
);
...
@@ -361,8 +422,6 @@ void SymbolPartList::drawItem(DC& dc, int x, int& i, bool parent_active, const S
...
@@ -361,8 +422,6 @@ void SymbolPartList::drawItem(DC& dc, int x, int& i, bool parent_active, const S
dc
.
DrawBitmap
(
symbolPreview
(),
x
,
y
);
dc
.
DrawBitmap
(
symbolPreview
(),
x
,
y
);
dc
.
DrawBitmap
(
itemPreview
(
i
,
part
),
x
,
y
);
dc
.
DrawBitmap
(
itemPreview
(
i
,
part
),
x
,
y
);
// draw item : border
// draw item : border
wxPen
line_pen
=
lerp
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOW
),
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
),
0.5
);
dc
.
SetPen
(
line_pen
);
dc
.
SetPen
(
line_pen
);
dc
.
DrawLine
(
x
+
ITEM_HEIGHT
,
y
,
x
+
ITEM_HEIGHT
,
y
+
ITEM_HEIGHT
+
1
);
// line after image
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
dc
.
DrawLine
(
x
,
y
+
ITEM_HEIGHT
,
size
.
x
,
y
+
ITEM_HEIGHT
);
// line below
...
@@ -370,29 +429,48 @@ void SymbolPartList::drawItem(DC& dc, int x, int& i, bool parent_active, const S
...
@@ -370,29 +429,48 @@ void SymbolPartList::drawItem(DC& dc, int x, int& i, bool parent_active, const S
if
(
selection
.
size
()
==
1
&&
active
)
{
if
(
selection
.
size
()
==
1
&&
active
)
{
updateCaret
(
dc
,
x
+
ITEM_HEIGHT
+
3
,
y
+
(
ITEM_HEIGHT
-
h
)
/
2
,
h
,
part
);
updateCaret
(
dc
,
x
+
ITEM_HEIGHT
+
3
,
y
+
(
ITEM_HEIGHT
-
h
)
/
2
,
h
,
part
);
}
}
// draw icon
state_icons
.
Draw
(
part
->
icon
(),
dc
,
size
.
x
-
10
,
y
+
1
);
// move down
// move down
i
+=
1
;
i
+=
1
;
// draw more?
}
if
(
SymbolShape
*
s
=
part
->
isSymbolShape
())
{
// Draw children
// combine state
int
child_x
=
part
==
symbol
?
x
:
x
+
5
;
state_icons
.
Draw
(
s
->
combine
,
dc
,
size
.
x
-
10
,
y
+
1
);
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
}
else
if
(
SymbolSymmetry
*
s
=
part
->
isSymbolSymmetry
())
{
FOR_EACH
(
p
,
g
->
parts
)
drawItem
(
dc
,
child_x
,
i
,
active
||
parent_active
,
p
);
// kind of symmetry
}
state_icons
.
Draw
(
s
->
kind
,
dc
,
size
.
x
-
10
,
y
+
1
);
// draw bar on the left?
// TODO: show clip mode?
int
old_y
=
y
+
ITEM_HEIGHT
+
1
;
// after part itself
}
else
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
int
new_y
=
i
*
(
ITEM_HEIGHT
+
1
);
// after children
state_icons
.
Draw
(
SYMMETRY_REFLECTION
+
1
,
dc
,
size
.
x
-
10
,
y
+
1
);
if
(
old_y
!=
new_y
&&
part
!=
symbol
)
{
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
.
SetPen
(
line_pen
);
dc
.
SetBrush
(
background
);
dc
.
SetBrush
(
background
);
dc
.
DrawRectangle
(
x
-
1
,
y
-
1
,
5
+
1
,
new_y
-
y
+
1
);
dc
.
DrawRectangle
(
x
-
1
,
old_y
-
1
,
5
+
1
,
new_y
-
old_y
+
1
);
}
// Drop indicator?
if
(
drag_parent
&&
drop_parent
)
{
dc
.
SetPen
(
wxPen
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_WINDOWTEXT
),
3
));
if
(
drop_inside
)
{
if
(
part
==
drop_parent
)
{
// drop inside part
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
DrawRectangle
(
x
,
y
,
w
,
new_y
-
y
);
}
}
else
if
(
drop_position
<
drop_parent
->
parts
.
size
())
{
if
(
part
==
drop_parent
->
parts
[
drop_position
])
{
// drop before part
dc
.
DrawLine
(
x
,
y
,
size
.
x
,
y
);
dc
.
DrawLine
(
x
,
y
-
3
,
x
,
y
+
3
);
dc
.
DrawLine
(
size
.
x
-
1
,
y
-
3
,
size
.
x
-
1
,
y
+
3
);
}
}
}
else
{
}
else
{
throw
"Unknown symbol part type"
;
if
(
part
==
drop_parent
)
{
// drop after part
dc
.
DrawLine
(
child_x
,
new_y
,
size
.
x
,
new_y
);
dc
.
DrawLine
(
child_x
,
new_y
-
3
,
child_x
,
new_y
+
3
);
dc
.
DrawLine
(
size
.
x
-
1
,
new_y
-
3
,
size
.
x
-
1
,
new_y
+
3
);
}
}
}
}
}
}
...
@@ -432,6 +510,7 @@ const Image& SymbolPartList::symbolPreview() {
...
@@ -432,6 +510,7 @@ const Image& SymbolPartList::symbolPreview() {
}
}
void
SymbolPartList
::
updateCaret
(
DC
&
dc
,
int
x
,
int
y
,
int
h
,
const
SymbolPartP
&
part
)
{
void
SymbolPartList
::
updateCaret
(
DC
&
dc
,
int
x
,
int
y
,
int
h
,
const
SymbolPartP
&
part
)
{
int
top
;
GetViewStart
(
0
,
&
top
);
// make caret
// make caret
wxCaret
*
caret
=
GetCaret
();
wxCaret
*
caret
=
GetCaret
();
if
(
!
caret
)
{
if
(
!
caret
)
{
...
@@ -446,7 +525,7 @@ void SymbolPartList::updateCaret(DC& dc, int x, int y, int h, const SymbolPartP&
...
@@ -446,7 +525,7 @@ void SymbolPartList::updateCaret(DC& dc, int x, int y, int h, const SymbolPartP&
cursor
=
min
(
cursor
,
typing_in
->
name
.
size
());
cursor
=
min
(
cursor
,
typing_in
->
name
.
size
());
int
w
;
int
w
;
dc
.
GetTextExtent
(
typing_in
->
name
.
substr
(
0
,
cursor
),
&
w
,
nullptr
);
dc
.
GetTextExtent
(
typing_in
->
name
.
substr
(
0
,
cursor
),
&
w
,
nullptr
);
caret
->
Move
(
x
+
w
,
y
);
caret
->
Move
(
x
+
w
,
y
-
top
*
(
ITEM_HEIGHT
+
1
)
);
if
(
!
caret
->
IsVisible
())
caret
->
Show
();
if
(
!
caret
->
IsVisible
())
caret
->
Show
();
}
}
...
...
src/gui/symbol/part_list.hpp
View file @
67c0e51f
...
@@ -12,6 +12,8 @@
...
@@ -12,6 +12,8 @@
#include <util/prec.hpp>
#include <util/prec.hpp>
#include <data/symbol.hpp>
#include <data/symbol.hpp>
class
SymbolPartsSelection
;
// ----------------------------------------------------------------------------- : Events
// ----------------------------------------------------------------------------- : Events
DECLARE_EVENT_TYPE
(
EVENT_PART_SELECT
,
<
not
used
>
)
DECLARE_EVENT_TYPE
(
EVENT_PART_SELECT
,
<
not
used
>
)
...
@@ -26,7 +28,7 @@ DECLARE_EVENT_TYPE(EVENT_PART_ACTIVATE, <not used>)
...
@@ -26,7 +28,7 @@ DECLARE_EVENT_TYPE(EVENT_PART_ACTIVATE, <not used>)
class
SymbolPartList
:
public
wxScrolledWindow
,
public
SymbolView
{
class
SymbolPartList
:
public
wxScrolledWindow
,
public
SymbolView
{
public:
public:
SymbolPartList
(
Window
*
parent
,
int
id
,
set
<
SymbolPartP
>
&
selection
,
SymbolP
symbol
=
SymbolP
());
SymbolPartList
(
Window
*
parent
,
int
id
,
SymbolPartsSelection
&
selection
,
SymbolP
symbol
=
SymbolP
());
/// Another symbol is being viewed
/// Another symbol is being viewed
virtual
void
onChangeSymbol
();
virtual
void
onChangeSymbol
();
...
@@ -41,12 +43,14 @@ class SymbolPartList : public wxScrolledWindow, public SymbolView {
...
@@ -41,12 +43,14 @@ class SymbolPartList : public wxScrolledWindow, public SymbolView {
protected:
protected:
virtual
wxSize
DoGetBestSize
()
const
;
virtual
wxSize
DoGetBestSize
()
const
;
private:
private:
set
<
SymbolPartP
>&
selection
;
///< Store selection here
SymbolPartsSelection
&
selection
;
///< Store selection here
SymbolPartP
mouse_down_on
;
int
drop_position
;
int
number_of_items
;
int
number_of_items
;
SymbolPartP
drag
;
SymbolGroupP
drag_parent
,
drop_parent
;
size_t
drag_position
,
drop_position
;
bool
drop_inside
;
// drop inside the drop parent, not at a specific position
SymbolPartP
typing_in
;
SymbolPartP
typing_in
;
size_t
cursor
;
size_t
cursor
;
...
@@ -79,8 +83,20 @@ class SymbolPartList : public wxScrolledWindow, public SymbolView {
...
@@ -79,8 +83,20 @@ class SymbolPartList : public wxScrolledWindow, public SymbolView {
const
Image
&
symbolPreview
();
const
Image
&
symbolPreview
();
void
updatePart
(
const
set
<
SymbolPartP
>&
parts
,
int
&
i
,
bool
parent_updated
,
const
SymbolPartP
&
part
);
void
updatePart
(
const
set
<
SymbolPartP
>&
parts
,
int
&
i
,
bool
parent_updated
,
const
SymbolPartP
&
part
);
SymbolPartP
findItem
(
int
i
)
const
;
/// find item by position
static
SymbolPartP
findItem
(
int
&
i
,
const
SymbolPartP
&
part
);
SymbolPartP
findItem
(
int
i
,
int
x
)
const
;
static
SymbolPartP
findItem
(
int
&
i
,
int
x
,
const
SymbolPartP
&
part
);
/// parent of 'of' and the position of 'of' in that parent
void
findParent
(
const
SymbolPart
&
of
,
SymbolGroupP
&
parent_out
,
size_t
&
pos_out
);
static
bool
findParent
(
const
SymbolPart
&
of
,
const
SymbolGroupP
&
in
,
SymbolGroupP
&
parent_out
,
size_t
&
pos_out
);
/// Where is the drop position?
/** i = index before which the cursor is
* before = is the cursor before or after the separator line?
* Returns whether a drop position was found, sets drop_...
*/
bool
findDropTarget
(
const
SymbolPartP
&
parent
,
int
&
i
,
bool
before
);
static
int
childCount
(
const
SymbolPartP
&
part
);
static
int
childCount
(
const
SymbolPartP
&
part
);
...
...
src/gui/symbol/select_editor.cpp
View file @
67c0e51f
...
@@ -21,6 +21,7 @@ DECLARE_TYPEOF_COLLECTION(SymbolPartP);
...
@@ -21,6 +21,7 @@ DECLARE_TYPEOF_COLLECTION(SymbolPartP);
SymbolSelectEditor
::
SymbolSelectEditor
(
SymbolControl
*
control
,
bool
rotate
)
SymbolSelectEditor
::
SymbolSelectEditor
(
SymbolControl
*
control
,
bool
rotate
)
:
SymbolEditorBase
(
control
)
:
SymbolEditorBase
(
control
)
,
click_mode
(
CLICK_NONE
)
,
rotate
(
rotate
)
,
rotate
(
rotate
)
,
cursorRotate
(
load_resource_cursor
(
_
(
"rotate"
)))
,
cursorRotate
(
load_resource_cursor
(
_
(
"rotate"
)))
,
cursorShearX
(
load_resource_cursor
(
_
(
"shear_x"
)))
,
cursorShearX
(
load_resource_cursor
(
_
(
"shear_x"
)))
...
@@ -45,15 +46,23 @@ SymbolSelectEditor::SymbolSelectEditor(SymbolControl* control, bool rotate)
...
@@ -45,15 +46,23 @@ SymbolSelectEditor::SymbolSelectEditor(SymbolControl* control, bool rotate)
void
SymbolSelectEditor
::
draw
(
DC
&
dc
)
{
void
SymbolSelectEditor
::
draw
(
DC
&
dc
)
{
// highlight selected parts
// highlight selected parts
FOR_EACH
(
p
,
control
.
selected_parts
)
{
FOR_EACH
(
p
,
control
.
selected_parts
.
get
()
)
{
control
.
highlightPart
(
dc
,
*
p
,
HIGHLIGHT_INTERIOR
);
control
.
highlightPart
(
dc
,
*
p
,
HIGHLIGHT_INTERIOR
);
}
}
// highlight the part under the cursor
// highlight the part under the cursor
if
(
highlightPart
)
{
if
(
highlightPart
)
{
control
.
highlightPart
(
dc
,
*
highlightPart
,
HIGHLIGHT_BORDER
);
control
.
highlightPart
(
dc
,
*
highlightPart
,
HIGHLIGHT_BORDER
);
}
}
if
(
click_mode
==
CLICK_RECT
)
{
// draw selection rectangle
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
SetPen
(
wxPen
(
*
wxBLUE
,
1
,
wxDOT
));
RealRect
rect
=
control
.
rotation
.
tr
(
RealRect
(
selection_rect_a
,
RealSize
(
selection_rect_b
-
selection_rect_a
)));
dc
.
DrawRectangle
(
rect
);
}
else
{
// draw handles
// draw handles
drawHandles
(
dc
);
drawHandles
(
dc
);
}
}
}
void
SymbolSelectEditor
::
drawHandles
(
DC
&
dc
)
{
void
SymbolSelectEditor
::
drawHandles
(
DC
&
dc
)
{
...
@@ -130,7 +139,7 @@ void SymbolSelectEditor::onUpdateUI(wxUpdateUIEvent& ev) {
...
@@ -130,7 +139,7 @@ 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
)
{
bool
enable
=
false
;
bool
enable
=
false
;
bool
check
=
true
;
bool
check
=
true
;
FOR_EACH
(
p
,
control
.
selected_parts
)
{
FOR_EACH
(
p
,
control
.
selected_parts
.
get
()
)
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
if
(
SymbolShape
*
s
=
p
->
isSymbolShape
())
{
enable
=
true
;
enable
=
true
;
if
(
s
->
combine
!=
ev
.
GetId
()
-
ID_SYMBOL_COMBINE
)
{
if
(
s
->
combine
!=
ev
.
GetId
()
-
ID_SYMBOL_COMBINE
)
{
...
@@ -147,8 +156,8 @@ void SymbolSelectEditor::onUpdateUI(wxUpdateUIEvent& ev) {
...
@@ -147,8 +156,8 @@ void SymbolSelectEditor::onUpdateUI(wxUpdateUIEvent& ev) {
ev
.
Enable
(
control
.
selected_parts
.
size
()
>=
2
);
ev
.
Enable
(
control
.
selected_parts
.
size
()
>=
2
);
}
else
if
(
ev
.
GetId
()
==
ID_EDIT_UNGROUP
)
{
}
else
if
(
ev
.
GetId
()
==
ID_EDIT_UNGROUP
)
{
// is a group selected
// is a group selected
FOR_EACH
(
p
,
control
.
selected_parts
)
{
FOR_EACH
(
p
,
control
.
selected_parts
.
get
()
)
{
if
(
p
->
isSymbolGroup
())
{
if
(
p
->
isSymbolGroup
()
&&
!
p
->
isSymbolSymmetry
()
)
{
ev
.
Enable
(
true
);
ev
.
Enable
(
true
);
return
;
return
;
}
}
...
@@ -163,21 +172,21 @@ void SymbolSelectEditor::onCommand(int id) {
...
@@ -163,21 +172,21 @@ void SymbolSelectEditor::onCommand(int id) {
if
(
id
>=
ID_SYMBOL_COMBINE
&&
id
<
ID_SYMBOL_COMBINE_MAX
)
{
if
(
id
>=
ID_SYMBOL_COMBINE
&&
id
<
ID_SYMBOL_COMBINE_MAX
)
{
// change combine mode
// change combine mode
getSymbol
()
->
actions
.
add
(
new
CombiningModeAction
(
getSymbol
()
->
actions
.
add
(
new
CombiningModeAction
(
control
.
selected_parts
,
control
.
selected_parts
.
get
()
,
static_cast
<
SymbolShapeCombine
>
(
id
-
ID_SYMBOL_COMBINE
)
static_cast
<
SymbolShapeCombine
>
(
id
-
ID_SYMBOL_COMBINE
)
));
));
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
getSymbol
()
->
actions
.
add
(
new
DuplicateSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
getSymbol
()
->
actions
.
add
(
new
DuplicateSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
.
get
()
));
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
}
else
if
(
id
==
ID_EDIT_GROUP
&&
!
isEditing
())
{
}
else
if
(
id
==
ID_EDIT_GROUP
&&
!
isEditing
())
{
// group selection, not when dragging
// group selection, not when dragging
getSymbol
()
->
actions
.
add
(
new
GroupSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
getSymbol
()
->
actions
.
add
(
new
GroupSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
.
get
(),
new_intrusive
<
SymbolGroup
>
()
));
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
}
else
if
(
id
==
ID_EDIT_UNGROUP
&&
!
isEditing
())
{
}
else
if
(
id
==
ID_EDIT_UNGROUP
&&
!
isEditing
())
{
// ungroup selection, not when dragging
// ungroup selection, not when dragging
getSymbol
()
->
actions
.
add
(
new
UngroupSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
getSymbol
()
->
actions
.
add
(
new
UngroupSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
.
get
()
));
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
}
}
}
}
...
@@ -189,36 +198,28 @@ int SymbolSelectEditor::modeToolId() {
...
@@ -189,36 +198,28 @@ int SymbolSelectEditor::modeToolId() {
// ----------------------------------------------------------------------------- : Mouse Events
// ----------------------------------------------------------------------------- : Mouse Events
void
SymbolSelectEditor
::
onLeftDown
(
const
Vector2D
&
pos
,
wxMouseEvent
&
ev
)
{
void
SymbolSelectEditor
::
onLeftDown
(
const
Vector2D
&
pos
,
wxMouseEvent
&
ev
)
{
have_dragged
=
true
;
// change selection
// change selection
// Are we on a handle?
// Are we on a handle?
int
dx
,
dy
;
int
dx
,
dy
;
if
(
onAnyHandle
(
pos
,
&
dx
,
&
dy
))
return
;
// don't change the selection
if
(
onAnyHandle
(
pos
,
&
dx
,
&
dy
))
{
click_mode
=
CLICK_HANDLE
;
return
;
// don't change the selection
}
// Select the part under the cursor
// Select the part under the cursor
SymbolPartP
part
=
findPart
(
pos
);
SymbolPartP
part
=
control
.
selected_parts
.
find
(
pos
);
if
(
part
)
{
if
(
part
)
{
if
(
ev
.
ShiftDown
())
{
click_mode
=
control
.
selected_parts
.
select
(
part
,
ev
.
ShiftDown
()
?
SELECT_TOGGLE
:
SELECT_IF_OUTSIDE
)
// toggle selection
?
(
ev
.
ShiftDown
()
?
CLICK_NONE
:
CLICK_MOVE
)
set
<
SymbolPartP
>::
iterator
it
=
control
.
selected_parts
.
find
(
part
);
:
CLICK_TOGGLE
;
if
(
it
!=
control
.
selected_parts
.
end
())
{
control
.
selected_parts
.
erase
(
it
);
}
else
{
control
.
selected_parts
.
insert
(
part
);
}
}
else
{
if
(
control
.
selected_parts
.
find
(
part
)
!=
control
.
selected_parts
.
end
())
{
// already selected, do nothing
have_dragged
=
false
;
// we haven't done anything
}
else
{
}
else
{
// select the part under the cursor
// selection rectangle
control
.
selected_parts
.
clear
();
click_mode
=
CLICK_RECT
;
control
.
selected_parts
.
insert
(
part
);
selection_rect_a
=
selection_rect_b
=
pos
;
}
if
(
!
ev
.
ShiftDown
())
{
}
}
else
if
(
!
ev
.
ShiftDown
())
{
// select nothing
// select nothing
control
.
selected_parts
.
clear
();
control
.
selected_parts
.
clear
();
}
}
}
// selection has changed
// selection has changed
updateBoundingBox
();
updateBoundingBox
();
control
.
signalSelectionChange
();
control
.
signalSelectionChange
();
...
@@ -231,24 +232,18 @@ void SymbolSelectEditor::onLeftUp (const Vector2D& pos, wxMouseEvent& ev) {
...
@@ -231,24 +232,18 @@ void SymbolSelectEditor::onLeftUp (const Vector2D& pos, wxMouseEvent& ev) {
resetActions
();
resetActions
();
}
else
{
}
else
{
// mouse not moved -> change selection
// mouse not moved -> change selection
if
(
!
have_dragged
&&
!
ev
.
ShiftDown
())
{
if
(
click_mode
==
CLICK_TOGGLE
)
{
int
dx
,
dy
;
// switch between rotate and resize mode
if
(
onAnyHandle
(
pos
,
&
dx
,
&
dy
))
return
;
// don't change the selection
// Find the part under the cursor
SymbolPartP
part
=
findPart
(
pos
);
if
(
control
.
selected_parts
.
find
(
part
)
!=
control
.
selected_parts
.
end
())
{
// already selected, don't change selection
// instead switch between rotate and resize mode
rotate
=
!
rotate
;
rotate
=
!
rotate
;
}
}
}
}
}
click_mode
=
CLICK_NONE
;
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
}
}
void
SymbolSelectEditor
::
onLeftDClick
(
const
Vector2D
&
pos
,
wxMouseEvent
&
ev
)
{
void
SymbolSelectEditor
::
onLeftDClick
(
const
Vector2D
&
pos
,
wxMouseEvent
&
ev
)
{
// start editing the points of the clicked part
// start editing the points of the clicked part
highlightPart
=
findPart
(
pos
);
highlightPart
=
control
.
selected_parts
.
find
(
pos
);
if
(
highlightPart
)
{
if
(
highlightPart
)
{
control
.
activatePart
(
highlightPart
);
control
.
activatePart
(
highlightPart
);
}
}
...
@@ -256,7 +251,7 @@ void SymbolSelectEditor::onLeftDClick(const Vector2D& pos, wxMouseEvent& ev) {
...
@@ -256,7 +251,7 @@ void SymbolSelectEditor::onLeftDClick(const Vector2D& pos, wxMouseEvent& ev) {
void
SymbolSelectEditor
::
onMouseMove
(
const
Vector2D
&
from
,
const
Vector2D
&
to
,
wxMouseEvent
&
ev
)
{
void
SymbolSelectEditor
::
onMouseMove
(
const
Vector2D
&
from
,
const
Vector2D
&
to
,
wxMouseEvent
&
ev
)
{
// can we highlight a part?
// can we highlight a part?
highlightPart
=
findPart
(
to
);
highlightPart
=
control
.
selected_parts
.
find
(
to
);
// are we on a handle?
// are we on a handle?
int
dx
,
dy
;
int
dx
,
dy
;
if
(
!
control
.
selected_parts
.
empty
()
&&
onAnyHandle
(
to
,
&
dx
,
&
dy
))
{
if
(
!
control
.
selected_parts
.
empty
()
&&
onAnyHandle
(
to
,
&
dx
,
&
dy
))
{
...
@@ -296,31 +291,39 @@ template <typename Event> int snap(Event& ev) {
...
@@ -296,31 +291,39 @@ template <typename Event> int snap(Event& ev) {
}
}
void
SymbolSelectEditor
::
onMouseDrag
(
const
Vector2D
&
from
,
const
Vector2D
&
to
,
wxMouseEvent
&
ev
)
{
void
SymbolSelectEditor
::
onMouseDrag
(
const
Vector2D
&
from
,
const
Vector2D
&
to
,
wxMouseEvent
&
ev
)
{
have_dragged
=
true
;
if
(
click_mode
==
CLICK_NONE
)
return
;
if
(
control
.
selected_parts
.
empty
())
return
;
if
(
control
.
selected_parts
.
empty
())
return
;
if
(
click_mode
==
CLICK_RECT
)
{
// rectangle
control
.
selected_parts
.
selectRect
(
selection_rect_a
,
selection_rect_b
,
to
,
SELECT_TOGGLE
);
selection_rect_b
=
to
;
control
.
Refresh
(
false
);
}
if
(
!
isEditing
())
{
if
(
!
isEditing
())
{
// we don't have an action yet, determine what to do
// we don't have an action yet, determine what to do
// note: base it on the from position, which is the position where dragging started
// note: base it on the from position, which is the position where dragging started
if
(
onAnyHandle
(
from
,
&
scaleX
,
&
scaleY
))
{
if
(
onAnyHandle
(
from
,
&
scaleX
,
&
scaleY
))
{
click_mode
=
CLICK_HANDLE
;
if
(
rotate
)
{
if
(
rotate
)
{
if
(
scaleX
==
0
||
scaleY
==
0
)
{
if
(
scaleX
==
0
||
scaleY
==
0
)
{
// shear, center/fixed point on the opposite side
// shear, center/fixed point on the opposite side
shearAction
=
new
SymbolPartShearAction
(
control
.
selected_parts
,
handlePos
(
-
scaleX
,
-
scaleY
));
shearAction
=
new
SymbolPartShearAction
(
control
.
selected_parts
.
get
()
,
handlePos
(
-
scaleX
,
-
scaleY
));
getSymbol
()
->
actions
.
add
(
shearAction
);
getSymbol
()
->
actions
.
add
(
shearAction
);
}
else
{
}
else
{
// rotate
// rotate
rotateAction
=
new
SymbolPartRotateAction
(
control
.
selected_parts
,
center
);
rotateAction
=
new
SymbolPartRotateAction
(
control
.
selected_parts
.
get
()
,
center
);
getSymbol
()
->
actions
.
add
(
rotateAction
);
getSymbol
()
->
actions
.
add
(
rotateAction
);
startAngle
=
angleTo
(
to
);
startAngle
=
angleTo
(
to
);
}
}
}
else
{
}
else
{
// we are on a handle; start scaling
// we are on a handle; start scaling
scaleAction
=
new
SymbolPartScaleAction
(
control
.
selected_parts
,
scaleX
,
scaleY
);
scaleAction
=
new
SymbolPartScaleAction
(
control
.
selected_parts
.
get
()
,
scaleX
,
scaleY
);
getSymbol
()
->
actions
.
add
(
scaleAction
);
getSymbol
()
->
actions
.
add
(
scaleAction
);
}
}
}
else
{
}
else
{
// move
// move
moveAction
=
new
SymbolPartMoveAction
(
control
.
selected_parts
);
click_mode
=
CLICK_MOVE
;
moveAction
=
new
SymbolPartMoveAction
(
control
.
selected_parts
.
get
());
getSymbol
()
->
actions
.
add
(
moveAction
);
getSymbol
()
->
actions
.
add
(
moveAction
);
}
}
}
}
...
@@ -391,8 +394,8 @@ void SymbolSelectEditor::onKeyChange (wxKeyEvent& ev) {
...
@@ -391,8 +394,8 @@ void SymbolSelectEditor::onKeyChange (wxKeyEvent& ev) {
void
SymbolSelectEditor
::
onChar
(
wxKeyEvent
&
ev
)
{
void
SymbolSelectEditor
::
onChar
(
wxKeyEvent
&
ev
)
{
if
(
ev
.
GetKeyCode
()
==
WXK_DELETE
)
{
if
(
ev
.
GetKeyCode
()
==
WXK_DELETE
)
{
// delete selected parts
// delete selected parts
getSymbol
()
->
actions
.
add
(
new
RemoveSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
));
getSymbol
()
->
actions
.
add
(
new
RemoveSymbolPartsAction
(
*
getSymbol
(),
control
.
selected_parts
.
get
()
));
if
(
control
.
selected_parts
.
find
(
highlightPart
)
!=
control
.
selected_parts
.
end
(
))
highlightPart
=
SymbolPartP
();
// deleted it
if
(
control
.
selected_parts
.
selected
(
highlightPart
))
highlightPart
=
SymbolPartP
();
// deleted it
control
.
selected_parts
.
clear
();
control
.
selected_parts
.
clear
();
resetActions
();
resetActions
();
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
...
@@ -408,7 +411,7 @@ void SymbolSelectEditor::onChar(wxKeyEvent& ev) {
...
@@ -408,7 +411,7 @@ void SymbolSelectEditor::onChar(wxKeyEvent& ev) {
ev
.
Skip
();
ev
.
Skip
();
return
;
return
;
}
}
getSymbol
()
->
actions
.
add
(
new
SymbolPartMoveAction
(
control
.
selected_parts
,
delta
));
getSymbol
()
->
actions
.
add
(
new
SymbolPartMoveAction
(
control
.
selected_parts
.
get
()
,
delta
));
}
}
}
}
...
@@ -450,35 +453,11 @@ double SymbolSelectEditor::angleTo(const Vector2D& pos) {
...
@@ -450,35 +453,11 @@ double SymbolSelectEditor::angleTo(const Vector2D& pos) {
return
atan2
(
center
.
x
-
pos
.
x
,
center
.
y
-
pos
.
y
);
return
atan2
(
center
.
x
-
pos
.
x
,
center
.
y
-
pos
.
y
);
}
}
SymbolPartP
find_part
(
const
SymbolPartP
&
part
,
const
Vector2D
&
pos
)
{
if
(
SymbolShape
*
s
=
part
->
isSymbolShape
())
{
if
(
point_in_shape
(
pos
,
*
s
))
return
part
;
}
else
if
(
SymbolSymmetry
*
s
=
part
->
isSymbolSymmetry
())
{
// TODO
}
else
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
if
(
find_part
(
p
,
pos
))
return
part
;
}
}
else
{
throw
InternalError
(
_
(
"Invalid symbol part type"
));
}
return
SymbolPartP
();
}
SymbolPartP
SymbolSelectEditor
::
findPart
(
const
Vector2D
&
pos
)
{
FOR_EACH
(
p
,
getSymbol
()
->
parts
)
{
SymbolPartP
found
=
find_part
(
p
,
pos
);
if
(
found
)
return
found
;
}
return
SymbolPartP
();
}
void
SymbolSelectEditor
::
updateBoundingBox
()
{
void
SymbolSelectEditor
::
updateBoundingBox
()
{
// Find min and max coordinates
// Find min and max coordinates
minV
=
Vector2D
::
infinity
();
minV
=
Vector2D
::
infinity
();
maxV
=
-
Vector2D
::
infinity
();
maxV
=
-
Vector2D
::
infinity
();
FOR_EACH
(
p
,
control
.
selected_parts
)
{
FOR_EACH
(
p
,
control
.
selected_parts
.
get
()
)
{
minV
=
piecewise_min
(
minV
,
p
->
min_pos
);
minV
=
piecewise_min
(
minV
,
p
->
min_pos
);
maxV
=
piecewise_max
(
maxV
,
p
->
max_pos
);
maxV
=
piecewise_max
(
maxV
,
p
->
max_pos
);
}
}
...
...
src/gui/symbol/select_editor.hpp
View file @
67c0e51f
...
@@ -74,6 +74,15 @@ class SymbolSelectEditor : public SymbolEditorBase {
...
@@ -74,6 +74,15 @@ class SymbolSelectEditor : public SymbolEditorBase {
Vector2D
minV
,
maxV
;
Vector2D
minV
,
maxV
;
// Where is the rotation center?
// Where is the rotation center?
Vector2D
center
;
Vector2D
center
;
// What kind of clicking/dragging are we doing
enum
ClickMode
{
CLICK_NONE
,
CLICK_MOVE
,
// moving parts around
CLICK_HANDLE
,
// dragging a handle
CLICK_CENTER
,
// dragging the rotation center
CLICK_RECT
,
// selection rectangle
CLICK_TOGGLE
,
// same selection, not moved -> switch to rotate mode
}
click_mode
;
// At what angle is the handle we started draging for rotation
// At what angle is the handle we started draging for rotation
double
startAngle
;
double
startAngle
;
// what side are we dragging/rotating on?
// what side are we dragging/rotating on?
...
@@ -82,6 +91,8 @@ class SymbolSelectEditor : public SymbolEditorBase {
...
@@ -82,6 +91,8 @@ class SymbolSelectEditor : public SymbolEditorBase {
bool
have_dragged
;
bool
have_dragged
;
// Do we want to rotate?
// Do we want to rotate?
bool
rotate
;
bool
rotate
;
// selection rectangle
Vector2D
selection_rect_a
,
selection_rect_b
;
// Graphics assets
// Graphics assets
wxCursor
cursorRotate
;
wxCursor
cursorRotate
;
wxCursor
cursorShearX
;
wxCursor
cursorShearX
;
...
@@ -104,9 +115,6 @@ class SymbolSelectEditor : public SymbolEditorBase {
...
@@ -104,9 +115,6 @@ class SymbolSelectEditor : public SymbolEditorBase {
/// Return the position of a handle, dx,dy in <-1, 0, 1>
/// Return the position of a handle, dx,dy in <-1, 0, 1>
Vector2D
handlePos
(
int
dx
,
int
dy
);
Vector2D
handlePos
(
int
dx
,
int
dy
);
/// Find the first part at the given position
SymbolPartP
findPart
(
const
Vector2D
&
pos
);
/// Update minV and maxV to be the bounding box of the selected_parts
/// Update minV and maxV to be the bounding box of the selected_parts
/// Updates center to be the rotation center of the parts
/// Updates center to be the rotation center of the parts
void
updateBoundingBox
();
void
updateBoundingBox
();
...
...
src/gui/symbol/window.cpp
View file @
67c0e51f
...
@@ -108,27 +108,27 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
...
@@ -108,27 +108,27 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
// Edit mode toolbar
// Edit mode toolbar
wxPanel
*
emp
=
new
wxPanel
(
this
,
wxID_ANY
);
wxPanel
*
emp
=
new
wxPanel
(
this
,
wxID_ANY
);
wxToolBar
*
em
=
new
wxToolBar
(
emp
,
wxID_ANY
,
wxDefaultPosition
,
wxDefaultSize
,
wxTB_FLAT
|
wxTB_VERTICAL
|
wxTB_TEXT
|
wxTB_HORZ_LAYOUT
);
wxToolBar
*
em
=
new
wxToolBar
(
emp
,
wxID_ANY
,
wxDefaultPosition
,
wxDefaultSize
,
wxTB_FLAT
|
wxTB_VERTICAL
|
wxTB_HORZ_TEXT
);
em
->
SetToolBitmapSize
(
wxSize
(
17
,
17
));
em
->
AddTool
(
ID_MODE_SELECT
,
_TOOL_
(
"select"
),
load_resource_tool_image
(
_
(
"mode_select"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"select"
),
_HELP_
(
"select"
));
em
->
AddTool
(
ID_MODE_SELECT
,
_TOOL_
(
"select"
),
load_resource_tool_image
(
_
(
"mode_select"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"select"
),
_HELP_
(
"select"
));
em
->
AddTool
(
ID_MODE_ROTATE
,
_TOOL_
(
"rotate"
),
load_resource_tool_image
(
_
(
"mode_rotate"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"rotate"
),
_HELP_
(
"rotate"
));
em
->
AddTool
(
ID_MODE_ROTATE
,
_TOOL_
(
"rotate"
),
load_resource_tool_image
(
_
(
"mode_rotate"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"rotate"
),
_HELP_
(
"rotate"
));
em
->
AddSeparator
();
em
->
AddSeparator
();
em
->
AddTool
(
ID_MODE_POINTS
,
_TOOL_
(
"points"
),
load_resource_tool_image
(
_
(
"mode_curve"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"points"
),
_HELP_
(
"points"
));
em
->
AddTool
(
ID_MODE_POINTS
,
_TOOL_
(
"points"
),
load_resource_tool_image
(
_
(
"mode_curve"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"points"
),
_HELP_
(
"points"
));
em
->
AddSeparator
();
em
->
AddSeparator
();
em
->
AddTool
(
ID_MODE_SHAPES
,
_TOOL_
(
"basic shapes"
),
load_resource_tool_image
(
_
(
"circle"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"basic shapes"
),
_HELP_
(
"basic shapes"
));
em
->
AddTool
(
ID_MODE_SHAPES
,
_TOOL_
(
"basic shapes"
),
load_resource_tool_image
(
_
(
"circle"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"basic shapes"
),
_HELP_
(
"basic shapes"
));
em
->
AddSeparator
();
em
->
AddTool
(
ID_MODE_SYMMETRY
,
_TOOL_
(
"symmetry"
),
load_resource_tool_image
(
_
(
"mode_symmetry"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"symmetry"
),
_HELP_
(
"symmetry"
));
em
->
AddTool
(
ID_MODE_PAINT
,
_TOOL_
(
"paint"
),
load_resource_tool_image
(
_
(
"mode_paint"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"paint"
),
_HELP_
(
"paint"
));
//em->AddTool(ID_MODE_PAINT, _TOOL_("paint"), load_resource_tool_image(_("mode_paint")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("paint"), _HELP_("paint"));
em
->
AddSeparator
();
em
->
Realize
();
em
->
Realize
();
// Lay out
wxSizer
*
es
=
new
wxBoxSizer
(
wxVERTICAL
);
es
->
Add
(
em
,
1
,
wxEXPAND
|
wxBOTTOM
|
wxALIGN_CENTER
,
5
);
emp
->
SetSizer
(
es
);
// Controls
// Controls
control
=
new
SymbolControl
(
this
,
ID_CONTROL
,
symbol
);
control
=
new
SymbolControl
(
this
,
ID_CONTROL
,
symbol
);
parts
=
new
SymbolPartList
(
this
,
ID_PART_LIST
,
control
->
selected_parts
,
symbol
);
parts
=
new
SymbolPartList
(
this
,
ID_PART_LIST
,
control
->
selected_parts
,
symbol
);
// Lay out
wxSizer
*
es
=
new
wxBoxSizer
(
wxHORIZONTAL
);
es
->
Add
(
em
,
1
,
wxEXPAND
|
wxTOP
|
wxBOTTOM
|
wxALIGN_CENTER
,
1
);
emp
->
SetSizer
(
es
);
wxSizer
*
s
=
new
wxBoxSizer
(
wxHORIZONTAL
);
wxSizer
*
s
=
new
wxBoxSizer
(
wxHORIZONTAL
);
wxSizer
*
v
=
new
wxBoxSizer
(
wxVERTICAL
);
wxSizer
*
v
=
new
wxBoxSizer
(
wxVERTICAL
);
v
->
Add
(
emp
,
0
,
wxEXPAND
);
v
->
Add
(
emp
,
0
,
wxEXPAND
);
...
@@ -137,6 +137,52 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
...
@@ -137,6 +137,52 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
s
->
Add
(
control
,
1
,
wxEXPAND
);
s
->
Add
(
control
,
1
,
wxEXPAND
);
SetSizer
(
s
);
SetSizer
(
s
);
#ifdef __WXMSW__
// only tested on msw, may not even be needed on other platforms
#define USE_HORRIBLE_HORRIBLE_HACK_TO_MAKE_TOOLBAR_THE_RIGHT_SIZE
#endif
#ifdef USE_HORRIBLE_HORRIBLE_HACK_TO_MAKE_TOOLBAR_THE_RIGHT_SIZE
// Welcome to HackWorld
// Prevent clipping of the bottom tool
Layout
();
em
->
SetSize
(
emp
->
GetSize
());
// HACK: force edit mode toolbar to be wide enough by adding spaces to tool names
int
n
=
0
;
while
(
em
->
GetSize
().
x
+
5
<
emp
->
GetSize
().
x
)
{
++
n
;
for
(
int
id
=
ID_MODE_SELECT
;
id
<=
ID_MODE_SYMMETRY
;
++
id
)
{
wxToolBarToolBase
*
tool
=
em
->
FindById
(
id
);
tool
->
SetLabel
(
tool
->
GetLabel
()
+
_
(
" "
));
}
em
->
Realize
();
}
// And now rebuild it, because the above meddling broke the toolbar for some unknown reason
em
->
Destroy
();
em
=
new
wxToolBar
(
emp
,
wxID_ANY
,
wxDefaultPosition
,
wxDefaultSize
,
wxTB_FLAT
|
wxTB_VERTICAL
|
wxTB_HORZ_TEXT
);
em
->
SetToolBitmapSize
(
wxSize
(
17
,
17
));
String
spaces
(
max
(
0
,
n
-
1
),
_
(
' '
));
em
->
AddTool
(
ID_MODE_SELECT
,
_TOOL_
(
"select"
)
+
spaces
,
load_resource_tool_image
(
_
(
"mode_select"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"select"
),
_HELP_
(
"select"
));
em
->
AddTool
(
ID_MODE_ROTATE
,
_TOOL_
(
"rotate"
)
+
spaces
,
load_resource_tool_image
(
_
(
"mode_rotate"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"rotate"
),
_HELP_
(
"rotate"
));
em
->
AddSeparator
();
em
->
AddTool
(
ID_MODE_POINTS
,
_TOOL_
(
"points"
)
+
spaces
,
load_resource_tool_image
(
_
(
"mode_curve"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"points"
),
_HELP_
(
"points"
));
em
->
AddSeparator
();
em
->
AddTool
(
ID_MODE_SHAPES
,
_TOOL_
(
"basic shapes"
)
+
spaces
,
load_resource_tool_image
(
_
(
"circle"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"basic shapes"
),
_HELP_
(
"basic shapes"
));
em
->
AddTool
(
ID_MODE_SYMMETRY
,
_TOOL_
(
"symmetry"
)
+
spaces
,
load_resource_tool_image
(
_
(
"mode_symmetry"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"symmetry"
),
_HELP_
(
"symmetry"
));
//em->AddTool(ID_MODE_PAINT, _TOOL_("paint") + spaces, load_resource_tool_image(_("mode_paint")), wxNullBitmap, wxITEM_CHECK, _TOOLTIP_("paint"), _HELP_("paint"));
em
->
Realize
();
es
=
new
wxBoxSizer
(
wxVERTICAL
);
es
->
Add
(
em
,
1
,
wxEXPAND
|
wxBOTTOM
|
wxALIGN_CENTER
,
5
);
emp
->
SetSizer
(
es
);
// Prevent clipping of the bottom tool
Layout
();
em
->
SetSize
(
emp
->
GetSize
());
#endif
// we want update ui events
// we want update ui events
wxUpdateUIEvent
::
SetMode
(
wxUPDATE_UI_PROCESS_SPECIFIED
);
wxUpdateUIEvent
::
SetMode
(
wxUPDATE_UI_PROCESS_SPECIFIED
);
SetExtraStyle
(
wxWS_EX_PROCESS_UI_UPDATES
);
SetExtraStyle
(
wxWS_EX_PROCESS_UI_UPDATES
);
...
...
src/mse.vcproj
View file @
67c0e51f
...
@@ -877,6 +877,18 @@
...
@@ -877,6 +877,18 @@
<File
<File
RelativePath=
".\gui\symbol\select_editor.hpp"
>
RelativePath=
".\gui\symbol\select_editor.hpp"
>
</File>
</File>
<File
RelativePath=
".\gui\symbol\selection.cpp"
>
</File>
<File
RelativePath=
".\gui\symbol\selection.hpp"
>
</File>
<File
RelativePath=
".\gui\symbol\symmetry_editor.cpp"
>
</File>
<File
RelativePath=
".\gui\symbol\symmetry_editor.hpp"
>
</File>
<File
<File
RelativePath=
".\gui\symbol\window.cpp"
>
RelativePath=
".\gui\symbol\window.cpp"
>
<FileConfiguration
<FileConfiguration
...
...
src/render/symbol/viewer.cpp
View file @
67c0e51f
...
@@ -164,7 +164,25 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolShape& shape, HighlightStyl
...
@@ -164,7 +164,25 @@ void SymbolViewer::highlightPart(DC& dc, const SymbolShape& shape, HighlightStyl
}
}
}
}
void
SymbolViewer
::
highlightPart
(
DC
&
dc
,
const
SymbolSymmetry
&
sym
)
{
void
SymbolViewer
::
highlightPart
(
DC
&
dc
,
const
SymbolSymmetry
&
sym
)
{
// TODO
// center
RealPoint
center
=
rotation
.
tr
(
sym
.
center
);
// draw 'spokes'
double
angle
=
atan2
(
sym
.
handle
.
y
,
sym
.
handle
.
x
);
dc
.
SetPen
(
wxPen
(
Color
(
255
,
200
,
0
),
3
));
for
(
int
i
=
0
;
i
<
sym
.
copies
;
++
i
)
{
double
a
=
angle
+
(
i
+
0.5
)
*
2
*
M_PI
/
sym
.
copies
;
Vector2D
dir
(
cos
(
a
),
sin
(
a
));
Vector2D
dir2
=
rotation
.
tr
(
sym
.
center
+
2
*
dir
);
dc
.
DrawLine
(
center
.
x
,
center
.
y
,
dir2
.
x
,
dir2
.
y
);
}
// draw center
dc
.
SetPen
(
*
wxBLACK_PEN
);
dc
.
SetBrush
(
Color
(
255
,
200
,
0
));
dc
.
DrawCircle
(
center
.
x
,
center
.
y
,
5
);
// draw handle
Vector2D
dir2
=
rotation
.
tr
(
sym
.
center
+
sym
.
handle
);
dc
.
SetPen
(
wxPen
(
Color
(
255
,
200
,
0
),
1
,
wxDOT
));
dc
.
DrawLine
(
center
.
x
,
center
.
y
,
dir2
.
x
,
dir2
.
y
);
}
}
void
SymbolViewer
::
highlightPart
(
DC
&
dc
,
const
SymbolGroup
&
group
,
HighlightStyle
style
)
{
void
SymbolViewer
::
highlightPart
(
DC
&
dc
,
const
SymbolGroup
&
group
,
HighlightStyle
style
)
{
if
(
style
==
HIGHLIGHT_BORDER
)
{
if
(
style
==
HIGHLIGHT_BORDER
)
{
...
...
src/script/context.cpp
View file @
67c0e51f
...
@@ -352,6 +352,7 @@ void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP&
...
@@ -352,6 +352,7 @@ void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP&
break
;
break
;
case
I_AND
:
OPERATOR_I
(
&&
);
case
I_AND
:
OPERATOR_I
(
&&
);
case
I_OR
:
OPERATOR_I
(
||
);
case
I_OR
:
OPERATOR_I
(
||
);
case
I_XOR
:
a
=
to_script
((
bool
)
*
a
!=
(
bool
)
*
b
);
break
;
case
I_EQ
:
OPERATOR_SDI
(
==
);
case
I_EQ
:
OPERATOR_SDI
(
==
);
case
I_NEQ
:
OPERATOR_SDI
(
!=
);
case
I_NEQ
:
OPERATOR_SDI
(
!=
);
case
I_LT
:
OPERATOR_DI
(
<
);
case
I_LT
:
OPERATOR_DI
(
<
);
...
...
src/script/parser.cpp
View file @
67c0e51f
...
@@ -582,6 +582,7 @@ void parseOper(TokenIterator& input, Script& script, Precedence minPrec, Instruc
...
@@ -582,6 +582,7 @@ void parseOper(TokenIterator& input, Script& script, Precedence minPrec, Instruc
parseOper
(
input
,
script
,
PREC_CMP
,
I_BINARY
,
I_OR
);
parseOper
(
input
,
script
,
PREC_CMP
,
I_BINARY
,
I_OR
);
}
}
}
}
else
if
(
minPrec
<=
PREC_AND
&&
token
==
_
(
"xor"
))
parseOper
(
input
,
script
,
PREC_CMP
,
I_BINARY
,
I_XOR
);
else
if
(
minPrec
<=
PREC_CMP
&&
token
==
_
(
"="
))
{
else
if
(
minPrec
<=
PREC_CMP
&&
token
==
_
(
"="
))
{
if
(
minPrec
<=
PREC_SET
)
{
if
(
minPrec
<=
PREC_SET
)
{
input
.
add_error
(
_
(
"Use of '=', did you mean ':=' or '=='?"
));
input
.
add_error
(
_
(
"Use of '=', did you mean ':=' or '=='?"
));
...
...
src/script/script.cpp
View file @
67c0e51f
...
@@ -146,6 +146,7 @@ String Script::dumpInstr(unsigned int pos, Instruction i) const {
...
@@ -146,6 +146,7 @@ String Script::dumpInstr(unsigned int pos, Instruction i) const {
case
I_MOD
:
ret
+=
_
(
"mod"
);
break
;
case
I_MOD
:
ret
+=
_
(
"mod"
);
break
;
case
I_AND
:
ret
+=
_
(
"and"
);
break
;
case
I_AND
:
ret
+=
_
(
"and"
);
break
;
case
I_OR
:
ret
+=
_
(
"or"
);
break
;
case
I_OR
:
ret
+=
_
(
"or"
);
break
;
case
I_XOR
:
ret
+=
_
(
"xor"
);
break
;
case
I_EQ
:
ret
+=
_
(
"=="
);
break
;
case
I_EQ
:
ret
+=
_
(
"=="
);
break
;
case
I_NEQ
:
ret
+=
_
(
"!="
);
break
;
case
I_NEQ
:
ret
+=
_
(
"!="
);
break
;
case
I_LT
:
ret
+=
_
(
"<"
);
break
;
case
I_LT
:
ret
+=
_
(
"<"
);
break
;
...
...
src/script/script.hpp
View file @
67c0e51f
...
@@ -63,6 +63,7 @@ enum BinaryInstructionType
...
@@ -63,6 +63,7 @@ enum BinaryInstructionType
// Logical
// Logical
,
I_AND
///< logical and
,
I_AND
///< logical and
,
I_OR
///< logical or
,
I_OR
///< logical or
,
I_XOR
///< logical xor
// Comparison
// Comparison
,
I_EQ
///< operator ==
,
I_EQ
///< operator ==
,
I_NEQ
///< operator !=
,
I_NEQ
///< operator !=
...
...
src/util/window_id.hpp
View file @
67c0e51f
...
@@ -152,6 +152,13 @@ enum ChildMenuID {
...
@@ -152,6 +152,13 @@ enum ChildMenuID {
,
ID_SHAPE_MAX
,
ID_SHAPE_MAX
,
ID_SIDES
,
ID_SIDES
// SymbolSymmetryEditor toolbar/menu
,
ID_SYMMETRY
=
2201
,
ID_SYMMETRY_ROTATION
=
ID_SHAPE
,
ID_SYMMETRY_REFLECTION
,
ID_SYMMETRY_MAX
,
ID_COPIES
// On cards panel
// On cards panel
,
ID_COLLAPSE_NOTES
=
3001
,
ID_COLLAPSE_NOTES
=
3001
...
...
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