diff --git a/build.sbt b/build.sbt
index 8cd59e9..897fed2 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,11 +1,29 @@
-name := "Scurses"
+import sbt.Keys._
+import sbt._
-version := "1.0"
-scalaVersion := "2.11.7"
+lazy val commonSettings: Seq[Setting[_]] = Seq(
+ version := "1.0",
+ scalaVersion := "2.11.7",
+ scalacOptions ++= Seq("-feature", "-unchecked")
+)
-scalacOptions ++= Seq("-feature", "-unchecked")
+lazy val root = (project in file("."))
+ .settings(commonSettings: _*)
+ .aggregate(scurses, onions)
-libraryDependencies += "com.lihaoyi" %% "fastparse" % "0.2.1"
+lazy val scurses = (project in file("scurses"))
+ .settings(commonSettings: _*)
+ .settings(
+ name := "Scurses",
+ libraryDependencies += "com.lihaoyi" %% "fastparse" % "0.2.1",
+ mainClass in (Compile, run) := Some("net.team2xh.scurses.examples.GameOfLife")
+ )
-mainClass in (Compile, run) := Some("net.team2xh.scurses.examples.StressTest")
\ No newline at end of file
+lazy val onions = (project in file("onions"))
+ .settings(commonSettings: _*)
+ .dependsOn(scurses)
+ .settings(
+ name := "Onions",
+ mainClass in (Compile, run) := Some("net.team2xh.onions.examples.ExampleUI")
+ )
\ No newline at end of file
diff --git a/src/main/scala/net/team2xh/onions/Component.scala b/onions/src/main/scala/net/team2xh/onions/Component.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/Component.scala
rename to onions/src/main/scala/net/team2xh/onions/Component.scala
diff --git a/src/main/scala/net/team2xh/onions/Palettes.scala b/onions/src/main/scala/net/team2xh/onions/Palettes.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/Palettes.scala
rename to onions/src/main/scala/net/team2xh/onions/Palettes.scala
diff --git a/src/main/scala/net/team2xh/onions/Symbols.scala b/onions/src/main/scala/net/team2xh/onions/Symbols.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/Symbols.scala
rename to onions/src/main/scala/net/team2xh/onions/Symbols.scala
diff --git a/src/main/scala/net/team2xh/onions/Themes.scala b/onions/src/main/scala/net/team2xh/onions/Themes.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/Themes.scala
rename to onions/src/main/scala/net/team2xh/onions/Themes.scala
diff --git a/src/main/scala/net/team2xh/onions/components/Frame.scala b/onions/src/main/scala/net/team2xh/onions/components/Frame.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/Frame.scala
rename to onions/src/main/scala/net/team2xh/onions/components/Frame.scala
diff --git a/src/main/scala/net/team2xh/onions/components/FramePanel.scala b/onions/src/main/scala/net/team2xh/onions/components/FramePanel.scala
similarity index 98%
rename from src/main/scala/net/team2xh/onions/components/FramePanel.scala
rename to onions/src/main/scala/net/team2xh/onions/components/FramePanel.scala
index 9c0bc6a..889c60c 100644
--- a/src/main/scala/net/team2xh/onions/components/FramePanel.scala
+++ b/onions/src/main/scala/net/team2xh/onions/components/FramePanel.scala
@@ -351,9 +351,9 @@ case class FramePanel(parent: Component)
else " " + ts
if (title != "") {
- screen.put(2, 0, r"[[$title$tabText]", theme)
+ screen.putRichText(2, 0, r"[[$title$tabText]", theme.foreground, theme.background)
} else if (tabText != "") {
- screen.put(2, 0, r"[[$tabText]", theme)
+ screen.putRichText(2, 0, r"[[$tabText]", theme.foreground, theme.background)
}
}
diff --git a/src/main/scala/net/team2xh/onions/components/Widget.scala b/onions/src/main/scala/net/team2xh/onions/components/Widget.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/Widget.scala
rename to onions/src/main/scala/net/team2xh/onions/components/Widget.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/BarChart.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/BarChart.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/BarChart.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/BarChart.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/BigText.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/BigText.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/BigText.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/BigText.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/BitMap.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/BitMap.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/BitMap.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/BitMap.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/CheckBox.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/CheckBox.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/CheckBox.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/CheckBox.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/FontMapper.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/FontMapper.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/FontMapper.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/FontMapper.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/HeatMap.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/HeatMap.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/HeatMap.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/HeatMap.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/Input.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/Input.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/Input.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/Input.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/Label.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/Label.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/Label.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/Label.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/Radio.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/Radio.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/Radio.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/Radio.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/RichLabel.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/RichLabel.scala
similarity index 91%
rename from src/main/scala/net/team2xh/onions/components/widgets/RichLabel.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/RichLabel.scala
index e3b0eb2..f408f85 100644
--- a/src/main/scala/net/team2xh/onions/components/widgets/RichLabel.scala
+++ b/onions/src/main/scala/net/team2xh/onions/components/widgets/RichLabel.scala
@@ -14,7 +14,7 @@ case class RichLabel(parent: FramePanel, text: Varying[RichText])
override def redraw(focus: Boolean, theme: ColorScheme): Unit = {
lines = TextWrap.wrapText(text.value, innerWidth - 1)
for ((line, i) <- lines.zipWithIndex) {
- screen.put(1, i, lines(i), theme)
+ screen.putRichText(1, i, lines(i), theme.foreground, theme.background)
}
}
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/ScatterPlot.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/ScatterPlot.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/ScatterPlot.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/ScatterPlot.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/Separator.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/Separator.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/Separator.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/Separator.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/SevenSegment.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/SevenSegment.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/SevenSegment.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/SevenSegment.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/Slider.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/Slider.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/Slider.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/Slider.scala
diff --git a/src/main/scala/net/team2xh/onions/components/widgets/Spacer.scala b/onions/src/main/scala/net/team2xh/onions/components/widgets/Spacer.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/components/widgets/Spacer.scala
rename to onions/src/main/scala/net/team2xh/onions/components/widgets/Spacer.scala
diff --git a/src/main/scala/net/team2xh/onions/examples/ExampleUI.scala b/onions/src/main/scala/net/team2xh/onions/examples/ExampleUI.scala
similarity index 98%
rename from src/main/scala/net/team2xh/onions/examples/ExampleUI.scala
rename to onions/src/main/scala/net/team2xh/onions/examples/ExampleUI.scala
index 4afec4d..d01d80a 100644
--- a/src/main/scala/net/team2xh/onions/examples/ExampleUI.scala
+++ b/onions/src/main/scala/net/team2xh/onions/examples/ExampleUI.scala
@@ -84,7 +84,7 @@ object ExampleUI extends App {
big.color := color
}
colB.addTab()
- BitMap(colB, "/src/main/scala/net/team2xh/onions/examples/logo.png", relative = true)
+ BitMap(colB, "/onions/src/main/scala/net/team2xh/onions/examples/logo.png", relative = true)
Separator(colB)
Label(colB, "Heat maps blur radius:")
val slider = Slider(colB, 1, 10)(3)
diff --git a/src/main/scala/net/team2xh/onions/examples/logo.png b/onions/src/main/scala/net/team2xh/onions/examples/logo.png
similarity index 100%
rename from src/main/scala/net/team2xh/onions/examples/logo.png
rename to onions/src/main/scala/net/team2xh/onions/examples/logo.png
diff --git a/src/main/scala/net/team2xh/onions/utils/Drawing.scala b/onions/src/main/scala/net/team2xh/onions/utils/Drawing.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/utils/Drawing.scala
rename to onions/src/main/scala/net/team2xh/onions/utils/Drawing.scala
diff --git a/src/main/scala/net/team2xh/onions/utils/Lorem.scala b/onions/src/main/scala/net/team2xh/onions/utils/Lorem.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/utils/Lorem.scala
rename to onions/src/main/scala/net/team2xh/onions/utils/Lorem.scala
diff --git a/src/main/scala/net/team2xh/onions/utils/Math.scala b/onions/src/main/scala/net/team2xh/onions/utils/Math.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/utils/Math.scala
rename to onions/src/main/scala/net/team2xh/onions/utils/Math.scala
diff --git a/src/main/scala/net/team2xh/onions/utils/TextWrap.scala b/onions/src/main/scala/net/team2xh/onions/utils/TextWrap.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/utils/TextWrap.scala
rename to onions/src/main/scala/net/team2xh/onions/utils/TextWrap.scala
diff --git a/src/main/scala/net/team2xh/onions/utils/Varying.scala b/onions/src/main/scala/net/team2xh/onions/utils/Varying.scala
similarity index 100%
rename from src/main/scala/net/team2xh/onions/utils/Varying.scala
rename to onions/src/main/scala/net/team2xh/onions/utils/Varying.scala
diff --git a/readme.md b/readme.md
index fc3413e..a6da54b 100644
--- a/readme.md
+++ b/readme.md
@@ -8,22 +8,21 @@ Terminal drawing API for Scala
- Hello World:
- ```R
- $ sbt
- > run net.team2xh.scurses.examples.HelloWorld
- ```
+```R
+$ sbt "scurses/run-main net.team2xh.scurses.examples.HelloWorld"
+```
+
- Game of life:
- ```R
- $ sbt
- > run net.teamx2h.scurses.examples.GameOfLife
- ```
+```R
+$ sbt scurses/run
+```
+
- Stress test:
- ```R
- $ sbt
- > run net.teamx2h.scurses.examples.StressTest
- ```
+```R
+$ sbt "scurses/run-main net.team2xh.scurses.examples.StressTest"
+```
### How to use
@@ -62,32 +61,61 @@ Scurses framework for easy terminal UI
What's been done so far:
```R
-$ sbt
-> run net.teamx2h.onions.examples.ExampleUI
+$ sbt onions/run
```
Goal is to provide an API full of widgets to make it really easy for users to quickly set up a dashboard to monitor their services in the terminal (graphs, histograms, logs, etc.)
-Currently taking "raw" input from keyboard with JLine, need to find something more powerful to grab inputs like ESC and key combinations, and also detect terminal resize.
-
### How to use
```scala
Scurses { implicit screen =>
val frame = Frame("Example UI")
// Three columns
- val p1 = frame.panel
- val p2 = p1.splitRight
- val p3 = p2.splitRight
- // Split second column in three rows (p2 will point to first row of second column)
- val p22 = p2.splitDown
- val p23 = p22.splitDown
- // Split third row of second column into two columns (p23 will point to the first column of the two)
- val p232 = p23.splitRight
+ val colA = frame.panel
+ val colB = colA.splitRight
+ val colC = colB.splitRight
+ // Split second column in three rows
+ val colB2 = colB.splitDown
+ val colB3 = colB2.splitDown
+ // Split third row of second column into two columns
+ val colB3B = colB3.splitRight
+ val colB3B2 = colB3B.splitDown
// Split last column into two rows
- val p32 = p3.splitDown
+ val colC2 = colC.splitDown
+
+ // Add a label in the first column
+ Label(colA, Lorem.Ipsum, TextWrap.JUSTIFY)
+
+ val r = Random
+ val points = (1 to 50) map (i => {
+ val x = r.nextInt(40)
+ val y = 50 - x + (r.nextGaussian() * 5).toInt - 2
+ (x, y max 0)
+ })
+
+ // Add a scatter plot in the first row of third column
+ ScatterPlot(colC, points, "Time", "Sales")
+
+ // Show a heat map of the same values in the second row
+ HeatMap(colC2, points, "Time", "Sales")
// Display and launch event loop
frame.show()
}
```
+
+For examples about all widgets, see `ExampleUI.scala`
+
+### Keyboard controls
+
+Keys | Action
+:---:|:------
+↑ / ↓ | Focus next widget in direction / Focus next panel in direction
+← / → | Focus next panel in direction
+⇥ / ⇧+⇥ | Focus next / previous panel
+CTRL+SPACE | Switch to next tab (if panel has multiple tabs)
+SPACE / ↵ | Activate label action, check radio or checkbox
+< / > | Move slider left / right (also with SPACE / ↵)
+ESC / CTRL+C | Exit
+
diff --git a/src/main/scala/net/team2xh/scurses/Colors.scala b/scurses/src/main/scala/net/team2xh/scurses/Colors.scala
similarity index 100%
rename from src/main/scala/net/team2xh/scurses/Colors.scala
rename to scurses/src/main/scala/net/team2xh/scurses/Colors.scala
diff --git a/src/main/scala/net/team2xh/scurses/EscapeCodes.scala b/scurses/src/main/scala/net/team2xh/scurses/EscapeCodes.scala
similarity index 100%
rename from src/main/scala/net/team2xh/scurses/EscapeCodes.scala
rename to scurses/src/main/scala/net/team2xh/scurses/EscapeCodes.scala
diff --git a/src/main/scala/net/team2xh/scurses/Keys.scala b/scurses/src/main/scala/net/team2xh/scurses/Keys.scala
similarity index 100%
rename from src/main/scala/net/team2xh/scurses/Keys.scala
rename to scurses/src/main/scala/net/team2xh/scurses/Keys.scala
diff --git a/src/main/scala/net/team2xh/scurses/RichText.scala b/scurses/src/main/scala/net/team2xh/scurses/RichText.scala
similarity index 100%
rename from src/main/scala/net/team2xh/scurses/RichText.scala
rename to scurses/src/main/scala/net/team2xh/scurses/RichText.scala
diff --git a/src/main/scala/net/team2xh/scurses/Scurses.scala b/scurses/src/main/scala/net/team2xh/scurses/Scurses.scala
similarity index 93%
rename from src/main/scala/net/team2xh/scurses/Scurses.scala
rename to scurses/src/main/scala/net/team2xh/scurses/Scurses.scala
index b897e63..edb2fb2 100644
--- a/src/main/scala/net/team2xh/scurses/Scurses.scala
+++ b/scurses/src/main/scala/net/team2xh/scurses/Scurses.scala
@@ -3,7 +3,6 @@ package net.team2xh.scurses
import java.io.BufferedOutputStream
import java.util.{TimerTask, Timer}
-import net.team2xh.onions.Themes.ColorScheme
import net.team2xh.scurses.RichText._
import sun.misc.{SignalHandler, Signal}
@@ -74,12 +73,12 @@ class Scurses {
ec.stopBackground()
}
- def put(x: Int, y: Int, richText: RichText, theme: ColorScheme): Unit = {
+ def putRichText(x: Int, y: Int, richText: RichText, foreground: Int = -1, background: Int = -1): Unit = {
if (outOfBounds(x, y))
return
ec.move(x + offsetX, y + offsetY)
- if (theme.foreground >= 0) ec.setForeground(theme.foreground)
- if (theme.background >= 0) ec.setBackground(theme.background)
+ if (foreground >= 0) ec.setForeground(foreground)
+ if (background >= 0) ec.setBackground(background)
for (instruction <- richText.instructions) {
instruction match {
case Text(text) => out.write(text.getBytes)
@@ -106,8 +105,8 @@ class Scurses {
case Underline => ec.stopUnderline()
case Blink => ec.stopBlink()
case Reverse => ec.stopReverse()
- case Foreground => if (theme.foreground >= 0) ec.setForeground(theme.foreground)
- case Background => if (theme.background >= 0) ec.setBackground(theme.background)
+ case Foreground => if (foreground >= 0) ec.setForeground(foreground)
+ case Background => if (background >= 0) ec.setBackground(background)
case _ =>
}
case ResetAttributes => ec.resetColors()
diff --git a/src/main/scala/net/team2xh/scurses/examples/GameOfLife.scala b/scurses/src/main/scala/net/team2xh/scurses/examples/GameOfLife.scala
similarity index 100%
rename from src/main/scala/net/team2xh/scurses/examples/GameOfLife.scala
rename to scurses/src/main/scala/net/team2xh/scurses/examples/GameOfLife.scala
diff --git a/src/main/scala/net/team2xh/scurses/examples/HelloWorld.scala b/scurses/src/main/scala/net/team2xh/scurses/examples/HelloWorld.scala
similarity index 100%
rename from src/main/scala/net/team2xh/scurses/examples/HelloWorld.scala
rename to scurses/src/main/scala/net/team2xh/scurses/examples/HelloWorld.scala
diff --git a/src/main/scala/net/team2xh/scurses/examples/StressTest.scala b/scurses/src/main/scala/net/team2xh/scurses/examples/StressTest.scala
similarity index 100%
rename from src/main/scala/net/team2xh/scurses/examples/StressTest.scala
rename to scurses/src/main/scala/net/team2xh/scurses/examples/StressTest.scala