aboutsummaryrefslogtreecommitdiff
path: root/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments
diff options
context:
space:
mode:
Diffstat (limited to 'mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments')
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Altimeter.scala18
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Bar.scala18
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Clock.scala23
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Compass.scala17
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Distribution.scala25
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Generic.scala40
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Horizon.scala19
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Instrument.scala25
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Led.scala17
-rw-r--r--mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/SvgInstrument.scala54
10 files changed, 256 insertions, 0 deletions
diff --git a/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Altimeter.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Altimeter.scala
new file mode 100644
index 0000000..b65b374
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Altimeter.scala
@@ -0,0 +1,18 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Bar.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Bar.scala
new file mode 100644
index 0000000..9f9f81c
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Bar.scala
@@ -0,0 +1,18 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Clock.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Clock.scala
new file mode 100644
index 0000000..a5bfc03
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Clock.scala
@@ -0,0 +1,23 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Compass.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Compass.scala
new file mode 100644
index 0000000..9f1ae4a
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Compass.scala
@@ -0,0 +1,17 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Distribution.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Distribution.scala
new file mode 100644
index 0000000..f750bab
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Distribution.scala
@@ -0,0 +1,25 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Generic.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Generic.scala
new file mode 100644
index 0000000..86c27e1
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Generic.scala
@@ -0,0 +1,40 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Horizon.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Horizon.scala
new file mode 100644
index 0000000..bbfe8cf
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Horizon.scala
@@ -0,0 +1,19 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Instrument.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Instrument.scala
new file mode 100644
index 0000000..bf5c9ca
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Instrument.scala
@@ -0,0 +1,25 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Led.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Led.scala
new file mode 100644
index 0000000..f5259b5
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/Led.scala
@@ -0,0 +1,17 @@
+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/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/SvgInstrument.scala b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/SvgInstrument.scala
new file mode 100644
index 0000000..fe6c58a
--- /dev/null
+++ b/mavigator-dashboard/src/main/scala/mavigator/dashboard/ui/instruments/SvgInstrument.scala
@@ -0,0 +1,54 @@
+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