Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
3f320e4d
Commit
3f320e4d
authored
Sep 27, 2013
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Some more comments and code formatting.
parent
6e0c7a93
Changes
21
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
852 additions
and
538 deletions
+852
-538
drawpanel_gal.cpp
common/drawpanel_gal.cpp
+0
-11
seg.cpp
common/geometry/seg.cpp
+63
-61
shape_collisions.cpp
common/geometry/shape_collisions.cpp
+71
-48
shape_index.cpp
common/geometry/shape_index.cpp
+0
-1
shape_line_chain.cpp
common/geometry/shape_line_chain.cpp
+225
-170
action_manager.cpp
common/tool/action_manager.cpp
+4
-3
context_menu.cpp
common/tool/context_menu.cpp
+13
-1
tool_dispatcher.cpp
common/tool/tool_dispatcher.cpp
+26
-12
tool_event.cpp
common/tool/tool_event.cpp
+1
-1
tool_manager.cpp
common/tool/tool_manager.cpp
+3
-7
shape_index.h
include/geometry/shape_index.h
+75
-59
shape_line_chain.h
include/geometry/shape_line_chain.h
+124
-114
action_manager.h
include/tool/action_manager.h
+11
-4
context_menu.h
include/tool/context_menu.h
+53
-5
tool_base.h
include/tool/tool_base.h
+53
-6
tool_dispatcher.h
include/tool/tool_dispatcher.h
+38
-3
tool_event.h
include/tool/tool_event.h
+53
-7
tool_interactive.h
include/tool/tool_interactive.h
+12
-8
move_tool.cpp
pcbnew/tools/move_tool.cpp
+11
-5
selection_area.h
pcbnew/tools/selection_area.h
+1
-0
selection_tool.cpp
pcbnew/tools/selection_tool.cpp
+15
-12
No files found.
common/drawpanel_gal.cpp
View file @
3f320e4d
...
...
@@ -121,11 +121,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
m_pendingRefresh
=
false
;
m_lastRefresh
=
wxGetLocalTimeMillis
();
#ifdef __WXDEBUG__
prof_counter
time
;
prof_start
(
&
time
,
false
);
#endif
/* __WXDEBUG__ */
m_gal
->
BeginDrawing
();
m_gal
->
SetBackgroundColor
(
KiGfx
::
COLOR4D
(
0.0
,
0.0
,
0.0
,
1.0
)
);
m_gal
->
ClearScreen
();
...
...
@@ -138,12 +133,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
m_gal
->
DrawCursor
(
m_viewControls
->
GetCursorPosition
()
);
m_gal
->
EndDrawing
();
#ifdef __WXDEBUG__
prof_end
(
&
time
);
wxLogDebug
(
wxT
(
"EDA_DRAW_PANEL_GAL::Refresh: %.0f ms (%.0f fps)"
),
static_cast
<
double
>
(
time
.
value
)
/
1000.0
,
1000000.0
/
static_cast
<
double
>
(
time
.
value
)
);
#endif
/* __WXDEBUG__ */
}
...
...
common/geometry/seg.cpp
View file @
3f320e4d
...
...
@@ -25,126 +25,128 @@
#include <geometry/seg.h>
template
<
typename
T
>
int
sgn
(
T
val
)
{
return
(
T
(
0
)
<
val
)
-
(
val
<
T
(
0
)
);
template
<
typename
T
>
int
sgn
(
T
val
)
{
return
(
T
(
0
)
<
val
)
-
(
val
<
T
(
0
)
);
}
bool
SEG
::
PointCloserThan
(
const
VECTOR2I
&
aP
,
int
dist
)
const
bool
SEG
::
PointCloserThan
(
const
VECTOR2I
&
aP
,
int
dist
)
const
{
VECTOR2I
d
=
b
-
a
;
ecoord
dist_sq
=
(
ecoord
)
dist
*
dist
;
SEG
::
ecoord
l_squared
=
d
.
Dot
(
d
);
SEG
::
ecoord
t
=
d
.
Dot
(
aP
-
a
);
SEG
::
ecoord
l_squared
=
d
.
Dot
(
d
);
SEG
::
ecoord
t
=
d
.
Dot
(
aP
-
a
);
if
(
t
<=
0
||
!
l_squared
)
return
(
aP
-
a
).
SquaredEuclideanNorm
()
<
dist_sq
;
return
(
aP
-
a
).
SquaredEuclideanNorm
()
<
dist_sq
;
else
if
(
t
>=
l_squared
)
return
(
aP
-
b
).
SquaredEuclideanNorm
()
<
dist_sq
;
return
(
aP
-
b
).
SquaredEuclideanNorm
()
<
dist_sq
;
int
dxdy
=
abs
(
d
.
x
)
-
abs
(
d
.
y
);
int
dxdy
=
abs
(
d
.
x
)
-
abs
(
d
.
y
);
if
(
(
dxdy
>=
-
1
&&
dxdy
<=
1
)
||
abs
(
d
.
x
)
<=
1
||
abs
(
d
.
y
)
<=
1
)
if
(
(
dxdy
>=
-
1
&&
dxdy
<=
1
)
||
abs
(
d
.
x
)
<=
1
||
abs
(
d
.
y
)
<=
1
)
{
int
ca
=
-
sgn
(
d
.
y
);
int
cb
=
sgn
(
d
.
x
);
int
ca
=
-
sgn
(
d
.
y
);
int
cb
=
sgn
(
d
.
x
);
int
cc
=
-
ca
*
a
.
x
-
cb
*
a
.
y
;
ecoord
num
=
ca
*
aP
.
x
+
cb
*
aP
.
y
+
cc
;
num
*=
num
;
if
(
ca
&&
cb
)
if
(
ca
&&
cb
)
num
>>=
1
;
if
(
num
>
(
dist_sq
+
100
)
)
if
(
num
>
(
dist_sq
+
100
)
)
return
false
;
else
if
(
num
<
(
dist_sq
-
100
)
)
else
if
(
num
<
(
dist_sq
-
100
)
)
return
true
;
}
VECTOR2I
nearest
;
nearest
.
x
=
a
.
x
+
rescale
(
t
,
(
ecoord
)
d
.
x
,
l_squared
);
nearest
.
y
=
a
.
y
+
rescale
(
t
,
(
ecoord
)
d
.
y
,
l_squared
);
nearest
.
x
=
a
.
x
+
rescale
(
t
,
(
ecoord
)
d
.
x
,
l_squared
);
nearest
.
y
=
a
.
y
+
rescale
(
t
,
(
ecoord
)
d
.
y
,
l_squared
);
return
(
nearest
-
aP
).
SquaredEuclideanNorm
()
<=
dist_sq
;
return
(
nearest
-
aP
).
SquaredEuclideanNorm
()
<=
dist_sq
;
}
SEG
::
ecoord
SEG
::
SquaredDistance
(
const
SEG
&
aSeg
)
const
{
// fixme: rather inefficient....
if
(
Intersect
(
aSeg
)
)
if
(
Intersect
(
aSeg
)
)
return
0
;
const
VECTOR2I
pts
[
4
]
=
{
aSeg
.
NearestPoint
(
a
)
-
a
,
aSeg
.
NearestPoint
(
b
)
-
b
,
NearestPoint
(
aSeg
.
a
)
-
aSeg
.
a
,
NearestPoint
(
aSeg
.
b
)
-
aSeg
.
b
aSeg
.
NearestPoint
(
a
)
-
a
,
aSeg
.
NearestPoint
(
b
)
-
b
,
NearestPoint
(
aSeg
.
a
)
-
aSeg
.
a
,
NearestPoint
(
aSeg
.
b
)
-
aSeg
.
b
};
ecoord
m
=
VECTOR2I
::
ECOORD_MAX
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
m
=
std
::
min
(
m
,
pts
[
i
].
SquaredEuclideanNorm
());
for
(
int
i
=
0
;
i
<
4
;
i
++
)
m
=
std
::
min
(
m
,
pts
[
i
].
SquaredEuclideanNorm
()
);
return
m
;
}
OPT_VECTOR2I
SEG
::
Intersect
(
const
SEG
&
aSeg
,
bool
aIgnoreEndpoints
,
bool
aLines
)
const
{
const
VECTOR2I
e
(
b
-
a
);
const
VECTOR2I
f
(
aSeg
.
b
-
aSeg
.
a
);
const
VECTOR2I
ac
(
aSeg
.
a
-
a
);
const
VECTOR2I
e
(
b
-
a
);
const
VECTOR2I
f
(
aSeg
.
b
-
aSeg
.
a
);
const
VECTOR2I
ac
(
aSeg
.
a
-
a
);
ecoord
d
=
f
.
Cross
(
e
);
ecoord
p
=
f
.
Cross
(
ac
);
ecoord
q
=
e
.
Cross
(
ac
);
ecoord
d
=
f
.
Cross
(
e
);
ecoord
p
=
f
.
Cross
(
ac
);
ecoord
q
=
e
.
Cross
(
ac
);
if
(
d
==
0
)
if
(
d
==
0
)
return
OPT_VECTOR2I
();
if
(
!
aLines
&&
d
>
0
&&
(
q
<
0
||
q
>
d
||
p
<
0
||
p
>
d
)
)
if
(
!
aLines
&&
d
>
0
&&
(
q
<
0
||
q
>
d
||
p
<
0
||
p
>
d
)
)
return
OPT_VECTOR2I
();
if
(
!
aLines
&&
d
<
0
&&
(
q
<
d
||
p
<
d
||
p
>
0
||
q
>
0
)
)
if
(
!
aLines
&&
d
<
0
&&
(
q
<
d
||
p
<
d
||
p
>
0
||
q
>
0
)
)
return
OPT_VECTOR2I
();
if
(
!
aLines
&&
aIgnoreEndpoints
&&
(
q
==
0
||
q
==
d
)
&&
(
p
==
0
||
p
==
d
)
)
if
(
!
aLines
&&
aIgnoreEndpoints
&&
(
q
==
0
||
q
==
d
)
&&
(
p
==
0
||
p
==
d
)
)
return
OPT_VECTOR2I
();
VECTOR2I
ip
(
aSeg
.
a
.
x
+
rescale
(
q
,
(
ecoord
)
f
.
x
,
d
),
aSeg
.
a
.
y
+
rescale
(
q
,
(
ecoord
)
f
.
y
,
d
)
);
VECTOR2I
ip
(
aSeg
.
a
.
x
+
rescale
(
q
,
(
ecoord
)
f
.
x
,
d
),
aSeg
.
a
.
y
+
rescale
(
q
,
(
ecoord
)
f
.
y
,
d
)
);
return
ip
;
}
bool
SEG
::
ccw
(
const
VECTOR2I
&
a
,
const
VECTOR2I
&
b
,
const
VECTOR2I
&
c
)
const
bool
SEG
::
ccw
(
const
VECTOR2I
&
a
,
const
VECTOR2I
&
b
,
const
VECTOR2I
&
c
)
const
{
return
(
ecoord
)(
c
.
y
-
a
.
y
)
*
(
b
.
x
-
a
.
x
)
>
(
ecoord
)(
b
.
y
-
a
.
y
)
*
(
c
.
x
-
a
.
x
);
return
(
ecoord
)(
c
.
y
-
a
.
y
)
*
(
b
.
x
-
a
.
x
)
>
(
ecoord
)(
b
.
y
-
a
.
y
)
*
(
c
.
x
-
a
.
x
);
}
bool
SEG
::
Collide
(
const
SEG
&
aSeg
,
int
aClearance
)
const
{
// check for intersection
// fixme: move to a method
if
(
ccw
(
a
,
aSeg
.
a
,
aSeg
.
b
)
!=
ccw
(
b
,
aSeg
.
a
,
aSeg
.
b
)
&&
ccw
(
a
,
b
,
aSeg
.
a
)
!=
ccw
(
a
,
b
,
aSeg
.
b
)
)
if
(
ccw
(
a
,
aSeg
.
a
,
aSeg
.
b
)
!=
ccw
(
b
,
aSeg
.
a
,
aSeg
.
b
)
&&
ccw
(
a
,
b
,
aSeg
.
a
)
!=
ccw
(
a
,
b
,
aSeg
.
b
)
)
return
true
;
#define CHK(_seg, _pt) \
if( (_seg).PointCloserThan (_pt, aClearance ) ) return true;
CHK
(
*
this
,
aSeg
.
a
);
CHK
(
*
this
,
aSeg
.
b
);
CHK
(
aSeg
,
a
);
CHK
(
aSeg
,
b
);
CHK
(
*
this
,
aSeg
.
a
);
CHK
(
*
this
,
aSeg
.
b
);
CHK
(
aSeg
,
a
);
CHK
(
aSeg
,
b
);
#undef CHK
return
false
;
}
bool
SEG
::
Contains
(
const
VECTOR2I
&
aP
)
const
bool
SEG
::
Contains
(
const
VECTOR2I
&
aP
)
const
{
return
PointCloserThan
(
aP
,
1
);
return
PointCloserThan
(
aP
,
1
);
}
common/geometry/shape_collisions.cpp
View file @
3f320e4d
...
...
@@ -31,7 +31,8 @@
typedef
VECTOR2I
::
extended_type
ecoord
;
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
a
,
const
SHAPE_CIRCLE
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
a
,
const
SHAPE_CIRCLE
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
ecoord
min_dist
=
clearance
+
a
.
GetRadius
()
+
b
.
GetRadius
();
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
...
...
@@ -44,12 +45,13 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int cl
return
false
;
if
(
needMTV
)
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
min_dist_sq
-
dist_sq
))
+
1
);
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
min_dist_sq
-
dist_sq
)
)
+
1
);
return
true
;
}
static
inline
bool
Collide
(
const
SHAPE_RECT
&
a
,
const
SHAPE_CIRCLE
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_RECT
&
a
,
const
SHAPE_CIRCLE
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
const
VECTOR2I
c
=
b
.
GetCenter
();
const
VECTOR2I
p0
=
a
.
GetPosition
();
...
...
@@ -58,7 +60,7 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
const
ecoord
min_dist
=
clearance
+
r
;
const
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
if
(
a
.
BBox
(
0
).
Contains
(
c
)
)
if
(
a
.
BBox
(
0
).
Contains
(
c
)
)
return
true
;
const
VECTOR2I
vts
[]
=
{
...
...
@@ -71,73 +73,77 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
ecoord
nearest_seg_dist_sq
=
VECTOR2I
::
ECOORD_MAX
;
VECTOR2I
nearest
;
bool
inside
=
c
.
x
>=
p0
.
x
&&
c
.
x
<=
(
p0
.
x
+
size
.
x
)
&&
c
.
y
>=
p0
.
y
&&
c
.
y
<=
(
p0
.
y
+
size
.
y
);
bool
inside
=
c
.
x
>=
p0
.
x
&&
c
.
x
<=
(
p0
.
x
+
size
.
x
)
&&
c
.
y
>=
p0
.
y
&&
c
.
y
<=
(
p0
.
y
+
size
.
y
);
if
(
!
inside
)
if
(
!
inside
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
const
SEG
seg
(
vts
[
i
],
vts
[
i
+
1
]
);
ecoord
dist_sq
=
seg
.
SquaredDistance
(
c
);
const
SEG
seg
(
vts
[
i
],
vts
[
i
+
1
]
);
ecoord
dist_sq
=
seg
.
SquaredDistance
(
c
);
if
(
dist_sq
<
min_dist_sq
)
if
(
dist_sq
<
min_dist_sq
)
{
if
(
!
needMTV
)
if
(
!
needMTV
)
return
true
;
else
{
nearest
=
seg
.
NearestPoint
(
c
);
nearest
=
seg
.
NearestPoint
(
c
);
nearest_seg_dist_sq
=
dist_sq
;
}
}
}
}
if
(
nearest_seg_dist_sq
>=
min_dist_sq
&&
!
inside
)
if
(
nearest_seg_dist_sq
>=
min_dist_sq
&&
!
inside
)
return
false
;
VECTOR2I
delta
=
c
-
nearest
;
if
(
!
needMTV
)
if
(
!
needMTV
)
return
true
;
if
(
inside
)
aMTV
=
-
delta
.
Resize
(
sqrt
(
abs
(
r
*
r
+
nearest_seg_dist_sq
)
+
1
)
);
if
(
inside
)
aMTV
=
-
delta
.
Resize
(
sqrt
(
abs
(
r
*
r
+
nearest_seg_dist_sq
)
+
1
)
);
else
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
r
*
r
-
nearest_seg_dist_sq
)
+
1
)
);
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
r
*
r
-
nearest_seg_dist_sq
)
+
1
)
);
return
true
;
}
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
for
(
int
s
=
0
;
s
<
b
.
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
b
.
SegmentCount
();
s
++
)
{
if
(
a
.
Collide
(
b
.
CSegment
(
s
),
clearance
)
)
if
(
a
.
Collide
(
b
.
CSegment
(
s
),
clearance
)
)
return
true
;
}
return
false
;
}
static
inline
bool
Collide
(
const
SHAPE_LINE_CHAIN
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_LINE_CHAIN
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
for
(
int
i
=
0
;
i
<
b
.
SegmentCount
()
;
i
++
)
if
(
a
.
Collide
(
b
.
CSegment
(
i
),
clearance
)
)
for
(
int
i
=
0
;
i
<
b
.
SegmentCount
()
;
i
++
)
if
(
a
.
Collide
(
b
.
CSegment
(
i
),
clearance
)
)
return
true
;
return
false
;
}
static
inline
bool
Collide
(
const
SHAPE_RECT
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_RECT
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
for
(
int
s
=
0
;
s
<
b
.
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
b
.
SegmentCount
();
s
++
)
{
SEG
seg
=
b
.
CSegment
(
s
);
if
(
a
.
Collide
(
seg
,
clearance
)
)
SEG
seg
=
b
.
CSegment
(
s
);
if
(
a
.
Collide
(
seg
,
clearance
)
)
return
true
;
}
...
...
@@ -145,66 +151,83 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int
}
bool
CollideShapes
(
const
SHAPE
*
a
,
const
SHAPE
*
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
bool
CollideShapes
(
const
SHAPE
*
a
,
const
SHAPE
*
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
switch
(
a
->
Type
()
)
switch
(
a
->
Type
()
)
{
case
SH_RECT
:
switch
(
b
->
Type
()
)
switch
(
b
->
Type
()
)
{
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
a
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
a
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
default:
break
;
}
case
SH_CIRCLE
:
switch
(
b
->
Type
()
)
switch
(
b
->
Type
()
)
{
case
SH_RECT
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
b
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
b
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
default:
break
;
}
case
SH_LINE_CHAIN
:
switch
(
b
->
Type
()
)
switch
(
b
->
Type
()
)
{
case
SH_RECT
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
b
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
b
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
default:
break
;
}
default:
break
;
}
bool
unsupported_collision
=
true
;
assert
(
unsupported_collision
==
false
);
assert
(
unsupported_collision
==
false
);
return
false
;
}
bool
SHAPE
::
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
,
VECTOR2I
&
aMTV
)
const
bool
SHAPE
::
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
,
VECTOR2I
&
aMTV
)
const
{
return
CollideShapes
(
this
,
aShape
,
aClerance
,
true
,
aMTV
);
}
bool
SHAPE
::
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
)
const
bool
SHAPE
::
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
)
const
{
VECTOR2I
dummy
;
return
CollideShapes
(
this
,
aShape
,
aClerance
,
false
,
dummy
);
return
CollideShapes
(
this
,
aShape
,
aClerance
,
false
,
dummy
);
}
common/geometry/shape_index.cpp
View file @
3f320e4d
...
...
@@ -30,4 +30,3 @@ const SHAPE* shapeFunctor( SHAPE* aItem )
{
return
aItem
;
}
common/geometry/shape_line_chain.cpp
View file @
3f320e4d
This diff is collapsed.
Click to expand it.
common/tool/action_manager.cpp
View file @
3f320e4d
...
...
@@ -52,8 +52,9 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
void
ACTION_MANAGER
::
UnregisterAction
(
TOOL_ACTION
*
aAction
)
{
// Indicate that
we
no longer care about the object
// Indicate that
the ACTION_MANAGER
no longer care about the object
aAction
->
setActionMgr
(
NULL
);
aAction
->
setId
(
-
1
);
m_actionNameIndex
.
erase
(
aAction
->
m_name
);
m_actionIdIndex
.
erase
(
aAction
->
m_id
);
...
...
@@ -75,7 +76,7 @@ bool ACTION_MANAGER::RunAction( const std::string& aActionName ) const
std
::
map
<
std
::
string
,
TOOL_ACTION
*>::
const_iterator
it
=
m_actionNameIndex
.
find
(
aActionName
);
if
(
it
==
m_actionNameIndex
.
end
()
)
return
false
;
return
false
;
// no action with given name found
runAction
(
it
->
second
);
...
...
@@ -88,7 +89,7 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
std
::
map
<
int
,
TOOL_ACTION
*>::
const_iterator
it
=
m_actionHotKeys
.
find
(
aHotKey
);
if
(
it
==
m_actionHotKeys
.
end
()
)
return
false
;
return
false
;
// no appropriate action found for the hotkey
runAction
(
it
->
second
);
...
...
common/tool/context_menu.cpp
View file @
3f320e4d
...
...
@@ -62,13 +62,15 @@ CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) :
wxEmptyString
,
wxITEM_NORMAL
)
);
}
// Copy tool actions that are available to choose from menu
// Copy tool actions that are available to choose from
context
menu
m_toolActions
=
aMenu
.
m_toolActions
;
}
void
CONTEXT_MENU
::
SetTitle
(
const
wxString
&
aTitle
)
{
// TODO handle an empty string (remove title and separator)
// Unfortunately wxMenu::SetTitle() does nothing..
if
(
m_titleSet
)
{
...
...
@@ -85,12 +87,18 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
void
CONTEXT_MENU
::
Add
(
const
wxString
&
aLabel
,
int
aId
)
{
#ifdef DEBUG
if
(
m_menu
.
FindItem
(
aId
)
!=
NULL
)
wxLogWarning
(
wxT
(
"Adding more than one menu entry with the same ID may result in"
"undefined behaviour"
)
);
#endif
m_menu
.
Append
(
new
wxMenuItem
(
&
m_menu
,
aId
,
aLabel
,
wxEmptyString
,
wxITEM_NORMAL
)
);
}
void
CONTEXT_MENU
::
Add
(
const
TOOL_ACTION
&
aAction
)
{
/// ID numbers for tool actions need to have a value higher than m_actionId
int
id
=
m_actionId
+
aAction
.
GetId
();
wxString
menuEntry
;
...
...
@@ -110,6 +118,7 @@ void CONTEXT_MENU::Clear()
{
m_titleSet
=
false
;
// Remove all the entries from context menu
for
(
unsigned
i
=
0
;
i
<
m_menu
.
GetMenuItemCount
();
++
i
)
m_menu
.
Destroy
(
m_menu
.
FindItemByPosition
(
0
)
);
...
...
@@ -144,15 +153,18 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent )
if
(
type
==
wxEVT_MENU_HIGHLIGHT
)
evt
=
TOOL_EVENT
(
TC_Command
,
TA_ContextMenuUpdate
,
aEvent
.
GetId
()
);
else
if
(
type
==
wxEVT_COMMAND_MENU_SELECTED
)
{
if
(
aEvent
.
GetId
()
>
m_actionId
)
{
// Handling TOOL_ACTIONs
if
(
m_menu
->
m_toolActions
.
count
(
aEvent
.
GetId
()
)
==
1
)
evt
=
m_menu
->
m_toolActions
[
aEvent
.
GetId
()]
->
GetEvent
();
}
else
{
// Handling common menu entries
evt
=
TOOL_EVENT
(
TC_Command
,
TA_ContextMenuChoice
,
aEvent
.
GetId
()
);
}
}
...
...
common/tool/tool_dispatcher.cpp
View file @
3f320e4d
...
...
@@ -42,28 +42,41 @@ using boost::optional;
struct
TOOL_DISPATCHER
::
ButtonState
{
ButtonState
(
TOOL_MouseButtons
aButton
,
const
wxEventType
&
aDownEvent
,
const
wxEventType
&
aUpEvent
,
bool
aTriggerMenu
=
false
)
:
const
wxEventType
&
aUpEvent
)
:
button
(
aButton
),
downEvent
(
aDownEvent
),
upEvent
(
aUpEvent
),
triggerContextMenu
(
aTriggerMenu
)
upEvent
(
aUpEvent
)
{};
///> Flag indicating that dragging is active for the given button.
bool
dragging
;
///> Flag indicating that the given button is pressed.
bool
pressed
;
///> Point where dragging has started (in world coordinates).
VECTOR2D
dragOrigin
;
///> Point where click event has occurred.
VECTOR2D
downPosition
;
///> Difference between drag origin point and current mouse position (expressed as distance in
///> pixels).
double
dragMaxDelta
;
///> Determines the mouse button for which information are stored.
TOOL_MouseButtons
button
;
///> The type of wxEvent that determines mouse button press.
wxEventType
downEvent
;
///> The type of wxEvent that determines mouse button release.
wxEventType
upEvent
;
bool
triggerContextMenu
;
///> Time stamp for the last mouse button press event.
wxLongLong
downTimestamp
;
///> Restores initial state.
void
Reset
()
{
dragging
=
false
;
...
...
@@ -76,7 +89,7 @@ TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditF
m_toolMgr
(
aToolMgr
),
m_editFrame
(
aEditFrame
)
{
m_buttons
.
push_back
(
new
ButtonState
(
MB_Left
,
wxEVT_LEFT_DOWN
,
wxEVT_LEFT_UP
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Right
,
wxEVT_RIGHT_DOWN
,
wxEVT_RIGHT_UP
,
true
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Right
,
wxEVT_RIGHT_DOWN
,
wxEVT_RIGHT_UP
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Middle
,
wxEVT_MIDDLE_DOWN
,
wxEVT_MIDDLE_UP
)
);
ResetState
();
...
...
@@ -131,7 +144,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
int
mods
=
decodeModifiers
(
static_cast
<
wxMouseEvent
*>
(
&
aEvent
)
);
int
args
=
st
->
button
|
mods
;
if
(
down
)
if
(
down
)
// Handle mouse button press
{
st
->
downTimestamp
=
wxGetLocalTimeMillis
();
st
->
dragOrigin
=
m_lastMousePos
;
...
...
@@ -140,7 +153,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
st
->
pressed
=
true
;
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseDown
,
args
);
}
else
if
(
up
)
else
if
(
up
)
// Handle mouse button release
{
st
->
pressed
=
false
;
...
...
@@ -148,6 +161,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
{
wxLongLong
t
=
wxGetLocalTimeMillis
();
// Determine if it was just a single click or beginning of dragging
if
(
t
-
st
->
downTimestamp
<
DragTimeThreshold
&&
st
->
dragMaxDelta
<
DragDistanceThreshold
)
isClick
=
true
;
...
...
@@ -157,7 +171,6 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
else
isClick
=
true
;
if
(
isClick
)
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseClick
,
args
);
...
...
@@ -208,6 +221,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
{
VECTOR2D
screenPos
=
m_toolMgr
->
GetViewControls
()
->
GetCursorPosition
();
VECTOR2D
pos
=
getView
()
->
ToWorld
(
screenPos
);
if
(
pos
!=
m_lastMousePos
||
type
==
KiGfx
::
WX_VIEW_CONTROLS
::
EVT_REFRESH_MOUSE
)
{
motion
=
true
;
...
...
@@ -251,7 +265,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
}
void
TOOL_DISPATCHER
::
DispatchWxCommand
(
wxCommandEvent
&
aEvent
)
void
TOOL_DISPATCHER
::
DispatchWxCommand
(
const
wxCommandEvent
&
aEvent
)
{
bool
activateTool
=
false
;
std
::
string
toolName
;
...
...
common/tool/tool_event.cpp
View file @
3f320e4d
...
...
@@ -25,7 +25,7 @@
#include <cstring>
#include <string>
#include <base_struct.h>
//
#include <base_struct.h>
#include <tool/tool_event.h>
#include <tool/tool_manager.h>
...
...
common/tool/tool_manager.cpp
View file @
3f320e4d
...
...
@@ -288,10 +288,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
st
->
pendingWait
=
false
;
st
->
waitEvents
.
clear
();
if
(
st
->
cofunc
&&
!
st
->
cofunc
->
Resume
()
)
{
// The couroutine has finished
finishTool
(
st
);
}
finishTool
(
st
);
// The couroutine has finished
// If the tool did not request to propagate
// the event to other tools, we should stop it now
...
...
@@ -303,6 +300,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
BOOST_FOREACH
(
TOOL_STATE
*
st
,
m_toolState
|
boost
::
adaptors
::
map_values
)
{
// the tool state handler is waiting for events (i.e. called Wait() method)
if
(
!
st
->
pendingWait
)
{
// no state handler in progress - check if there are any transitions (defined by
...
...
@@ -324,9 +322,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
st
->
cofunc
->
Call
(
aEvent
);
if
(
!
st
->
cofunc
->
Running
()
)
{
finishTool
(
st
);
}
finishTool
(
st
);
// The couroutine has finished
}
}
}
...
...
include/geometry/shape_index.h
View file @
3f320e4d
...
...
@@ -93,28 +93,27 @@ void acceptVisitor( T object, V visitor )
* @param minDistance minimum collision distance
* @return if object and anotherObject collide
*/
template
<
class
T
,
class
U
>
template
<
class
T
,
class
U
>
bool
collide
(
T
object
,
U
anotherObject
,
int
minDistance
)
{
return
shapeFunctor
(
object
)
->
Collide
(
anotherObject
,
minDistance
);
return
shapeFunctor
(
object
)
->
Collide
(
anotherObject
,
minDistance
);
}
template
<
class
T
,
class
V
>
bool
queryCallback
(
T
shape
,
void
*
context
)
{
bool
queryCallback
(
T
shape
,
void
*
context
)
{
V
*
visitor
=
(
V
*
)
context
;
acceptVisitor
<
T
,
V
>
(
shape
,
*
visitor
);
acceptVisitor
<
T
,
V
>
(
shape
,
*
visitor
);
return
true
;
}
template
<
class
T
=
SHAPE
*>
template
<
class
T
=
SHAPE
*>
class
SHAPE_INDEX
{
public
:
class
Iterator
{
private
:
typedef
typename
RTree
<
T
,
int
,
2
,
float
>::
Iterator
RTreeIterator
;
RTreeIterator
iterator
;
...
...
@@ -124,20 +123,21 @@ class SHAPE_INDEX {
* Setup the internal tree iterator.
* @param tree pointer to a RTREE object
*/
void
Init
(
RTree
<
T
,
int
,
2
,
float
>*
tree
)
{
tree
->
GetFirst
(
iterator
);
void
Init
(
RTree
<
T
,
int
,
2
,
float
>*
tree
)
{
tree
->
GetFirst
(
iterator
);
}
public
:
/**
* Iterator constructor
*
* Creates an iterator for the index object
* @param index SHAPE_INDEX object to iterate
*/
Iterator
(
SHAPE_INDEX
*
index
)
{
Init
(
index
->
m_tree
);
Iterator
(
SHAPE_INDEX
*
index
)
{
Init
(
index
->
m_tree
);
}
/**
...
...
@@ -145,7 +145,8 @@ class SHAPE_INDEX {
*
* Returns the next data element.
*/
T
operator
*
()
{
T
operator
*
()
{
return
*
iterator
;
}
...
...
@@ -154,7 +155,8 @@ class SHAPE_INDEX {
*
* Shifts the iterator to the next element.
*/
bool
operator
++
()
{
bool
operator
++
()
{
return
++
iterator
;
}
...
...
@@ -163,7 +165,8 @@ class SHAPE_INDEX {
*
* Shifts the iterator to the next element.
*/
bool
operator
++
(
int
)
{
bool
operator
++
(
int
)
{
return
++
iterator
;
}
...
...
@@ -173,7 +176,8 @@ class SHAPE_INDEX {
* Checks if the iterator has reached the end.
* @return true if it is in an invalid position (data finished)
*/
bool
IsNull
()
{
bool
IsNull
()
{
return
iterator
.
IsNull
();
}
...
...
@@ -183,7 +187,8 @@ class SHAPE_INDEX {
* Checks if the iterator has not reached the end.
* @return true if it is in an valid position (data not finished)
*/
bool
IsNotNull
()
{
bool
IsNotNull
()
{
return
iterator
.
IsNotNull
();
}
...
...
@@ -192,12 +197,13 @@ class SHAPE_INDEX {
*
* Returns the current element of the iterator and moves to the next
* position.
* @return SHAPE object pointed by the iterator before moving to the
* next position.
* @return SHAPE object pointed by the iterator before moving to the next position.
*/
T
Next
()
{
T
Next
()
{
T
object
=
*
iterator
;
++
iterator
;
return
object
;
}
};
...
...
@@ -210,17 +216,17 @@ class SHAPE_INDEX {
* Function Add()
*
* Adds a SHAPE to the index.
* @param
shape the new SHAPE
* @param
aShape is the new SHAPE.
*/
void
Add
(
T
s
hape
);
void
Add
(
T
aS
hape
);
/**
* Function Remove()
*
* Removes a SHAPE to the index.
* @param
shape the new SHAPE
* @param
aShape is the new SHAPE.
*/
void
Remove
(
T
s
hape
);
void
Remove
(
T
aS
hape
);
/**
* Function RemoveAll()
...
...
@@ -236,12 +242,14 @@ class SHAPE_INDEX {
* @param visitor Visitor object to be run
*/
template
<
class
V
>
void
Accept
(
V
v
isitor
)
void
Accept
(
V
aV
isitor
)
{
Iterator
iter
=
this
->
Begin
();
while
(
!
iter
.
IsNull
())
{
while
(
!
iter
.
IsNull
()
)
{
T
shape
=
*
iter
;
acceptVisitor
(
shape
,
visitor
);
acceptVisitor
(
shape
,
aVisitor
);
iter
++
;
}
}
...
...
@@ -262,17 +270,16 @@ class SHAPE_INDEX {
* @param minDistance distance threshold
* @param visitor object to be invoked on every object contained in the search area.
*/
template
<
class
V
>
int
Query
(
const
SHAPE
*
shape
,
int
minDistance
,
V
&
v
isitor
,
bool
aExact
)
int
Query
(
const
SHAPE
*
aShape
,
int
aMinDistance
,
V
&
aV
isitor
,
bool
aExact
)
{
BOX2I
box
=
s
hape
->
BBox
();
box
.
Inflate
(
minDistance
);
BOX2I
box
=
aS
hape
->
BBox
();
box
.
Inflate
(
aMinDistance
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
return
this
->
m_tree
->
Search
(
min
,
max
,
visitor
);
return
this
->
m_tree
->
Search
(
min
,
max
,
aVisitor
);
}
/**
...
...
@@ -284,7 +291,6 @@ class SHAPE_INDEX {
Iterator
Begin
();
private
:
RTree
<
T
,
int
,
2
,
float
>*
m_tree
;
};
...
...
@@ -293,58 +299,68 @@ class SHAPE_INDEX {
*/
template
<
class
T
>
SHAPE_INDEX
<
T
>::
SHAPE_INDEX
()
{
SHAPE_INDEX
<
T
>::
SHAPE_INDEX
()
{
this
->
m_tree
=
new
RTree
<
T
,
int
,
2
,
float
>
();
}
template
<
class
T
>
SHAPE_INDEX
<
T
>::~
SHAPE_INDEX
()
{
SHAPE_INDEX
<
T
>::~
SHAPE_INDEX
()
{
delete
this
->
m_tree
;
}
template
<
class
T
>
void
SHAPE_INDEX
<
T
>::
Add
(
T
shape
)
{
BOX2I
box
=
boundingBox
(
shape
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()};
this
->
m_tree
->
Insert
(
min
,
max
,
shape
);
void
SHAPE_INDEX
<
T
>::
Add
(
T
aShape
)
{
BOX2I
box
=
boundingBox
(
aShape
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
this
->
m_tree
->
Insert
(
min
,
max
,
aShape
);
}
template
<
class
T
>
void
SHAPE_INDEX
<
T
>::
Remove
(
T
shape
)
{
BOX2I
box
=
boundingBox
(
shape
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()};
this
->
m_tree
->
Remove
(
min
,
max
,
shape
);
void
SHAPE_INDEX
<
T
>::
Remove
(
T
aShape
)
{
BOX2I
box
=
boundingBox
(
aShape
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
this
->
m_tree
->
Remove
(
min
,
max
,
aShape
);
}
template
<
class
T
>
void
SHAPE_INDEX
<
T
>::
RemoveAll
()
{
void
SHAPE_INDEX
<
T
>::
RemoveAll
()
{
this
->
m_tree
->
RemoveAll
();
}
template
<
class
T
>
void
SHAPE_INDEX
<
T
>::
Reindex
()
{
void
SHAPE_INDEX
<
T
>::
Reindex
()
{
RTree
<
T
,
int
,
2
,
float
>*
newTree
;
newTree
=
new
RTree
<
T
,
int
,
2
,
float
>
();
Iterator
iter
=
this
->
Begin
();
while
(
!
iter
.
IsNull
())
{
while
(
!
iter
.
IsNull
()
)
{
T
shape
=
*
iter
;
BOX2I
box
=
boundingBox
(
shape
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
newTree
->
Insert
(
min
,
max
,
shape
);
BOX2I
box
=
boundingBox
(
shape
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
newTree
->
Insert
(
min
,
max
,
shape
);
iter
++
;
}
delete
this
->
m_tree
;
this
->
m_tree
=
newTree
;
}
template
<
class
T
>
typename
SHAPE_INDEX
<
T
>::
Iterator
SHAPE_INDEX
<
T
>::
Begin
()
{
return
Iterator
(
this
);
typename
SHAPE_INDEX
<
T
>::
Iterator
SHAPE_INDEX
<
T
>::
Begin
()
{
return
Iterator
(
this
);
}
#endif
include/geometry/shape_line_chain.h
View file @
3f320e4d
This diff is collapsed.
Click to expand it.
include/tool/action_manager.h
View file @
3f320e4d
...
...
@@ -43,21 +43,21 @@ public:
/**
* Function RegisterAction()
* Adds a tool action to the manager
set
and sets it up. After that is is possible to invoke
* the action using hotkeys or its name.
* Adds a tool action to the manager and sets it up. After that is is possible to invoke
* the action using hotkeys or
sending a command event with
its name.
* @param aAction: action to be added. Ownership is not transferred.
*/
void
RegisterAction
(
TOOL_ACTION
*
aAction
);
/**
* Function UnregisterAction()
* Removes a tool action from the manager
set
and makes it unavailable for further usage.
* Removes a tool action from the manager and makes it unavailable for further usage.
* @param aAction: action to be removed.
*/
void
UnregisterAction
(
TOOL_ACTION
*
aAction
);
/**
* Generates an unique ID from for a
tool
with given name.
* Generates an unique ID from for a
n action
with given name.
*/
static
int
MakeActionId
(
const
std
::
string
&
aActionName
);
...
...
@@ -82,9 +82,16 @@ public:
bool
RunHotKey
(
int
aHotKey
)
const
;
private
:
///> Tool manager needed to run actions
TOOL_MANAGER
*
m_toolMgr
;
///> Map for indexing actions by their IDs
std
::
map
<
int
,
TOOL_ACTION
*>
m_actionIdIndex
;
///> Map for indexing actions by their names
std
::
map
<
std
::
string
,
TOOL_ACTION
*>
m_actionNameIndex
;
///> Map for indexing actions by their hotkeys
std
::
map
<
int
,
TOOL_ACTION
*>
m_actionHotKeys
;
/**
...
...
include/tool/context_menu.h
View file @
3f320e4d
...
...
@@ -29,7 +29,6 @@
#include <tool/tool_action.h>
#include <map>
class
wxMenu
;
class
TOOL_INTERACTIVE
;
/**
...
...
@@ -40,53 +39,102 @@ class TOOL_INTERACTIVE;
*/
class
CONTEXT_MENU
{
public
:
///> Default constructor
CONTEXT_MENU
();
///> Copy constructor
CONTEXT_MENU
(
const
CONTEXT_MENU
&
aMenu
);
/**
* Function SetTitle()
* Sets title for the context menu. The title is shown as a text label shown on the top of
* the menu.
* @param aTitle is the new title.
*/
void
SetTitle
(
const
wxString
&
aTitle
);
/**
* Function Add()
* Adds an entry to the menu. After highlighting/selecting the entry, a TOOL_EVENT command is
* sent that contains ID of the entry.
* @param aLabel is the text label show in the menu.
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
*/
void
Add
(
const
wxString
&
aLabel
,
int
aId
);
/**
* Function Add()
* Adds an entry to the menu, basing on the TOOL_ACTION object. After selecting the entry,
* a TOOL_EVENT command containing name of the action is sent.
* @param aAction is the action to be added to menu entry.
*/
void
Add
(
const
TOOL_ACTION
&
aAction
);
/**
* Function Clear()
* Removes all the entries from the menu (as well as its title). It leaves the menu in the
* initial state.
*/
void
Clear
();
/**
* Function GetMenu()
* Returns the instance of wxMenu object used to display the menu.
*/
wxMenu
*
GetMenu
()
const
{
return
const_cast
<
wxMenu
*>
(
&
m_menu
);
}
private
:
///> Class CMEventHandler takes care of handling menu events. After reception of particular
///> events, it translates them to TOOL_EVENTs that may control tools.
class
CMEventHandler
:
public
wxEvtHandler
{
public
:
///> Default constructor
///> aMenu is the CONTEXT_MENU instance for which it handles events.
CMEventHandler
(
CONTEXT_MENU
*
aMenu
)
:
m_menu
(
aMenu
)
{};
///> Handler for menu events.
void
onEvent
(
wxEvent
&
aEvent
);
private
:
///> CONTEXT_MENU instance for which it handles events.
CONTEXT_MENU
*
m_menu
;
};
friend
class
TOOL_INTERACTIVE
;
/**
* Function setTool()
* Sets a tool that is the creator of the menu.
* @param aTool is the tool that created the menu.
*/
void
setTool
(
TOOL_INTERACTIVE
*
aTool
)
{
m_tool
=
aTool
;
}
/**
* Function getHotKeyDescription()
* Returns a hot key in the string format accepted by wxMenu.
*
* @param aAction is the action with hot key to be converted.
* @param aAction is the action with hot key to be translated..
* @return Hot key in the string format compatible with wxMenu.
*/
std
::
string
getHotKeyDescription
(
const
TOOL_ACTION
&
aAction
)
const
;
///
Flag indicating that the menu title was set up
///
> Flag indicating that the menu title was set up.
bool
m_titleSet
;
///> Instance of wxMenu used for display of the context menu.
wxMenu
m_menu
;
///> Instance of menu event handler.
CMEventHandler
m_handler
;
///> Creator of the menu
TOOL_INTERACTIVE
*
m_tool
;
/// Menu items with ID higher than that are considered TOOL_ACTIONs
...
...
include/tool/tool_base.h
View file @
3f320e4d
...
...
@@ -42,17 +42,21 @@ class VIEW_CONTROLS;
enum
TOOL_Type
{
TOOL_Interactive
=
0x1
,
TOOL_Batch
=
0x2
///> Tool that interacts with the user
TOOL_Interactive
=
0x01
,
///> Tool that runs in the background without any user intervention
TOOL_Batch
=
0x02
};
/// Unique identifier for tools
typedef
int
TOOL_ID
;
typedef
DELEGATE
<
int
,
TOOL_EVENT
&>
TOOL_STATE_FUNC
;
/**
* Class TOOL_BASE
*
* Base abstract interface for all kinds of tools
* Base abstract interface for all kinds of tools
.
*/
class
TOOL_BASE
...
...
@@ -61,25 +65,49 @@ public:
TOOL_BASE
(
TOOL_Type
aType
,
TOOL_ID
aId
,
const
std
::
string
&
aName
=
std
::
string
(
""
)
)
:
m_type
(
aType
),
m_toolId
(
aId
),
m_toolName
(
aName
)
{};
m_toolName
(
aName
),
m_toolMgr
(
NULL
){};
virtual
~
TOOL_BASE
()
{};
/**
* Function GetType()
* Returns the type of the tool.
* @return The type of the tool.
*/
TOOL_Type
GetType
()
const
{
return
m_type
;
}
/**
* Function GetId()
* Returns the unique identifier of the tool. The identifier is set by an instance of
* TOOL_MANAGER.
* @return Identifier of the tool.
*/
TOOL_ID
GetId
()
const
{
return
m_toolId
;
}
/**
* Function GetName()
* Returns the name of the tool. Tool names are expected to obey the format:
* application.ToolName (eg. pcbnew.InteractiveSelection).
* @return The name of the tool.
*/
const
std
::
string
&
GetName
()
const
{
return
m_toolName
;
}
/**
* Function GetManager()
* Returns the instance of TOOL_MANAGER that takes care of the tool.
* @return Instance of the TOOL_MANAGER. If there is no TOOL_MANAGER associated, it returns
* NULL.
*/
TOOL_MANAGER
*
GetManager
()
const
{
return
m_toolMgr
;
...
...
@@ -96,14 +124,27 @@ protected:
*/
void
attachManager
(
TOOL_MANAGER
*
aManager
);
/**
* Function getView()
*
* Returns the instance of VIEW object used in the application. It allows tools to draw.
* @return The instance of VIEW.
*/
KiGfx
::
VIEW
*
getView
()
const
;
/**
* Function getViewControls()
*
* Returns the instance of VIEW_CONTROLS object used in the application. It allows tools to
* read & modify user input and its settings (eg. show cursor, enable snapping to grid, etc.)
* @return The instance of VIEW_CONTROLS.
*/
KiGfx
::
VIEW_CONTROLS
*
getViewControls
()
const
;
/**
* Function getEditFrame()
*
* Returns the application window object, casted to requested user type, possibly with
* run-time type check
* Returns the application window object, casted to requested user type.
*/
template
<
typename
T
>
T
*
getEditFrame
()
const
...
...
@@ -124,8 +165,14 @@ protected:
return
static_cast
<
T
*>
(
m
);
}
///> Stores the type of the tool.
TOOL_Type
m_type
;
///> Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
TOOL_ID
m_toolId
;
///> Name of the tool. Names are expected to obey the format application.ToolName
///> (eg. pcbnew.InteractiveSelection).
std
::
string
m_toolName
;
TOOL_MANAGER
*
m_toolMgr
;
...
...
include/tool/tool_dispatcher.h
View file @
3f320e4d
...
...
@@ -29,7 +29,6 @@
#include <tool/tool_event.h>
//#include <wx/event.h>
#include <wx/kbdstate.h>
class
TOOL_MANAGER
;
...
...
@@ -61,26 +60,62 @@ public:
TOOL_DISPATCHER
(
TOOL_MANAGER
*
aToolMgr
,
PCB_BASE_FRAME
*
aEditFrame
);
virtual
~
TOOL_DISPATCHER
();
/**
* Function ResetState()
* Brings the dispatcher to its initial state.
*/
virtual
void
ResetState
();
/**
* Function DispatchWxEvent()
* Processes wxEvents (mostly UI events), translates them to TOOL_EVENTs, and makes tools
* handle those.
* @param aEvent is the wxWidgets event to be processed.
*/
virtual
void
DispatchWxEvent
(
wxEvent
&
aEvent
);
virtual
void
DispatchWxCommand
(
wxCommandEvent
&
aEvent
);
/**
* Function DispatchWxCommand()
* Processes wxCommands (mostly menu related events) and runs appropriate actions (eg. run the
* specified tool).
* @param aEvent is the wxCommandEvent to be processed.
*/
virtual
void
DispatchWxCommand
(
const
wxCommandEvent
&
aEvent
);
private
:
///> Number of mouse buttons that is handled in events.
static
const
int
MouseButtonCount
=
3
;
///> The time threshold for a mouse button press that distinguishes between a single mouse
///> click and a beginning of drag event (expressed in milliseconds).
static
const
int
DragTimeThreshold
=
300
;
///> The distance threshold for mouse cursor that disinguishes between a single mouse click
///> and a beginning of drag event (expressed in screen pixels).
static
const
int
DragDistanceThreshold
=
8
;
///> Handles mouse related events (click, motion, dragging)
bool
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
);
bool
handlePopupMenu
(
wxEvent
&
aEvent
);
///> Saves the state of key modifiers (Alt, Ctrl and so on).
int
decodeModifiers
(
const
wxKeyboardState
*
aState
)
const
;
///> Stores all the informations regarding a mouse button state.
struct
ButtonState
;
///> The last mouse cursor position (in world coordinates).
VECTOR2D
m_lastMousePos
;
///> State of mouse buttons.
std
::
vector
<
ButtonState
*>
m_buttons
;
///> Returns the instance of VIEW, used by the application.
KiGfx
::
VIEW
*
getView
();
///> Instance of tool manager that cooperates with the dispatcher.
TOOL_MANAGER
*
m_toolMgr
;
///> Instance of wxFrame that is the source of UI events.
PCB_BASE_FRAME
*
m_editFrame
;
};
...
...
include/tool/tool_event.h
View file @
3f320e4d
...
...
@@ -29,6 +29,7 @@
#include <deque>
#include <math/vector2d.h>
#include <cassert>
#include <boost/optional.hpp>
...
...
@@ -71,17 +72,19 @@ enum TOOL_Actions
TA_ViewDirty
=
0x0800
,
TA_ChangeLayer
=
0x1000
,
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from the context menu.
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// the context menu.
TA_CancelTool
=
0x2000
,
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
over one of choices.
//
Used in dynamic highligting in disambiguation menu
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
//
over one of choices. Used in dynamic highligting in disambiguation menu
TA_ContextMenuUpdate
=
0x4000
,
// Context menu choice. Sent if the user picked something from the context menu or closed it without selecting anything.
// Context menu choice. Sent if the user picked something from the context menu or
// closed it without selecting anything.
TA_ContextMenuChoice
=
0x8000
,
// Tool action
// Tool action
(allows to control tools)
TA_Action
=
0x10000
,
TA_Any
=
0xffffffff
...
...
@@ -129,6 +132,12 @@ enum CONTEXT_MENU_TRIGGER
class
TOOL_EVENT
{
public
:
/**
* Function Format()
* Returns information about event in form of a human-readable string.
*
* @return Event information.
*/
const
std
::
string
Format
()
const
;
TOOL_EVENT
(
TOOL_EventCategory
aCategory
=
TC_None
,
TOOL_Actions
aAction
=
TA_None
,
...
...
@@ -175,33 +184,44 @@ public:
m_commandStr
=
aExtraParam
;
}
///> Returns the category (eg. mouse/keyboard/action) of an event..
TOOL_EventCategory
Category
()
const
{
return
m_category
;
}
///> Returns more specific information about the type of an event.
TOOL_Actions
Action
()
const
{
return
m_actions
;
}
///> Returns information about difference between current mouse cursor position and the place
///> where dragging has started.
const
VECTOR2D
Delta
()
const
{
assert
(
m_category
==
TC_Mouse
);
// this should be used only with mouse events
return
m_mouseDelta
;
}
///> Returns mouse cursor position in world coordinates.
const
VECTOR2D
&
Position
()
const
{
assert
(
m_category
==
TC_Mouse
);
// this should be used only with mouse events
return
m_mousePos
;
}
///> Returns the point where dragging has started.
const
VECTOR2D
&
DragOrigin
()
const
{
assert
(
m_category
==
TC_Mouse
);
// this should be used only with mouse events
return
m_mouseDragOrigin
;
}
///> Returns information about mouse buttons state.
int
Buttons
()
const
{
assert
(
m_category
==
TC_Mouse
);
// this should be used only with mouse events
return
m_mouseButtons
;
}
...
...
@@ -231,6 +251,7 @@ public:
return
m_actions
==
TA_CancelTool
;
}
///> Returns information about key modifiers state (Ctrl, Alt, etc.)
int
Modifier
(
int
aMask
=
MD_ModifierMask
)
const
{
return
(
m_modifiers
&
aMask
);
...
...
@@ -251,8 +272,6 @@ public:
return
m_actions
==
TA_KeyDown
;
}
void
Ignore
();
void
SetMouseDragOrigin
(
const
VECTOR2D
&
aP
)
{
m_mouseDragOrigin
=
aP
;
...
...
@@ -268,6 +287,13 @@ public:
m_mouseDelta
=
aP
;
}
/**
* Function Matches()
* Tests whether two events match in terms of category & action or command.
*
* @param aEvent is the event to test against.
* @return True if two events match, false otherwise.
*/
bool
Matches
(
const
TOOL_EVENT
&
aEvent
)
const
{
if
(
!
(
m_category
&
aEvent
.
m_category
)
)
...
...
@@ -299,13 +325,25 @@ private:
TOOL_Actions
m_actions
;
TOOL_ActionScope
m_scope
;
///> Difference between mouse cursor position and
///> the point where dragging event has started
VECTOR2D
m_mouseDelta
;
///> Current mouse cursor position
VECTOR2D
m_mousePos
;
///> Point where dragging has started
VECTOR2D
m_mouseDragOrigin
;
///> State of mouse buttons
int
m_mouseButtons
;
///> Stores code of pressed/released key
int
m_keyCode
;
///> State of key modifierts (Ctrl/Alt/etc.)
int
m_modifiers
;
boost
::
optional
<
int
>
m_commandId
;
boost
::
optional
<
std
::
string
>
m_commandStr
;
};
...
...
@@ -324,7 +362,10 @@ public:
typedef
std
::
deque
<
TOOL_EVENT
>::
iterator
iterator
;
typedef
std
::
deque
<
TOOL_EVENT
>::
const_iterator
const_iterator
;
///> Default constructor. Creates an empty list.
TOOL_EVENT_LIST
()
{};
///> Constructor for a list containing only one TOOL_EVENT.
TOOL_EVENT_LIST
(
const
TOOL_EVENT
&
aSingleEvent
)
{
m_events
.
push_back
(
aSingleEvent
);
...
...
@@ -346,6 +387,11 @@ public:
return
boost
::
optional
<
const
TOOL_EVENT
&>
();
}
/**
* Function Add()
* Adds a tool event to the list.
* @param aEvent is the tool event to be addded.
*/
void
Add
(
const
TOOL_EVENT
&
aEvent
)
{
m_events
.
push_back
(
aEvent
);
...
...
include/tool/tool_interactive.h
View file @
3f320e4d
...
...
@@ -35,6 +35,10 @@ class CONTEXT_MENU;
class
TOOL_INTERACTIVE
:
public
TOOL_BASE
{
public
:
/**
* Constructor
*
* Creates a tool with given id & name. The name must be unique. */
TOOL_INTERACTIVE
(
TOOL_ID
aId
,
const
std
::
string
&
aName
);
/**
...
...
@@ -46,8 +50,8 @@ public:
/**
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
the model or the view,
* it must release it when its reset.
* Brings the tool to a known, initial state. If the tool claimed anything from
*
the model or the view,
it must release it when its reset.
*/
virtual
void
Reset
()
=
0
;
...
...
@@ -65,7 +69,9 @@ public:
/**
* Function SetContextMenu()
*
* Assigns a context menu and tells when it should be activated
* Assigns a context menu and tells when it should be activated.
* @param aMenu is the menu to be assigned.
* @param aTrigger determines conditions upon which the context menu is activated.
*/
void
SetContextMenu
(
CONTEXT_MENU
*
aMenu
,
CONTEXT_MENU_TRIGGER
aTrigger
=
CMENU_BUTTON
);
...
...
@@ -87,9 +93,8 @@ public:
*/
OPT_TOOL_EVENT
Wait
(
const
TOOL_EVENT_LIST
&
aEventList
=
TOOL_EVENT
(
TC_Any
,
TA_Any
)
);
/** functions below are not yet implemented - their interface may change */
template
<
class
Parameters
,
class
ReturnValue
>
/*
template<class Parameters, class ReturnValue>
bool InvokeTool( const std::string& aToolName, const Parameters& parameters,
ReturnValue& returnValue );
...
...
@@ -98,11 +103,10 @@ public:
ReturnValue& returnValue );
template<class T>
void
Yield
(
const
T
&
returnValue
);
void Yield( const T& returnValue );
*/
protected
:
/* helper functions for constructing events for Wait() and Go() with
less typing */
/* helper functions for constructing events for Wait() and Go() with less typing */
const
TOOL_EVENT
evActivate
(
std
::
string
aToolName
=
""
);
const
TOOL_EVENT
evCommand
(
int
aCommandId
=
-
1
);
const
TOOL_EVENT
evCommand
(
std
::
string
aCommandStr
=
""
);
...
...
pcbnew/tools/move_tool.cpp
View file @
3f320e4d
...
...
@@ -36,6 +36,8 @@ using boost::optional;
MOVE_TOOL
::
MOVE_TOOL
()
:
TOOL_INTERACTIVE
(
"pcbnew.InteractiveMove"
),
m_selectionTool
(
NULL
),
// Available actions:
m_activate
(
m_toolName
,
AS_GLOBAL
,
'M'
,
"Move"
,
"Moves the selected item(s)"
),
m_rotate
(
m_toolName
+
".rotate"
,
AS_CONTEXT
,
' '
,
"Rotate"
,
"Rotates selected item(s)"
),
m_flip
(
m_toolName
+
".flip"
,
AS_CONTEXT
,
'F'
,
"Flip"
,
"Flips selected item(s)"
)
...
...
@@ -69,7 +71,7 @@ bool MOVE_TOOL::Init()
m_toolMgr
->
RegisterAction
(
&
m_rotate
);
m_toolMgr
->
RegisterAction
(
&
m_flip
);
// Add context menu entries
for the selection tool
// Add context menu entries
that are displayed when selection tool is active
m_selectionTool
->
AddMenuItem
(
m_activate
);
m_selectionTool
->
AddMenuItem
(
m_rotate
);
m_selectionTool
->
AddMenuItem
(
m_flip
);
...
...
@@ -92,7 +94,9 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
VIEW
*
view
=
getView
();
VIEW_CONTROLS
*
controls
=
getViewControls
();
// Add a VIEW_GROUP that will hold all modified items
view
->
Add
(
&
m_items
);
controls
->
ShowCursor
(
true
);
controls
->
SetSnapping
(
true
);
controls
->
SetAutoPan
(
true
);
...
...
@@ -102,7 +106,7 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
{
if
(
evt
->
IsCancel
()
)
{
restore
=
true
;
restore
=
true
;
// Cancelling the tool means that items have to be restored
break
;
// Finish
}
...
...
@@ -111,12 +115,12 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
{
VECTOR2D
cursorPos
=
getView
()
->
ToWorld
(
getViewControls
()
->
GetCursorPosition
()
);
if
(
evt
->
Matches
(
m_rotate
.
GetEvent
()
)
)
if
(
evt
->
Matches
(
m_rotate
.
GetEvent
()
)
)
// got rotation event?
{
m_state
.
Rotate
(
cursorPos
,
900.0
);
m_items
.
ViewUpdate
(
VIEW_ITEM
::
GEOMETRY
);
}
else
if
(
evt
->
Matches
(
m_flip
.
GetEvent
()
)
)
else
if
(
evt
->
Matches
(
m_flip
.
GetEvent
()
)
)
// got flip event?
{
m_state
.
Flip
(
cursorPos
);
m_items
.
ViewUpdate
(
VIEW_ITEM
::
GEOMETRY
);
...
...
@@ -165,20 +169,22 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
// Restore visibility of the original items
vgSetVisibility
(
&
m_items
,
true
);
// Movement has to be rollbacked, so restore the previous state of items
if
(
restore
)
{
// Modifications has to be rollbacked, so restore the previous state of items
vgUpdate
(
&
m_items
,
VIEW_ITEM
::
APPEARANCE
);
m_state
.
RestoreAll
();
}
else
{
// Changes are applied, so update the items
vgUpdate
(
&
m_items
,
m_state
.
GetUpdateFlag
()
);
m_state
.
Apply
();
}
m_items
.
Clear
();
view
->
Remove
(
&
m_items
);
controls
->
ShowCursor
(
false
);
controls
->
SetSnapping
(
false
);
controls
->
SetAutoPan
(
false
);
...
...
pcbnew/tools/selection_area.h
View file @
3f320e4d
...
...
@@ -50,6 +50,7 @@ public:
virtual
const
BOX2I
ViewBBox
()
const
;
void
ViewDraw
(
int
aLayer
,
KiGfx
::
GAL
*
aGal
)
const
;
void
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
;
void
SetOrigin
(
VECTOR2I
aOrigin
)
...
...
pcbnew/tools/selection_tool.cpp
View file @
3f320e4d
...
...
@@ -83,7 +83,6 @@ bool SELECTION_TOOL::Init()
int
SELECTION_TOOL
::
Main
(
TOOL_EVENT
&
aEvent
)
{
BOARD
*
board
=
getModel
<
BOARD
>
(
PCB_T
);
assert
(
board
!=
NULL
);
// Main loop: keep receiving events
...
...
@@ -116,13 +115,16 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
}
else
{
// Check if dragging has started within any of selected items bounding box
if
(
containsSelected
(
evt
->
Position
()
)
)
{
// Yes -> run the move tool and wait till it finishes
m_toolMgr
->
InvokeTool
(
"pcbnew.InteractiveMove"
);
Wait
();
}
else
{
// No -> clear the selection list
clearSelection
();
}
}
...
...
@@ -135,7 +137,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
void
SELECTION_TOOL
::
AddMenuItem
(
const
TOOL_ACTION
&
aAction
)
{
assert
(
aAction
.
GetId
()
>
0
);
// Check if the action was registered before
assert
(
aAction
.
GetId
()
>
0
);
// Check if the action was registered before
in ACTION_MANAGER
m_menu
.
Add
(
aAction
);
}
...
...
@@ -259,9 +261,9 @@ BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector
bool
SELECTION_TOOL
::
selectMultiple
()
{
VIEW
*
view
=
getView
();
bool
cancelled
=
false
;
bool
cancelled
=
false
;
// Was the tool cancelled while it was running?
m_multiple
=
true
;
// Multiple selection mode is active
VIEW
*
view
=
getView
();
getViewControls
()
->
SetAutoPan
(
true
);
// Those 2 lines remove the blink-in-the-random-place effect
...
...
@@ -291,7 +293,7 @@ bool SELECTION_TOOL::selectMultiple()
if
(
evt
->
IsMouseUp
(
MB_Left
)
)
{
// End drawing
a
selection box
// End drawing
the
selection box
m_selArea
->
ViewSetVisible
(
false
);
// Mark items within the selection box as selected
...
...
@@ -315,6 +317,7 @@ bool SELECTION_TOOL::selectMultiple()
// Now the context menu should be enabled
if
(
!
m_selectedItems
.
empty
()
)
SetContextMenu
(
&
m_menu
,
CMENU_BUTTON
);
break
;
}
}
...
...
@@ -367,6 +370,7 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
{
optional
<
int
>
id
=
evt
->
GetCommandId
();
// User has selected an item, so this one will be returned
if
(
id
&&
(
*
id
>=
0
)
)
current
=
(
*
aCollector
)[
*
id
];
...
...
@@ -392,11 +396,12 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
bool
SELECTION_TOOL
::
selectable
(
const
BOARD_ITEM
*
aItem
)
const
{
// Is high contrast mode enabled?
bool
highContrast
=
getView
()
->
GetPainter
()
->
GetSettings
()
->
GetHighContrast
();
if
(
highContrast
)
{
bool
onActive
=
false
;
bool
onActive
=
false
;
// Is the item on any of active layers?
int
layers
[
KiGfx
::
VIEW
::
VIEW_MAX_LAYERS
],
layers_count
;
// Filter out items that do not belong to active layers
...
...
@@ -406,14 +411,14 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
for
(
int
i
=
0
;
i
<
layers_count
;
++
i
)
{
if
(
activeLayers
.
count
(
layers
[
i
]
)
>
0
)
// Item is on at least one
active layer
if
(
activeLayers
.
count
(
layers
[
i
]
)
>
0
)
// Item is on at least one
of active layers
{
onActive
=
true
;
break
;
}
}
if
(
!
onActive
)
if
(
!
onActive
)
// We do not want to select items that are in the background
return
false
;
}
...
...
@@ -426,8 +431,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
LAYER_NUM
top
,
bottom
;
static_cast
<
const
SEGVIA
*>
(
aItem
)
->
ReturnLayerPair
(
&
top
,
&
bottom
);
return
(
board
->
IsLayerVisible
(
top
)
||
board
->
IsLayerVisible
(
bottom
)
);
return
(
board
->
IsLayerVisible
(
top
)
||
board
->
IsLayerVisible
(
bottom
)
);
}
break
;
...
...
@@ -473,8 +477,7 @@ bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const
{
// Check if the point is located within any of the currently selected items bounding boxes
std
::
set
<
BOARD_ITEM
*>::
iterator
it
,
it_end
;
for
(
it
=
m_selectedItems
.
begin
(),
it_end
=
m_selectedItems
.
end
();
it
!=
it_end
;
++
it
)
for
(
it
=
m_selectedItems
.
begin
(),
it_end
=
m_selectedItems
.
end
();
it
!=
it_end
;
++
it
)
{
BOX2I
itemBox
=
(
*
it
)
->
ViewBBox
();
itemBox
.
Inflate
(
500000
);
// Give some margin for gripping an item
...
...
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