From 19ff6ddcaa0e64b9a8c8003402c8b4c3c6417d45 Mon Sep 17 00:00:00 2001
From: Devine Lu Linvega <aliceffekt@gmail.com>
Date: Mon, 20 Nov 2017 17:37:02 +1300
Subject: [PATCH] Implemented globals for scale and color

---
 BUILD.md                          |  6 +++-
 README.md                         |  9 +++--
 main.js                           |  2 +-
 sources/links/main.css            |  7 ++--
 sources/scripts/core/commander.js |  4 ++-
 sources/scripts/core/cursor.js    | 60 +++++++++++++++++++++++++++----
 sources/scripts/core/docs.js      | 12 ++++---
 sources/scripts/core/hint.js      |  4 +--
 sources/scripts/core/keyboard.js  | 11 ++++++
 sources/scripts/layers/guide.js   | 20 +++++++++--
 sources/scripts/modules/brush.js  |  3 +-
 sources/scripts/modules/filter.js |  2 +-
 sources/scripts/modules/path.js   |  2 +-
 sources/scripts/ronin.js          |  1 +
 14 files changed, 114 insertions(+), 29 deletions(-)

diff --git a/BUILD.md b/BUILD.md
index ccd9401..c92f180 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -32,4 +32,8 @@ rm -r /xxiivv/Nataniev/public/public.projects/builds/Ronin-linux-x64/
 rm -r /xxiivv/Nataniev/public/public.projects/builds/Ronin-win32-x64/
 
 ~/butler status hundredrabbits/ronin
-```
\ No newline at end of file
+```
+
+### Etcs.
+
+`var angleDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;`
\ No newline at end of file
diff --git a/README.md b/README.md
index fabe2b1..6d6d9b5 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,12 @@ Ronin is a simple open-source graphic design tool.
 <img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/PREVIEW.jpg' width='600'/>
 
 ## Cursor
-- `$` replace with **Pos**.
-- `$+shift` replace with **Rect**.
+Include `$` in a query and click on the canvas to inject the cursor position in the query.
+- `$ click` inject a **Pos**.
+- `$+ click` inject a **Pos**, and append `$+` for multiple positions.
+- `$ shift click` inject a **Rect**.
 
+- `#$ click` inject a **Color**.
 ## Modules
 ## brush
 
@@ -62,7 +65,7 @@ Pixel filter
 
 ### Methods
 - `balance:#ff0033` Filter color balance.
-- `saturation:0.5,0.5` Filter color saturation.
+- `saturation:#ff00333` Filter color saturation.
 
 ## type
 
diff --git a/main.js b/main.js
index 30cae61..1883ce5 100644
--- a/main.js
+++ b/main.js
@@ -56,7 +56,7 @@ app.on('ready', () =>
     is_shown = true;
   })
   // Open the DevTools.
