Starting implementing path and magnet
This commit is contained in:
68
sources/scripts/core/commander.js
Normal file
68
sources/scripts/core/commander.js
Normal file
@@ -0,0 +1,68 @@
|
||||
function Commander()
|
||||
{
|
||||
this.el = document.createElement('yu');
|
||||
this.el.id = "commander";
|
||||
this.input_el = document.createElement('input');
|
||||
this.input_el.value = "";
|
||||
|
||||
this.install = function()
|
||||
{
|
||||
this.el.appendChild(this.input_el);
|
||||
ronin.el.appendChild(this.el);
|
||||
this.input_el.focus();
|
||||
}
|
||||
|
||||
this.validate = function(q = ronin.commander.query())
|
||||
{
|
||||
if(!ronin.modules[q.module]){ console.log("Unknown module",q.module); return; }
|
||||
if(q.raw.indexOf("$") > -1){ console.log("Variables present"); return; }
|
||||
|
||||
// Update settings
|
||||
for(setting_id in q.settings){
|
||||
var setting_value = q.settings[setting_id];
|
||||
if(!ronin.modules[q.module].settings[setting_id]){ console.log("Missing setting",setting_id); return; }
|
||||
ronin.modules[q.module].settings[setting_id] = setting_value;
|
||||
}
|
||||
|
||||
ronin.modules[q.module].routes = q.routes;
|
||||
|
||||
// Run methods
|
||||
for(method_id in q.methods){
|
||||
var method_param = q.methods[method_id];
|
||||
if(!ronin.modules[q.module].methods[method_id]){ console.log("Missing method",method_id); return; }
|
||||
ronin.modules[q.module].methods[method_id](method_param);
|
||||
}
|
||||
|
||||
ronin.commander.input_el.value = "";
|
||||
ronin.hint.update();
|
||||
ronin.guide.update();
|
||||
}
|
||||
|
||||
this.on_input = function(e)
|
||||
{
|
||||
console.log("input");
|
||||
ronin.hint.update();
|
||||
ronin.guide.update();
|
||||
}
|
||||
|
||||
this.blur = function()
|
||||
{
|
||||
this.input_el.blur();
|
||||
}
|
||||
|
||||
this.active_module = function()
|
||||
{
|
||||
return this.query().module;
|
||||
}
|
||||
|
||||
this.inject = function(str)
|
||||
{
|
||||
ronin.commander.input_el.value = str;
|
||||
ronin.guide.update();
|
||||
}
|
||||
|
||||
this.query = function()
|
||||
{
|
||||
return new Query(ronin.commander.input_el.value);
|
||||
}
|
||||
}
|
||||
76
sources/scripts/core/cursor.js
Normal file
76
sources/scripts/core/cursor.js
Normal file
@@ -0,0 +1,76 @@
|
||||
function Cursor(rune)
|
||||
{
|
||||
this.line = {origin:null,from:null,to:null,destination:null};
|
||||
this.is_down = false;
|
||||
|
||||
this.query = null;
|
||||
|
||||
this.mouse_down = function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
ronin.cursor.line.origin = {x:e.clientX,y:e.clientY};
|
||||
ronin.cursor.line.from = {x:e.clientX,y:e.clientY};
|
||||
|
||||
// Save original query
|
||||
ronin.cursor.query = ronin.commander.input_el.value;
|
||||
}
|
||||
|
||||
this.mouse_move = function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
if(!ronin.cursor.line.from){ return; }
|
||||
|
||||
ronin.cursor.line.to = {x:e.clientX,y:e.clientY};
|
||||
|
||||
if(ronin.commander.active_module()){
|
||||
|
||||
}
|
||||
else if(e.altKey){
|
||||
ronin.eraser.stroke(ronin.cursor.line);
|
||||
}
|
||||
else{
|
||||
ronin.brush.stroke(ronin.cursor.line);
|
||||
}
|
||||
|
||||
ronin.cursor.inject_query();
|
||||
|
||||
ronin.cursor.line.from = {x:e.clientX,y:e.clientY};
|
||||
}
|
||||
|
||||
this.mouse_up = function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
ronin.cursor.line.destination = {x:e.clientX,y:e.clientY};
|
||||
|
||||
ronin.cursor.inject_query();
|
||||
|
||||
ronin.cursor.is_down = false;
|
||||
ronin.cursor.line = {};
|
||||
}
|
||||
|
||||
this.inject_query = function()
|
||||
{
|
||||
if(ronin.cursor.query.indexOf("$") < 0){ return; }
|
||||
|
||||
var a = ronin.cursor.line.origin;
|
||||
var b = ronin.cursor.line.destination ? ronin.cursor.line.destination : ronin.cursor.line.from;
|
||||
|
||||
if(distance_between(a,b) > 10){
|
||||
var offset = a.x+","+a.y;
|
||||
var rect = (b.x - a.x)+"x"+(b.y - a.y);
|
||||
var str = offset+"|"+rect;
|
||||
}
|
||||
else{
|
||||
var str = a.x+","+a.y;
|
||||
}
|
||||
ronin.commander.inject(ronin.cursor.query.replace("$",str));
|
||||
}
|
||||
|
||||
function distance_between(a,b)
|
||||
{
|
||||
return Math.sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
|
||||
}
|
||||
}
|
||||
85
sources/scripts/core/docs.js
Normal file
85
sources/scripts/core/docs.js
Normal file
@@ -0,0 +1,85 @@
|
||||
function Docs()
|
||||
{
|
||||
this.export = function()
|
||||
{
|
||||
var html = "";
|
||||
|
||||
html += this.print_intro();
|
||||
html += "## Modules\n";
|
||||
html += this.print_modules(ronin.modules);
|
||||
|
||||
html += this.print_license();
|
||||
|
||||
dialog.showSaveDialog((fileName) => {
|
||||
if (fileName === undefined){ return; }
|
||||
fs.writeFile(fileName, html, (err) => {
|
||||
if(err){ alert("An error ocurred creating the file "+ err.message); return; }
|
||||
});
|
||||
});
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
this.print_intro = function()
|
||||
{
|
||||
html = "# Ronin\n";
|
||||
html += "Ronin is a simple open-source graphic design tool.\n\n";
|
||||
html += "<img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/PREVIEW.jpg' width='600'/>\n\n";
|
||||
return html;
|
||||
}
|
||||
|
||||
this.print_modules = function(modules)
|
||||
{
|
||||
var html = "";
|
||||
|
||||
for(module_name in modules){
|
||||
var module = modules[module_name];
|
||||
html += "## "+module_name+"\n\n";
|
||||
html += module.docs+"\n\n";
|
||||
html += this.print_settings(module.settings)+"\n";
|
||||
html += this.print_methods(module.methods)+"\n";
|
||||
html += this.print_ports(module.ports)+"\n";
|
||||
}
|
||||
return html+"\n";
|
||||
}
|
||||
|
||||
this.print_settings = function(settings)
|
||||
{
|
||||
var html = "### Settings\n";
|
||||
|
||||
for(setting_name in settings){
|
||||
var setting_val = settings[setting_name];
|
||||
html += "- `"+setting_name+"`, default "+setting_val+"\n";
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
this.print_methods = function(methods)
|
||||
{
|
||||
var html = "### Methods\n";
|
||||
|
||||
for(method_name in methods){
|
||||
var method_val = methods[method_name];
|
||||
html += "- `"+method_name+":`, no details.\n";
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
this.print_ports = function(ports)
|
||||
{
|
||||
var html = "### Ports\n";
|
||||
|
||||
for(port_name in ports){
|
||||
var port = ports[port_name];
|
||||
html += "- `"+(port.input ? '->' : '')+""+port.name+""+(port.output ? '->' : '')+"` **("+port.value+"/"+port.max+")** "+port.docs+".\n";
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
this.print_license = function()
|
||||
{
|
||||
html = "## License\n";
|
||||
html += "See the [LICENSE](LICENSE.md) file for license rights and limitations (CC).\n";
|
||||
return html;
|
||||
}
|
||||
}
|
||||
31
sources/scripts/core/hint.js
Normal file
31
sources/scripts/core/hint.js
Normal file
@@ -0,0 +1,31 @@
|
||||
function Hint()
|
||||
{
|
||||
this.el = document.createElement('yu');
|
||||
this.el.id = "hint";
|
||||
|
||||
this.install = function()
|
||||
{
|
||||
ronin.el.appendChild(this.el);
|
||||
this.el.innerHTML = "";
|
||||
}
|
||||
|
||||
this.update = function(e = null)
|
||||
{
|
||||
var html = ""
|
||||
|
||||
for(module_id in ronin.modules){
|
||||
var module = ronin.modules[module_id];
|
||||
html += module.hint()+" ";
|
||||
}
|
||||
this.el.innerHTML = this.pad(ronin.commander.input_el.value)+(ronin.commander.input_el.value == "" ? html : "");
|
||||
}
|
||||
|
||||
this.pad = function(input)
|
||||
{
|
||||
var s = "";
|
||||
for (i = 0; i < input.length+1; i++){
|
||||
s += "_";
|
||||
}
|
||||
return "<span style='color:RGBA(0,0,0,0)'>"+s+"</span>";
|
||||
}
|
||||
}
|
||||
58
sources/scripts/core/keyboard.js
Normal file
58
sources/scripts/core/keyboard.js
Normal file
@@ -0,0 +1,58 @@
|
||||
function Keyboard()
|
||||
{
|
||||
this.key_up = function(e)
|
||||
{
|
||||
ronin.hint.update(e);
|
||||
}
|
||||
|
||||
this.key_down = function(e)
|
||||
{
|
||||
if(e.key == "Enter"){
|
||||
e.preventDefault();
|
||||
ronin.commander.validate();
|
||||
}
|
||||
|
||||
if(e.key == "Escape"){
|
||||
e.preventDefault();
|
||||
ronin.commander.input_el.blur();
|
||||
ronin.commander.input_el.value = "";
|
||||
ronin.guide.update();
|
||||
}
|
||||
|
||||
if(e.key == "]"){
|
||||
e.preventDefault();
|
||||
ronin.brush.mod_size(1);
|
||||
}
|
||||
if(e.key == "["){
|
||||
e.preventDefault();
|
||||
ronin.brush.mod_size(-1);
|
||||
}
|
||||
|
||||
if(e.key == "n" && (e.ctrlKey || e.metaKey)){
|
||||
e.preventDefault();
|
||||
ronin.render.clear();
|
||||
}
|
||||
|
||||
if(e.key == "o" && (e.ctrlKey || e.metaKey)){
|
||||
e.preventDefault();
|
||||
ronin.io.load();
|
||||
}
|
||||
|
||||
if(e.key == "s" && (e.ctrlKey || e.metaKey)){
|
||||
e.preventDefault();
|
||||
ronin.io.save();
|
||||
}
|
||||
|
||||
if(e.key == "r" && (e.ctrlKey || e.metaKey)){
|
||||
e.preventDefault();
|
||||
ronin.io.render();
|
||||
}
|
||||
|
||||
if(e.key == "H" && (e.ctrlKey || e.metaKey) && e.shiftKey){
|
||||
e.preventDefault();
|
||||
ronin.docs.export();
|
||||
}
|
||||
|
||||
ronin.hint.update(e);
|
||||
}
|
||||
}
|
||||
53
sources/scripts/core/layer.js
Normal file
53
sources/scripts/core/layer.js
Normal file
@@ -0,0 +1,53 @@
|
||||
function Layer()
|
||||
{
|
||||
this.el = document.createElement('canvas');
|
||||
|
||||
this.install = function()
|
||||
{
|
||||
ronin.el.appendChild(this.el);
|
||||
}
|
||||
|
||||
this.update = function()
|
||||
{
|
||||
this.el.width = window.innerWidth * 2;
|
||||
this.el.height = window.innerHeight * 2;
|
||||
this.el.style.width = (window.innerWidth)+"px";
|
||||
this.el.style.height = (window.innerHeight)+"px";
|
||||
}
|
||||
|
||||
this.context = function()
|
||||
{
|
||||
return this.el.getContext('2d');
|
||||
}
|
||||
|
||||
this.resize_to = function(size)
|
||||
{
|
||||
this.el.width = size.width * 2;
|
||||
this.el.height = size.height * 2;
|
||||
this.el.style.width = size.width+"px";
|
||||
this.el.style.height = size.height+"px";
|
||||
}
|
||||
|
||||
this.select = function(x,y,width,height)
|
||||
{
|
||||
return this.context().getImageData(x, y, width * 2, height * 2);
|
||||
}
|
||||
|
||||
this.to_data = function()
|
||||
{
|
||||
return this.el.toDataURL('image/png');
|
||||
}
|
||||
|
||||
this.to_img = function()
|
||||
{
|
||||
var img = new Image();
|
||||
img.src = this.to_data();
|
||||
return img;
|
||||
}
|
||||
|
||||
this.clear = function()
|
||||
{
|
||||
console.log("Clear")
|
||||
this.context().clearRect(0, 0, this.el.width * 2, this.el.height * 2);
|
||||
}
|
||||
}
|
||||
26
sources/scripts/core/module.js
Normal file
26
sources/scripts/core/module.js
Normal file
@@ -0,0 +1,26 @@
|
||||
function Module(name,docs = "Missing documentation.")
|
||||
{
|
||||
this.name = name;
|
||||
this.methods = {};
|
||||
this.settings = {};
|
||||
this.routes = {};
|
||||
this.ports = {};
|
||||
this.docs = docs;
|
||||
|
||||
this.hint = function()
|
||||
{
|
||||
var html = "";
|
||||
|
||||
for(setting_id in this.settings){
|
||||
var setting_value = this.settings[setting_id];
|
||||
html += setting_id+"="+setting_value+" ";
|
||||
}
|
||||
|
||||
for(route_id in this.routes){
|
||||
var route_val = this.routes[route_id];
|
||||
html += route_id+"->"+route_val+" ";
|
||||
}
|
||||
|
||||
return html.trim() != "" ? "<b>"+this.name+"</b> "+html.trim() : "";
|
||||
}
|
||||
}
|
||||
22
sources/scripts/core/port.js
Normal file
22
sources/scripts/core/port.js
Normal file
@@ -0,0 +1,22 @@
|
||||
function Port(host,name,input,output,value,max,docs)
|
||||
{
|
||||
this.host = host;
|
||||
|
||||
this.name = name;
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.value = value;
|
||||
this.max = max;
|
||||
this.docs = docs;
|
||||
|
||||
this.write = function(value)
|
||||
{
|
||||
this.value = value;
|
||||
var target = this.host.routes[this.name];
|
||||
|
||||
if(!this.output){ return; }
|
||||
if(!target){ console.log("No output for",this.name); return; }
|
||||
|
||||
this.host.ports[target].write(this.value);
|
||||
}
|
||||
}
|
||||
102
sources/scripts/core/query.js
Normal file
102
sources/scripts/core/query.js
Normal file
@@ -0,0 +1,102 @@
|
||||
function Query(query_str = "")
|
||||
{
|
||||
this.module = query_str.split(" ")[0];
|
||||
var parts = query_str.split(" ").splice(1);
|
||||
this.raw = parts.join(" ");
|
||||
this.methods = {};
|
||||
this.settings = {};
|
||||
this.routes = {};
|
||||
|
||||
for(part_id in parts){
|
||||
var part = parts[part_id];
|
||||
// Method
|
||||
if(part.indexOf(":") > -1){
|
||||
var key = part.indexOf(":") > -1 ? part.split(":")[0] : "any";
|
||||
var value = part.indexOf(":") > -1 ? part.split(":")[1] : part;
|
||||
this.methods[key] = parse_parameters(value);
|
||||
}
|
||||
// Setting
|
||||
else if(part.indexOf("=") > -1){
|
||||
var key = part.indexOf("=") > -1 ? part.split("=")[0] : "any";
|
||||
var value = part.indexOf("=") > -1 ? part.split("=")[1] : part;
|
||||
this.settings[key] = parse_parameters(value);
|
||||
}
|
||||
// Port
|
||||
else if(part.indexOf("->") > -1){
|
||||
var key = part.indexOf("->") > -1 ? part.split("->")[0] : "any";
|
||||
var value = part.indexOf("->") > -1 ? part.split("->")[1] : part;
|
||||
this.routes[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function parse_parameters(param_str)
|
||||
{
|
||||
// Modifier
|
||||
if(param_str.indexOf(">>") > -1){
|
||||
return parse_modifier(param_str);
|
||||
}
|
||||
else{
|
||||
if(param_str.indexOf("&") > -1){
|
||||
return parse_sequence(param_str);
|
||||
}
|
||||
else{
|
||||
return parse_unit(param_str);
|
||||
}
|
||||
}
|
||||
return param_str;
|
||||
}
|
||||
|
||||
function parse_modifier(mod_str)
|
||||
{
|
||||
var h = {};
|
||||
|
||||
var parts = mod_str.split(">>");
|
||||
|
||||
if(parts[0].indexOf("&") > -1){
|
||||
h.from = parse_sequence(parts[0]);
|
||||
}
|
||||
else{
|
||||
h.from = parse_unit(parts[0]);
|
||||
}
|
||||
|
||||
if(parts[1].indexOf("&") > -1){
|
||||
h.to = parse_sequence(parts[1]);
|
||||
}
|
||||
else{
|
||||
h.to = parse_unit(parts[1]);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
function parse_sequence(seq_str)
|
||||
{
|
||||
var a = [];
|
||||
|
||||
var parts = seq_str.split("&");
|
||||
for(part_id in parts){
|
||||
var part = parts[part_id];
|
||||
a.push(parse_unit(part));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
function parse_unit(unit_str)
|
||||
{
|
||||
if(unit_str.indexOf(".") > -1 && unit_str.indexOf("/") > -1 ){
|
||||
return unit_str;
|
||||
}
|
||||
if(unit_str.indexOf("|") > -1 && unit_str.indexOf(",") > -1 && unit_str.indexOf("x") > -1){
|
||||
return Object.assign(parse_unit(unit_str.split("|")[0]), parse_unit(unit_str.split("|")[1]));
|
||||
}
|
||||
if(unit_str.indexOf(",") > -1){
|
||||
return {x:parseInt(unit_str.split(",")[0]),y:parseInt(unit_str.split(",")[1])};
|
||||
}
|
||||
if(unit_str.indexOf("x") > -1){
|
||||
return {width:parseInt(unit_str.split("x")[0]),height:parseInt(unit_str.split("x")[1])};
|
||||
}
|
||||
if(unit_str.indexOf(".") > -1 ){
|
||||
return parseFloat(unit_str);
|
||||
}
|
||||
return unit_str;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user