diff --git a/main.js b/main.js
index 5fa3f2c..032212d 100644
--- a/main.js
+++ b/main.js
@@ -1,61 +1,48 @@
-const {app, BrowserWindow, webFrame, Menu} = require('electron')
+const {app, BrowserWindow, webFrame, Menu, dialog} = require('electron')
const path = require('path')
const url = require('url')
const shell = require('electron').shell
-let win
+let is_shown = true;
+
+app.inspect = function()
+{
+ app.win.toggleDevTools();
+}
+
+app.toggle_fullscreen = function()
+{
+ app.win.setFullScreen(app.win.isFullScreen() ? false : true);
+}
+
+app.toggle_visible = function()
+{
+ if(is_shown){ app.win.hide(); } else{ app.win.show(); }
+}
+
+app.inject_menu = function(m)
+{
+ Menu.setApplicationMenu(Menu.buildFromTemplate(m));
+}
+
+app.win = null;
app.on('ready', () =>
{
- win = new BrowserWindow({width: 930, height: 540, frame:false,autoHideMenuBar: true, backgroundColor: '#000', show:false, resizable:true, icon: __dirname + '/icon.ico'})
+ app.win = new BrowserWindow({width: 930, height: 540, minWidth: 930, minHeight: 540, backgroundColor:"#000", frame:false, autoHideMenuBar: true, icon: __dirname + '/icon.ico'})
- var nativeHandleBuffer = win.getNativeWindowHandle();
+ app.win.loadURL(`file://${__dirname}/sources/index.html`);
- win.loadURL(`file://${__dirname}/sources/index.html`)
-
- let is_shown = true;
- let is_fullscreen = false;
-
- Menu.setApplicationMenu(Menu.buildFromTemplate([
- {
- label: 'File',
- submenu: [
- { label: 'Inspector', accelerator: 'CmdOrCtrl+.', click: () => { win.webContents.openDevTools(); }},
- { label: 'Guide', accelerator: 'CmdOrCtrl+,', click: () => { shell.openExternal('https://github.com/hundredrabbits/Ronin'); }},
- { label: 'Quit', accelerator: 'CmdOrCtrl+Q', click: () => { force_quit=true; app.exit(); }}
- ]
- },
- {
- label: 'Edit',
- submenu: [
- { role: 'undo' },
- { role: 'redo' },
- { role: 'cut' },
- { role: 'copy' },
- { role: 'paste' },
- { role: 'delete' },
- { role: 'selectall' }
- ]
- },
- {
- label: 'Window',
- submenu : [
- { label: 'Hide', accelerator: 'CmdOrCtrl+H',click: () => { if(is_shown){ win.hide(); } else{ win.show(); }}},
- { label: 'Minimize', accelerator: 'CmdOrCtrl+M',click: () => { win.minimize(); }},
- { label: 'Fullscreen', accelerator: 'CmdOrCtrl+Enter',click: () => { win.setFullScreen(win.isFullScreen() ? false : true); }}
- ]
- }
- ]));
-
- win.on('ready-to-show',function() {
- win.show();
+ app.win.on('closed', () => {
+ win = null
+ app.quit()
})
- win.on('hide',function() {
+ app.win.on('hide',function() {
is_shown = false;
})
- win.on('show',function() {
+ app.win.on('show',function() {
is_shown = true;
})
})
@@ -66,7 +53,7 @@ app.on('window-all-closed', () =>
})
app.on('activate', () => {
- if (win === null) {
+ if (app.win === null) {
createWindow()
}
else{
diff --git a/sources/index.html b/sources/index.html
index 5267004..381bb9f 100644
--- a/sources/index.html
+++ b/sources/index.html
@@ -1,6 +1,8 @@
+
+
@@ -15,9 +17,7 @@
-
-
@@ -39,6 +39,7 @@
const {dialog,app} = require('electron').remote;
const fs = require('fs');
+
const app_path = app.getAppPath();
var ronin = new Ronin();
diff --git a/sources/links/main.css b/sources/links/main.css
index 1f1ae1e..48ea9be 100644
--- a/sources/links/main.css
+++ b/sources/links/main.css
@@ -7,10 +7,8 @@ yu { display:block; }
#cursor { z-index:899; position: fixed; }
#guide { z-index:810;position: fixed; display: none}
-#preview { z-index:805; position: fixed; display: none}
-#above { z-index:800; position: fixed; }
-#below { z-index:799; position: fixed; }
-#grid { z-index:795;position: fixed; display: none}
+#above { z-index:800; position: absolute; }
+#below { z-index:799; position: absolute; }
#ronin { background-color:#ccc; height: 100vh; width:100vw; background-image:url(../media/assets/grid.svg);}
#commander, #hint { width: 100vw;line-height: 40px;-webkit-user-select: none;-webkit-app-region: drag;z-index: 900;height: 40px; font-size:11px; cursor: default;}
@@ -38,4 +36,6 @@ yu { display:block; }
#commander icon.brush icon.primary { display: block;width: 6px;height: 20px;border-radius: 20px;border-style: solid;top: 10px;left: 16px;position: absolute;background: pink;transform: rotate(23deg);}
#commander icon.brush icon.secondary { display: block;width: 6px;height: 20px;border-radius: 20px;border-style: solid;top: 10px;left: 24px;position: absolute;background: pink;transform: rotate(23deg);}
-.layer { transition: all 150ms; left:0px; top:0px; border-radius: 4px; overflow: hidden;}
\ No newline at end of file
+surface { display: block; background:pink; position: absolute; top:0px; transition: all 100ms; }
+surface .layer { border-radius: 4px; overflow: hidden; width:100%; height:100%;}
+
diff --git a/sources/scripts/controller.js b/sources/scripts/controller.js
new file mode 100644
index 0000000..e11fb58
--- /dev/null
+++ b/sources/scripts/controller.js
@@ -0,0 +1,152 @@
+function Controller()
+{
+ this.menu = {default:{}};
+ this.mode = "default";
+
+ this.app = require('electron').remote.app;
+
+ this.start = function()
+ {
+ }
+
+ this.add = function(mode,cat,label,fn,accelerator)
+ {
+ if(!this.menu[mode]){ this.menu[mode] = {}; }
+ if(!this.menu[mode][cat]){ this.menu[mode][cat] = {}; }
+ this.menu[mode][cat][label] = {fn:fn,accelerator:accelerator};
+ console.log(`${mode}/${cat}/${label} <${accelerator}>`);
+ }
+
+ this.set = function(mode)
+ {
+ this.mode = mode;
+ this.commit();
+ }
+
+ this.format = function()
+ {
+ var f = [];
+ var m = this.menu[this.mode];
+ for(cat in m){
+ var submenu = [];
+ for(name in m[cat]){
+ var option = m[cat][name];
+ submenu.push({label:name,accelerator:option.accelerator,click:option.fn})
+ }
+ f.push({label:cat,submenu:submenu});
+ }
+ return f;
+ }
+
+ this.commit = function()
+ {
+ this.app.inject_menu(this.format());
+ }
+
+ this.docs = function()
+ {
+ console.log("Generating docs..");
+ var svg = this.generate(this.format())
+ dialog.showSaveDialog((fileName) => {
+ if (fileName === undefined){ return; }
+ fileName = fileName.substr(-4,4) != ".svg" ? fileName+".svg" : fileName;
+ fs.writeFile(fileName,svg);
+ });
+ }
+
+ this.generate = function(m)
+ {
+ var svg_html = "";
+
+ for(id in this.layout){
+ var key = this.layout[id];
+ var acc = this.accelerator_for_key(key.name,m);
+ svg_html += ``;
+ svg_html += ``;
+ svg_html += `${key.name.toUpperCase()}`;
+ svg_html += acc && acc.basic ? `${acc.basic}` : '';
+ svg_html += acc && acc.ctrl ? `${acc.ctrl}` : '';
+ }
+ return ``;
+ }
+
+ this.accelerator_for_key = function(key,menu)
+ {
+ var acc = {basic:null,ctrl:null}
+ for(cat in menu){
+ var options = menu[cat];
+ for(id in options.submenu){
+ var option = options.submenu[id];
+ acc.basic = (option.accelerator.toLowerCase() == key.toLowerCase()) ? option.label.toUpperCase().replace("TOGGLE ","").substr(0,8).trim() : acc.basic;
+ acc.ctrl = (option.accelerator.toLowerCase() == ("CmdOrCtrl+"+key).toLowerCase()) ? option.label.toUpperCase().replace("TOGGLE ","").substr(0,8).trim() : acc.ctrl;
+ }
+ }
+ return acc;
+ }
+
+ this.layout = [
+ {x:0, y:0, width:60, height:60, name:"esc"},
+ {x:60, y:0, width:60, height:60, name:"1"},
+ {x:120, y:0, width:60, height:60, name:"2"},
+ {x:180, y:0, width:60, height:60, name:"3"},
+ {x:240, y:0, width:60, height:60, name:"4"},
+ {x:300, y:0, width:60, height:60, name:"5"},
+ {x:360, y:0, width:60, height:60, name:"6"},
+ {x:420, y:0, width:60, height:60, name:"7"},
+ {x:480, y:0, width:60, height:60, name:"8"},
+ {x:540, y:0, width:60, height:60, name:"9"},
+ {x:600, y:0, width:60, height:60, name:"0"},
+ {x:660, y:0, width:60, height:60, name:"-"},
+ {x:720, y:0, width:60, height:60, name:"+"},
+ {x:780, y:0, width:120, height:60, name:"backspace"},
+ {x:0, y:60, width:90, height:60, name:"tab"},
+ {x:90, y:60, width:60, height:60, name:"q"},
+ {x:150, y:60, width:60, height:60, name:"w"},
+ {x:210, y:60, width:60, height:60, name:"e"},
+ {x:270, y:60, width:60, height:60, name:"r"},
+ {x:330, y:60, width:60, height:60, name:"t"},
+ {x:390, y:60, width:60, height:60, name:"y"},
+ {x:450, y:60, width:60, height:60, name:"u"},
+ {x:510, y:60, width:60, height:60, name:"i"},
+ {x:570, y:60, width:60, height:60, name:"o"},
+ {x:630, y:60, width:60, height:60, name:"p"},
+ {x:690, y:60, width:60, height:60, name:"["},
+ {x:750, y:60, width:60, height:60, name:"]"},
+ {x:810, y:60, width:90, height:60, name:"|"},
+ {x:0, y:120, width:105, height:60, name:"caps"},
+ {x:105, y:120, width:60, height:60, name:"a"},
+ {x:165, y:120, width:60, height:60, name:"s"},
+ {x:225, y:120, width:60, height:60, name:"d"},
+ {x:285, y:120, width:60, height:60, name:"f"},
+ {x:345, y:120, width:60, height:60, name:"g"},
+ {x:405, y:120, width:60, height:60, name:"h"},
+ {x:465, y:120, width:60, height:60, name:"j"},
+ {x:525, y:120, width:60, height:60, name:"k"},
+ {x:585, y:120, width:60, height:60, name:"l"},
+ {x:645, y:120, width:60, height:60, name:";"},
+ {x:705, y:120, width:60, height:60, name:"'"},
+ {x:765, y:120, width:135, height:60, name:"enter"},
+ {x:0, y:180, width:135, height:60, name:"shift"},
+ {x:135, y:180, width:60, height:60, name:"z"},
+ {x:195, y:180, width:60, height:60, name:"x"},
+ {x:255, y:180, width:60, height:60, name:"c"},
+ {x:315, y:180, width:60, height:60, name:"v"},
+ {x:375, y:180, width:60, height:60, name:"b"},
+ {x:435, y:180, width:60, height:60, name:"n"},
+ {x:495, y:180, width:60, height:60, name:"m"},
+ {x:555, y:180, width:60, height:60, name:","},
+ {x:615, y:180, width:60, height:60, name:"."},
+ {x:675, y:180, width:60, height:60, name:"/"},
+ {x:735, y:180, width:165, height:60, name:"capslock"},
+ {x:0, y:240, width:90, height:60, name:"ctrl"},
+ {x:90, y:240, width:90, height:60, name:"cmd"},
+ {x:180, y:240, width:90, height:60, name:"alt"},
+ {x:270, y:240, width:270, height:60, name:"space"},
+ {x:810, y:240, width:90, height:60, name:"ctrl"},
+ {x:720, y:240, width:90, height:60, name:"pn"},
+ {x:630, y:240, width:90, height:60, name:"fn"},
+ {x:540, y:240, width:90, height:60, name:"alt"}
+ ];
+}
+
+module.exports = new Controller();
\ No newline at end of file
diff --git a/sources/scripts/core/keyboard.js b/sources/scripts/core/keyboard.js
index 6675284..a41f9df 100644
--- a/sources/scripts/core/keyboard.js
+++ b/sources/scripts/core/keyboard.js
@@ -39,7 +39,6 @@ function Keyboard()
ronin.guide.update();
ronin.guide.clear();
ronin.guide.inspect = false;
- ronin.preview.clear();
if(!ronin.commander.is_focused()){
ronin.commander.hide();
}
@@ -56,15 +55,6 @@ function Keyboard()
return;
}
- 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.key == "Backspace") && (e.ctrlKey || e.metaKey)){
e.preventDefault();
ronin.guide.inspect = false;
@@ -102,21 +92,6 @@ function Keyboard()
ronin.cursor.swap_layer();
}
- if(e.key == "1"){
- e.preventDefault();
- ronin.frame.methods.zoom.run(1);
- }
-
- if(e.key == "2"){
- e.preventDefault();
- ronin.frame.methods.zoom.run(2);
- }
-
- if(e.key == "3"){
- e.preventDefault();
- ronin.frame.methods.zoom.run(4);
- }
-
ronin.hint.update(e);
}
}
\ No newline at end of file
diff --git a/sources/scripts/core/layer.js b/sources/scripts/core/layer.js
index a2e6c29..64b965e 100644
--- a/sources/scripts/core/layer.js
+++ b/sources/scripts/core/layer.js
@@ -7,16 +7,14 @@ function Layer(name)
this.install = function()
{
- ronin.el.appendChild(this.el);
+ ronin.frame.el.appendChild(this.el);
}
this.update = function(zoom = {scale:1,offset:{x:0,y:0}})
{
console.log(`Updated ${this.name}`);
- this.el.style.width = (ronin.frame.width * ronin.frame.zoom.scale)+"px";
- this.el.style.height = (ronin.frame.height * ronin.frame.zoom.scale)+"px";
- this.el.style.left = zoom.offset.x+"px";
- this.el.style.top = zoom.offset.y+"px";
+ // this.el.style.width = (ronin.frame.width)+"px";
+ // this.el.style.height = (ronin.frame.height)+"px";
}
this.context = function()
diff --git a/sources/scripts/layers/grid.js b/sources/scripts/layers/grid.js
deleted file mode 100644
index a28b5aa..0000000
--- a/sources/scripts/layers/grid.js
+++ /dev/null
@@ -1,44 +0,0 @@
-function Grid()
-{
- Layer.call(this);
-
- this.el.id = "grid";
-
- this.draw = function(size = 60, step = 5)
- {
- this.clear();
-
- var x = 1;
- var size = size * 2;
- while(x < this.el.width/size){
- var y = 1;
- while(y < (this.el.height/size)-1){
- var is_marker = (x % step == 0 && y % step == 0)
- this.draw_vertex(x * size,y * size,is_marker)
- y += 1;
- }
- x += 1;
- }
- }
-
- this.draw_vertex = function(x,y,is_marker)
- {
- var ctx = this.context();
- var r = 1.5;
- ctx.beginPath();
- ctx.arc(x, y, 1.5, 0, 2 * Math.PI, false);
- ctx.fillStyle = is_marker ? '#000' : '#ccc';
- ctx.fill();
- ctx.closePath();
- }
-
- 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.draw();
- }
-}
\ No newline at end of file
diff --git a/sources/scripts/layers/preview.js b/sources/scripts/layers/preview.js
deleted file mode 100644
index 5f0ef77..0000000
--- a/sources/scripts/layers/preview.js
+++ /dev/null
@@ -1,6 +0,0 @@
-function Preview()
-{
- Layer.call(this);
-
- this.el.id = "preview";
-}
\ No newline at end of file
diff --git a/sources/scripts/modules/frame.js b/sources/scripts/modules/frame.js
index e9f1f38..01bb816 100644
--- a/sources/scripts/modules/frame.js
+++ b/sources/scripts/modules/frame.js
@@ -2,6 +2,13 @@ function Frame()
{
Module.call(this,"frame","Manager for the canvas size");
+ this.el = document.createElement('surface');
+
+ this.install = function()
+ {
+ ronin.el.appendChild(this.el);
+ }
+
this.width = 400;
this.height = 400;
this.zoom = {scale:1,offset:{x:0,y:0}};
@@ -43,16 +50,19 @@ function Frame()
if(ronin.frame.zoom.scale == parseInt(q)){ return; }
ronin.frame.zoom.scale = parseInt(q);
+
+ ronin.frame.el.style.width = `${ronin.frame.width * ronin.frame.zoom.scale}px`;
+ ronin.frame.el.style.height = `${ronin.frame.height * ronin.frame.zoom.scale}px`;
ronin.frame.zoom.offset.x = ronin.frame.zoom.scale == 1 ? 0 : ((-ronin.cursor.pos.x * ronin.frame.zoom.scale) + (ronin.frame.width/2));
ronin.frame.zoom.offset.y = ronin.frame.zoom.scale == 1 ? 0 : ((-ronin.cursor.pos.y * ronin.frame.zoom.scale) + (ronin.frame.height/2));
-
- ronin.layers.above.zoom(ronin.frame.zoom);
- ronin.layers.below.zoom(ronin.frame.zoom);
- ronin.layers.guide.zoom(ronin.frame.zoom);
+ ronin.frame.el.style.top = `${ronin.frame.zoom.offset.y}px`;
+ ronin.frame.el.style.left = `${ronin.frame.zoom.offset.x}px`;
});
this.resize_to = function(size)
{
+ this.el.style.width = `${size.width}px`;
+ this.el.style.height = `${size.height}px`;
ronin.frame.width = size.width;
ronin.frame.height = size.height;
@@ -61,9 +71,7 @@ function Frame()
win.setSize(size.width,size.height);
ronin.layers.above.resize_to(size);
ronin.layers.below.resize_to(size);
- ronin.grid.resize_to(size);
ronin.guide.resize_to(size);
ronin.cursor.resize_to(size);
- ronin.preview.resize_to(size);
}
}
\ No newline at end of file
diff --git a/sources/scripts/ronin.js b/sources/scripts/ronin.js
index f19c96d..2170a06 100644
--- a/sources/scripts/ronin.js
+++ b/sources/scripts/ronin.js
@@ -3,17 +3,17 @@ function Ronin()
this.el = document.createElement('yu');
this.el.id = "ronin";
+ this.controller = new Controller();
+
this.keyboard = new Keyboard();
this.commander = new Commander();
this.cursor = new Cursor();
this.hint = new Hint();
this.docs = new Docs();
- this.grid = new Grid();
this.guide = new Guide();
this.above = new Layer("above");
this.below = new Layer("below");
- this.preview = new Preview();
this.io = new IO();
this.brush = new Brush();
@@ -24,12 +24,10 @@ function Ronin()
this.type = new Type();
this.layers = {
- grid : this.grid,
guide : this.guide,
above : this.above,
below : this.below,
cursor : this.cursor,
- preview : this.preview,
};
this.modules = {
@@ -49,16 +47,16 @@ function Ronin()
this.frame.width = window.innerWidth;
this.frame.height = window.innerHeight;
+ this.commander.install();
+ this.frame.install();
+
this.cursor.target = this.layers.above;
- this.grid.install();
- this.guide.install();
+ // this.guide.install();
this.above.install();
this.below.install();
- this.preview.install();
this.cursor.install();
- this.commander.install();
this.hint.install();
this.start();
@@ -66,6 +64,27 @@ function Ronin()
this.start = function()
{
+ this.controller.add("default","*","About",() => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Ronin'); },"CmdOrCtrl+,");
+ this.controller.add("default","*","Fullscreen",() => { app.toggle_fullscreen(); },"CmdOrCtrl+Enter");
+ this.controller.add("default","*","Hide",() => { app.toggle_visible(); },"CmdOrCtrl+H");
+ this.controller.add("default","*","Inspect",() => { app.inspect(); },"CmdOrCtrl+.");
+ this.controller.add("default","*","Documentation",() => { ronin.controller.docs(); },"CmdOrCtrl+Esc");
+ this.controller.add("default","*","Reset",() => { ronin.reset(); },"CmdOrCtrl+Backspace");
+ this.controller.add("default","*","Quit",() => { app.exit(); },"CmdOrCtrl+Q");
+
+ this.controller.add("default","File","New",() => { ronin.new(); },"CmdOrCtrl+N");
+ this.controller.add("default","File","Open",() => { ronin.open(); },"CmdOrCtrl+O");
+ this.controller.add("default","File","Save",() => { ronin.save(); },"CmdOrCtrl+S");
+
+ this.controller.add("default","Brush","Inc Size",() => { ronin.brush.mod_size(1); },"]");
+ this.controller.add("default","Brush","Dec Size",() => { ronin.brush.mod_size(-1); },"[");
+
+ this.controller.add("default","View","Reset Zoom",() => { ronin.frame.methods.zoom.run(1); },"1");
+ this.controller.add("default","View","Zoom 2x",() => { ronin.frame.methods.zoom.run(2); },"2");
+ this.controller.add("default","View","Zoom 4x",() => { ronin.frame.methods.zoom.run(4); },"3");
+
+ this.controller.commit();
+
window.addEventListener('dragover', ronin.io.drag_over);
window.addEventListener('drop', ronin.io.drop);
ronin.cursor.el.addEventListener('mousedown', ronin.cursor.mouse_down);
@@ -79,10 +98,8 @@ function Ronin()
console.log("Ronin","Started");
this.above.update();
this.below.update();
- this.grid.update();
this.guide.update();
this.cursor.update();
- this.preview.update();
this.commander.update();
this.frame.resize_to({width:930,height:540});