-  win.webContents.openDevTools()
+  // win.webContents.openDevTools()
 })
 
 app.on('window-all-closed', () => 
diff --git a/sources/links/main.css b/sources/links/main.css
index 1f1cf51..6375c33 100644
--- a/sources/links/main.css
+++ b/sources/links/main.css
@@ -1,7 +1,7 @@
 body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_medium",courier,monospace; background:red;}
 *:focus {outline: none; }
 
-* { cursor: none }
+canvas { cursor: none }
 
 yu { display:block; }
 
@@ -12,7 +12,7 @@ yu { display:block; }
 #grid { z-index:795;position: fixed; }
 
 #ronin { background:#eee; height: 100vh; width:100vw; }
-#commander, #hint { position: fixed;bottom: 0px;left: 0px;width: 100vw;line-height: 40px;-webkit-user-select: none;-webkit-app-region: drag;z-index: 900;height: 40px; font-size:11px;}
+#commander, #hint { position: fixed;bottom: 0px;left: 0px;width: 100vw;line-height: 40px;-webkit-user-select: none;-webkit-app-region: drag;z-index: 900;height: 40px; font-size:11px; cursor: default;}
 #commander { z-index: 9000; background:black; }
 #commander input { background: transparent;width: calc(100vw - 30px);display: block;line-height: 40px;font-size: 11px;color: white; margin-left:20px;    z-index: 9000;position: relative; }
 #hint {  color:#666; padding-left:20px;}
@@ -20,4 +20,5 @@ yu { display:block; }
 #hint i { font-style: italic; }
 #hint .autocomplete { background:white; color:black; }
 
-#cursor_hint { position: absolute;top: 0px;right: 20px;color: white; font-family: courier; padding: 0px 10px; }
\ No newline at end of file
+#cursor_hint { position: absolute;top: 0px;right: 20px;color: white; padding: 0px 10px; color:#555; font-size:11px; text-transform: uppercase; }
+#cursor_hint .mode {}
\ No newline at end of file
diff --git a/sources/scripts/core/commander.js b/sources/scripts/core/commander.js
index 91b8ec9..dd97536 100644
--- a/sources/scripts/core/commander.js
+++ b/sources/scripts/core/commander.js
@@ -68,14 +68,16 @@ function Commander()
 
   this.autocomplete = function()
   {
+
     var target_module = ronin.commander.query().module;
 
     var ac = ronin.modules[target_module] ? ronin.hint.find_autocomplete(ronin.modules[target_module].methods,":") : ronin.hint.find_autocomplete(ronin.modules," ")
 
+    this.focus();
     if(ac.lenght < 1 || !ac[0]){ return; }
+    if(ronin.commander.query().string.length < 1){ return; }
 
     this.append(ac[0]);
-    this.focus();
   }
 
   this.on_input = function(e)
diff --git a/sources/scripts/core/cursor.js b/sources/scripts/core/cursor.js
index 3fee7aa..a48276e 100644
--- a/sources/scripts/core/cursor.js
+++ b/sources/scripts/core/cursor.js
@@ -8,7 +8,7 @@ function Cursor(rune)
   this.query = null;
   this.mode = "vertex";
 
-  this.color = "#f0f"
+  this.color = "#f00"
   this.size = 4;
 
   this.draw_cursor = function(pos,touch = false)
@@ -35,6 +35,14 @@ function Cursor(rune)
 
     var pos = ronin.magnet.filter({x:e.clientX,y:e.clientY});
 
+    // Color Pick
+    if(ronin.commander.input_el.value == "~"){
+      ronin.brush.methods.pick.run({x:pos.x,y:pos.y})
+      ronin.commander.input_el.value = "";
+      ronin.commander.update();
+      return;
+    }
+
     ronin.cursor.draw_cursor({x:pos.x,y:pos.y},true);
 
     ronin.cursor.line.origin = {x:pos.x,y:pos.y};
@@ -43,6 +51,10 @@ function Cursor(rune)
     // Save original query
     ronin.cursor.query = ronin.commander.input_el.value;
 
+    if(e.altKey && e.shiftKey){
+      ronin.brush.methods.pick.run(pos);
+    }
+
     if(e.shiftKey){ ronin.cursor.mode = "rect"; }
     if(e.altKey){ ronin.cursor.mode = "arc_to"; }
     if(e.ctrlKey){ ronin.cursor.mode = "cc_arc_to"; }
@@ -63,8 +75,8 @@ function Cursor(rune)
     if(ronin.commander.active_module()){
 
     }
-    else if(e.shiftKey && e.altKey){
-      ronin.brush.pick(ronin.cursor.line);
+    else if(e.altKey && e.shiftKey){
+      ronin.brush.methods.pick.run(pos);
     }
     else if(e.altKey){
       ronin.brush.erase(ronin.cursor.line);
@@ -137,16 +149,50 @@ function Cursor(rune)
       str = "@<"+b.x+","+b.y;
     }
     // 
-    var i = ronin.cursor.query.indexOf("$");
-    var i1 = ronin.cursor.query.substr(i,2);
-    if(i1 == "$+"){
+    var i = ronin.cursor.query ? ronin.cursor.query.indexOf("$") : '';
+    var i1 = ronin.cursor.query ? ronin.cursor.query.substr(i,2) : '';
+    var e1 = ronin.cursor.query ? ronin.cursor.query.substr(i-1,2) : '';
+
+    if(e1 == "#$"){
+      var r = parseInt((b.x/ronin.frame.width) * 255);
+      var g = 255 - parseInt((b.x/ronin.frame.width) * 255);
+      var b = parseInt((b.y/ronin.frame.height) * 255);
+      var str = new Color().rgb_to_hex([r,g,b]);
+      ronin.commander.inject(ronin.cursor.query.replace("#$",str+" "));
+    }
+    else if(i1 == "$+"){
       ronin.commander.inject(ronin.cursor.query.replace("$+",str+"&$+"));
     }
-    else{
+    else if(ronin.cursor.query){
       ronin.commander.inject(ronin.cursor.query.replace("$",str));
     }
   }
 
+  this.hint = function()
+  {
+    var html = "";
+
+    var mode = "PAINT";
+
+    if(ronin.commander.input_el.value.indexOf("$+") > -1){
+      mode = "[MULTI]POS/SHIFT-RECT"
+    }
+    else if(ronin.commander.input_el.value.indexOf("$") > -1){
+      mode = "POS/SHIFT-RECT"
+    }
+    else if(ronin.keyboard.is_down["Alt"] && ronin.keyboard.is_down["Shift"]){
+      mode = "PICK";
+    }
+    else if(ronin.keyboard.is_down["Alt"]){
+      mode = "ERASE";
+    }
+    else if(ronin.keyboard.is_down["Shift"]){
+      mode = "DRAG";
+    }
+
+    return "<t class='mode'>"+mode+"</t><t class='size'>"+ronin.cursor.size+"</t> <t class='color' style='color:"+ronin.cursor.color+"'>●</t>";
+  }
+
   function distance_between(a,b)
   {
     return Math.sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
diff --git a/sources/scripts/core/docs.js b/sources/scripts/core/docs.js
index 97fc770..f3cb977 100644
--- a/sources/scripts/core/docs.js
+++ b/sources/scripts/core/docs.js
@@ -5,9 +5,13 @@ function Docs()
     var html = "";
 
     html += this.print_intro();
+
     html += "## Cursor\n";
-    html += "- `$` replace with **Pos**.\n";
-    html += "- `$+shift` replace with **Rect**.\n\n";
+    html += "Include `$` in a query and click on the canvas to inject the cursor position in the query.\n";
+    html += "- `$ click` inject a **Pos**.\n";
+    html += "- `$+ click` inject a **Pos**, and append `$+` for multiple positions.\n";
+    html += "- `$ shift click` inject a **Rect**.\n\n";
+    html += "- `#$ click` inject a **Color**.\n";
     
     html += "## Modules\n";
     html += this.print_modules(ronin.modules);
@@ -23,7 +27,7 @@ function Docs()
   this.print_intro = function()
   {
     html = "# Ronin\n";
-    html += "Ronin is a simple open-source graphic design tool.\n\n";
+    html += "Ronin is a graphic design tool, to paint, resize and export graphics.\n\n";
     html += "<img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/PREVIEW.jpg' width='600'/>\n\n";
     return html;
   }
@@ -55,7 +59,7 @@ function Docs()
   this.print_license = function()
   {
     html = "## License\n";
-    html += "See the [LICENSE](LICENSE.md) file for license rights and limitations (CC).\n";
+    html += "See the [LICENSE](LICENSE.md) file for license rights and limitations.\n";
     return html;
   }
 }
\ No newline at end of file
diff --git a/sources/scripts/core/hint.js b/sources/scripts/core/hint.js
index e88a53d..bd0c605 100644
--- a/sources/scripts/core/hint.js
+++ b/sources/scripts/core/hint.js
@@ -9,9 +9,6 @@ function Hint()
   {
     ronin.commander.el.appendChild(this.el);
     ronin.commander.el.appendChild(this.cursor_hint_el);
-    this.cursor_hint_el.innerHTML = "●";
-    this.cursor_hint_el.title = ronin.cursor.color;
-    this.cursor_hint_el.style.color = ronin.cursor.color;
   }
 
   this.find_autocomplete = function(collection,append = "")
@@ -65,6 +62,7 @@ function Hint()
         this.el.innerHTML = this.pad(ronin.commander.input_el.value)+" > Unknown command."  
       }
     }
+    this.cursor_hint_el.innerHTML = ronin.cursor.hint();
   }
 
   this.pad = function(input)
