commit:681674186038002a222a3ea5c101f6b06b180887
author:Chip Black
committer:Chip Black
date:Tue Oct 20 00:48:05 2015 -0500
parents:4dca643fd17e3dfc51ac66c04e6fee5c704103b1
Add more palettes and palette editing
diff --git a/src/Palette.js b/src/Palette.js
line changes: +219/-19
index 6ec4287..1917f64
--- a/src/Palette.js
+++ b/src/Palette.js
@@ -1,7 +1,19 @@
 import Controller from './Controller.js';
 
-var palettes = [
-    [   // Palette 0 - VGA
+const palette_names = [
+    "EGA 16-color",
+    "Gray/RGB",
+    "Red/Blue/Yellow",
+    "Purple/Orange/Green",
+    "Red/Green",
+    "Orange/Blue",
+    "Yellow/Purple",
+    "Red",
+    "Green",
+    "Blue",
+];
+const palettes = [
+    [   // Palette 0 - EGA 16-color
         [0x00, 0x00, 0x00], // black
         [0x00, 0x00, 0xAA], // blue
         [0x00, 0xAA, 0x00], // green
@@ -19,23 +31,167 @@ var palettes = [
         [0xFF, 0xFF, 0x55], // bright yellow
         [0xFF, 0xFF, 0xFF], // white
     ],
-    [   // Palette 1 - Perceptual RGB
-        [0x1F, 0x1F, 0x1F],
-        [0x5D, 0x5D, 0x5D],
-        [0x8C, 0x8C, 0x8C],
-        [0xD9, 0xD9, 0xD9],
-        [0x62, 0x00, 0x00],
-        [0x80, 0x00, 0x00],
-        [0xB0, 0x00, 0x00],
-        [0xDE, 0x00, 0x00],
-        [0x00, 0x54, 0x00],
-        [0x00, 0x73, 0x00],
-        [0x00, 0xA6, 0x00],
-        [0x00, 0xD4, 0x00],
-        [0x00, 0x00, 0x8C],
-        [0x00, 0x00, 0xB6],
-        [0x00, 0x00, 0xDC],
-        [0x28, 0x28, 0xFF],
+    [   // Palette 1 - Gray4/R4/G4/B4
+        [0x00, 0x00, 0x00],
+        [0x3B, 0x3B, 0x3B],
+        [0x76, 0x76, 0x76],
+        [0xB8, 0xB8, 0xB8],
+        [0x68, 0x00, 0x00],
+        [0x9E, 0x00, 0x00],
+        [0xD7, 0x00, 0x00],
+        [0xFE, 0x41, 0x41],
+        [0x00, 0x39, 0x00],
+        [0x00, 0x59, 0x00],
+        [0x00, 0x7C, 0x00],
+        [0x00, 0xA0, 0x00],
+        [0x00, 0x2B, 0x71],
+        [0x00, 0x46, 0xAA],
+        [0x00, 0x61, 0xE7],
+        [0x54, 0x83, 0xFE],
+    ],
+    [   // Palette 2 - Black/R5/B5/Yellow5
+        [0x00, 0x00, 0x00],
+        [0x54, 0x00, 0x00],
+        [0x7D, 0x00, 0x00],
+        [0xA9, 0x00, 0x00],
+        [0xD7, 0x00, 0x00],
+        [0xFE, 0x27, 0x28],
+        [0x00, 0x22, 0x5B],
+        [0x00, 0x36, 0x87],
+        [0x00, 0x4B, 0xB6],
+        [0x00, 0x61, 0xE7],
+        [0x44, 0x7C, 0xFE],
+        [0x43, 0x43, 0x00],
+        [0x70, 0x70, 0x00],
+        [0xA1, 0xA1, 0x00],
+        [0xD4, 0xD5, 0x00],
+        [0xFF, 0xFE, 0xFE],
+    ],
+    [   // Palette 3 - Black/Purple5/Orange5/Green5
+        [0x00, 0x00, 0x00],
+        [0x4B, 0x00, 0x43],
+        [0x70, 0x00, 0x65],
+        [0x98, 0x00, 0x89],
+        [0xC1, 0x00, 0xAF],
+        [0xED, 0x00, 0xD6],
+        [0x48, 0x2D, 0x00],
+        [0x73, 0x4B, 0x00],
+        [0xA2, 0x6B, 0x00],
+        [0xD2, 0x8D, 0x00],
+        [0xFF, 0xB2, 0x48],
+        [0x00, 0x2D, 0x00],
+        [0x00, 0x46, 0x00],
+        [0x00, 0x60, 0x00],
+        [0x00, 0x7C, 0x00],
+        [0x00, 0x99, 0x00],
+    ],
+    [   // Palette 4 - Red/Green
+        [0x41, 0x00, 0x00],
+        [0x68, 0x00, 0x00],
+        [0x7D, 0x00, 0x00],
+        [0x93, 0x00, 0x00],
+        [0xA9, 0x00, 0x00],
+        [0xC0, 0x00, 0x00],
+        [0xD7, 0x00, 0x00],
+        [0xEF, 0x00, 0x00],
+        [0x00, 0x21, 0x00],
+        [0x00, 0x39, 0x00],
+        [0x00, 0x46, 0x00],
+        [0x00, 0x53, 0x00],
+        [0x00, 0x60, 0x00],
+        [0x00, 0x6E, 0x00],
+        [0x00, 0x7C, 0x00],
+        [0x00, 0x8A, 0x00],
+    ],
+    [   // Palette 5 - Orange/Blue
+        [0x48, 0x2D, 0x00],
+        [0x5D, 0x3C, 0x00],
+        [0x73, 0x4B, 0x00],
+        [0x8A, 0x5B, 0x00],
+        [0xA2, 0x6B, 0x00],
+        [0xBA, 0x7B, 0x00],
+        [0xD2, 0x8D, 0x00],
+        [0xEC, 0x9E, 0x00],
+        [0x00, 0x22, 0x5B],
+        [0x00, 0x2B, 0x71],
+        [0x00, 0x36, 0x87],
+        [0x00, 0x40, 0x9E],
+        [0x00, 0x4B, 0xB6],
+        [0x00, 0x56, 0xCE],
+        [0x00, 0x61, 0xE7],
+        [0x0D, 0x6D, 0xFE],
+    ],
+    [   // Palette 6 - Yellow/Purple
+        [0x2E, 0x2E, 0x00],
+        [0x59, 0x59, 0x00],
+        [0x70, 0x70, 0x00],
+        [0x88, 0x88, 0x00],
+        [0xA1, 0xA1, 0x00],
+        [0xBA, 0xBB, 0x00],
+        [0xD4, 0xD5, 0x00],
+        [0xEF, 0xEF, 0x00],
+        [0x39, 0x00, 0x33],
+        [0x5D, 0x00, 0x53],
+        [0x70, 0x00, 0x65],
+        [0x83, 0x00, 0x77],
+        [0x98, 0x00, 0x89],
+        [0xAC, 0x00, 0x9C],
+        [0xC1, 0x00, 0xAF],
+        [0xD7, 0x00, 0xC2],
+    ],
+    [   // Palette 7 - Red
+        [0x22, 0x00, 0x00],
+        [0x32, 0x00, 0x00],
+        [0x3E, 0x00, 0x00],
+        [0x4A, 0x00, 0x00],
+        [0x56, 0x00, 0x00],
+        [0x63, 0x00, 0x00],
+        [0x70, 0x00, 0x00],
+        [0x7D, 0x00, 0x00],
+        [0x8B, 0x00, 0x00],
+        [0x98, 0x00, 0x00],
+        [0xA6, 0x00, 0x00],
+        [0xB4, 0x00, 0x00],
+        [0xC3, 0x00, 0x00],
+        [0xD1, 0x00, 0x00],
+        [0xE0, 0x00, 0x00],
+        [0xEF, 0x00, 0x00],
+    ],
+    [   // Palette 8 - Green
+        [0x00, 0x0F, 0x00],
+        [0x00, 0x18, 0x00],
+        [0x00, 0x20, 0x00],
+        [0x00, 0x27, 0x00],
+        [0x00, 0x2E, 0x00],
+        [0x00, 0x36, 0x00],
+        [0x00, 0x3E, 0x00],
+        [0x00, 0x46, 0x00],
+        [0x00, 0x4E, 0x00],
+        [0x00, 0x56, 0x00],
+        [0x00, 0x5F, 0x00],
+        [0x00, 0x67, 0x00],
+        [0x00, 0x70, 0x00],
+        [0x00, 0x78, 0x00],
+        [0x00, 0x81, 0x00],
+        [0x00, 0x8A, 0x00],
+    ],
+    [   // Palette 9 - Blue
+        [0x00, 0x09, 0x25],
+        [0x00, 0x11, 0x37],
+        [0x00, 0x17, 0x44],
+        [0x00, 0x1D, 0x50],
+        [0x00, 0x23, 0x5E],
+        [0x00, 0x29, 0x6B],
+        [0x00, 0x2F, 0x79],
+        [0x00, 0x36, 0x87],
+        [0x00, 0x3C, 0x95],
+        [0x00, 0x43, 0xA4],
+        [0x00, 0x4A, 0xB3],
+        [0x00, 0x51, 0xC2],
+        [0x00, 0x58, 0xD1],
+        [0x00, 0x5F, 0xE1],
+        [0x00, 0x66, 0xF1],
+        [0x0D, 0x6D, 0xFE],
     ],
 ]
 
@@ -49,6 +205,7 @@ export default class Palette extends Controller {
             if (c.className == 'swatch') {
                 let n = this.swatches.length;
                 c.addEventListener('mousedown', event => this.selectColor(n))
+                c.addEventListener('dblclick', event => this.editColor(n));
                 this.swatches.push(c);
             }
         }
@@ -63,6 +220,7 @@ export default class Palette extends Controller {
         for (i = 0; i < 16; i++) {
             this.swatches[i].style.backgroundColor = 'rgb(' + p[i][0] + ',' + p[i][1] + ',' + p[i][2] + ')';
         }
+        document.getElementById('palette-id').textContent = palette_names[n];
     }
     nextPalette() {
         this.selectPalette((this.palette + 1) % palettes.length);
@@ -100,4 +258,46 @@ export default class Palette extends Controller {
 
         return closest;
     }
+    editColor(n) {
+        let colorpicker = document.getElementById('dialog-colorpicker');
+        colorpicker.style.display = null;
+        let colorpicker_color = document.getElementById('colorpicker-color');
+        let colorpicker_red = document.getElementById('colorpicker-red');
+        let colorpicker_green = document.getElementById('colorpicker-green');
+        let colorpicker_blue = document.getElementById('colorpicker-blue');
+        let colorpicker_ok = document.getElementById('colorpicker-ok');
+        let colorpicker_cancel = document.getElementById('colorpicker-cancel');
+
+        let currentPalette = this.palette;
+        colorpicker_red.value = palettes[currentPalette][n][0];
+        colorpicker_green.value = palettes[currentPalette][n][1];
+        colorpicker_blue.value = palettes[currentPalette][n][2];
+
+        let changefunc = () => {
+            let r = colorpicker_red.value;
+            let g = colorpicker_green.value;
+            let b = colorpicker_blue.value;
+            colorpicker_color.style.backgroundColor = 'rgb(' + r + ',' + g + ',' + b + ')';
+        };
+        colorpicker_red.onkeyup = changefunc;
+        colorpicker_green.onkeyup = changefunc;
+        colorpicker_blue.onkeyup = changefunc;
+        changefunc();
+
+        colorpicker_cancel.onclick = () => {
+            colorpicker.style.display = 'none';
+        }
+
+        colorpicker_ok.onclick = () => {
+            palette_names[currentPalette] = "Custom " + n;
+            let r = colorpicker_red.value;
+            let g = colorpicker_green.value;
+            let b = colorpicker_blue.value;
+            palettes[currentPalette][n] = [r, g, b];
+            this.selectPalette(currentPalette);
+            this.state.pixelEditor.redraw();
+            this.state.pixelEditor.refresh();
+            colorpicker.style.display = 'none';
+        }
+    }
 }

diff --git a/src/index.html b/src/index.html
line changes: +17/-0
index e433395..20e3b90
--- a/src/index.html
+++ b/src/index.html
@@ -39,6 +39,7 @@
         <button onclick="prevPalette()">&larr;</button>
         <button onclick="nextPalette()">&rarr;</button>
       </div>
+      <div id="palette-id"></div>
       <div class="palette" id="palette">
         <div class="swatch"></div>
         <div class="swatch"></div>
@@ -67,5 +68,21 @@
   </div>
 </div>
 
+<div class="dialog" id="dialog-colorpicker" style="display: none">
+  <h2>Edit Color</h2>
+  <div class="content">
+    <div id="colorpicker-color"></div>
+    <div class="colorpicker-values">
+      <div>Red: <input id="colorpicker-red" type="text" size="3"></div>
+      <div>Green: <input id="colorpicker-green" type="text" size="3"></div>
+      <div>Blue: <input id="colorpicker-blue" type="text" size="3"></div>
+    </div>
+  </div>
+  <div class="controls">
+    <button id="colorpicker-cancel">Cancel</button>
+    <button id="colorpicker-ok">OK</button>
+  </div>
+</div>
+
 <iframe id="saver"></iframe>
 <input id="loader" type="file">

diff --git a/src/main.js b/src/main.js
line changes: +3/-1
index e66a2d3..3e6c195
--- a/src/main.js
+++ b/src/main.js
@@ -28,9 +28,11 @@ window.loadFile = function loadFile() {
         let img = document.createElement('img');
         img.src = url;
         img.onload = function() {
+            URL.revokeObjectURL(url);
             appState.pixelEditor.loadFromImage(img);
         };
         img.onerror = function() {
+            URL.revokeObjectURL(url);
             alert("This doesn't appear to be an image");
         };
     };
@@ -43,7 +45,7 @@ window.nextPalette = function() {
 }
 
 window.prevPalette = function() {
-    appState.palette.nextPalette();
+    appState.palette.prevPalette();
     appState.pixelEditor.paletteChanged();
 }
 

diff --git a/src/style.css b/src/style.css
line changes: +63/-2
index 4c76b88..f44c7e7
--- a/src/style.css
+++ b/src/style.css
@@ -1,13 +1,14 @@
 body {
 	background-color: black;
 	color: white;
+	font-family: monospace;
+	font-size: 14px;
 }
 
 button {
 	border: 1px solid white;
 	background-color: black;
 	color: white;
-	display: block;
 	margin: 2px;
 }
 
@@ -107,7 +108,15 @@ button.active {
 
 .palette-switch button {
 	width: 48px;
-	height: 48px;
+	height: 32px;
+}
+
+#palette-id {
+	width: 96px;
+	padding: 4px 0;
+	font-family: monospace;
+	font-size: 12px;
+	text-align: center;
 }
 
 .palette {
@@ -144,6 +153,58 @@ button.active {
 	flex: none;
 }
 
+.dialog {
+	position: absolute;
+	width: 50%;
+	min-width: 320px;
+	max-width: 480px;
+	height: 50%;
+	min-height: 160px;
+	left: 0;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	margin: auto;
+
+	background-color: black;
+	border: 2px solid white;
+	padding: 8px;
+
+	display: flex;
+	flex-flow: column;
+}
+
+.dialog h2 {
+	margin: 0 0 8px 0;
+	font-size: 16px;
+}
+
+.dialog .content {
+	flex: auto;
+}
+
+.dialog .controls {
+	text-align: right;
+}
+
+.dialog .controls buttons {
+	margin: 0;
+}
+
+#dialog-colorpicker .content {
+	display: flex;
+	flex-flow: row;
+}
+
+#colorpicker-color {
+	width: 96px;
+}
+
+.colorpicker-values {
+	display: flex;
+	flex-flow: column;
+}
+
 #saver, #loader {
 	width: 0;
 	height: 0;