From d44012044b1a832120613a49aef607bfb4f3498a Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Fri, 28 Apr 2017 18:13:41 +0100
Subject: [PATCH] [client] Tweak brush indicator, and add keyboard controls

---
 Nibriboard/ClientFiles/BoardWindow.js | 17 +++++++++-
 Nibriboard/ClientFiles/Interface.js   | 49 ++++++++++++++++++++++++---
 Nibriboard/ClientFiles/Nibri.css      | 23 +++++++++++++
 Nibriboard/ClientFiles/Pencil.js      |  5 +--
 Nibriboard/ClientFiles/index.html     |  5 +--
 5 files changed, 90 insertions(+), 9 deletions(-)

diff --git a/Nibriboard/ClientFiles/BoardWindow.js b/Nibriboard/ClientFiles/BoardWindow.js
index e386d7a..8dcb11b 100644
--- a/Nibriboard/ClientFiles/BoardWindow.js
+++ b/Nibriboard/ClientFiles/BoardWindow.js
@@ -95,7 +95,19 @@ class BoardWindow extends EventEmitter
 		this.keyboard.on("keyup-g", (function(event) {
 		    this.displayGrid = this.displayGrid ? false : true;
 			console.info(`[BoardWindow/KeyboardHandler] Grid display set to ${this.displayGrid ? "on" : "off"}`);
-		}).bind(this))
+		}).bind(this));
+		this.keyboard.on("keyup-left", (function(event) {
+		    this.interface.seekColour("backwards");
+		}).bind(this));
+		this.keyboard.on("keyup-right", (function(event) {
+		    this.interface.seekColour("forwards");
+		}).bind(this));
+		this.keyboard.on("keyup-up", (function(event) {
+		    this.interface.updateBrushWidth(this.interface.currentBrushWidth + 2, true);
+		}).bind(this));
+		this.keyboard.on("keyup-down", (function(event) {
+		    this.interface.updateBrushWidth(this.interface.currentBrushWidth - 2, true);
+		}).bind(this));
 		
 		// --~~~--
 		
@@ -149,6 +161,9 @@ class BoardWindow extends EventEmitter
 				InitialAbsCursorPosition: this.cursorPosition
 			});
 		}).bind(this));
+		this.rippleLink.on("disconnect", (function(event) {
+		    this.interface.setConnectedStatus(false);
+		}).bind(this))
 		
 		// Keep the server up to date on our viewport and cursor position
 		this.viewportSyncer = new ViewportSyncer(this.rippleLink, this.cursorUpdateFrequency)
diff --git a/Nibriboard/ClientFiles/Interface.js b/Nibriboard/ClientFiles/Interface.js
index 431a918..10df6c3 100644
--- a/Nibriboard/ClientFiles/Interface.js
+++ b/Nibriboard/ClientFiles/Interface.js
@@ -79,8 +79,18 @@ class Interface extends EventEmitter
 	 */
 	handleSelectColour(event)
 	{
-		delete this.currentColourElement.datasest.selected;
-		this.currentColourElement = event.target;
+		this.switchColourTo(event.target);
+	}
+	
+	/**
+	 * Switches the current colour out to be the colour held by the specified
+	 * colour palette element.
+	 * @param  {HTMLElement} paletteElement The colour palette element to switch to.
+	 */
+	switchColourTo(paletteElement)
+	{
+		delete this.currentColourElement.dataset.selected;
+		this.currentColourElement = paletteElement;
 		this.currentColourElement.dataset.selected = "yes";
 		this.currentColour = this.currentColourElement.style.backgroundColor;
 		
@@ -90,15 +100,46 @@ class Interface extends EventEmitter
 		this.emit("colourchange", { newColour: this.currentColour });
 	}
 	
