« get me outta code hell

A long-due cleanup + examples + things - tui-lib - Pure Node.js library for making visual command-line programs (ala vim, ncdu)
about summary refs log tree commit diff
path: root/examples
diff options
context:
space:
mode:
authorliam4 <towerofnix@gmail.com>2017-07-03 18:59:57 -0300
committerliam4 <towerofnix@gmail.com>2017-07-03 19:00:01 -0300
commit769413468e88acba1a180baa0113139d929a3b9f (patch)
treef29af36826077178259b7bcc8bf9927cebfe71e3 /examples
parent489e4d0c78d5f393729cda0e1f6ac9a0a1237b4a (diff)
A long-due cleanup + examples + things
..Obviously this breaks old things (particularly, see changes in
FocusElement).
Diffstat (limited to 'examples')
-rw-r--r--examples/basic-app.js51
-rw-r--r--examples/interfacer-command-line.js24
-rw-r--r--examples/interfacer-telnet.js56
-rw-r--r--examples/label.js22
4 files changed, 153 insertions, 0 deletions
diff --git a/examples/basic-app.js b/examples/basic-app.js
new file mode 100644
index 0000000..bf8aa41
--- /dev/null
+++ b/examples/basic-app.js
@@ -0,0 +1,51 @@
+// Basic app demo:
+// - Structuring a basic element tree
+// - Creating a pane and text input
+// - Using content width/height to layout elements
+// - Subclassing a FocusElement and using its focused method
+// - Sending a quit-app request via Control-C
+//
+// This script cannot actually be used on its own; see the examples on
+// interfacers (interfacer-command-line.js and inerfacer-telnet.js) for a
+// working demo.
+
+const Pane = require('../ui/Pane')
+const FocusElement = require('../ui/form/FocusElement')
+const TextInput = require('../ui/form/TextInput')
+
+module.exports = class AppElement extends FocusElement {
+  constructor() {
+    super()
+
+    this.pane = new Pane()
+    this.addChild(this.pane)
+
+    this.textInput = new TextInput()
+    this.pane.addChild(this.textInput)
+  }
+
+  fixLayout() {
+    this.w = this.parent.contentW
+    this.h = this.parent.contentH
+
+    this.pane.w = this.contentW
+    this.pane.h = this.contentH
+
+    this.textInput.x = 4
+    this.textInput.y = 2
+    this.textInput.w = this.pane.contentW - 8
+  }
+
+  focused() {
+    this.root.select(this.textInput)
+  }
+
+  keyPressed(keyBuf) {
+    if (keyBuf[0] === 0x03) { // 0x03 is Control-C
+      this.emit('quitRequested')
+      return 
+    }
+
+    super.keyPressed(keyBuf)
+  }
+}
diff --git a/examples/interfacer-command-line.js b/examples/interfacer-command-line.js
new file mode 100644
index 0000000..1da6adf
--- /dev/null
+++ b/examples/interfacer-command-line.js
@@ -0,0 +1,24 @@
+const Root = require('../ui/Root')
+const CommandLineInterfacer = require('../util/CommandLineInterfacer')
+const AppElement = require('./basic-app')
+
+const interfacer = new CommandLineInterfacer()
+
+interfacer.getScreenSize().then(size => {
+  const root = new Root(interfacer)
+  root.w = size.width
+  root.h = size.height
+
+  const appElement = new AppElement()
+  root.addChild(appElement)
+  root.select(appElement)
+
+  appElement.on('quitRequested', () => {
+    process.exit(0)
+  })
+
+  setInterval(() => root.render(), 100)
+}).catch(error => {
+  console.error(error)
+  process.exit(1)
+})
diff --git a/examples/interfacer-telnet.js b/examples/interfacer-telnet.js
new file mode 100644
index 0000000..8cb804b
--- /dev/null
+++ b/examples/interfacer-telnet.js
@@ -0,0 +1,56 @@
+// Telnet demo:
+// - Basic telnet socket handling using the TelnetInterfacer
+// - Handling client's screen size
+// - Handling socket being closed by client
+// - Handling cleanly closing the socket by hand
+
+const net = require('net')
+const Root = require('../ui/Root')
+const TelnetInterfacer = require('../TelnetInterfacer')
+const AppElement = require('./basic-app')
+
+const server = new net.Server(socket => {
+  const interfacer = new TelnetInterfacer(socket)
+
+  interfacer.getScreenSize().then(size => {
+    const root = new Root(interfacer)
+    root.w = size.width
+    root.h = size.height
+
+    interfacer.on('screenSizeUpdated', newSize => {
+      root.w = newSize.width
+      root.h = newSize.height
+      root.fixAllLayout()
+    })
+
+    const appElement = new AppElement()
+    root.addChild(appElement)
+    root.select(appElement)
+
+    let closed = false
+
+    appElement.on('quitRequested', () => {
+      if (!closed) {
+        interfacer.cleanTelnetOptions()
+        socket.write('Goodbye!\n')
+        socket.end()
+        clearInterval(interval)
+        closed = true
+      }
+    })
+
+    socket.on('close', () => {
+      if (!closed) {
+        clearInterval(interval)
+        closed = true
+      }
+    })
+
+    const interval = setInterval(() => root.render(), 100)
+  }).catch(error => {
+    console.error(error)
+    process.exit(1)
+  })
+})
+
+server.listen(8008)
diff --git a/examples/label.js b/examples/label.js
new file mode 100644
index 0000000..b8992d2
--- /dev/null
+++ b/examples/label.js
@@ -0,0 +1,22 @@
+// An example of basic label usage.
+
+const ansi = require('../util/ansi')
+const Label = require('../ui/Label')
+
+const label1 = new Label('Hello, world!')
+const label2 = new Label('I love labels.')
+
+label1.x = 3
+label1.y = 2
+
+label2.x = label1.x
+label2.y = label1.y + 1
+
+process.stdout.write(ansi.clearScreen())
+label1.drawTo(process.stdout)
+label2.drawTo(process.stdout)
+
+process.stdin.once('data', () => {
+  process.stdout.write(ansi.clearScreen())
+  process.exit(0)
+})