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
b90e2dda
Commit
b90e2dda
authored
Jul 09, 2007
by
twanvl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented selection using rectangles in symbol editor
parent
67c0e51f
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
479 additions
and
11 deletions
+479
-11
src/data/action/symbol.cpp
src/data/action/symbol.cpp
+19
-6
src/data/action/symbol.hpp
src/data/action/symbol.hpp
+15
-2
src/gui/symbol/select_editor.cpp
src/gui/symbol/select_editor.cpp
+6
-3
src/gui/symbol/selection.cpp
src/gui/symbol/selection.cpp
+132
-0
src/gui/symbol/selection.hpp
src/gui/symbol/selection.hpp
+81
-0
src/gui/symbol/symmetry_editor.cpp
src/gui/symbol/symmetry_editor.cpp
+160
-0
src/gui/symbol/symmetry_editor.hpp
src/gui/symbol/symmetry_editor.hpp
+64
-0
src/script/parser.cpp
src/script/parser.cpp
+2
-0
No files found.
src/data/action/symbol.cpp
View file @
b90e2dda
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
DECLARE_TYPEOF_COLLECTION
(
pair
<
SymbolShapeP
COMMA
SymbolShapeCombine
>
);
DECLARE_TYPEOF_COLLECTION
(
pair
<
SymbolShapeP
COMMA
SymbolShapeCombine
>
);
DECLARE_TYPEOF_COLLECTION
(
pair
<
SymbolPartP
COMMA
size_t
>
);
DECLARE_TYPEOF_COLLECTION
(
pair
<
SymbolPartP
COMMA
size_t
>
);
DECLARE_TYPEOF_COLLECTION
(
RemoveSymbolPartsAction
::
Removal
);
DECLARE_TYPEOF_COLLECTION
(
SymbolPartP
);
DECLARE_TYPEOF_COLLECTION
(
SymbolPartP
);
DECLARE_TYPEOF_COLLECTION
(
ControlPointP
);
DECLARE_TYPEOF_COLLECTION
(
ControlPointP
);
...
@@ -375,13 +376,25 @@ void AddSymbolPartAction::perform(bool to_undo) {
...
@@ -375,13 +376,25 @@ void AddSymbolPartAction::perform(bool to_undo) {
RemoveSymbolPartsAction
::
RemoveSymbolPartsAction
(
Symbol
&
symbol
,
const
set
<
SymbolPartP
>&
parts
)
RemoveSymbolPartsAction
::
RemoveSymbolPartsAction
(
Symbol
&
symbol
,
const
set
<
SymbolPartP
>&
parts
)
:
symbol
(
symbol
)
:
symbol
(
symbol
)
{
{
check
(
symbol
,
parts
);
}
void
RemoveSymbolPartsAction
::
check
(
SymbolGroup
&
group
,
const
set
<
SymbolPartP
>&
parts
)
{
size_t
index
=
0
;
size_t
index
=
0
;
FOR_EACH
(
p
,
symbol
.
parts
)
{
size_t
removed
=
0
;
FOR_EACH
(
p
,
group
.
parts
)
{
if
(
parts
.
find
(
p
)
!=
parts
.
end
())
{
if
(
parts
.
find
(
p
)
!=
parts
.
end
())
{
removals
.
push_back
(
make_pair
(
p
,
index
));
// remove this part
removals
.
push_back
(
Removal
(
group
,
index
,
p
));
// remove this part
++
removed
;
}
else
if
(
SymbolGroup
*
g
=
p
->
isSymbolGroup
())
{
check
(
*
g
,
parts
);
}
}
++
index
;
++
index
;
}
}
if
(
!
group
.
isSymbolSymmetry
()
&&
&
group
!=
&
symbol
)
{
// remove empty groups
// TODO
}
}
}
String
RemoveSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
String
RemoveSymbolPartsAction
::
getName
(
bool
to_undo
)
const
{
...
@@ -393,15 +406,15 @@ void RemoveSymbolPartsAction::perform(bool to_undo) {
...
@@ -393,15 +406,15 @@ void RemoveSymbolPartsAction::perform(bool to_undo) {
// reinsert the parts
// reinsert the parts
// ascending order, this is the reverse of removal
// ascending order, this is the reverse of removal
FOR_EACH
(
r
,
removals
)
{
FOR_EACH
(
r
,
removals
)
{
assert
(
r
.
second
<=
symbol
.
parts
.
size
());
assert
(
r
.
pos
<=
r
.
parent
->
parts
.
size
());
symbol
.
parts
.
insert
(
symbol
.
parts
.
begin
()
+
r
.
second
,
r
.
first
);
r
.
parent
->
parts
.
insert
(
r
.
parent
->
parts
.
begin
()
+
r
.
pos
,
r
.
removed
);
}
}
}
else
{
}
else
{
// remove the parts
// remove the parts
// descending order, because earlier removals shift the rest of the vector
// descending order, because earlier removals shift the rest of the vector
FOR_EACH_REVERSE
(
r
,
removals
)
{
FOR_EACH_REVERSE
(
r
,
removals
)
{
assert
(
r
.
second
<
symbol
.
parts
.
size
());
assert
(
r
.
pos
<
r
.
parent
->
parts
.
size
());
symbol
.
parts
.
erase
(
symbol
.
parts
.
begin
()
+
r
.
second
);
r
.
parent
->
parts
.
erase
(
r
.
parent
->
parts
.
begin
()
+
r
.
pos
);
}
}
}
}
}
}
...
...
src/data/action/symbol.hpp
View file @
b90e2dda
...
@@ -211,8 +211,21 @@ class RemoveSymbolPartsAction : public SymbolPartListAction {
...
@@ -211,8 +211,21 @@ class RemoveSymbolPartsAction : public SymbolPartListAction {
private:
private:
Symbol
&
symbol
;
Symbol
&
symbol
;
/// Removed parts and their positions, sorted by ascending pos
/// Check for removals in a group
vector
<
pair
<
SymbolPartP
,
size_t
>
>
removals
;
void
check
(
SymbolGroup
&
group
,
const
set
<
SymbolPartP
>&
parts
);
public:
/// A removal step
struct
Removal
{
inline
Removal
(
SymbolGroup
&
parent
,
size_t
pos
,
const
SymbolPartP
&
removed
)
:
parent
(
&
parent
),
pos
(
pos
),
removed
(
removed
)
{}
SymbolGroup
*
parent
;
size_t
pos
;
SymbolPartP
removed
;
};
private:
/// Removed parts, sorted by ascending pos
vector
<
Removal
>
removals
;
};
};
// ----------------------------------------------------------------------------- : Duplicate symbol parts
// ----------------------------------------------------------------------------- : Duplicate symbol parts
...
...
src/gui/symbol/select_editor.cpp
View file @
b90e2dda
...
@@ -56,7 +56,7 @@ void SymbolSelectEditor::draw(DC& dc) {
...
@@ -56,7 +56,7 @@ void SymbolSelectEditor::draw(DC& dc) {
if
(
click_mode
==
CLICK_RECT
)
{
if
(
click_mode
==
CLICK_RECT
)
{
// draw selection rectangle
// draw selection rectangle
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
SetBrush
(
*
wxTRANSPARENT_BRUSH
);
dc
.
SetPen
(
wxPen
(
*
wx
BLUE
,
1
,
wxDOT
));
dc
.
SetPen
(
wxPen
(
*
wx
CYAN
,
1
,
wxDOT
));
RealRect
rect
=
control
.
rotation
.
tr
(
RealRect
(
selection_rect_a
,
RealSize
(
selection_rect_b
-
selection_rect_a
)));
RealRect
rect
=
control
.
rotation
.
tr
(
RealRect
(
selection_rect_a
,
RealSize
(
selection_rect_b
-
selection_rect_a
)));
dc
.
DrawRectangle
(
rect
);
dc
.
DrawRectangle
(
rect
);
}
else
{
}
else
{
...
@@ -292,13 +292,16 @@ template <typename Event> int snap(Event& ev) {
...
@@ -292,13 +292,16 @@ 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
)
{
if
(
click_mode
==
CLICK_NONE
)
return
;
if
(
click_mode
==
CLICK_NONE
)
return
;
if
(
control
.
selected_parts
.
empty
())
return
;
if
(
click_mode
==
CLICK_RECT
)
{
if
(
click_mode
==
CLICK_RECT
)
{
// rectangle
// rectangle
control
.
selected_parts
.
selectRect
(
selection_rect_a
,
selection_rect_b
,
to
,
SELECT_TOGGLE
);
if
(
control
.
selected_parts
.
selectRect
(
selection_rect_a
,
selection_rect_b
,
to
))
{
control
.
signalSelectionChange
();
}
selection_rect_b
=
to
;
selection_rect_b
=
to
;
control
.
Refresh
(
false
);
control
.
Refresh
(
false
);
return
;
}
}
if
(
control
.
selected_parts
.
empty
())
return
;
if
(
!
isEditing
())
{
if
(
!
isEditing
())
{
// we don't have an action yet, determine what to do
// we don't have an action yet, determine what to do
// note: base it on the from position, which is the position where dragging started
// note: base it on the from position, which is the position where dragging started
...
...
src/gui/symbol/selection.cpp
0 → 100644
View file @
b90e2dda
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2007 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <gui/symbol/selection.hpp>
#include <data/symbol.hpp>
#include <gfx/bezier.hpp>
DECLARE_TYPEOF_COLLECTION
(
SymbolPartP
);
// ----------------------------------------------------------------------------- : Selection
void
SymbolPartsSelection
::
setSymbol
(
const
SymbolP
&
symbol
)
{
root
=
symbol
.
get
();
clear
();
}
void
SymbolPartsSelection
::
clear
()
{
selection
.
clear
();
}
bool
SymbolPartsSelection
::
select
(
const
SymbolPartP
&
part
,
SelectMode
mode
)
{
// make sure part is not the decendent of a part that is already selected
if
(
mode
!=
SELECT_OVERRIDE
)
{
FOR_EACH
(
s
,
selection
)
{
if
(
isAncestor
(
s
.
get
(),
part
.
get
()))
return
false
;
}
}
// select
if
(
mode
==
SELECT_OVERRIDE
)
{
if
(
selection
.
size
()
==
1
&&
*
selection
.
begin
()
==
part
)
return
false
;
// already selected
selection
.
clear
();
selection
.
insert
(
part
);
}
else
if
(
mode
==
SELECT_IF_OUTSIDE
)
{
if
(
selected
(
part
))
{
return
false
;
}
else
{
selection
.
clear
();
selection
.
insert
(
part
);
}
}
else
{
if
(
selected
(
part
))
{
selection
.
erase
(
part
);
}
else
{
selection
.
insert
(
part
);
// make part is not the ancestor of a part that is already selected
clearChildren
(
part
.
get
());
}
}
return
true
;
}
SymbolShapeP
SymbolPartsSelection
::
getAShape
()
const
{
FOR_EACH
(
s
,
selection
)
{
if
(
s
->
isSymbolShape
())
return
static_pointer_cast
<
SymbolShape
>
(
s
);
}
return
SymbolShapeP
();
}
void
SymbolPartsSelection
::
clearChildren
(
SymbolPart
*
part
)
{
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
if
(
selected
(
p
))
selection
.
erase
(
p
);
clearChildren
(
p
.
get
());
}
}
}
bool
SymbolPartsSelection
::
isAncestor
(
SymbolPart
*
ancestor
,
SymbolPart
*
part
)
{
if
(
SymbolGroup
*
g
=
ancestor
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
if
(
part
==
p
.
get
())
return
true
;
if
(
isAncestor
(
p
.
get
(),
part
))
return
true
;
}
}
return
false
;
}
// ----------------------------------------------------------------------------- : Position based
SymbolPartP
SymbolPartsSelection
::
find
(
const
SymbolPartP
&
part
,
const
Vector2D
&
pos
)
const
{
if
(
SymbolShape
*
s
=
part
->
isSymbolShape
())
{
if
(
point_in_shape
(
pos
,
*
s
))
return
part
;
}
if
(
SymbolGroup
*
g
=
part
->
isSymbolGroup
())
{
FOR_EACH
(
p
,
g
->
parts
)
{
SymbolPartP
found
=
find
(
p
,
pos
);
if
(
found
)
{
if
(
part
->
isSymbolSymmetry
()
||
selected
(
found
))
{
return
found
;
}
else
{
return
part
;
// don't select inside groups
}
}
}
}
return
SymbolPartP
();
}
SymbolPartP
SymbolPartsSelection
::
find
(
const
Vector2D
&
position
)
const
{
FOR_EACH
(
p
,
root
->
parts
)
{
SymbolPartP
found
=
find
(
p
,
position
);
if
(
found
)
return
found
;
}
return
SymbolPartP
();
}
// ----------------------------------------------------------------------------- : Rectangle based
bool
SymbolPartsSelection
::
selectRect
(
const
Vector2D
&
a
,
const
Vector2D
&
b
,
const
Vector2D
&
c
)
{
return
selectRect
(
*
root
,
a
,
b
,
c
);
}
bool
SymbolPartsSelection
::
selectRect
(
const
SymbolGroup
&
parent
,
const
Vector2D
&
a
,
const
Vector2D
&
b
,
const
Vector2D
&
c
)
{
bool
changes
=
false
;
FOR_EACH_CONST
(
p
,
root
->
parts
)
{
bool
in_ab
=
(
p
->
min_pos
.
x
>=
min
(
a
.
x
,
b
.
x
)
&&
p
->
min_pos
.
y
>=
min
(
a
.
y
,
b
.
y
)
&&
p
->
max_pos
.
x
<=
max
(
a
.
x
,
b
.
x
)
&&
p
->
max_pos
.
y
<=
max
(
a
.
y
,
b
.
y
));
bool
in_bc
=
(
p
->
min_pos
.
x
>=
min
(
a
.
x
,
c
.
x
)
&&
p
->
min_pos
.
y
>=
min
(
a
.
y
,
c
.
y
)
&&
p
->
max_pos
.
x
<=
max
(
a
.
x
,
c
.
x
)
&&
p
->
max_pos
.
y
<=
max
(
a
.
y
,
c
.
y
));
if
(
in_ab
!=
in_bc
)
{
select
(
p
,
SELECT_TOGGLE
);
changes
=
true
;
}
else
if
(
SymbolGroup
*
g
=
p
->
isSymbolGroup
())
{
if
(
p
->
isSymbolSymmetry
()
||
selected
(
p
))
{
selectRect
(
*
g
,
a
,
b
,
c
);
}
}
}
return
changes
;
}
src/gui/symbol/selection.hpp
0 → 100644
View file @
b90e2dda
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2007 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_GUI_SYMBOL_SELECTION
#define HEADER_GUI_SYMBOL_SELECTION
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
class
Vector2D
;
DECLARE_POINTER_TYPE
(
Symbol
);
DECLARE_POINTER_TYPE
(
SymbolPart
);
DECLARE_POINTER_TYPE
(
SymbolShape
);
class
SymbolGroup
;
// ----------------------------------------------------------------------------- : Selection
enum
SelectMode
{
SELECT_OVERRIDE
// give a completely new selection
,
SELECT_IF_OUTSIDE
// define a new selection if the affected part is not already selected
,
SELECT_TOGGLE
// toggle selection of affected part
};
/// The selected parts of a symbol, enforcing constraints
class
SymbolPartsSelection
{
public:
inline
SymbolPartsSelection
()
:
root
(
nullptr
)
{}
void
setSymbol
(
const
SymbolP
&
symbol
);
/// Clear selection
void
clear
();
/// Select a part or toggle its selection
/** Return true if the selection changed */
bool
select
(
const
SymbolPartP
&
part
,
SelectMode
mode
=
SELECT_OVERRIDE
);
/// Toggle the selection of the parts in a rectangle (a,b) or (a,c) but not in both
/** Return true if the selection changed */
bool
selectRect
(
const
Vector2D
&
a
,
const
Vector2D
&
b
,
const
Vector2D
&
c
);
/// Find a part by position (not just in the selection!)
/** Returns SymbolPartP() if nothing is found.
* Does not select inside groups unless the part in question is already selected.
*/
SymbolPartP
find
(
const
Vector2D
&
position
)
const
;
/// Get the selection
inline
const
set
<
SymbolPartP
>&
get
()
const
{
return
selection
;
}
/// Is the selection empty?
inline
bool
empty
()
const
{
return
selection
.
empty
();
}
/// Number of items selected
inline
size_t
size
()
const
{
return
selection
.
size
();
}
/// Is a part selected?
inline
bool
selected
(
const
SymbolPartP
&
part
)
const
{
return
selection
.
find
(
part
)
!=
selection
.
end
();
}
/// Get any SymbolShape if there is one selected
SymbolShapeP
getAShape
()
const
;
private:
Symbol
*
root
;
set
<
SymbolPartP
>
selection
;
/// Find a part, in some root
SymbolPartP
find
(
const
SymbolPartP
&
part
,
const
Vector2D
&
pos
)
const
;
/// Select rect for some parent
bool
selectRect
(
const
SymbolGroup
&
parent
,
const
Vector2D
&
a
,
const
Vector2D
&
b
,
const
Vector2D
&
c
);
/// Make sure not both a parent and its child/decendant are selected
void
clearChildren
(
SymbolPart
*
part
);
/// Is a part another's ancestor?
static
bool
isAncestor
(
SymbolPart
*
ancestor
,
SymbolPart
*
part
);
};
// ----------------------------------------------------------------------------- : EOF
#endif
src/gui/symbol/symmetry_editor.cpp
0 → 100644
View file @
b90e2dda
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2007 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <gui/symbol/symmetry_editor.hpp>
#include <gui/util.hpp>
#include <util/window_id.hpp>
#include <data/settings.hpp>
#include <data/action/symbol.hpp>
#include <data/action/symbol_part.hpp>
#include <wx/spinctrl.h>
// ----------------------------------------------------------------------------- : SymbolSymmetryEditor
SymbolSymmetryEditor
::
SymbolSymmetryEditor
(
SymbolControl
*
control
)
:
SymbolEditorBase
(
control
)
,
mode
(
ID_SYMMETRY_ROTATION
)
,
drawing
(
false
)
{
control
->
SetCursor
(
*
wxCROSS_CURSOR
);
}
// ----------------------------------------------------------------------------- : Drawing
void
SymbolSymmetryEditor
::
draw
(
DC
&
dc
)
{
if
(
symmetry
)
{
control
.
highlightPart
(
dc
,
*
symmetry
);
}
}
// ----------------------------------------------------------------------------- : UI
void
SymbolSymmetryEditor
::
initUI
(
wxToolBar
*
tb
,
wxMenuBar
*
mb
)
{
copies
=
new
wxSpinCtrl
(
tb
,
ID_COPIES
,
_
(
"2"
),
wxDefaultPosition
,
wxDefaultSize
,
wxSP_ARROW_KEYS
,
2
,
10
,
2
);
copies
->
SetHelpText
(
_HELP_
(
"copies"
));
copies
->
SetSize
(
50
,
-
1
);
tb
->
AddSeparator
();
tb
->
AddTool
(
ID_SYMMETRY_ROTATION
,
_TOOL_
(
"rotation"
),
load_resource_image
(
_
(
"symmetry_rotation"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"rotation"
),
_HELP_
(
"rotation"
));
tb
->
AddTool
(
ID_SYMMETRY_REFLECTION
,
_TOOL_
(
"reflection"
),
load_resource_image
(
_
(
"symmetry_reflection"
)),
wxNullBitmap
,
wxITEM_CHECK
,
_TOOLTIP_
(
"reflection"
),
_HELP_
(
"reflection"
));
tb
->
AddControl
(
copies
);
tb
->
Realize
();
control
.
SetCursor
(
*
wxCROSS_CURSOR
);
stopActions
();
// set status text
}
void
SymbolSymmetryEditor
::
destroyUI
(
wxToolBar
*
tb
,
wxMenuBar
*
mb
)
{
tb
->
DeleteTool
(
ID_SYMMETRY_REFLECTION
);
tb
->
DeleteTool
(
ID_SYMMETRY_ROTATION
);
// HACK: hardcoded size of rest of toolbar
tb
->
DeleteToolByPos
(
7
);
// delete separator
tb
->
DeleteTool
(
ID_COPIES
);
// delete sides
#if wxVERSION_NUMBER < 2600
delete
sides
;
#endif
}
void
SymbolSymmetryEditor
::
onUpdateUI
(
wxUpdateUIEvent
&
ev
)
{
if
(
ev
.
GetId
()
>=
ID_SYMMETRY
&&
ev
.
GetId
()
<
ID_SYMMETRY_MAX
)
{
ev
.
Check
(
ev
.
GetId
()
==
mode
);
}
else
if
(
ev
.
GetId
()
==
ID_COPIES
)
{
ev
.
Enable
(
true
);
}
else
{
ev
.
Enable
(
false
);
// we don't know about this item
}
}
void
SymbolSymmetryEditor
::
onCommand
(
int
id
)
{
if
(
id
>=
ID_SYMMETRY
&&
id
<
ID_SYMMETRY_MAX
)
{
mode
=
id
;
stopActions
();
}
}
int
SymbolSymmetryEditor
::
modeToolId
()
{
return
ID_MODE_SYMMETRY
;
}
// ----------------------------------------------------------------------------- : Mouse events
void
SymbolSymmetryEditor
::
onLeftDown
(
const
Vector2D
&
pos
,
wxMouseEvent
&
ev
)
{
// Start drawing
drawing
=
true
;
center
=
handle
=
pos
;
SetStatusText
(
_HELP_
(
"drag to draw symmetry"
));
}
void
SymbolSymmetryEditor
::
onLeftUp
(
const
Vector2D
&
pos
,
wxMouseEvent
&
ev
)
{
if
(
drawing
&&
symmetry
)
{
// Finalize the symmetry
getSymbol
()
->
actions
.
add
(
new
AddSymbolPartAction
(
*
getSymbol
(),
symmetry
));
// Select the part
control
.
selectPart
(
symmetry
);
// No need to clean up, this editor gets destroyed
//stopActions();
}
}
void
SymbolSymmetryEditor
::
onMouseDrag
(
const
Vector2D
&
from
,
const
Vector2D
&
to
,
wxMouseEvent
&
ev
)
{
// Resize the object
if
(
drawing
)
{
handle
=
to
;
makePart
(
center
,
handle
,
ev
.
ControlDown
(),
settings
.
symbol_grid_snap
!=
ev
.
ShiftDown
());
control
.
Refresh
(
false
);
}
}
// ----------------------------------------------------------------------------- : Other events
void
SymbolSymmetryEditor
::
onKeyChange
(
wxKeyEvent
&
ev
)
{
if
(
drawing
)
{
if
(
ev
.
GetKeyCode
()
==
WXK_CONTROL
||
ev
.
GetKeyCode
()
==
WXK_SHIFT
)
{
// changed constrains
makePart
(
center
,
handle
,
ev
.
ControlDown
(),
settings
.
symbol_grid_snap
!=
ev
.
ShiftDown
());
control
.
Refresh
(
false
);
}
else
if
(
ev
.
GetKeyCode
()
==
WXK_ESCAPE
)
{
// cancel drawing
stopActions
();
}
}
}
bool
SymbolSymmetryEditor
::
isEditing
()
{
return
drawing
;
}
// ----------------------------------------------------------------------------- : Generating shapes
void
SymbolSymmetryEditor
::
stopActions
()
{
symmetry
=
SymbolSymmetryP
();
drawing
=
false
;
SetStatusText
(
_HELP_
(
"draw symmetry"
));
control
.
Refresh
(
false
);
}
void
SymbolSymmetryEditor
::
makePart
(
Vector2D
a
,
Vector2D
b
,
bool
constrained
,
bool
snap
)
{
// snap
if
(
snap
)
{
a
=
snap_vector
(
a
,
settings
.
symbol_grid_size
);
b
=
snap_vector
(
b
,
settings
.
symbol_grid_size
);
}
// constrain
Vector2D
dir
=
b
-
a
;
if
(
constrained
)
{
double
angle
=
atan2
(
dir
.
y
,
dir
.
x
);
// multiples of 2pi/24 i.e. 24 stops
double
mult
=
(
2
*
M_PI
)
/
24
;
angle
=
floor
(
angle
/
mult
+
0.5
)
*
mult
;
dir
=
Vector2D
(
cos
(
angle
),
sin
(
angle
))
*
dir
.
length
();
}
// make part
if
(
!
symmetry
)
{
symmetry
=
new_intrusive
<
SymbolSymmetry
>
();
}
symmetry
->
kind
=
mode
==
ID_SYMMETRY_ROTATION
?
SYMMETRY_ROTATION
:
SYMMETRY_REFLECTION
;
symmetry
->
copies
=
copies
->
GetValue
();
symmetry
->
center
=
a
;
symmetry
->
handle
=
dir
;
symmetry
->
name
=
capitalize
(
mode
==
ID_SYMMETRY_ROTATION
?
_TYPE_
(
"rotation"
)
:
_TYPE_
(
"reflection"
))
+
String
::
Format
(
_
(
" (%d)"
),
symmetry
->
copies
);
}
src/gui/symbol/symmetry_editor.hpp
0 → 100644
View file @
b90e2dda
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2007 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_GUI_SYMBOL_SYMMETRY_EDITOR
#define HEADER_GUI_SYMBOL_SYMMETRY_EDITOR
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <gui/symbol/editor.hpp>
// ----------------------------------------------------------------------------- : SymbolSymmetryEditor
/// Editor for adding symmetries
class
SymbolSymmetryEditor
:
public
SymbolEditorBase
{
public:
SymbolSymmetryEditor
(
SymbolControl
*
control
);
// --------------------------------------------------- : Drawing
virtual
void
draw
(
DC
&
dc
);
// --------------------------------------------------- : UI
virtual
void
initUI
(
wxToolBar
*
tb
,
wxMenuBar
*
mb
);
virtual
void
destroyUI
(
wxToolBar
*
tb
,
wxMenuBar
*
mb
);
virtual
void
onUpdateUI
(
wxUpdateUIEvent
&
);
virtual
void
onCommand
(
int
id
);
virtual
int
modeToolId
();
// --------------------------------------------------- : Mouse events
virtual
void
onLeftDown
(
const
Vector2D
&
pos
,
wxMouseEvent
&
ev
);
virtual
void
onLeftUp
(
const
Vector2D
&
pos
,
wxMouseEvent
&
ev
);
virtual
void
onMouseDrag
(
const
Vector2D
&
from
,
const
Vector2D
&
to
,
wxMouseEvent
&
ev
);
// --------------------------------------------------- : Other events
virtual
void
onKeyChange
(
wxKeyEvent
&
ev
);
virtual
bool
isEditing
();
// --------------------------------------------------- : Data
private:
int
mode
;
SymbolSymmetryP
symmetry
;
bool
drawing
;
Vector2D
center
,
handle
;
// controls
wxSpinCtrl
*
copies
;
/// Cancel the drawing
void
stopActions
();
/// Make the symmetry object
void
makePart
(
Vector2D
a
,
Vector2D
b
,
bool
constrained
,
bool
snap
);
};
// ----------------------------------------------------------------------------- : EOF
#endif
src/script/parser.cpp
View file @
b90e2dda
...
@@ -565,6 +565,8 @@ void parseOper(TokenIterator& input, Script& script, Precedence minPrec, Instruc
...
@@ -565,6 +565,8 @@ void parseOper(TokenIterator& input, Script& script, Precedence minPrec, Instruc
}
else
if
(
minPrec
<=
PREC_SET
&&
token
==
_
(
":="
))
{
}
else
if
(
minPrec
<=
PREC_SET
&&
token
==
_
(
":="
))
{
// We made a mistake, the part before the := should be a variable name,
// We made a mistake, the part before the := should be a variable name,
// not an expression. Remove that instruction.
// not an expression. Remove that instruction.
// TODO: There is a bug here:
// (if x then a else b) := c will use the 'b' as variable name
Instruction
instr
=
script
.
getInstructions
().
back
();
Instruction
instr
=
script
.
getInstructions
().
back
();
if
(
instr
.
instr
!=
I_GET_VAR
)
{
if
(
instr
.
instr
!=
I_GET_VAR
)
{
input
.
add_error
(
_
(
"Can only assign to variables"
));
input
.
add_error
(
_
(
"Can only assign to variables"
));
...
...
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