+	seekColour(direction = "forwards")
+	{
+		var newPaletteElement = null;
+		if(direction == "forwards")
+			newPaletteElement = this.currentColourElement.nextElementSibling || this.currentColourElement.parentElement.firstElementChild;
+		else if(direction == "backwards")
+			newPaletteElement = this.currentColourElement.previousElementSibling || this.currentColourElement.parentElement.lastElementChild;
+		else
+			throw new Error(`Unknown direction ${direction} when switching colour!`);
+		
+		this.switchColourTo(newPaletteElement);
+	}
+	
 	/**
 	 * Handles brush widdth changes requested by the user
 	 */
 	handleBrushWidthChange(event)
 	{
-		this.currentBrushWidth = parseInt(event.target.value);
+		// Update the brush width, but don't update the interface, since that's where we got the new value from :P
+		this.updateBrushWidth(parseInt(event.target.value, false));
+	}
+	
+	/**
+	 * Sets the brush width to the specified value, updating everyone else
+	 * on the change.
+	 * @param  {number} newWidth The new width of the brush.
+	 */
+	updateBrushWidth(newWidth, updateInterface = true)
+	{
+		// Clamp the new width to make sure it's in-bounds
+		if(newWidth < 1) newWidth = 1;
+		if(newWidth > parseInt(this.brushWidthElement.max)) newWidth = parseInt(this.brushWidthElement.max);
 		
+		this.currentBrushWidth = newWidth; // Store the new value
+		if(updateInterface)
+			this.brushWidthElement.value = newWidth; // Update the interface
+		
+		// Update the brush indicator
 		this.updateBrushIndicator();
-		
+		// Emit the brush width change event
 		this.emit("brushwidthchange", { newWidth: this.currentLineWidth });
 	}
 	
diff --git a/Nibriboard/ClientFiles/Nibri.css b/Nibriboard/ClientFiles/Nibri.css
index 681e7fa..fde9cdc 100644
--- a/Nibriboard/ClientFiles/Nibri.css
+++ b/Nibriboard/ClientFiles/Nibri.css
@@ -4,6 +4,13 @@ body
     font-family: sans-serif;
 }
 
+hr
+{
+    width: 80%; height: 0;
+    border: 0;
+    border-top: 0.1em solid hsl(237, 48%, 47%);
+}
+
 #canvas-main
 {
     position: absolute;
@@ -58,8 +65,23 @@ body
     border-top: 0.2em solid rgba(255, 255, 255, 0.3);
 }
 
+.brush-settings
+{
+    display: flex; flex-direction: column;
+    min-height: 5em;
+}
+
+.brush-preview-display
+{
+    flex: 1;
+}
+
 .brush-indicator
 {
+    position: relative;
+    top: 50%; left: 50%; transform: translate(-50%, -50%);
+    
+    margin: 1em 0 0 0;
     border-radius: 50%;
 }
 
@@ -82,6 +104,7 @@ body
 {
     float: left;
     width: 50%; height: 3em;
+    box-sizing: border-box;
     
     cursor: pointer;
 }
diff --git a/Nibriboard/ClientFiles/Pencil.js b/Nibriboard/ClientFiles/Pencil.js
index 3c75aa6..edab1ad 100644
--- a/Nibriboard/ClientFiles/Pencil.js
+++ b/Nibriboard/ClientFiles/Pencil.js
@@ -69,9 +69,10 @@ class Pencil
 		if(this.boardWindow.keyboard.DownKeys.includes(17))
 			return;
 		
+		// The server only supports ints atm, so we have to round here :-(
 		var nextPoint = new Vector(
-			event.clientX + this.boardWindow.viewport.x,
-			event.clientY + this.boardWindow.viewport.y
+			Math.floor(event.clientX + this.boardWindow.viewport.x),
+			Math.floor(event.clientY + this.boardWindow.viewport.y)
 		);
 		this.unsentSegments.push(nextPoint);
 		this.currentLineSegments.push(nextPoint);
diff --git a/Nibriboard/ClientFiles/index.html b/Nibriboard/ClientFiles/index.html
index 48ba1b7..d5ae8e6 100644
--- a/Nibriboard/ClientFiles/index.html
+++ b/Nibriboard/ClientFiles/index.html
@@ -15,8 +15,9 @@
 			<hr />
 			
 			<section class="brush-settings">
-				<div class="brush-indicator"></div>
-				
+				<div class="brush-preview-display">
+					<div class="brush-indicator"></div>
+				</div>
 				<input type="range" min="1" max="30" step="0.1" class="brush-width-controls" />
 			</section>
 			
