aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2015-03-24 10:51:42 +0100
committerJakob Odersky <jodersky@gmail.com>2015-03-27 09:33:01 +0100
commitde730793fdb650e7e9a8dcc88ae84c3b153cd479 (patch)
tree22bdc2993769637212f066da45f841dc0701ed01
parent2881fb6ba97cbd496eebb4d785b2ba6e59fa303c (diff)
downloadmavigator-de730793fdb650e7e9a8dcc88ae84c3b153cd479.tar.gz
mavigator-de730793fdb650e7e9a8dcc88ae84c3b153cd479.tar.bz2
mavigator-de730793fdb650e7e9a8dcc88ae84c3b153cd479.zip
implement flexbox based layout
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala83
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Communication.scala6
-rw-r--r--vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Primary.scala6
-rw-r--r--vfd-main/app/views/dashboard.scala.html27
-rw-r--r--vfd-main/public/stylesheets/main.css191
5 files changed, 225 insertions, 88 deletions
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 4ec695e..0264e5f 100644
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/Layout.scala
@@ -1,12 +1,11 @@
package vfd.dashboard.ui
import org.scalajs.dom.html
-
import scalatags.JsDom.all.ExtendedString
import scalatags.JsDom.all.Int2CssNumber
-import scalatags.JsDom.all.bindNode
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
@@ -16,12 +15,69 @@ 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 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
+
+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 #"))
-class Layout(socket: MavlinkSocket) {
+ 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)
+
+ 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(
width := 100.pct,
@@ -35,24 +91,5 @@ class Layout(socket: MavlinkSocket) {
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(implicit env: Environment): html.Element = div(`class` := "container-fluid")(
- div(`class` := "row")(
- div(`class` := "col-xs-12")(
- div(`class` := "panel panel-default")(
- div(`class` := "panel-body")()))),
- div(`class` := "row")(
- div(`class` := "col-xs-4")(
- div(`class` := "panel panel-default")(
- div(`class` := "panel-body")(
- map))),
- div(`class` := "col-xs-5")(
- div(`class` := "panel panel-default")(
- div(`class` := "panel-body")(
- feed)),
- div(`class` := "panel panel-default")(
- div(`class` := "panel-body")(Primary(socket)))),
- div(`class` := "col-xs-3")(
- div(`class` := "panel panel-default")(
- div(`class` := "panel-body")(Communication(socket)))))).render
-
+ def element: html.Element = layout.render
} \ No newline at end of file
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
index 220a7b8..c9a5c90 100644
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Communication.scala
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Communication.scala
@@ -4,7 +4,6 @@ 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`
@@ -26,10 +25,11 @@ 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): html.Element = {
+ def apply(socket: MavlinkSocket)(implicit app: Environment): Frag = {
val hb = i(`class` := "fa fa-heart heartbeat").render
@@ -107,7 +107,7 @@ object Communication {
tr(
td(motor2.element),
td(),
- td(motor3.element))))).render
+ 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
index 6f66208..5308b40 100644
--- a/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Primary.scala
+++ b/vfd-dashboard/src/main/scala/vfd/dashboard/ui/panels/Primary.scala
@@ -2,7 +2,6 @@ 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`
@@ -16,10 +15,11 @@ 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): html.Element = {
+ def apply(socket: MavlinkSocket)(implicit env: Environment): Frag = {
val compass = new Compass
val horizon = new Horizon
@@ -39,7 +39,7 @@ object Primary {
tr(
td(compass.element),
td(horizon.element),
- td(altimeter.element)))).render
+ td(altimeter.element))))
}
diff --git a/vfd-main/app/views/dashboard.scala.html b/vfd-main/app/views/dashboard.scala.html
index 02a79f7..b2cfdfd 100644
--- a/vfd-main/app/views/dashboard.scala.html
+++ b/vfd-main/app/views/dashboard.scala.html
@@ -2,33 +2,6 @@
@main("Main"){
- <header>
- <nav class="navbar navbar-inverse navbar-static-top" role="navigation">
- <div class="container-fluid">
- <!-- Brand and toggle get grouped for better mobile display -->
- <div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-main-collapse">
- <span class="sr-only">Toggle navigation</span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="@routes.Application.index">
- <!-- <img style="max-height: 100%;" src="@routes.Assets.at("images/logo-invert.svg")" alt="logo"> -->
- Flight Control Panel
- </a>
- </div>
-
- <!-- Collect the nav links, forms, and other content for toggling -->
- <div class="collapse navbar-collapse" id="navbar-main-collapse">
- <div class="nav navbar-nav navbar-right">
- <p class="navbar-text">Remote System @remoteSystemId</p>
- </div>
- </div><!-- /.navbar-collapse -->
- </div><!-- /.container-fluid -->
- </nav>
- </header>
-
@app("vfd-dashboard")(
"socketUrl" -> socket,
"remoteSystemId" -> remoteSystemId.toString,
diff --git a/vfd-main/public/stylesheets/main.css b/vfd-main/public/stylesheets/main.css
index e92cd24..072f167 100644
--- a/vfd-main/public/stylesheets/main.css
+++ b/vfd-main/public/stylesheets/main.css
@@ -1,18 +1,9 @@
-@font-face {
- font-family: ds-digi;
- src: url('../fonts/ds-digi.ttf')
-}
-
-html {
- height: 100%;
-}
-
-body {
- height: 100%;
+html, body {
+ height: 100%;
}
body {
- background-color: #e6e6e6;
+ background-color: #e6e6e6;
}
.loader {
@@ -21,6 +12,144 @@ body {
text-align: center;
}
+#vfd-dashboard {
+ width: 100%;
+ height: 100%;
+}
+
+#vfd-dashboard header {
+ color: #eeeeee;
+ background-color: #222222;
+ padding-left: 15px;
+ padding-right: 15px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ margin-bottom: 5px;
+ display: flex;
+}
+
+#vfd-dashboard header > * {
+ margin: 5px;
+ flex: 1;
+}
+
+#vfd-dashboard header > :nth-child(1) {
+ text-align: left;
+}
+
+#vfd-dashboard header > :nth-child(2) {
+ text-align: center;
+}
+
+#vfd-dashboard header > :nth-child(3) {
+ text-align: right;
+}
+
+/* dashboard layout */
+.d-container {
+ display: flex;
+ align-content: flex-start;
+ align-items: stretch;
+}
+
+.d-container > * {
+ flex: 1;
+}
+
+.d-column {
+ flex-direction: column;
+ height: 100%;
+}
+
+.d-row {
+ flex-direction: row;
+ width: 100%;
+}
+
+.d-above {
+ flex: none;
+}
+
+.d-left {
+ flex: 1 1 30%;
+}
+
+.d-middle {
+ flex: 1 1 45%;
+}
+
+.d-right {
+ flex: 1 1 25%;
+}
+
+.d-center {
+ flex: none;
+}
+
+.d-below {
+ flex: 1;
+}
+
+.d-details {
+ display: none;
+}
+
+.d-detailed .d-left, .d-detailed .d-right {
+ display: none;
+}
+
+.d-detailed .d-middle {
+ flex: 1 1 25%;
+}
+
+.d-detailed .d-details {
+ display: flex;
+ flex: 1 1 75%;
+ overerflow-y: scroll;
+}
+
+.d-panel {
+ margin: 5px;
+ padding: 15px;
+ background-color: white;
+ border-radius: 3px;
+}
+
+
+/* Mode styles */
+.mode {
+ display: inline-block;
+ box-sizing: border-box;
+ text-decoration: normal;
+ margin-right: 5px;
+}
+
+.mode.danger {
+ color: #d9534f;
+ text-shadow: 0 0 5px #d9534f;
+}
+
+.mode.warning {
+ color: #f0ad4e;
+ text-shadow: 0 0 5px #f0ad4e;
+}
+
+.mode.info {
+ color: #5bc0de;
+ text-shadow: 0 0 5px #5bc0de;
+}
+
+.mode.success {
+ color: #5cb85c;
+ text-shadow: 0 0 5px #5cb85c;
+}
+
+.mode.off {
+ color: #eeeeee;
+ text-shadow: none;
+}
+
+/* TODO: Rules below are maybe obsolete and need to be reviewed */
.table-instrument {
table-layout: fixed;
width: 100%;
@@ -31,25 +160,23 @@ body {
}
.heartbeat {
- color: rgba(165, 25, 25, 1);
- animation: heartbeat 2s linear infinite;
+ color: rgba(165, 25, 25, 1);
+ animation: heartbeat 2s linear infinite;
}
-
@keyframes heartbeat {
- 0% {
- transform: scale(1);
- }
- 7% {
- transform: scale(1.3);
- }
- 14% {
- transform: scale(1);
- }
- 21% {
- transform: scale(1.3);
- }
- 28% {
- transform: scale(1);
- }
-}
-
+ 0% {
+ transform: scale(1);
+ }
+ 7% {
+ transform: scale(1.3);
+ }
+ 14% {
+ transform: scale(1);
+ }
+ 21% {
+ transform: scale(1.3);
+ }
+ 28% {
+ transform: scale(1);
+ }
+} \ No newline at end of file