Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
gate
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
openmole
gate
Commits
42bdff67
Commit
42bdff67
authored
Mar 31, 2017
by
Mathieu leclaire
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rely on Scaladget JsRxTags
parent
96ce80cc
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
44 additions
and
275 deletions
+44
-275
FlowChart.scala
client/src/main/scala/fr/iscpif/client/FlowChart.scala
+44
-46
JsRxTags.scala
client/src/main/scala/fr/iscpif/client/JsRxTags.scala
+0
-229
No files found.
client/src/main/scala/fr/iscpif/client/FlowChart.scala
View file @
42bdff67
...
@@ -26,7 +26,7 @@ import scalatags.JsDom.svgAttrs
...
@@ -26,7 +26,7 @@ import scalatags.JsDom.svgAttrs
import
scalatags.JsDom.svgTags
import
scalatags.JsDom.svgTags
import
scaladget.stylesheet.all._
import
scaladget.stylesheet.all._
import
scaladget.api.svg._
import
scaladget.api.svg._
import
client
.JsRxTags._
import
scaladget.tools
.JsRxTags._
import
org.scalajs.dom.raw._
import
org.scalajs.dom.raw._
trait
Selectable
{
trait
Selectable
{
...
@@ -42,10 +42,12 @@ object Graph {
...
@@ -42,10 +42,12 @@ object Graph {
val
target
:
Var
[
Task
])
extends
Selectable
val
target
:
Var
[
Task
])
extends
Selectable
def
task
(
title
:
String
,
x
:
Double
,
y
:
Double
)
=
Task
(
Var
(
title
),
Var
((
x
,
y
)))
def
task
(
title
:
String
,
x
:
Double
,
y
:
Double
)
=
Task
(
Var
(
title
),
Var
((
x
,
y
)))
def
edge
(
source
:
Task
,
target
:
Task
)
=
new
Edge
(
Var
(
source
),
Var
(
target
))
def
edge
(
source
:
Task
,
target
:
Task
)
=
new
Edge
(
Var
(
source
),
Var
(
target
))
}
}
import
Graph._
import
Graph._
class
Window
(
nodes
:
Seq
[
Task
]
=
Seq
(),
edges
:
Seq
[
Edge
]
=
Seq
())
{
class
Window
(
nodes
:
Seq
[
Task
]
=
Seq
(),
edges
:
Seq
[
Edge
]
=
Seq
())
{
val
svgNode
=
{
val
svgNode
=
{
...
@@ -75,10 +77,9 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
...
@@ -75,10 +77,9 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
val
DELETE_KEY
=
46
val
DELETE_KEY
=
46
val
NODE_RADIUS
=
50
val
NODE_RADIUS
=
50
val
END_ARROW
:
String
=
"end-arrow"
val
END_ARROW
:
String
=
"end-arrow"
val
URL_END_ARROW
:
String
=
"url(#end-arrow
)"
val
URL_END_ARROW
:
String
=
s
"url(#${END_ARROW}
)"
val
MARK_END_ARROW
:
String
=
"mark-end-arrow"
val
MARK_END_ARROW
:
String
=
"mark-end-arrow"
val
URL_MARK_END_ARROW
:
String
=
"url(#mark-end-arrow)"
val
URL_MARK_END_ARROW
:
String
=
s
"url(#${MARK_END_ARROW})"
class
DragLine
{
class
DragLine
{
private
val
m
:
Var
[(
Int
,
Int
)]
=
Var
((
0
,
0
))
private
val
m
:
Var
[(
Int
,
Int
)]
=
Var
((
0
,
0
))
...
@@ -97,10 +98,10 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
...
@@ -97,10 +98,10 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
this
this
}
}
val
render
=
Rx
{
val
render
:
SVGElement
=
Rx
{
path
(
ms
=
ms
(
s
"$LINK_DRAGLINE ${
path
(
ms
=
ms
(
s
"$LINK_DRAGLINE ${
if (dragging()) "" else HIDDEN
if (dragging()) "" else HIDDEN
}"
)).
m
(
m
().
_1
,
m
().
_2
).
l
(
l
().
_1
,
l
().
_2
)(
svgAttrs
.
markerEnd
:=
URL_MARK_END_ARROW
).
render
.
render
}"
)).
m
(
m
().
_1
,
m
().
_2
).
l
(
l
().
_1
,
l
().
_2
)(
svgAttrs
.
markerEnd
:=
URL_MARK_END_ARROW
).
render
}
}
}
}
...
@@ -141,7 +142,7 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
...
@@ -141,7 +142,7 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
// Hide the drag line
// Hide the drag line
if
(
me
.
shiftKey
&&
!
dragLine
.
dragging
.
now
)
{
if
(
me
.
shiftKey
&&
!
dragLine
.
dragging
.
now
)
{
val
(
x
,
y
)
=
(
me
.
clientX
,
me
.
clientY
)
val
(
x
,
y
)
=
(
me
.
clientX
,
me
.
clientY
)
addTask
(
task
(
UUID
.
randomUUID
().
toString
,
x
,
y
))
addTask
(
task
(
UUID
.
randomUUID
().
toString
,
x
,
y
))
}
}
mouseDownTask
()
=
None
mouseDownTask
()
=
None
dragLine
.
dragging
()
=
false
dragLine
.
dragging
()
=
false
...
@@ -177,22 +178,18 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
...
@@ -177,22 +178,18 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
}
}
def
circle
(
task
:
Task
)
=
{
def
circle
(
task
:
Task
)
=
{
val
gCircle
:
SVGElement
=
{
val
element
:
SVGElement
=
Rx
{
svgTags
.
g
(
svgTags
.
g
(
rxSVGMod
(
ms
(
CIRCLE
+
{
Rx
{
if
(
task
.
selected
())
s
" $SELECTED"
else
""
svgTags
.
g
(
})
ms
(
CIRCLE
+
{
)(
if
(
task
.
selected
())
s
" $SELECTED"
else
""
svgAttrs
.
transform
:=
s
"translate(${
})
val location = task.location()
)(
s"
$
{
location
.
_1
},
$
{
location
.
_2
}
"
svgAttrs
.
transform
:=
s
"translate(${
})"
)(
svgTags
.
circle
(
svgAttrs
.
r
:=
NODE_RADIUS
).
render
)
val location = task.location()
}
s"
$
{
location
.
_1
},
$
{
location
.
_2
}
"
val
gCircle
=
svgTags
.
g
(
element
).
render
})"
)(
svgTags
.
circle
(
svgAttrs
.
r
:=
NODE_RADIUS
).
render
)
}
))
}.
render
gCircle
.
onmousedown
=
(
me
:
MouseEvent
)
=>
{
gCircle
.
onmousedown
=
(
me
:
MouseEvent
)
=>
{
mouseDownTask
()
=
Some
(
task
)
mouseDownTask
()
=
Some
(
task
)
...
@@ -217,30 +214,30 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
...
@@ -217,30 +214,30 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
addEdge
(
edge
(
e
.
source
.
now
,
e
.
target
.
now
))
addEdge
(
edge
(
e
.
source
.
now
,
e
.
target
.
now
))
}
}
def
link
(
edge
:
Edge
)
=
def
link
(
edge
:
Edge
)
=
{
svgTags
.
g
(
val
sVGElement
:
SVGElement
=
Rx
{
rxSVGMod
(
Rx
{
val
p
=
path
(
ms
=
(
if
(
edge
.
selected
())
ms
(
SELECTED
)
else
emptyMod
)
+++
val
p
=
path
(
ms
=
(
if
(
edge
.
selected
())
ms
(
"selected"
)
else
emptyMod
)
+++
ms
(
LINK
)).
m
(
ms
(
LINK
)).
m
(
edge
.
source
().
location
().
_1
.
toInt
,
edge
.
source
().
location
().
_1
.
toInt
,
edge
.
source
().
location
().
_2
.
toInt
edge
.
source
().
location
().
_2
.
toInt
).
l
(
).
l
(
edge
.
target
().
location
().
_1
.
toInt
,
edge
.
target
().
location
().
_1
.
toInt
,
edge
.
target
().
location
().
_2
.
toInt
edge
.
target
().
location
().
_2
.
toInt
).
render
(
svgAttrs
.
markerEnd
:=
URL_END_ARROW
).
render
).
render
(
svgAttrs
.
markerEnd
:=
URL_END_ARROW
).
render
p
.
onmousedown
=
(
me
:
MouseEvent
)
=>
{
p
.
onmousedown
=
(
me
:
MouseEvent
)
=>
{
unselectTasks
unselectTasks
unselectEdges
unselectEdges
edge
.
selected
()
=
!
edge
.
selected
.
now
edge
.
selected
()
=
!
edge
.
selected
.
now
}
svgTags
.
g
(
p
)
}
}
)
p
).
render
}
svgTags
.
g
(
sVGElement
).
render
}
def
addToScene
[
T
](
s
:
Var
[
Seq
[
Var
[
T
]]],
draw
:
T
=>
SVGElement
)
=
svgG
.
appendChild
(
svgTags
.
g
(
def
addToScene
[
T
](
s
:
Var
[
Seq
[
Var
[
T
]]],
draw
:
T
=>
SVGElement
)
=
{
rxSVGMod
(
Rx
{
val
element
:
SVGElement
=
Rx
{
svgTags
.
g
(
svgTags
.
g
(
for
{
for
{
t
<-
s
()
t
<-
s
()
...
@@ -248,8 +245,9 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
...
@@ -248,8 +245,9 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
draw
(
t
.
now
)
draw
(
t
.
now
)
}
}
)
)
}).
render
}
).
render
)
svgG
.
appendChild
(
svgTags
.
g
(
element
).
render
).
render
}
addToScene
(
edges
,
link
)
addToScene
(
edges
,
link
)
addToScene
(
tasks
,
circle
)
addToScene
(
tasks
,
circle
)
...
...
client/src/main/scala/fr/iscpif/client/JsRxTags.scala
deleted
100644 → 0
View file @
96ce80cc
/*
* Copyright (C) 21/07/14 mathieu
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package
client
import
org.scalajs.dom.raw.
{
HTMLDivElement
,
HTMLElement
,
Node
,
SVGElement
}
import
scalatags.JsDom._
import
scala.util.
{
Failure
,
Success
}
import
all._
import
rx._
import
org.scalajs.dom.Element
import
scaladget.stylesheet.all._
/**
* A minimal binding between Scala.Rx and Scalatags and Scala-Js-Dom
*/
object
JsRxTags
{
implicit
val
ctx
:
Ctx.Owner
=
Ctx
.
Owner
.
safe
()
/**
* Wraps reactive strings in spans, so they can be referenced/replaced
* when the Rx changes.
*/
implicit
def
RxStr
[
T
](
r
:
Rx
[
T
])(
implicit
f
:
T
⇒
Modifier
)
:
Modifier
=
{
rxHTMLMod
(
Rx
(
span
(
r
())))
}
// implicit def RxModifierSeq(r: TypedTag[Rx[ModifierSeq]]): TypedTag[ModifierSeq] = {
// r.copy(modifiers = r.modifiers)
// }
/**
* Sticks some Rx into a Scalatags fragment, which means hooking up an Obs
* to propagate changes into the DOM via the element's ID. Monkey-patches
* the Obs onto the element itself so we have a reference to kill it when
* the element leaves the DOM (e.g. it gets deleted).
*/
implicit
def
rxHTMLMod
[
T
<:
HtmlTag
](
r
:
Rx
[
T
])
:
Modifier
=
bindNode
(
rxHTMLNode
(
r
))
// implicit def rxHTMLTagedType[T <: HtmlTag](r: Rx[T]): Modifier = bindNode(rxHTMLNode(r))
implicit
def
rxHTMLNode
[
T
<:
TypedTag
[
HTMLElement
]](
r
:
Rx
[
T
])
:
HTMLElement
=
{
def
rSafe
=
r
.
toTry
match
{
case
Success
(
v
)
⇒
v
.
render
case
Failure
(
e
)
⇒
span
(
e
.
toString
,
backgroundColor
:=
"red"
).
render
}
var
last
=
rSafe
r
.
triggerLater
{
val
newLast
=
rSafe
last
.
parentNode
.
replaceChild
(
newLast
,
last
)
last
=
newLast
}
last
}
/**
* Idem for SVG elements
*/
implicit
def
rxSVGMod
[
T
<:
TypedTag
[
SVGElement
]](
r
:
Rx
[
T
])
:
SVGElement
=
{
def
rSafe
=
r
.
now
.
render
//r.toTry match {
// case Success(v) ⇒ v.render
// case Failure(e) ⇒ span(e.toString, backgroundColor := "red").render
// }
var
last
=
rSafe
r
.
triggerLater
{
val
newLast
=
rSafe
last
.
parentNode
.
replaceChild
(
newLast
,
last
)
last
=
newLast
}
last
}
implicit
def
RxAttrValue
[
T:
scalatags.JsDom.AttrValue
]
=
new
scalatags
.
JsDom
.
AttrValue
[
Rx.Dynamic
[
T
]]
{
def
apply
(
t
:
Element
,
a
:
Attr
,
r
:
Rx.Dynamic
[
T
])
:
Unit
=
{
r
.
trigger
{
implicitly
[
scalatags.JsDom.AttrValue
[
T
]].
apply
(
t
,
a
,
r
.
now
)
}
}
}
implicit
def
RxStyleValue
[
T:
scalatags.JsDom.StyleValue
]
=
new
scalatags
.
JsDom
.
StyleValue
[
Rx.Dynamic
[
T
]]
{
def
apply
(
t
:
Element
,
s
:
Style
,
r
:
Rx.Dynamic
[
T
])
:
Unit
=
{
r
.
trigger
{
implicitly
[
scalatags.JsDom.StyleValue
[
T
]].
apply
(
t
,
s
,
r
.
now
)
}
}
}
// Convenient implicit conversions
def
rxIf
[
T
](
dynamic
:
Rx.Dynamic
[
Boolean
],
yes
:
T
,
no
:
T
)
=
{
rx
.
Rx
{
if
(
dynamic
())
yes
else
no
}
}
def
rxIf
[
T
](
dynamic
:
Var
[
Boolean
],
yes
:
T
,
no
:
T
)
=
{
rx
.
Rx
{
if
(
dynamic
())
yes
else
no
}
}
implicit
def
rxNode
(
r
:
Rx
[
Node
])
:
Node
=
{
def
oo
=
{
def
rSafe
=
r
.
now
var
last
=
rSafe
r
.
triggerLater
{
val
newLast
=
rSafe
last
.
parentNode
.
replaceChild
(
newLast
,
last
)
last
=
newLast
}
last
}
bindNode
(
oo
).
render
}
// implicit val ctx: Ctx.Owner = Ctx.Owner.safe()
//
// /**
// * Wraps reactive strings in spans, so they can be referenced/replaced
// * when the Rx changes.
// */
// implicit def RxStr[T](r: Rx[T])(implicit f: T ⇒ Modifier): Modifier = {
// rxHTMLMod(Rx(span(r())))
// }
//
// implicit def rxNode(r: Rx[Node]): Node = {
//
// def oo = {
// def rSafe = r.now
//
// var last = rSafe
//
// r.triggerLater {
// val newLast = rSafe
// last.parentNode.replaceChild(newLast, last)
// last = newLast
// }
// last
// }
//
// bindNode(oo).render
// }
// /**
// * Sticks some Rx into a Scalatags fragment, which means hooking up an Obs
// * to propagate changes into the DOM via the element's ID. Monkey-patches
// * the Obs onto the element itself so we have a reference to kill it when
// * the element leaves the DOM (e.g. it gets deleted).
// */
// implicit def rxHTMLMod[T <: HtmlTag](r: Rx[T]): Modifier = bindNode(rxHTMLNode(r))
//
// // implicit def rxHTMLTagedType[T <: HtmlTag](r: Rx[T]): Modifier = bindNode(rxHTMLNode(r))
//
// implicit def rxHTMLNode[T <: HtmlTag](r: Rx[T]): Node = {
// def rSafe = r.toTry match {
// case Success(v) ⇒ v.render
// case Failure(e) ⇒ span(e.toString, backgroundColor := "red").render
// }
// var last = rSafe
// r.triggerLater {
// val newLast = rSafe
// last.parentNode.replaceChild(newLast, last)
// last = newLast
// }
// last
// }
//
// /**
// * Idem for SVG elements
// */
// implicit def rxSVGMod[T <: TypedTag[SVGElement]](r: Rx[T]): Modifier = {
// def rSafe = r.toTry match {
// case Success(v) ⇒ v.render
// case Failure(e) ⇒ span(e.toString, backgroundColor := "red").render
// }
// var last = rSafe
// r.triggerLater {
// val newLast = rSafe
// last.parentNode.replaceChild(newLast, last)
// last = newLast
// }
// last
// }
//
// implicit def RxAttrValue[T: scalatags.JsDom.AttrValue] = new scalatags.JsDom.AttrValue[Rx.Dynamic[T]] {
// def apply(t: Element, a: Attr, r: Rx.Dynamic[T]): Unit = {
// r.trigger {
// implicitly[scalatags.JsDom.AttrValue[T]].apply(t, a, r.now)
// }
// }
// }
//
// implicit def RxStyleValue[T: scalatags.JsDom.StyleValue] = new scalatags.JsDom.StyleValue[Rx.Dynamic[T]] {
// def apply(t: Element, s: Style, r: Rx.Dynamic[T]): Unit = {
// r.trigger {
// implicitly[scalatags.JsDom.StyleValue[T]].apply(t, s, r.now)
// }
// }
// }
}
\ No newline at end of file
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