aboutsummaryrefslogtreecommitdiff
path: root/vfd-dashboard/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'vfd-dashboard/src/main')
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/Environment.scala14
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/Main.scala25
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/MavlinkSocket.scala69
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/RxUtil.scala70
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/Hud.scala47
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala266
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Altimeter.scala18
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Bar.scala18
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Clock.scala23
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Compass.scala17
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Distribution.scala25
-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.scala19
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Instrument.scala25
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Led.scala17
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/SvgInstrument.scala54
16 files changed, 0 insertions, 747 deletions
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/Environment.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/Environment.scala
deleted file mode 100644
index 57cd39d..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/Environment.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-package vfd.dashboard
-
-import org.scalajs.dom.html
-
-/** Represents an application's environment */
-trait Environment {
-
- /** The application's root element. */
- def root: html.Element
-
- /** Retrieve an asset's URL based on its file location. */
- def asset(file: String): String
-
-} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/Main.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/Main.scala
deleted file mode 100644
index 71c5378..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/Main.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package vfd.dashboard
-
-import scala.scalajs.js
-import scala.scalajs.js.annotation.JSExport
-
-import org.scalajs.dom.html
-
-import vfd.dashboard.ui.Layout
-
-@JSExport("Main")
-object Main {
-
- @JSExport
- def main(rootElement: html.Element, assetsBase: String, args: js.Dictionary[String]) = {
- implicit val env = new Environment {
- def root = rootElement
- def asset(file: String) = assetsBase + "/" + file
- }
-
- val socket = new MavlinkSocket(args("socketUrl"), args("remoteSystemId").toInt)
- val layout = new Layout(socket)
-
- env.root.appendChild(layout.element)
- }
-} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/MavlinkSocket.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/MavlinkSocket.scala
deleted file mode 100644
index 2fe8262..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/MavlinkSocket.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-package vfd.dashboard
-
-import scala.scalajs.js
-import scala.scalajs.js.Any.fromFunction1
-import org.mavlink.Packet
-import org.mavlink.Parser
-import org.mavlink.Parser.Errors._
-import org.mavlink.messages.Message
-import org.scalajs.dom
-import scala.concurrent.duration._
-import rx._
-import rx.ops._
-import scala.concurrent.ExecutionContext.Implicits.global
-
-class MavlinkSocket(url: String, val remoteSystemId: Int) {
- implicit val scheduler = new DomScheduler
-
- lazy val packet: Var[Packet] = Var(Packet.empty)
- lazy val message: Rx[Message] = packet.map{p =>
- Message.unpack(p.messageId, p.payload)
- }
-
- object stats {
- private val DebounceTime = 1.seconds
-
- private[MavlinkSocket] val _crcErrors = Var(0)
- private[MavlinkSocket] val _overflows = Var(0)
- private[MavlinkSocket] val _wrongIds = Var(0)
- private[MavlinkSocket] val _packets = Var(0)
-
- val crcErrors = _crcErrors.debounce(DebounceTime)
- val overflows = _overflows.debounce(DebounceTime)
- val wrongIds = _wrongIds.debounce(DebounceTime)
- val packets = _packets.debounce(DebounceTime)
- val open = Var(false)
- }
-
- private val parser = new Parser(
- {
- case pckt@Packet(seq, `remoteSystemId`, compId, msgId, payload) =>
- packet() = pckt
- stats._packets() += 1
- case _ =>
- stats._wrongIds() += 1
- },
- {
- case CrcError => stats._crcErrors() += 1
- case OverflowError => stats._overflows() += 1
- })
-
- private val connection = new dom.WebSocket(url)
-
- connection.binaryType = "arraybuffer"
- connection.onopen = (e: dom.Event) => {
- stats.open() = true
- }
- connection.onmessage = (e: dom.MessageEvent) => {
- val buffer = e.data.asInstanceOf[js.typedarray.ArrayBuffer]
- val view = new js.typedarray.DataView(buffer)
-
- for (i <- 0 until view.byteLength) {
- parser.push(view.getInt8(i))
- }
- }
- connection.onclose = (e: dom.CloseEvent) => {
- stats.open() = false
- }
-
-} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/RxUtil.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/RxUtil.scala
deleted file mode 100644
index a73c3ba..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/RxUtil.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-package vfd.dashboard
-
-import scala.language.implicitConversions
-import scala.util.Failure
-import scala.util.Success
-
-import org.scalajs.dom.html
-
-import rx.Obs
-import rx.Rx
-import rx.Rx
-import rx.Var
-import rx.Var
-import scalatags.JsDom.all.Frag
-import scalatags.JsDom.all.HtmlTag
-import scalatags.JsDom.all.backgroundColor
-import scalatags.JsDom.all.bindNode
-import scalatags.JsDom.all.span
-import scalatags.JsDom.all.stringFrag
-import scalatags.JsDom.all.stringStyle
-
-package object rxutil {
-
- /** Rx, implicitly enhanced with additional methods. */
- implicit class RichRx(val rx: Rx[_]) extends AnyVal {
-
- /**
- * Builds a new Rx by applying a partial function to all values of
- * this Rx on which the function is defined.
- * @param initial initial value of the returned Rx
- * @param pf the partial function which filters and maps this Rx
- * @return a new Rx resulting from applying the given partial
- * function pf to each value on which it is defined and collecting
- * the result
- */
- def collect[B](initial: B)(pf: PartialFunction[Any, B]): Rx[B] = {
- val result: Var[B] = Var(initial)
- Obs(rx, skipInitial = true) {
- if (pf.isDefinedAt(rx())) {
- result() = pf(rx())
- }
- }
- result
- }
-
- }
-
- /**
- * Copied from https://github.com/lihaoyi/workbench-example-app/blob/todomvc/src/main/scala/example/Framework.scala
- *
- * 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 rxMod[T <: html.Element](r: Rx[HtmlTag]): Frag = {
- def rSafe = r.toTry match {
- case Success(v) => v.render
- case Failure(e) => span(e.toString, backgroundColor := "red").render
- }
- var last = rSafe
- Obs(r, skipInitial = true) {
- val newLast = rSafe
- last.parentElement.replaceChild(newLast, last)
- last = newLast
- }
- bindNode(last)
- }
-
-} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Hud.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Hud.scala
deleted file mode 100644
index 6abdb36..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Hud.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-package vfd.dashboard.ui
-
-import vfd.dashboard.Environment
-import vfd.dashboard.ui.instruments._
-
-import scalatags.JsDom.all._
-import rx._
-
-class Hud(attitude: Rx[(Double, Double)])(implicit env: Environment) {
-
- private def overlay(name: String, z: Int, thinnerThanWide: Boolean = false) = {
- val direction = if (thinnerThanWide) "row" else "column"
- div(
- style:=
- "position: absolute; left: 0; right: 0; top: 0; bottom: 0;" +
- s"display: flex; align-content: center; align-items: stretch; flex-direction: $direction;"+
- s"z-index: $z;"
- )(
- `object`(`type`:="image/svg+xml", "data".attr:=env.asset("images/hud/" + name + ".svg"), style := "flex: 1 1 100%;")
- )
- }
-
- object Horizon extends SvgInstrument[(Double, Double)] {
- import SvgInstrument._
-
- val value = attitude
-
- lazy val element = `object`(`type`:="image/svg+xml", "data".attr:=env.asset("images/hud/horizon.svg"), style:="flex: 1 1 100%;").render
- lazy val horizon = part("horizon")
- lazy val moveable = Seq(horizon)
-
- protected def update(pitchRoll: (Double, Double)) = {
- rotate(horizon, pitchRoll._2)
- //translate(horizon, 0, (pitchRoll._1 * 180 / math.Pi).toInt) // 1deg === 1px
- }
- }
-
- val element = div(
- style:=
- "position: absolute; left: 0; right: 0; top: 0; bottom: 0;" +
- "display: flex; align-content: stretch; align-items: stretch; flex-direction: row;"+
- "z-index: 0;"
- )(
- Horizon.element
- )
-}
-
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala
deleted file mode 100644
index fe1b34f..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala
+++ /dev/null
@@ -1,266 +0,0 @@
-package vfd.dashboard.ui
-
-import rx._
-import scalatags.JsDom.all._
-import vfd.dashboard.Environment
-import vfd.dashboard.MavlinkSocket
-import vfd.dashboard.ui.instruments._
-import org.mavlink.messages._
-import vfd.dashboard.rxutil._
-
-class Layout(socket: MavlinkSocket)(implicit env: Environment) {
-
- private def panel(contents: Frag*) = div(`class` := "d-panel")(contents: _*)
-
- 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),
- mode("STABILIZED", "info", true),
- mode("GUIDED", "success", true),
- mode("AUTO", "success", true))
-
- val infos = div(
- mode("BAY", "info"),
- mode("RECOVERY", "danger"),
- mode("NOGPS", "warning", true),
- mode("OVERLOAD", "danger", true),
- mode("BATTERY", "danger", false),
- mode("LINK", "danger", true),
- mode("SOCKET", "danger", true),
- div(style := "float: right")(mode("CRITICAL", "danger", true)))
-
- val map = iframe(
- "frameborder".attr := "0",
- "scrolling".attr := "no",
- "marginheight".attr := "0",
- "marginwidth".attr := "0",
- src := "http://www.openstreetmap.org/export/embed.html?bbox=6.5611016750335684%2C46.51718501017836%2C6.570038795471191%2C46.520577350893525&amp;layer=mapnik")
-
- val feed = div(style := "width: 100%; height: 100%; color: #ffffff; background-color: #c2c2c2; text-align: center;")
-
- val altimeter = new Altimeter(
- Var(0.0)
- )
- val horizon = new Horizon(socket.message.collect((0.0, 0.0)) {
- case att: Attitude => (att.pitch, att.roll)
- })
- val compass = new Compass(socket.message.collect(0.0) {
- case att: Attitude => att.yaw
- })
- val motor0 = new Generic(0, 50, 100, "%", socket.message.collect(0.0) {
- case s: ServoOutputRaw => 100 * (s.servo1Raw - 1000) / 1000
- })
- val motor1 = new Generic(0, 50, 100, "%", socket.message.collect(0.0) {
- case s: ServoOutputRaw => 100 * (s.servo2Raw - 1000) / 1000
- })
- val motor2 = new Generic(0, 50, 100, "%", socket.message.collect(0.0) {
- case s: ServoOutputRaw => 100 * (s.servo3Raw - 1000) / 1000
- })
- val motor3 = new Generic(0, 50, 100, "%", socket.message.collect(0.0) {
- case s: ServoOutputRaw => 100 * (s.servo4Raw - 1000) / 1000
- })
- val powerDistribution = new Distribution(
- socket.message.collect((0.0, 0.0, 0.0, 0.0)) {
- case s: ServoOutputRaw =>
- (
- 1.0 * (s.servo1Raw - 1000) / 1000,
- 1.0 * (s.servo2Raw - 1000) / 1000,
- 1.0 * (s.servo3Raw - 1000) / 1000,
- 1.0 * (s.servo4Raw - 1000) / 1000
- )
- }
- )
- val batteryLevel = new Bar(
- Var(0.0)
- )
-
- val top = header(
- div("Flight Control Panel"),
- div((new Clock).element),
- div("UAV " + socket.remoteSystemId)
- )
-
- val left = div(
- panel(
- table(`class` := "table-instrument")(
- thead("Communication"),
- tbody(
- tr(
- td("Uplink RSSI"),
- td("89"),
- td("Socket"),
- td("5ms")
- ),
- tr(
- td("Something else"),
- td("unknown"),
- td("Heartbeat"),
- td(i(`class` := "fa fa-heart heartbeat"))
- )
- )
- ),
- table(`class` := "table-instrument")(
- thead("Packets"),
- tbody(
- tr(
- td("OK"),
- Rx { td(socket.stats.packets()) },
- td("CRC"),
- Rx { td(socket.stats.crcErrors()) },
- td("OFLW"),
- Rx { td(socket.stats.overflows()) },
- td("BID"),
- Rx { td(socket.stats.wrongIds()) }
- ),
- tr(
- td("Ratio"),
- Rx {
- import socket.stats._
- val sum = packets() + crcErrors() + overflows() + wrongIds()
- td(1.0 * packets() / sum formatted "%.2f")
- },
- td(),
- td(),
- td(),
- td(),
- td(),
- td()
- )
- )
- )
- ),
- panel(
- table(`class` := "table-instrument")(
- tbody(
- tr(
- td(compass.element),
- td(horizon.element),
- td(altimeter.element),
- td(altimeter.element)
- )
- )
- )
- ),
- panel(
- div(style := "width: 50%; display: inline-block;")(
- table(`class` := "table-instrument")(
- tbody(
- tr(
- td(motor1.element),
- td(),
- td(motor0.element)
- ),
- tr(
- td(),
- td(powerDistribution.element),
- td()
- ),
- tr(
- td(motor2.element),
- td(),
- td(motor3.element)
- )
- )
- )
- ),
- div(style := "width: 50%; display: inline-block;")(
- table(`class` := "table-instrument")(
- thead("Power"),
- tbody(
- tr(
- td("VHIGH"),
- td("12.6V"),
- td("VLOW"),
- td("9V")
- ),
- tr(
- td("Voltage"),
- td("11.2V"),
- td("Remaining"),
- td("80%")
- ),
- tr(
- td("Flight"),
- td("05:00"),
- td("Endurance"),
- td("12:00")
- )
- )
- ),
- table(`class` := "table-instrument")(
- thead("Navigation"),
- tbody(
- tr(
- td("Satellites"),
- td("5"),
- td("Precision"),
- td("10cm")
- ),
- tr(
- td("LON"),
- td(""),
- td("LAT"),
- td("")
- ),
- tr(
- td("GSpeed"),
- td("3 m/s"),
- td(),
- td()
- ),
- tr(
- td("Travelled"),
- td("5000m"),
- td("Home"),
- td("1200m")
- )
- )
- )
- )
- )
- )
-
-
-
- val hud = {
- def overlay(name: String, z: Int, thinnerThanWide: Boolean = false) = {
- val direction = if (thinnerThanWide) "row" else "column"
- div(
- style:=
- "position: absolute; left: 0; right: 0; top: 0; bottom: 0;" +
- s"display: flex; align-content: center; align-items: stretch; flex-direction: $direction;"+
- s"z-index: $z;"
- )(
- `object`(`type`:="image/svg+xml", "data".attr:=env.asset("images/hud/" + name + ".svg"), style := "flex: 1 1 100%;")
- )
-
- }
-
- Seq(
- overlay("horizon", 0),
- overlay("roll", 1)
- )
- }
-
-
-
- val element = div(`class` := "d-container d-column", style:="width: 100%; height: 100%;")(
- 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-left")(
- left
- ),
- div(`class` := "d-main", style:="position: relative;")(
- (new Hud(horizon.value)).element
- )
- )
- ).render
-
-}
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
deleted file mode 100644
index b65b374..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Altimeter.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import org.scalajs.dom.html
-import rx._
-import vfd.dashboard.Environment
-
-class Altimeter(val value: Rx[Double])(implicit env: Environment) extends SvgInstrument[Double] {
- import SvgInstrument._
-
- lazy val element = svgObject("altimeter")
- lazy val hand = part("hand")
- lazy val moveable = Seq(hand)
-
- // 1m === 36deg = 2Pi / 10 ~= 0.62832
- protected def update(altitude: Double) = {
- rotate(hand, (altitude * 0.62832).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
deleted file mode 100644
index 9f9f81c..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Bar.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import org.scalajs.dom.html
-import rx._
-import vfd.dashboard.Environment
-
-class Bar(val value: Rx[Double])(implicit env: Environment) extends SvgInstrument[Double] {
- import SvgInstrument._
-
- 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/Clock.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Clock.scala
deleted file mode 100644
index a5bfc03..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Clock.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import org.scalajs.dom
-import rx._
-import scala.scalajs.js.Date
-import scalatags.JsDom.all._
-
-class Clock extends Instrument[Date] {
-
- def format(date: Date) = date.toLocaleTimeString()
-
- val value = Var(new Date)
-
- val element = span(format(value())).render
-
- protected def update(value: Date) = {
- element.innerHTML = format(value)
- }
-
- dom.setInterval(() => {value() = new Date}, 1000)
- ready()
-
-} \ 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
deleted file mode 100644
index 9f1ae4a..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Compass.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import org.scalajs.dom.html
-import rx._
-import vfd.dashboard.Environment
-
-class Compass(val value: Rx[Double])(implicit env: Environment) extends SvgInstrument[Double] {
- import SvgInstrument._
-
- lazy val element = svgObject("compass")
- lazy val plate = part("heading")
- lazy val moveable = Seq(plate)
-
- protected def update(heading: Double) = {
- rotate(plate, heading)
- }
-} \ No newline at end of file
diff --git a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Distribution.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Distribution.scala
deleted file mode 100644
index f750bab..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Distribution.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import org.scalajs.dom.html
-import rx._
-import vfd.dashboard.Environment
-
-class Distribution(val value: Rx[(Double, Double, Double, Double)])(implicit env: Environment) extends SvgInstrument[(Double, Double, Double, Double)] {
- import SvgInstrument._
-
- lazy val element = svgObject("distribution")
- lazy val position = part("position")
- lazy val moveable = Seq(position)
-
- private final val Radius = 50 //px
-
- protected def update(value: (Double, Double, Double, Double)) = {
- val sum = value._1 + value._2 + value._3 + value._4
- val i = (value._1 - value._3) / sum
- val j = (value._2 - value._4) / sum
- val x = math.sqrt(2) / 2 * (i - j)
- val y = math.sqrt(2) / 2 * (-i - j)
- translate(position, (x * Radius).toInt, (y * Radius).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
deleted file mode 100644
index 86c27e1..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Generic.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import org.scalajs.dom
-import org.scalajs.dom.html
-import rx._
-import vfd.dashboard.Environment
-
-class Generic(
- min: Double,
- med: Double,
- max: Double,
- unit: String,
- val value: Rx[Double])
- (implicit env: Environment)
- extends SvgInstrument[Double] {
-
- import SvgInstrument._
-
- 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
- super.load(e)
- }
-
- protected def update(value: Double) = {
- rotate(handElement, value / (max - min) * math.Pi * 3 / 2)
- 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
deleted file mode 100644
index bbfe8cf..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Horizon.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import org.scalajs.dom.html
-import rx._
-import vfd.dashboard.Environment
-
-class Horizon(val value: Rx[(Double, Double)])(implicit env: Environment) extends SvgInstrument[(Double, Double)] {
- import SvgInstrument._
-
- 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 * 180 / math.Pi).toInt) // 1deg === 1px
- rotate(roll, pitchRoll._2)
- }
-}
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
deleted file mode 100644
index bf5c9ca..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Instrument.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import rx._
-import org.scalajs.dom.html
-
-/** Common trait to all flight instruments. */
-trait Instrument[A] {
-
- /** Current value that is displayed in the instrument. */
- val value: Rx[A]
-
- /** 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
deleted file mode 100644
index f5259b5..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/Led.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-import rx._
-import scalatags.JsDom.all._
-import vfd.dashboard.Environment
-
-class Led(val value: Rx[String])(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
- 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/instruments/SvgInstrument.scala b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/SvgInstrument.scala
deleted file mode 100644
index fe6c58a..0000000
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/instruments/SvgInstrument.scala
+++ /dev/null
@@ -1,54 +0,0 @@
-package vfd.dashboard.ui.instruments
-
-
-import org.scalajs.dom
-import org.scalajs.dom.html
-
-import scalatags.JsDom.all._
-
-import vfd.dashboard.Environment
-
-/** An instrument backed by an SVG image. */
-trait SvgInstrument[A] extends Instrument[A] {
-
- /** SVG object element that contains the rendered instrument */
- val element: html.Object
-
- /** Retrieves an element of the underlying SVG document by ID. */
- protected def part(id: String) = element.contentDocument.getElementById(id).asInstanceOf[html.Element]
-
- /** Movable parts of the instrument */
- protected def moveable: Seq[html.Element]
-
- /** Called when element has been loaded. */
- protected def load(event: dom.Event): Unit = {
- for (part <- moveable) {
- part.style.transition = "transform 50ms ease-out"
- }
- ready()
- }
-
- element.addEventListener("load", (e: dom.Event) => load(e))
-}
-
-/** Contains helpers for SVG instruments. */
-object SvgInstrument {
-
- /** 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, rad: Double): Unit = {
- elem.style.transform = "rotateZ(" + rad + "rad)";
- }
-
-} \ No newline at end of file