diff --git a/sources/scripts/core/keyboard.js b/sources/scripts/core/keyboard.js
index 2560912..1ee3705 100644
--- a/sources/scripts/core/keyboard.js
+++ b/sources/scripts/core/keyboard.js
@@ -1,12 +1,23 @@
 function Keyboard()
 {
+  this.is_down = {};
+
   this.key_up = function(e)
   {
+    ronin.keyboard.is_down[e.key] = false;
     ronin.hint.update(e);
   }
 
   this.key_down = function(e)
   {
+    ronin.keyboard.is_down[e.key] = true;
+
+    if(e.key == "~"){
+      e.preventDefault();
+      ronin.commander.inject("~")
+      return;
+    }
+
     if(e.key == "Enter"){
       e.preventDefault();
       ronin.commander.validate();
diff --git a/sources/scripts/layers/guide.js b/sources/scripts/layers/guide.js
index 0bb3419..676ce00 100644
--- a/sources/scripts/layers/guide.js
+++ b/sources/scripts/layers/guide.js
@@ -20,8 +20,9 @@ function Guide()
       this.draw_inspector();
     }
 
-    // Color picker
-    this.toggle_color_picker(ronin.commander.query().last_char == "#")
+    if(ronin.commander.input_el.value == "~"){
+      this.toggle_color_picker(true);
+    }
 
     // Brush mirrors
     for(id in ronin.brush.pointers){
@@ -39,7 +40,20 @@ function Guide()
 
   this.toggle_color_picker = function(show)
   {
-    console.log("Picker",show)
+    if(!show){ return; }
+    var originalData = ronin.render.context().getImageData(0, 0, ronin.frame.width*2, ronin.frame.height*2);
+    var data = originalData.data;
+
+    for(var i = 0; i < data.length; i += 4) {
+      var x = i % (ronin.frame.width*8)
+      var y = i / (ronin.frame.width*32)
+      data[i]     = x/32;
+      data[i + 1] = 255 - (x/32);
+      data[i + 2] = y;
+      data[i + 3] = 255;
+    }
+
+    ronin.layers.guide.context().putImageData(originalData, 0, 0);
   }
 
   this.draw = function(u = null)
diff --git a/sources/scripts/modules/brush.js b/sources/scripts/modules/brush.js
index 6cb50e1..c628737 100644
--- a/sources/scripts/modules/brush.js
+++ b/sources/scripts/modules/brush.js
@@ -17,10 +17,11 @@ function Brush()
   })
 
   this.methods.pick = new Method("pick","x,y","Set brush color to a position's pixel.",function(q){
-    var pixel = ronin.render.context().getImageData(q.x*2, q.y*2, 1, 1).data;
+    var pixel = (ronin.commander.input_el.value == "~" ? ronin.guide: ronin.render).context() .getImageData(q.x*2, q.y*2, 1, 1).data;
     var c = new Color().rgb_to_hex(pixel);
     var color = new Color(c);
     ronin.cursor.color = color.hex;
+    ronin.hint.update();
   })
 
   this.absolute_thickness = 0;
diff --git a/sources/scripts/modules/filter.js b/sources/scripts/modules/filter.js
index d16cee3..ad4b122 100644
--- a/sources/scripts/modules/filter.js
+++ b/sources/scripts/modules/filter.js
@@ -18,7 +18,7 @@ function Filter()
     ronin.render.context().putImageData(originalData, 0, 0);
   });
 
