Gitlab CSE Unil
Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
M. Chardon
ADIM
Commits
46db4303
Commit
46db4303
authored
Jun 23, 2015
by
Julien Furrer
Browse files
Big packed commit with a lot of mixed good stuff
Missing intermediate commits with good comments....
parent
b7fc9b91
Changes
69
Expand all
Hide whitespace changes
Inline
Side-by-side
adim_project/adim/migrations/0005_anobj_env.py
0 → 100644
View file @
46db4303
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'adim'
,
'0004_auto_20150424_1209'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'anobj'
,
name
=
'env'
,
field
=
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
choices
=
[(
''
,
'Standard'
),
(
'cimaf'
,
'CIMAF'
)]),
),
]
adim_project/adim/models/annotables.py
View file @
46db4303
...
...
@@ -28,6 +28,10 @@ RANDOM_NODE = random.randrange(0, 1 << 48L) | 0x010000000000L
# Destination path for uploaded images, relative to MEDIA_ROOT
AO_IMAGES_PATH
=
'ao_images'
AO_ENVIRON
=
(
(
''
,
'Standard'
),
(
'cimaf'
,
'CIMAF'
),
)
class
AOType
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
128
)
...
...
@@ -106,6 +110,8 @@ class AnObj(models.Model):
members
=
models
.
ManyToManyField
(
User
,
verbose_name
=
_
(
"members"
),
through
=
'AnObjMembership'
,
related_name
=
'shared_anobjs'
,
blank
=
True
)
env
=
models
.
CharField
(
max_length
=
64
,
choices
=
AO_ENVIRON
,
blank
=
True
)
image
=
models
.
ImageField
(
upload_to
=
get_image_path
,
verbose_name
=
_
(
"image"
),
blank
=
True
,
null
=
True
)
image_url
=
models
.
CharField
(
max_length
=
512
,
verbose_name
=
_
(
"image url"
),
blank
=
True
,
null
=
True
,
default
=
""
)
...
...
adim_project/adim/serializers.py
View file @
46db4303
...
...
@@ -102,7 +102,7 @@ class AnObjSerializer(BaseAnObjSerializer):
class
Meta
:
model
=
AnObj
fields
=
(
'id'
,
'uuid'
,
'name'
,
'owners'
,
'owner'
,
'owner_name'
,
'annotations'
,
'members'
,
'sharing_mode'
,
'sharing_opts'
,
'locked'
,
'allow_public_publishing'
)
'sharing_mode'
,
'sharing_opts'
,
'locked'
,
'allow_public_publishing'
,
'env'
)
class
SharedAnObjSerializer
(
BaseAnObjSerializer
):
...
...
adim_project/adim_app/static/_src/adim/config.js
View file @
46db4303
...
...
@@ -52,6 +52,10 @@ function($){
},
// If not defined or empty, will be built from the tools button found on the page.
// Otherwise use the value given. If an annotation type is not found in `activeTools` it wont be displayed
activeTools
:
[],
userEngine
:
{
limit
:
7
,
remoteUrl
:
"
http://path/to/suggestion/url/?q=%QUERY
"
,
...
...
@@ -82,6 +86,15 @@ function($){
},
window
[
adim_config_varname
]
||
{},
true
);
if
(
!
config
.
activeTools
||
config
.
activeTools
.
length
==
0
)
try
{
config
.
activeTools
=
$
(
"
#draw-tool-tb [data-tool-name]
"
).
map
(
function
(){
return
$
(
this
).
attr
(
'
data-tool-name
'
)
});
}
catch
(
e
)
{
config
.
activeTools
=
null
;
}
if
(
config
.
csrfToken
)
{
$
.
ajaxSetup
({
beforeSend
:
function
(
xhr
)
{
...
...
adim_project/adim_app/static/_src/adim/env/cimaf/env.js
0 → 100644
View file @
46db4303
/**
* Created by jfurrer on 22.06.15.
*/
define
([
"
jquery
"
,
"
underscore
"
,
"
paper
"
,
"
signals
"
,
"
adim/config
"
,
"
adim/view
"
,
"
adim/attributes
"
,
"
adim/io
"
,
"
adim/tools
"
,
"
adim/ui
"
],
function
(
$
,
_
,
paper
,
Signal
,
config
,
view
,
attributes
,
io
,
tools
,
ui
){
/**
* Signal binding specific to CIMAF environment
* @private
*/
function
_initSignalRouting
(){
console
.
info
(
"
_initSignalRouting from env/cimaf
"
);
var
userLayer
;
/**
* Count the number of intersections for each CMS Area.
* Only intersection with concordant stria are relevant.
*
* @param [annotation] {object} The annotation responsible for the update. If it is a 'cmsarea' it means
* this area was created/edited, so we don't need to update the count for other area.
*/
function
updateAreaIntersectionCount
(
annotation
)
{
// If annotation is not area or concordant stria, there is no need for computation
if
(
annotation
&&
[
'
cmsarea
'
,
'
concordantstr
'
].
indexOf
(
annotation
.
data
.
type
)
<
0
)
return
;
if
(
!
userLayer
)
{
userLayer
=
view
.
getOrCreateUserLayer
(
config
.
user
.
id
,
config
.
user
.
full_name
)
}
if
(
!
userLayer
)
return
;
var
zones
=
userLayer
.
children
.
filter
(
function
(
a
)
{
return
a
.
data
.
type
&&
a
.
data
.
type
===
'
cmsarea
'
;
});
var
striae
=
userLayer
.
children
.
filter
(
function
(
a
)
{
return
a
.
data
.
type
&&
a
.
data
.
type
===
'
concordantstr
'
;
});
// If the current selection is an area, keep it's current nbConcordances
var
items
=
paper
.
project
.
getSelectedItems
();
var
selectedArea
=
(
items
.
length
===
1
&&
items
[
0
].
data
.
type
===
'
cmsarea
'
)
?
items
[
0
]
:
null
;
var
selectedAreaCount
=
selectedArea
?
selectedArea
.
data
.
prop
.
nbConcordances
:
null
;
var
zone
,
nbInter
,
i
,
ii
,
nbStria
=
striae
.
length
;
for
(
i
=
0
;
zone
=
zones
[
i
];
i
++
)
{
nbInter
=
0
;
for
(
ii
=
0
;
ii
<
nbStria
;
ii
++
)
{
nbInter
+=
Math
.
round
(
zone
.
getIntersections
(
striae
[
ii
]).
length
/
2
);
}
zone
.
data
.
prop
.
nbConcordances
=
nbInter
;
}
if
(
selectedAreaCount
!==
null
&&
selectedArea
.
data
.
prop
.
nbConcordances
!==
selectedAreaCount
)
{
ui
.
displayProperties
(
selectedArea
);
}
}
tools
.
events
.
annotationAdded
.
add
(
function
(
annotation
)
{
updateAreaIntersectionCount
(
annotation
);
},
this
,
100
);
tools
.
events
.
annotationChanged
.
add
(
function
(
annotations
)
{
updateAreaIntersectionCount
(
annotations
.
length
===
1
?
annotations
[
0
]
:
void
(
0
));
},
this
,
100
);
// This should be called before the annotations are rendered, so we bind it to the imageLoaded event
// before the image loading is started. To do so we set a higher priority (100)
// than the handler defined in main. @TODO: get the cut position and cut margin from config
io
.
events
.
annotableLoaded
.
add
(
function
(
annotableData
){
var
concordantstrTool
=
tools
.
tools
[
'
concordantstr
'
];
var
discordantstrTool
=
tools
.
tools
[
'
discordantstr
'
];
var
cmsareaTool
=
tools
.
tools
[
'
cmsarea
'
];
view
.
events
.
imageLoaded
.
add
(
function
(
p
){
var
cutPos
=
p
.
raster
.
scaling
.
x
*
p
.
raster
.
width
/
2
;
var
cutMargin
=
25
;
concordantstrTool
.
listeners
.
onCutPositionChanged
(
cutPos
);
discordantstrTool
.
listeners
.
onCutPositionChanged
(
cutPos
);
cmsareaTool
.
listeners
.
onCutPositionChanged
(
cutPos
);
cmsareaTool
.
listeners
.
onSetAreaWidth
(
cutMargin
*
2
);
});
},
100
);
}
function
_initUI
(
params
)
{
/**
* UI initialization for CIMF. Called after ui.init by main
*/
// Init Type Display Selector
$
(
"
.adim-display-type-selector
"
).
find
(
"
button
"
).
on
(
'
click
'
,
function
(
event
)
{
var
$but
=
$
(
this
);
var
activate
=
!
$but
.
hasClass
(
"
active
"
);
var
typeName
=
$but
.
data
(
'
typeName
'
);
if
(
event
.
metaKey
)
{
if
(
typeName
!==
'
image
'
)
{
view
.
selectItemsByType
(
typeName
);
}
}
else
{
$but
.
toggleClass
(
"
active
"
,
activate
);
if
(
typeName
===
'
image
'
)
{
attributes
.
setImageOpacity
(
activate
?
100
:
0
,
true
);
//_opacitySlider.slider('setValue', activate ? 100 : 0);
}
else
{
view
.
toggleItemsByType
(
$but
.
data
(
'
typeName
'
),
activate
);
ui
.
enableTool
(
typeName
,
activate
);
}
}
});
}
return
{
name
:
'
cimaf
'
,
initSignalRouting
:
_initSignalRouting
,
initUI
:
_initUI
}
});
\ No newline at end of file
adim_project/adim_app/static/_src/adim/env/env.js
0 → 100644
View file @
46db4303
/**
* This module is a proxy for the various environement defined
* It could be bypassed if the environment is directly defined in
* the main app by overriding the "env" path. See su_app.js
*/
define
([
"
underscore
"
,
"
adim/config
"
,
// below are environments modules
"
env/cimaf/env
"
],
function
(
_
,
config
){
var
_envs
=
_
.
filter
(
Array
.
prototype
.
slice
.
call
(
arguments
,
2
),
{
name
:
config
.
annotable
.
env
}
);
function
_proxy
(
fname
)
{
return
function
()
{
_
.
invoke
(
_envs
,
fname
,
arguments
);
}
}
return
{
name
:
'
default
'
,
initSignalRouting
:
_proxy
(
'
initSignalRouting
'
)
,
initUI
:
_proxy
(
'
initUI
'
)
}
});
\ No newline at end of file
adim_project/adim_app/static/_src/adim/helper/bootstrap-rating-input.js
0 → 100755
View file @
46db4303
// Customized version of https://github.com/javiertoledo/bootstrap-rating-input
// based on an old old version
(
function
(
$
)
{
$
.
fn
.
rating
=
function
(
cmd
)
{
var
element
;
var
classActive
=
'
label label-warning rating-on
'
;
//'glyphicon glyphicon-star';
var
classInactive
=
'
label label-default rating-off
'
;
//'glyphicon glyphicon-star-empty';
// A private function to highlight a star corresponding to a given value
function
_paintValue
(
ratingInput
,
value
)
{
var
selectedStar
=
$
(
ratingInput
).
find
(
'
[data-value=
'
+
value
+
'
]
'
);
selectedStar
.
removeClass
(
classInactive
).
addClass
(
classActive
);
selectedStar
.
prevAll
(
'
[data-value]
'
).
removeClass
(
classInactive
).
addClass
(
classActive
);
selectedStar
.
nextAll
(
'
[data-value]
'
).
removeClass
(
classActive
).
addClass
(
classInactive
);
}
// A private function to remove the selected rating
function
_clearValue
(
ratingInput
)
{
var
self
=
$
(
ratingInput
);
self
.
find
(
'
[data-value]
'
).
removeClass
(
classActive
).
addClass
(
classInactive
);
self
.
find
(
'
.rating-clear
'
).
hide
();
var
input
=
self
.
find
(
'
input
'
);
input
.
val
(
input
.
data
(
'
empty-value
'
)).
trigger
(
'
change
'
);
}
function
buildWidgets
(
elems
)
{
// Iterate and transform all selected inputs
for
(
element
=
elems
.
length
-
1
;
element
>=
0
;
element
--
)
{
var
el
,
i
,
originalInput
=
$
(
elems
[
element
]),
max
=
originalInput
.
data
(
'
max
'
)
||
5
,
min
=
originalInput
.
data
(
'
min
'
)
||
0
,
clearable
=
originalInput
.
data
(
'
clearable
'
)
||
null
,
displayValue
=
originalInput
.
data
(
'
display
'
)
||
null
,
stars
=
''
;
// HTML element construction
for
(
i
=
min
;
i
<=
max
;
i
++
)
{
// Create <max> empty stars
stars
+=
[
'
<span class="
'
,
classInactive
,
'
" data-value="
'
,
i
,
'
">
'
,
displayValue
?
i
:
""
,
'
</span>
'
].
join
(
''
);
}
// Add a clear link if clearable option is set
if
(
clearable
)
{
stars
+=
[
'
<a class="rating-clear" style="display:none;" href="javascript:void">
'
,
'
<span class="glyphicon glyphicon-remove"></span>
'
,
clearable
,
'
</a>
'
].
join
(
''
);
}
// Clone the original input to preserve any additional data bindings using attributes.
var
newInput
=
originalInput
.
clone
()
.
attr
(
'
type
'
,
'
hidden
'
)
.
data
(
'
max
'
,
max
)
.
data
(
'
min
'
,
min
);
// Rating widget is wrapped inside a div
el
=
[
'
<div class="rating-input">
'
,
stars
,
'
</div>
'
].
join
(
''
);
// Replace original inputs HTML with the new one
originalInput
.
replaceWith
(
$
(
el
).
append
(
newInput
));
enableWidgets
(
newInput
);
}
}
function
enableWidgets
(
elemInput
)
{
elemInput
.
removeAttr
(
"
disabled
"
);
// Give live to the newly generated widgets
elemInput
.
closest
(
'
.rating-input
'
)
.
removeClass
(
"
disabled
"
)
// Highlight stars on hovering
.
on
(
'
mouseenter
'
,
'
[data-value]
'
,
function
()
{
var
self
=
$
(
this
);
_paintValue
(
self
.
closest
(
'
.rating-input
'
),
self
.
data
(
'
value
'
));
})
// View current value while mouse is out
.
on
(
'
mouseleave
'
,
'
[data-value]
'
,
function
()
{
var
self
=
$
(
this
),
input
=
self
.
siblings
(
'
input
'
),
val
=
input
.
val
(),
min
=
input
.
data
(
'
min
'
),
max
=
input
.
data
(
'
max
'
);
if
(
val
>=
min
&&
val
<=
max
)
{
_paintValue
(
self
.
closest
(
'
.rating-input
'
),
val
);
}
else
{
_clearValue
(
self
.
closest
(
'
.rating-input
'
));
}
})
// Set the selected value to the hidden field
.
on
(
'
click
'
,
'
[data-value]
'
,
function
(
e
)
{
var
self
=
$
(
this
);
var
val
=
self
.
data
(
'
value
'
);
self
.
siblings
(
'
input
'
).
val
(
val
).
trigger
(
'
change
'
);
self
.
siblings
(
'
.rating-clear
'
).
show
();
e
.
preventDefault
();
return
false
;
})
// Remove value on clear
.
on
(
'
click
'
,
'
.rating-clear
'
,
function
(
e
)
{
_clearValue
(
$
(
this
).
closest
(
'
.rating-input
'
));
e
.
preventDefault
();
return
false
;
})
// Initialize view with default value
.
each
(
function
()
{
var
input
=
$
(
this
).
find
(
'
input
'
),
val
=
input
.
val
(),
min
=
input
.
data
(
'
min
'
),
max
=
input
.
data
(
'
max
'
);
if
(
val
!==
""
&&
+
val
>=
min
&&
+
val
<=
max
)
{
_paintValue
(
this
,
val
);
$
(
this
).
find
(
'
.rating-clear
'
).
show
();
}
else
{
_clearValue
(
this
);
}
});
}
function
disableWidgets
(
elemInput
)
{
elemInput
.
attr
(
"
disabled
"
,
"
disabled
"
);
var
ratingInput
=
elemInput
.
closest
(
'
.rating-input
'
);
ratingInput
.
addClass
(
"
disabled
"
)
.
off
(
'
mouseenter
'
,
'
[data-value]
'
)
.
off
(
'
mouseleave
'
,
'
[data-value]
'
)
.
off
(
'
click
'
,
'
[data-value]
'
)
.
off
(
'
click
'
,
'
.rating-clear
'
)
;
_clearValue
(
ratingInput
);
}
function
setValue
(
elemInput
,
val
)
{
var
value
=
parseInt
(
val
,
10
);
if
(
!
isNaN
(
value
))
{
var
ratingInput
=
elemInput
.
closest
(
'
.rating-input
'
);
elemInput
.
val
(
val
);
_paintValue
(
ratingInput
,
value
);
}
}
if
(
cmd
)
{
if
(
cmd
===
'
disable
'
)
{
this
.
each
(
function
(
i
,
n
){
disableWidgets
(
$
(
n
));
});
}
else
if
(
cmd
===
'
enable
'
)
{
this
.
each
(
function
(
i
,
n
){
enableWidgets
(
$
(
n
));
});
}
else
if
(
cmd
===
'
setValue
'
&&
arguments
.
length
>
1
)
{
var
val
=
arguments
[
1
];
this
.
each
(
function
(
i
,
n
){
setValue
(
$
(
n
),
val
);
});
}
}
else
{
buildWidgets
(
this
);
}
};
// Auto apply conversion of number fields with class 'rating' into rating-fields
$
(
function
()
{
if
(
$
(
'
input.rating[type=number]
'
).
length
>
0
)
{
$
(
'
input.rating[type=number]
'
).
rating
();
}
});
}(
jQuery
));
adim_project/adim_app/static/_src/adim/main-su.js
View file @
46db4303
This diff is collapsed.
Click to expand it.
adim_project/adim_app/static/_src/adim/tools.js
View file @
46db4303
...
...
@@ -23,7 +23,7 @@ define([
"
underscore
"
,
"
signals
"
,
// -----
app
// -----
The tools
"
tools/select
"
,
"
tools/pan
"
,
"
tools/drawing
"
,
...
...
@@ -31,8 +31,13 @@ define([
"
tools/ellipse
"
,
"
tools/rectangle
"
,
"
tools/text
"
,
"
tools/arrow
"
// "tools/arrow1"
"
tools/arrow
"
,
// ----- CIMAF specific tools
"
tools/fieldedges
"
,
"
tools/concordantstr
"
,
"
tools/discordantstr
"
,
"
tools/cmsarea
"
],
function
(
_
,
Signal
){
// ----- Locale variables -----------------------------
...
...
adim_project/adim_app/static/_src/adim/tools/cmsarea.js
View file @
46db4303
...
...
@@ -123,12 +123,14 @@ define(["paper", "helper/utils"], function (paper, utils) {
tId
:
"
a
"
+
newArea
.
_id
,
type
:
TOOL_TYPE
,
prop
:
o
.
prop
,
setStrokeWidth
:
_noop
setStrokeWidth
:
_noop
,
// Mouse Event
itemMouseDrag
:
itemMouseDrag
};
if
(
noEventListening
!==
true
)
{
newArea
.
onMouseDown
=
itemMouseDown
;
newArea
.
onMouseDrag
=
itemMouseDrag
;
//
newArea.onMouseDrag = itemMouseDrag;
// --> in data.itemMouseDrag
newArea
.
onMouseUp
=
itemMouseUp
;
newArea
.
onKeyDown
=
itemKeyDown
;
newArea
.
onKeyUp
=
itemKeyUp
;
...
...
@@ -176,8 +178,6 @@ define(["paper", "helper/utils"], function (paper, utils) {
function
itemMouseUp
(
event
)
{
if
(
!
event
.
tool
)
// catches only tool's events, item's mouseUpOutside is not catched...
return
;
if
(
_editedArea
)
{
// TODO: add a flag to indicate if a modification really occured or if it's just a click
_events
.
annotationChanged
.
dispatch
([
_editedArea
]);
...
...
adim_project/adim_app/static/_src/adim/tools/concordantstr.js
View file @
46db4303
...
...
@@ -93,12 +93,15 @@ define(["paper", "helper/utils"], function (paper, utils) {
var
_startPoint
=
null
;
var
_drawingLine
=
null
;
var
terminateOnRelease
=
false
;
var
_editedStria
=
null
,
_editedSegmentIdx
=
null
;
var
_editedStria
=
null
,
// The edited stria (selected)
_editedSegmentIdx
=
null
,
// Index of the currently edited segment (click on stria's end)
_editedSegmentXLimit
=
null
,
// The X value at the cut position with thershold
_editedStriaLeftIdx
=
null
,
// Edited stria's left segment index
_editedStriaRightIdx
=
null
;
// Edited stria's right segment index
var
_striaChanged
=
false
;
var
cutThreshold
=
50
;
// Le dépassement minimum audela du couteau pour que la concordance soit valide
var
_
cutThreshold
=
50
;
// Le dépassement minimum audela du couteau pour que la concordance soit valide
var
defaultProperties
=
{
confidence
:
3
,
...
...
@@ -122,7 +125,9 @@ define(["paper", "helper/utils"], function (paper, utils) {
newStria
.
data
=
{
tId
:
"
a
"
+
newStria
.
_id
,
type
:
TOOL_TYPE
,
prop
:
o
.
prop
prop
:
o
.
prop
,
// Mouse Event
itemMouseDrag
:
itemMouseDrag
};
// Select new stria
...
...
@@ -133,7 +138,7 @@ define(["paper", "helper/utils"], function (paper, utils) {
// Add event listeners
newStria
.
onMouseDown
=
itemMouseDown
;
newStria
.
onMouseDrag
=
itemMouseDrag
;
//
newStria.onMouseDrag = itemMouseDrag;
// --> in data.itemMouseDrag
newStria
.
onMouseUp
=
itemMouseUp
;
newStria
.
onKeyDown
=
itemKeyDown
;
newStria
.
onKeyUp
=
itemKeyUp
;
...
...
@@ -155,9 +160,15 @@ define(["paper", "helper/utils"], function (paper, utils) {
hitItem
.
selected
=
true
;
_events
.
annotationSelected
.
dispatch
(
hitItem
);
_editedSegmentIdx
=
null
;
_editedSegmentIdx
=
_editedStriaLeftIdx
=
_editedStriaRightIdx
=
_editedSegmentXLimit
=
null
;
if
(
hitResult
.
type
===
'
segment
'
)
{
_editedSegmentIdx
=
hitResult
.
segment
.
index
;
_editedSegmentXLimit
=
_cutPosition
+
(
(
_editedStria
.
segments
[
1
-
_editedSegmentIdx
].
point
.
x
<
_cutPosition
?
1
:
-
1
)
*
_cutThreshold
);
}
else
{
_editedStriaLeftIdx
=
(
_editedStria
.
getFirstSegment
().
point
.
x
<
_cutPosition
)
?
0
:
1
;
_editedStriaRightIdx
=
1
-
_editedStriaLeftIdx
;
}
_events
.
annotationSelected
.
dispatch
(
hitItem
);
}
...
...
@@ -172,7 +183,12 @@ define(["paper", "helper/utils"], function (paper, utils) {
editStria
(
event
);
}
else
if
(
_editedStria
)
{
// TODO: valider la position par rapport au couteau
_editedStria
.
translate
(
event
.
delta
);
if
(
_editedStria
.
segments
[
_editedStriaLeftIdx
].
point
.
x
+
event
.
delta
.
x
<=
_cutPosition
-
_cutThreshold
&&
_editedStria
.
segments
[
_editedStriaRightIdx
].
point
.
x
+
event
.
delta
.
x
>=
_cutPosition
+
_cutThreshold
)
{
_editedStria
.
translate
(
event
.
delta
);
}
}
}
...
...
@@ -184,7 +200,7 @@ define(["paper", "helper/utils"], function (paper, utils) {
// TODO: add a flag to indicate if a modification really occured or if it's just a click
_events
.
annotationChanged
.
dispatch
([
_editedStria
]);
}
_editedSegmentIdx
=
_editedStria
=
null
;
_editedSegmentIdx
=
_editedStria
LeftIdx
=
_editedStriaRightIdx
=
_editedStria
=
_editedSegmentXLimit
=
null
;
}
...
...
@@ -234,8 +250,8 @@ define(["paper", "helper/utils"], function (paper, utils) {
function
validatePosition
(
from
,
to
){
// A concordant stria should cross the cut
return
(
from
.
x
<=
_cutPosition
&&
to
.
x
>=
(
_cutPosition
+
cutThreshold
)
)
||
(
from
.
x
>=
_cutPosition
&&
to
.
x
<=
(
_cutPosition
-
cutThreshold
)
);
return
(
from
.
x
<=
_cutPosition
&&
to
.
x
>=
(
_cutPosition
+
_
cutThreshold
)
)
||
(
from
.
x
>=
_cutPosition
&&
to
.
x
<=
(
_cutPosition
-
_
cutThreshold
)
);
}
function
cancelCreate
()
{
...
...
@@ -307,8 +323,9 @@ define(["paper", "helper/utils"], function (paper, utils) {
*/
function
editStria
(
event
)
{
var
dstPoint
=
event
.
point
.
clone
();
if
(
!
validatePosition
(
_editedStria
.
segments
[
1
-
_editedSegmentIdx
].
point
,
dstPo