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
import
scalatags.JsDom.svgTags
import
scaladget.stylesheet.all._
import
scaladget.api.svg._
import
client
.JsRxTags._
import
scaladget.tools
.JsRxTags._
import
org.scalajs.dom.raw._
trait
Selectable
{
...
...
@@ -42,10 +42,12 @@ object Graph {
val
target
:
Var
[
Task
])
extends
Selectable
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
))
}
import
Graph._
class
Window
(
nodes
:
Seq
[
Task
]
=
Seq
(),
edges
:
Seq
[
Edge
]
=
Seq
())
{
val
svgNode
=
{
...
...
@@ -75,10 +77,9 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
val
DELETE_KEY
=
46
val
NODE_RADIUS
=
50
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
URL_MARK_END_ARROW
:
String
=
"url(#mark-end-arrow)"
val
URL_MARK_END_ARROW
:
String
=
s
"url(#${MARK_END_ARROW})"
class
DragLine
{
private
val
m
:
Var
[(
Int
,
Int
)]
=
Var
((
0
,
0
))
...
...
@@ -97,10 +98,10 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
this
}
val
render
=
Rx
{
val
render
:
SVGElement
=
Rx
{
path
(
ms
=
ms
(
s
"$LINK_DRAGLINE ${
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]) {
// Hide the drag line
if
(
me
.
shiftKey
&&
!
dragLine
.
dragging
.
now
)
{
val
(
x
,
y
)
=
(
me
.
clientX
,
me
.
clientY
)
addTask
(
task
(
UUID
.
randomUUID
().
toString
,
x
,
y
))
addTask
(
task
(
UUID
.
randomUUID
().
toString
,
x
,
y
))
}
mouseDownTask
()
=
None
dragLine
.
dragging
()
=
false
...
...
@@ -177,22 +178,18 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
}
def
circle
(
task
:
Task
)
=
{
val
gCircle
:
SVGElement
=
{
val
element
:
SVGElement
=
Rx
{
svgTags
.
g
(
rxSVGMod
(
Rx
{
svgTags
.
g
(
ms
(
CIRCLE
+
{
if
(
task
.
selected
())
s
" $SELECTED"
else
""
})
)(
svgAttrs
.
transform
:=
s
"translate(${
val location = task.location()
s"
$
{
location
.
_1
},
$
{
location
.
_2
}
"
})"
)(
svgTags
.
circle
(
svgAttrs
.
r
:=
NODE_RADIUS
).
render
)
}
))
}.
render
ms
(
CIRCLE
+
{
if
(
task
.
selected
())
s
" $SELECTED"
else
""
})
)(
svgAttrs
.
transform
:=
s
"translate(${
val location = task.location()
s"
$
{
location
.
_1
},
$
{
location
.
_2
}
"
})"
)(
svgTags
.
circle
(
svgAttrs
.
r
:=
NODE_RADIUS
).
render
)
}
val
gCircle
=
svgTags
.
g
(
element
).
render
gCircle
.
onmousedown
=
(
me
:
MouseEvent
)
=>
{
mouseDownTask
()
=
Some
(
task
)
...
...
@@ -217,30 +214,30 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
addEdge
(
edge
(
e
.
source
.
now
,
e
.
target
.
now
))
}
def
link
(
edge
:
Edge
)
=
svgTags
.
g
(
rxSVGMod
(
Rx
{
val
p
=
path
(
ms
=
(
if
(
edge
.
selected
())
ms
(
"selected"
)
else
emptyMod
)
+++
ms
(
LINK
)).
m
(
edge
.
source
().
location
().
_1
.
toInt
,
edge
.
source
().
location
().
_2
.
toInt
).
l
(
edge
.
target
().
location
().
_1
.
toInt
,
edge
.
target
().
location
().
_2
.
toInt
).
render
(
svgAttrs
.
markerEnd
:=
URL_END_ARROW
).
render
p
.
onmousedown
=
(
me
:
MouseEvent
)
=>
{
unselectTasks
unselectEdges
edge
.
selected
()
=
!
edge
.
selected
.
now
}
svgTags
.
g
(
p
)
def
link
(
edge
:
Edge
)
=
{
val
sVGElement
:
SVGElement
=
Rx
{
val
p
=
path
(
ms
=
(
if
(
edge
.
selected
())
ms
(
SELECTED
)
else
emptyMod
)
+++
ms
(
LINK
)).
m
(
edge
.
source
().
location
().
_1
.
toInt
,
edge
.
source
().
location
().
_2
.
toInt
).
l
(
edge
.
target
().
location
().
_1
.
toInt
,
edge
.
target
().
location
().
_2
.
toInt
).
render
(
svgAttrs
.
markerEnd
:=
URL_END_ARROW
).
render
p
.
onmousedown
=
(
me
:
MouseEvent
)
=>
{
unselectTasks
unselectEdges
edge
.
selected
()
=
!
edge
.
selected
.
now
}
)
).
render
p
}
svgTags
.
g
(
sVGElement
).
render
}
def
addToScene
[
T
](
s
:
Var
[
Seq
[
Var
[
T
]]],
draw
:
T
=>
SVGElement
)
=
svgG
.
appendChild
(
svgTags
.
g
(
rxSVGMod
(
Rx
{
def
addToScene
[
T
](
s
:
Var
[
Seq
[
Var
[
T
]]],
draw
:
T
=>
SVGElement
)
=
{
val
element
:
SVGElement
=
Rx
{
svgTags
.
g
(
for
{
t
<-
s
()
...
...
@@ -248,8 +245,9 @@ class GraphCreator(svg: SVGElement, _tasks: Seq[Task], _edges: Seq[Edge]) {
draw
(
t
.
now
)
}
)
}).
render
).
render
)
}
svgG
.
appendChild
(
svgTags
.
g
(
element
).
render
).
render
}
addToScene
(
edges
,
link
)
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