-  this.methods.saturation = new Method("saturation","0.5,0.5","Filter color saturation.",function(q){
+  this.methods.saturation = new Method("saturation","#ff00333","Filter color saturation.",function(q){
 
     var color = new Color(q).floats();
 
diff --git a/sources/scripts/modules/path.js b/sources/scripts/modules/path.js
index 99adff8..79e6ce5 100644
--- a/sources/scripts/modules/path.js
+++ b/sources/scripts/modules/path.js
@@ -54,7 +54,7 @@ function Path()
 
     var ctx = ronin.preview.context();
     ctx.beginPath();
-    ctx.lineCap = q.settings.cap ? q.settings.cap : ronin.path.settings.cap;
+    ctx.lineCap = ronin.path.settings.cap;
     ctx.lineWidth = ronin.cursor.size;
     ctx.strokeStyle = ronin.cursor.color;
     ctx.stroke(new Path2D(path));
diff --git a/sources/scripts/ronin.js b/sources/scripts/ronin.js
index 3e6ae60..803d164 100644
--- a/sources/scripts/ronin.js
+++ b/sources/scripts/ronin.js
@@ -67,6 +67,7 @@ function Ronin()
     ronin.cursor.el.addEventListener('mousemove', ronin.cursor.mouse_move);
     ronin.cursor.el.addEventListener('mouseup', ronin.cursor.mouse_up);
     window.addEventListener('keydown', ronin.keyboard.key_down);
+    window.addEventListener('keyup', ronin.keyboard.key_up);
     ronin.commander.input_el.addEventListener('input', ronin.commander.on_input);
 
     console.log("Ronin","Started");