aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2015-03-27 12:48:24 +0100
committerJakob Odersky <jodersky@gmail.com>2015-03-27 12:48:24 +0100
commitbd174539d8bb2921bef94cccd994a61e334a3dd7 (patch)
treefa89d47f97779c16d3a54b62518b8c83fc907d3c
parentf7f157cea1afd3386e46938a110c5a2ed72933fb (diff)
parentc2b0a3de4dca16cb9143acffdcc7a9ad1a730b50 (diff)
downloadmavigator-concise-dialect.tar.gz
mavigator-concise-dialect.tar.bz2
mavigator-concise-dialect.zip
Merge pull request #12 from jodersky/design/cleanupconcise-dialect
Clean up internal structure of dashboard ui
-rw-r--r--project/Build.scala2
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala169
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/components/instruments.scala126
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Altimeter.scala19
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Balance.scala27
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Bar.scala19
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Compass.scala18
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Generic.scala40
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Horizon.scala20
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Instrument.scala28
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Led.scala18
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/SvgInstrument.scala (renamed from vfd-dashboard/src/main/scala/vfd/dashboard/ui/components/SvgInstrument.scala)35
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Communication.scala113
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Primary.scala46
14 files changed, 320 insertions, 360 deletions
diff --git a/project/Build.scala b/project/Build.scala
index 9dd17c5..2cd1589 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -80,7 +80,7 @@ object ApplicationBuild extends Build {
val scalajs = Seq(
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-dom" % "0.8.0",
- "com.lihaoyi" %%% "scalatags" % "0.4.6",
+ "com.lihaoyi" %%% "scalatags" % "0.5.0",
"com.lihaoyi" %%% "scalarx" % "0.2.8"
)
)
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala
index 0264e5f..f17e91a 100644
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala
@@ -1,67 +1,25 @@
package vfd.dashboard.ui
-import org.scalajs.dom.html
-import scalatags.JsDom.all.ExtendedString
-import scalatags.JsDom.all.Int2CssNumber
-import scalatags.JsDom.all.`class`
-import scalatags.JsDom.all.div
-import scalatags.JsDom.all.header
-import scalatags.JsDom.all.height
-import scalatags.JsDom.all.iframe
-import scalatags.JsDom.all.p
-import scalatags.JsDom.all.src
-import scalatags.JsDom.all.stringAttr
-import scalatags.JsDom.all.stringFrag
-import scalatags.JsDom.all.stringPixelStyle
-import scalatags.JsDom.all.style
-import scalatags.JsDom.all.width
-import scalatags.JsDom.all.button
-import scalatags.JsDom.all.id
+import org.mavlink.messages.Attitude
+import org.mavlink.messages.Motor
+import org.mavlink.messages.Power
+
+import rx.Obs
import scalatags.JsDom.all._
-import scalatags.jsdom._
-import scalatags.jsdom.Frag
import vfd.dashboard.Environment
import vfd.dashboard.MavlinkSocket
-import vfd.dashboard.ui.panels.Communication
-import vfd.dashboard.ui.panels.Primary
-import org.scalajs.dom.MouseEvent
-import org.scalajs.dom
+import vfd.dashboard.ui.instruments.Altimeter
+import vfd.dashboard.ui.instruments.Balance
+import vfd.dashboard.ui.instruments.Bar
+import vfd.dashboard.ui.instruments.Compass
+import vfd.dashboard.ui.instruments.Generic
+import vfd.dashboard.ui.instruments.Horizon
class Layout(socket: MavlinkSocket)(implicit env: Environment) {
private def panel(contents: Frag*) = div(`class` := "d-panel")(contents: _*)
- def layout =
- div(`class` := "d-container d-column")(
- div(`class` := "d-above")(
- top),
- div(`class` := "d-above d-container d-row")(
- panel(modes),
- panel(infos)),
- div(`class` := "d-container d-row")(
- div(`class` := "d-container d-details")(
- panel("foo")),
- div(`class` := "d-container d-left")(
- left),
- div(`class` := "d-container d-column d-middle")(
- div(`class` := "d-container d-center")(
- center),
- div(`class` := "d-container d-below")(
- below)),
- div(`class` := "d-container d-right")(
- right)))
-
- def top = header(
- div("Flight Control Panel"),
- div("00:00:00"),
- div("System #"))
-
- def left = panel(map)
- def center = panel(feed)
- def below = panel(Primary(socket))
- def right = panel(Communication(socket))
-
- def mode(name: String, kind: String, on: Boolean = false) = div(`class` := s"mode $kind ${if (!on) "off"}")(name)
+ private def mode(name: String, kind: String, on: Boolean = false) = div(`class` := s"mode $kind ${if (!on) "off"}")(name)
val modes = div(
mode("MANUAL", "warning", true),
@@ -91,5 +49,106 @@ class Layout(socket: MavlinkSocket)(implicit env: Environment) {
val feed = div(style := "width: 100%; height: 460px; color: #ffffff; background-color: #c2c2c2; text-align: center;")(
p(style := "padding-top: 220px")("video feed"))
- def element: html.Element = layout.render
+ val altimeter = new Altimeter
+ val horizon = new Horizon
+ val compass = new Compass
+ val motor0 = new Generic(0, 50, 100, "%")
+ val motor1 = new Generic(0, 50, 100, "%")
+ val motor2 = new Generic(0, 50, 100, "%")
+ val motor3 = new Generic(0, 50, 100, "%")
+ val powerDistribution = new Balance()
+ val batteryLevel = new Bar()
+
+ val top = header(
+ div("Flight Control Panel"),
+ div("00:00:00"),
+ div("System #"))
+
+ val left = panel(
+ map,
+ table(`class` := "table-instrument")(
+ thead("Motors"),
+ tbody(
+ tr(
+ td(motor0.element),
+ td(),
+ td(motor1.element),
+ td()
+ ),
+ tr(
+ td(),
+ td(powerDistribution.element),
+ td(),
+ td()
+ ),
+ tr(
+ td(motor2.element),
+ td(),
+ td(motor3.element),
+ td()
+ )
+ )
+ )
+ )
+
+ val center = panel(feed)
+
+ val below = panel(
+ table(`class` := "table-instrument")(
+ tbody(
+ tr(
+ td(compass.element),
+ td(horizon.element),
+ td(altimeter.element)
+ )
+ )
+ )
+ )
+
+ val right = panel()
+
+ val element = div(`class` := "d-container d-column")(
+ div(`class` := "d-above")(
+ top),
+ div(`class` := "d-above d-container d-row")(
+ panel(modes),
+ panel(infos)),
+ div(`class` := "d-container d-row")(
+ div(`class` := "d-container d-details")(
+ panel("foo")),
+ div(`class` := "d-container d-left")(
+ left),
+ div(`class` := "d-container d-column d-middle")(
+ div(`class` := "d-container d-center")(
+ center),
+ div(`class` := "d-container d-below")(
+ below)
+ ),
+ div(`class` := "d-container d-right")(
+ right
+ )
+ )
+ ).render
+
+ //message router
+ Obs(socket.message, skipInitial = true) {
+ socket.message() match {
+
+ case Motor(m0, m1, m2, m3) =>
+ motor0.value() = m0
+ motor1.value() = m1
+ motor2.value() = m2
+ motor3.value() = m3
+ powerDistribution.value() = (m0, m1, m2, m3)
+
+ case Power(mV) =>
+ batteryLevel.value() = (100 * (mV - 9600) / 12600)
+
+ case Attitude(roll, pitch, yaw) =>
+ horizon.value() = (pitch, roll)
+ compass.value() = (yaw)
+
+ }
+ }
+
} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/components/instruments.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/components/instruments.scala
deleted file mode 100644
index a508eb0..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/components/instruments.scala
+++ /dev/null
@@ -1,126 +0,0 @@
-package vfd.dashboard.ui.components
-
-import org.scalajs.dom
-import org.scalajs.dom.html
-
-import scalatags.JsDom.all.ExtendedString
-import scalatags.JsDom.all.Int2CssNumber
-import scalatags.JsDom.all.`object`
-import scalatags.JsDom.all.stringAttr
-import scalatags.JsDom.all.stringFrag
-import scalatags.JsDom.all.stringPixelStyle
-import scalatags.JsDom.all.`type`
-import scalatags.JsDom.all.width
-import vfd.dashboard.Environment
-
-class Led(implicit env: Environment) extends SvgInstrument[String] {
- lazy val element = `object`(`type` := "image/svg+xml", "data".attr := env.asset("images/leds/led.svg"), width := 100.pct)(
- "Error loading led.").render
-
- def update(color: String) = {
- content.getElementById("light").setAttribute("fill", color)
- }
-
- protected def moveable = Seq()
-
-}
-
-class Horizon(implicit env: Environment) extends SvgInstrument[(Double, Double)] {
- lazy val element = SvgInstrument.svg("horizon")
-
- def pitch = content.getElementById("pitch").asInstanceOf[html.Element]
- def roll = content.getElementById("roll").asInstanceOf[html.Element]
- protected def moveable = Seq(pitch, roll)
-
- def update(pitchRoll: (Double, Double)) = {
- SvgInstrument.translate(pitch, 0, pitchRoll._1.toInt)
- SvgInstrument.rotate(roll, pitchRoll._2.toInt)
- }
-}
-
-class Altimeter(implicit env: Environment) extends SvgInstrument[Double] {
- lazy val element = SvgInstrument.svg("altimeter")
-
- def hand = content.getElementById("hand").asInstanceOf[html.Element]
- protected def moveable = Seq(hand)
-
- // 36deg === 1m
- def update(altitude: Double) = {
- SvgInstrument.rotate(hand, (altitude * 36).toInt)
- }
-}
-
-class Compass(implicit env: Environment) extends SvgInstrument[Double] {
- lazy val element = SvgInstrument.svg("compass")
-
- def plate = content.getElementById("heading").asInstanceOf[html.Element]
- protected def moveable = Seq(plate)
-
- def update(heading: Double) = {
- SvgInstrument.rotate(plate, heading.toInt)
- }
-}
-
-class Generic(
- min: Double,
- med: Double,
- max: Double,
- unit: String)(implicit env: Environment) extends SvgInstrument[Double] {
-
- lazy val element = SvgInstrument.svg("generic")
-
- def handElement = content.getElementById("hand").asInstanceOf[html.Element]
- def unitElement = content.getElementById("unit")
- def valueElement = content.getElementById("value")
- def minElement = content.getElementById("min")
- def medElement = content.getElementById("med")
- def maxElement = content.getElementById("max")
- protected def moveable = Seq(handElement)
-
- override protected def load(e: dom.Event) = {
- unitElement.textContent = unit
- minElement.textContent = min.toString
- medElement.textContent = med.toString
- maxElement.textContent = max.toString
- update(min)
- super.load(e)
- }
-
- def update(value: Double) = {
- SvgInstrument.rotate(handElement, (value * 270 / (max - min)).toInt)
- valueElement.textContent = value.toString
- }
-}
-
-class Bar(implicit env: Environment) extends SvgInstrument[Double] {
-
- lazy val element = SvgInstrument.svg("bar")
-
- def level = content.getElementById("level").asInstanceOf[html.Element]
- protected def moveable = Seq(level)
-
- def update(value: Double) = {
- SvgInstrument.translate(level, 0, (97 * (1 - value / 100)).toInt)
- }
-
-}
-
-class Balance(implicit env: Environment) extends SvgInstrument[(Double, Double, Double, Double)] {
- lazy val element = SvgInstrument.svg("balance")
-
- def position = content.getElementById("position").asInstanceOf[html.Element]
- protected def moveable = Seq(position)
-
- def update(value: (Double, Double, Double, Double)) = {
- val m0 = value._1
- val m1 = value._2
- val m2 = value._3
- val m3 = value._4
- val s = m0 + m1 + m2 + m3
- val i = (m0 - m2) / s
- val j = (m1 - m3) / s
- val x = 0.5 * (i - j)
- val y = 0.5 * (-i - j)
- SvgInstrument.translate(position, (x * 50).toInt, (y * 50).toInt)
- }
-} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Altimeter.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Altimeter.scala
new file mode 100644
index 0000000..9ff3bb5
--- /dev/null
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Altimeter.scala
@@ -0,0 +1,19 @@
+package vfd.dashboard.ui.instruments
+
+import org.scalajs.dom.html
+import vfd.dashboard.Environment
+
+class Altimeter(implicit env: Environment) extends SvgInstrument[Double] {
+ import SvgInstrument._
+
+ val initial = 0.0
+
+ lazy val element = svgObject("altimeter")
+ lazy val hand = part("hand")
+ lazy val moveable = Seq(hand)
+
+ // 36deg === 1m
+ protected def update(altitude: Double) = {
+ rotate(hand, (altitude * 36).toInt)
+ }
+} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Balance.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Balance.scala
new file mode 100644
index 0000000..ef5a3cc
--- /dev/null
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Balance.scala
@@ -0,0 +1,27 @@
+package vfd.dashboard.ui.instruments
+
+import org.scalajs.dom.html
+import vfd.dashboard.Environment
+
+class Balance(implicit env: Environment) extends SvgInstrument[(Double, Double, Double, Double)] {
+ import SvgInstrument._
+
+ val initial = (0.0, 0.0, 0.0, 0.0)
+
+ lazy val element = svgObject("balance")
+ lazy val position = part("position")
+ lazy val moveable = Seq(position)
+
+ protected def update(value: (Double, Double, Double, Double)) = {
+ val m0 = value._1
+ val m1 = value._2
+ val m2 = value._3
+ val m3 = value._4
+ val s = m0 + m1 + m2 + m3
+ val i = (m0 - m2) / s
+ val j = (m1 - m3) / s
+ val x = 0.5 * (i - j)
+ val y = 0.5 * (-i - j)
+ translate(position, (x * 50).toInt, (y * 50).toInt)
+ }
+} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Bar.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Bar.scala
new file mode 100644
index 0000000..7cda301
--- /dev/null
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Bar.scala
@@ -0,0 +1,19 @@
+package vfd.dashboard.ui.instruments
+
+import org.scalajs.dom.html
+import vfd.dashboard.Environment
+
+class Bar(implicit env: Environment) extends SvgInstrument[Double] {
+ import SvgInstrument._
+
+ val initial = 0.0
+
+ lazy val element = svgObject("bar")
+ lazy val level = part("level")
+ lazy val moveable = Seq(level)
+
+ protected def update(value: Double) = {
+ translate(level, 0, (97 * (1 - value / 100)).toInt)
+ }
+
+} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Compass.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Compass.scala
new file mode 100644
index 0000000..e2d79e4
--- /dev/null
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Compass.scala
@@ -0,0 +1,18 @@
+package vfd.dashboard.ui.instruments
+
+import org.scalajs.dom.html
+import vfd.dashboard.Environment
+
+class Compass(implicit env: Environment) extends SvgInstrument[Double] {
+ import SvgInstrument._
+
+ val initial = 0.0
+
+ lazy val element = svgObject("compass")
+ lazy val plate = part("heading")
+ lazy val moveable = Seq(plate)
+
+ protected def update(heading: Double) = {
+ rotate(plate, heading.toInt)
+ }
+} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Generic.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Generic.scala
new file mode 100644
index 0000000..c46bdcc
--- /dev/null
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Generic.scala
@@ -0,0 +1,40 @@
+package vfd.dashboard.ui.instruments
+
+import org.scalajs.dom
+import org.scalajs.dom.html
+import vfd.dashboard.Environment
+
+class Generic(
+ min: Double,
+ med: Double,
+ max: Double,
+ unit: String)(implicit env: Environment)
+ extends SvgInstrument[Double] {
+
+ import SvgInstrument._
+
+ val initial = 0.0
+
+ lazy val element = svgObject("generic")
+ lazy val handElement = part("hand")
+ lazy val unitElement = element.contentDocument.getElementById("unit")
+ lazy val valueElement = element.contentDocument.getElementById("value")
+ lazy val minElement = element.contentDocument.getElementById("min")
+ lazy val medElement = element.contentDocument.getElementById("med")
+ lazy val maxElement = element.contentDocument.getElementById("max")
+ lazy val moveable = Seq(handElement)
+
+ override protected def load(e: dom.Event) = {
+ unitElement.textContent = unit
+ minElement.textContent = min.toString
+ medElement.textContent = med.toString
+ maxElement.textContent = max.toString
+ update(min)
+ super.load(e)
+ }
+
+ protected def update(value: Double) = {
+ rotate(handElement, (value * 270 / (max - min)).toInt)
+ valueElement.textContent = value.toString
+ }
+} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Horizon.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Horizon.scala
new file mode 100644
index 0000000..2484561
--- /dev/null
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Horizon.scala
@@ -0,0 +1,20 @@
+package vfd.dashboard.ui.instruments
+
+import org.scalajs.dom.html
+import vfd.dashboard.Environment
+
+class Horizon(implicit env: Environment) extends SvgInstrument[(Double, Double)] {
+ import SvgInstrument._
+
+ val initial = (0.0, 0.0)
+
+ lazy val element = svgObject("horizon")
+ lazy val pitch = part("pitch")
+ lazy val roll = part("roll")
+ lazy val moveable = Seq(pitch, roll)
+
+ protected def update(pitchRoll: (Double, Double)) = {
+ translate(pitch, 0, pitchRoll._1.toInt)
+ rotate(roll, pitchRoll._2.toInt)
+ }
+}
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Instrument.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Instrument.scala
new file mode 100644
index 0000000..5b0a13d
--- /dev/null
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Instrument.scala
@@ -0,0 +1,28 @@
+package vfd.dashboard.ui.instruments
+
+import rx._
+import org.scalajs.dom.html
+
+/** Common trait to all flight instruments. */
+trait Instrument[A] {
+
+ /** Initial value. */
+ val initial: A
+
+ /** Current value that is displayed in the instrument. */
+ val value: Var[A] = Var(initial)
+
+ /** HTML element that contains the rendered instrument */
+ val element: html.Element
+
+ /** Performs the actual UI update of this instrument. */
+ protected def update(newValue: A): Unit
+
+ /** Call when instrument has finished setting up its UI. */
+ protected def ready() = {
+ Obs(value, skipInitial = true) {
+ update(value())
+ }
+ }
+
+} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Led.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Led.scala
new file mode 100644
index 0000000..4173f37
--- /dev/null
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Led.scala
@@ -0,0 +1,18 @@
+package vfd.dashboard.ui.instruments
+
+import scalatags.JsDom.all._
+import vfd.dashboard.Environment
+
+class Led(implicit env: Environment) extends SvgInstrument[String] {
+
+ val initial = "none"
+
+ lazy val element = `object`(`type` := "image/svg+xml", "data".attr := env.asset("images/leds/led.svg"), width := 100.pct)(
+ "Error loading led.").render
+ protected def moveable = Seq()
+
+ protected def update(color: String) = {
+ part("light").setAttribute("fill", color)
+ }
+
+} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/components/SvgInstrument.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/SvgInstrument.scala
index dc8ee5e..c639cec 100644
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/components/SvgInstrument.scala
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/SvgInstrument.scala
@@ -1,55 +1,52 @@
-package vfd.dashboard.ui.components
+package vfd.dashboard.ui.instruments
-import scala.scalajs.js.Any.fromFunction1
import org.scalajs.dom
import org.scalajs.dom.html
-import scalatags.JsDom.all.ExtendedString
-import scalatags.JsDom.all.Int2CssNumber
-import scalatags.JsDom.all.`object`
-import scalatags.JsDom.all.stringAttr
-import scalatags.JsDom.all.stringFrag
-import scalatags.JsDom.all.stringPixelStyle
-import scalatags.JsDom.all.`type`
-import scalatags.JsDom.all.width
+import scalatags.JsDom.all._
+
import vfd.dashboard.Environment
-trait SvgInstrument[A] {
+/** An instrument backed by an SVG image. */
+trait SvgInstrument[A] extends Instrument[A] {
/** SVG object element that contains the rendered instrument */
- def element: html.Object
+ val element: html.Object
- /** Actual svg document */
- protected def content = element.contentDocument
+ /** Retrieves an element of the underlying SVG document by ID. */
+ protected def part(id: String) = element.contentDocument.getElementById(id).asInstanceOf[html.Element]
- /** Moveable parts of the instrument */
+ /** Movable parts of the instrument */
protected def moveable: Seq[html.Element]
- /** Updates the instrument to show a new value */
- def update(value: A): Unit
-
+ /** Called when element has been loaded. */
protected def load(event: dom.Event): Unit = {
for (part <- moveable) {
part.style.transition = "transform 250ms ease-out"
}
+ ready()
}
element.addEventListener("load", (e: dom.Event) => load(e))
}
+/** Contains helpers for SVG instruments. */
object SvgInstrument {
- def svg(name: String)(implicit app: Environment): html.Object = {
+ /** Retrieves an SVG object element by its instrument's name. */
+ def svgObject(name: String)(implicit app: Environment): html.Object = {
val path = app.asset("images/instruments/" + name + ".svg")
`object`(`type` := "image/svg+xml", "data".attr := path, width := 100.pct)(
"Error loading instrument " + name).render
}
+ /** Applies translation styling to an element. */
def translate(elem: html.Element, x: Int, y: Int): Unit = {
elem.style.transform = "translate(" + x + "px, " + y + "px)";
}
+ /** Applies rotation styling to an element. */
def rotate(elem: html.Element, deg: Int): Unit = {
elem.style.transform = "rotateZ(" + deg + "deg)";
}
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Communication.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Communication.scala
deleted file mode 100644
index c9a5c90..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Communication.scala
+++ /dev/null
@@ -1,113 +0,0 @@
-package vfd.dashboard.ui.panels
-
-import org.mavlink.messages.Heartbeat
-import org.mavlink.messages.Motor
-import org.mavlink.messages.Power
-import org.scalajs.dom.html
-import rx.core.Obs
-import scalatags.JsDom.all.bindNode
-import scalatags.JsDom.all.`class`
-import scalatags.JsDom.all.div
-import scalatags.JsDom.all.i
-import scalatags.JsDom.all.stringAttr
-import scalatags.JsDom.all.stringFrag
-import scalatags.JsDom.all.stringPixelStyle
-import scalatags.JsDom.all.style
-import scalatags.JsDom.all.table
-import scalatags.JsDom.all.tbody
-import scalatags.JsDom.all.td
-import scalatags.JsDom.all.thead
-import scalatags.JsDom.all.tr
-import scalatags.JsDom.all.width
-import vfd.dashboard.Environment
-import vfd.dashboard.MavlinkSocket
-import vfd.dashboard.ui.components.Balance
-import vfd.dashboard.ui.components.Bar
-import vfd.dashboard.ui.components.Generic
-import vfd.dashboard.ui.components.Led
-import scalatags.jsdom.Frag
-
-object Communication {
-
- def apply(socket: MavlinkSocket)(implicit app: Environment): Frag = {
-
- val hb = i(`class` := "fa fa-heart heartbeat").render
-
- def foo() = {
- hb.textContent = ""
- }
-
- val motor0 = new Generic(0, 50, 100, "%")
- val motor1 = new Generic(0, 50, 100, "%")
- val motor2 = new Generic(0, 50, 100, "%")
- val motor3 = new Generic(0, 50, 100, "%")
- val powerDistribution = new Balance()
- val batteryLevel = new Bar()
-
- Obs(socket.message, skipInitial = true) {
- socket.message() match {
- case Motor(m0, m1, m2, m3) =>
- motor0.update(m0)
- motor1.update(m1)
- motor2.update(m2)
- motor3.update(m3)
- powerDistribution.update(m0, m1, m2, m3)
-
- case Power(mV) =>
- batteryLevel.update(100 * (mV - 9600) / 12600)
- case Heartbeat(_) => {
- hb.style.visibility = "hidden"
- hb.style.visibility = "visible"
- //hb.classList.remove("heartbeat")
- //hb.offsetHeight
- //hb.classList.add("heartbeat")
- }
- case _ =>
- }
- }
-
- div(
- table(`class` := "table")(
- thead("Communication"),
- tbody(
- tr(
- td("Conn"),
- div(width := "20px")(td((new Led()).element)),
- td("Server"),
- td("5 ms")),
- tr(
- td("Uplink"),
- td("-20 dBm"),
- td("Heartbeat"),
- td(hb)))),
- table(`class` := "table-instrument", style := "height: 100px")(
- tbody(
- tr(
- td(),
- td(),
- td(),
- td(),
- td(),
- td(),
- td(),
- td(),
- td(),
- td(batteryLevel.element)))),
- table (`class` := "table-instrument")(
- thead("Motors"),
- tbody(
- tr(
- td(motor0.element),
- td(),
- td(motor1.element)),
- tr(
- td(),
- td(powerDistribution.element),
- td()),
- tr(
- td(motor2.element),
- td(),
- td(motor3.element)))))
- }
-
-} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Primary.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Primary.scala
deleted file mode 100644
index 5308b40..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Primary.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-package vfd.dashboard.ui.panels
-
-import org.mavlink.messages.Attitude
-import org.scalajs.dom.html
-import rx.core.Obs
-import scalatags.JsDom.all.bindNode
-import scalatags.JsDom.all.`class`
-import scalatags.JsDom.all.stringAttr
-import scalatags.JsDom.all.table
-import scalatags.JsDom.all.tbody
-import scalatags.JsDom.all.td
-import scalatags.JsDom.all.tr
-import vfd.dashboard.Environment
-import vfd.dashboard.MavlinkSocket
-import vfd.dashboard.ui.components.Altimeter
-import vfd.dashboard.ui.components.Compass
-import vfd.dashboard.ui.components.Horizon
-import scalatags.jsdom.Frag
-
-object Primary {
-
- def apply(socket: MavlinkSocket)(implicit env: Environment): Frag = {
-
- val compass = new Compass
- val horizon = new Horizon
- val altimeter = new Altimeter
-
- Obs(socket.message, skipInitial = true) {
- socket.message() match {
- case Attitude(roll, pitch, yaw) =>
- horizon.update(pitch, roll)
- compass.update(yaw)
- case _ => ()
- }
- }
-
- table(`class` := "table-instrument")(
- tbody(
- tr(
- td(compass.element),
- td(horizon.element),
- td(altimeter.element))))
-
- }
-
-} \ No newline at end of file