Implemented themes

This commit is contained in:
Devine Lu Linvega 2018-01-28 10:45:56 +13:00
parent ab2406247c
commit 82b891cce2
12 changed files with 178 additions and 56 deletions

View File

@ -29,7 +29,9 @@ app.win = null;
app.on('ready', () => app.on('ready', () =>
{ {
app.win = new BrowserWindow({width: 930, height: 540, minWidth: 930, minHeight: 540, backgroundColor:"#000", frame:false, autoHideMenuBar: true, icon: __dirname + '/icon.ico'}) app.win = new BrowserWindow({width: 900, height: 540, minWidth: 900, minHeight: 540, backgroundColor:"#000", frame:false, autoHideMenuBar: true, icon: __dirname + '/icon.ico'})
app.win.toggleDevTools();
app.win.loadURL(`file://${__dirname}/sources/index.html`); app.win.loadURL(`file://${__dirname}/sources/index.html`);

View File

@ -1,6 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<head> <head>
<meta charset='UTF-8'> <meta charset='UTF-8'>
<script type="text/javascript" src="scripts/theme.js"></script>
<script type="text/javascript" src="scripts/controller.js"></script> <script type="text/javascript" src="scripts/controller.js"></script>
<script type="text/javascript" src="scripts/units/color.js"></script> <script type="text/javascript" src="scripts/units/color.js"></script>
@ -18,11 +19,14 @@
<script type="text/javascript" src="scripts/core/layer.js"></script> <script type="text/javascript" src="scripts/core/layer.js"></script>
<script type="text/javascript" src="scripts/layers/guide.js"></script> <script type="text/javascript" src="scripts/layers/guide.js"></script>
<script type="text/javascript" src="scripts/core/cursor.js"></script>
<script type="text/javascript" src="scripts/core/swatch.js"></script>
<script type="text/javascript" src="scripts/core/docs.js"></script> <script type="text/javascript" src="scripts/core/docs.js"></script>
<script type="text/javascript" src="scripts/core/port.js"></script> <script type="text/javascript" src="scripts/core/port.js"></script>
<script type="text/javascript" src="scripts/core/query.js"></script> <script type="text/javascript" src="scripts/core/query.js"></script>
<script type="text/javascript" src="scripts/core/keyboard.js"></script> <script type="text/javascript" src="scripts/core/keyboard.js"></script>
<script type="text/javascript" src="scripts/core/cursor.js"></script>
<script type="text/javascript" src="scripts/core/hint.js"></script> <script type="text/javascript" src="scripts/core/hint.js"></script>
<script type="text/javascript" src="scripts/core/commander.js"></script> <script type="text/javascript" src="scripts/core/commander.js"></script>

View File

@ -3,25 +3,27 @@ body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_medium"
yu { display:block; } yu { display:block; }
:root { --background: "#222"; --f_high: "#fff";--f_med: "#777";--f_low: "#444";--f_inv: "#000";--b_high: "#000";--b_med: "#affec7";--b_low: "#000";--b_inv: "#affec7"; }
#cursor { z-index:899; position: absolute; } #cursor { z-index:899; position: absolute; }
#guide { z-index:810;position: absolute; transition: opacity 250ms; opacity: 0} #guide { z-index:810;position: absolute; transition: opacity 250ms; opacity: 0}
#above { z-index:800; position: absolute; } #above { z-index:800; position: absolute; }
#below { z-index:799; position: absolute; } #below { z-index:799; position: absolute; }
#ronin { background-color:#ccc; height: 100vh; width:100vw; background-image:url(../media/assets/grid.svg);} #ronin { background:var(--b_low); 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;} #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;}
#commander { z-index: 9000;background: #000;bottom: 0px;position: relative; transition: top 150ms; } #commander { z-index: 9000;background: #000;bottom: 0px;position: relative; transition: top 150ms; }
#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; } #commander input { background: transparent;width: calc(100vw - 30px);display: block;line-height: 40px;font-size: 11px;color: var(--f_low); margin-left:20px; z-index: 9000;position: relative; }
#commander.hidden { top:-40px; } #commander.hidden { top:-40px; }
#commander.visible { top:0px; } #commander.visible { top:0px; }
#hint { color:#666; padding-left:20px; position: absolute;top: 0px;} #hint { color:var(--f_med); padding-left:20px; position: absolute;top: 0px;}
#hint b { font-family: 'input_mono_regular'; color:#999;} #hint b { font-family: 'input_mono_regular'; color:var(--f_low);}
#hint i { font-style: italic; } #hint i { font-style: italic; }
#hint .autocomplete { background:white; color:black; } #hint .autocomplete { background:var(--b_high); color:var(--f_low); }
#commander #cursor_hint { position: fixed;top: 0px;right: 10px;color: white; padding: 0px 10px; color:#555; font-size:11px; padding-right: 40px; } #commander #cursor_hint { position: fixed;top: 0px;right: 10px;color: var(--f_med); padding: 0px 10px; font-size:11px; padding-right: 40px; }
#commander #cursor_hint .mode {} #commander #cursor_hint .mode {}
#commander #cursor_hint .zoom::after { content:"*"; } #commander #cursor_hint .zoom::after { content:"*"; }
#commander #cursor_hint .pick::after { content:"#"; } #commander #cursor_hint .pick::after { content:"#"; }
@ -30,10 +32,10 @@ yu { display:block; }
#commander #cursor_hint .drag::after { content:"/"; } #commander #cursor_hint .drag::after { content:"/"; }
#commander #cursor_hint .target_above::after { content:"^"; } #commander #cursor_hint .target_above::after { content:"^"; }
#commander #cursor_hint .target_below::after { content:"v"; } #commander #cursor_hint .target_below::after { content:"v"; }
#commander icon.brush { display: block;width: 40px;height: 40px;position: absolute;top: 0px;right: 0px; }
#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);}
surface { display: block; background:pink; position: absolute; top:0px; transition: all 100ms; } #commander #swatch { background:red; display: block; position:fixed; top:10px; right:10px; width:20px; height:20px; border-radius:10px; }
#commander #swatch .primary { background: red;display: block;position: fixed;top: 20px;right: 20px;width: 20px;height: 20px;border-radius: 10px; }
surface { display: block; background:var(--background); position: absolute; top:0px; transition: all 100ms; }
surface .layer { border-radius: 4px; overflow: hidden; width:100%; height:100%;} surface .layer { border-radius: 4px; overflow: hidden; width:100%; height:100%;}

View File

@ -17,7 +17,14 @@ function Controller()
console.log(`${mode}/${cat}/${label} <${accelerator}>`); console.log(`${mode}/${cat}/${label} <${accelerator}>`);
} }
this.set = function(mode) this.add_role = function(mode,cat,label)
{
if(!this.menu[mode]){ this.menu[mode] = {}; }
if(!this.menu[mode][cat]){ this.menu[mode][cat] = {}; }
this.menu[mode][cat][label] = {role:label};
}
this.set = function(mode = "default")
{ {
this.mode = mode; this.mode = mode;
this.commit(); this.commit();
@ -31,7 +38,12 @@ function Controller()
var submenu = []; var submenu = [];
for(name in m[cat]){ for(name in m[cat]){
var option = m[cat][name]; var option = m[cat][name];
submenu.push({label:name,accelerator:option.accelerator,click:option.fn}) if(option.role){
submenu.push({role:option.role})
}
else{
submenu.push({label:name,accelerator:option.accelerator,click:option.fn})
}
} }
f.push({label:cat,submenu:submenu}); f.push({label:cat,submenu:submenu});
} }
@ -76,7 +88,7 @@ function Controller()
for(cat in menu){ for(cat in menu){
var options = menu[cat]; var options = menu[cat];
for(id in options.submenu){ for(id in options.submenu){
var option = options.submenu[id]; var option = options.submenu[id]; if(option.role){ continue; }
acc.basic = (option.accelerator.toLowerCase() == key.toLowerCase()) ? option.label.toUpperCase().replace("TOGGLE ","").substr(0,8).trim() : acc.basic; 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; acc.ctrl = (option.accelerator.toLowerCase() == ("CmdOrCtrl+"+key).toLowerCase()) ? option.label.toUpperCase().replace("TOGGLE ","").substr(0,8).trim() : acc.ctrl;
} }
@ -97,7 +109,7 @@ function Controller()
{x:540, y:0, width:60, height:60, name:"9"}, {x:540, y:0, width:60, height:60, name:"9"},
{x:600, y:0, width:60, height:60, name:"0"}, {x:600, y:0, width:60, height:60, name:"0"},
{x:660, y:0, width:60, height:60, name:"-"}, {x:660, y:0, width:60, height:60, name:"-"},
{x:720, y:0, width:60, height:60, name:"+"}, {x:720, y:0, width:60, height:60, name:"plus"},
{x:780, y:0, width:120, height:60, name:"backspace"}, {x:780, y:0, width:120, height:60, name:"backspace"},
{x:0, y:60, width:90, height:60, name:"tab"}, {x:0, y:60, width:90, height:60, name:"tab"},
{x:90, y:60, width:60, height:60, name:"q"}, {x:90, y:60, width:60, height:60, name:"q"},

View File

@ -120,7 +120,6 @@ function Commander()
this.activate = function() this.activate = function()
{ {
ronin.cursor.update();
ronin.commander.autocomplete(); ronin.commander.autocomplete();
ronin.commander.show(); ronin.commander.show();
setTimeout(()=>{ronin.commander.focus},100) setTimeout(()=>{ronin.commander.focus},100)

View File

@ -5,8 +5,6 @@ function Cursor(rune)
this.query = null; this.query = null;
this.mode = "vertex"; this.mode = "vertex";
this.color = "#000000"
this.color_alt = "#ffffff"
this.size = 2; this.size = 2;
this.pos = {x:0,y:0}; this.pos = {x:0,y:0};
@ -30,25 +28,17 @@ function Cursor(rune)
e.preventDefault(); e.preventDefault();
var pos = ronin.cursor.mouse_pos(e); var pos = ronin.cursor.mouse_pos(e);
ronin.cursor.pos = pos;
ronin.commander.blur(); ronin.commander.blur();
// 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.line.origin = {x:pos.x,y:pos.y}; ronin.cursor.line.origin = {x:pos.x,y:pos.y};
ronin.cursor.line.from = {x:pos.x,y:pos.y}; ronin.cursor.line.from = {x:pos.x,y:pos.y};
// Save original query // Save original query
ronin.cursor.query = ronin.commander.input_el.value; ronin.cursor.query = ronin.commander.input_el.value;
if(ronin.commander.active_module()){ } if(ronin.commander.active_module()){ /* DO NOTHING */ }
else if(e.shiftKey){ /* DO NOTHING */ }
else if(e.altKey && e.shiftKey){ ronin.brush.methods.pick.run(pos); } else if(e.altKey && e.shiftKey){ ronin.brush.methods.pick.run(pos); }
else if(e.altKey){ ronin.brush.erase(ronin.cursor.line); } else if(e.altKey){ ronin.brush.erase(ronin.cursor.line); }
else{ ronin.brush.stroke(ronin.cursor.line); } else{ ronin.brush.stroke(ronin.cursor.line); }
@ -69,13 +59,12 @@ function Cursor(rune)
ronin.cursor.line.to = {x:pos.x,y:pos.y}; ronin.cursor.line.to = {x:pos.x,y:pos.y};
if(e.altKey && e.shiftKey){ ronin.brush.methods.pick.run(pos); } if(ronin.commander.active_module()){ ronin.cursor.inject_query(); }
else if(e.altKey && e.shiftKey){ ronin.brush.methods.pick.run(pos); }
else if(e.shiftKey){ ronin.cursor.drag(ronin.cursor.line); } else if(e.shiftKey){ ronin.cursor.drag(ronin.cursor.line); }
else if(e.altKey){ ronin.brush.erase(ronin.cursor.line); } else if(e.altKey){ ronin.brush.erase(ronin.cursor.line); }
else{ ronin.brush.stroke(ronin.cursor.line); } else{ ronin.brush.stroke(ronin.cursor.line); }
ronin.cursor.inject_query();
ronin.cursor.line.from = {x:pos.x,y:pos.y}; ronin.cursor.line.from = {x:pos.x,y:pos.y};
} }
@ -84,7 +73,6 @@ function Cursor(rune)
e.preventDefault(); e.preventDefault();
var pos = ronin.cursor.mouse_pos(e); var pos = ronin.cursor.mouse_pos(e);
ronin.cursor.pos = pos;
ronin.cursor.line.destination = {x:pos.x,y:pos.y}; ronin.cursor.line.destination = {x:pos.x,y:pos.y};
@ -110,14 +98,6 @@ function Cursor(rune)
ronin.cursor.target.context().putImageData(data, offset.x * -2, offset.y * -2); ronin.cursor.target.context().putImageData(data, offset.x * -2, offset.y * -2);
} }
this.swap_colors = function()
{
var c = this.color_alt
this.color_alt = this.color;
this.color = c;
ronin.commander.update();
}
this.swap_layer = function() this.swap_layer = function()
{ {
this.target = this.target.name == "above" ? ronin.layers.below : ronin.layers.above; this.target = this.target.name == "above" ? ronin.layers.below : ronin.layers.above;
@ -195,9 +175,9 @@ function Cursor(rune)
} }
return ` return `
<t class='frame'>${ronin.frame.width}x${ronin.frame.height}</t> <t class='frame'>${ronin.frame.width}X${ronin.frame.height} ${(ronin.frame.width/ronin.frame.height).toFixed(2)}:1</t>
<t class='target_${ronin.cursor.target.name}'></t><t class='size ${mode}'>${ronin.cursor.size}</t><t class='zoom'>${ronin.frame.zoom.scale}</t> <t class='target_${ronin.cursor.target.name}'></t><t class='size ${mode}'>${ronin.cursor.size}</t><t class='zoom'>${ronin.frame.zoom.scale}</t>
<icon class='brush'><icon class='primary' style='background:${ronin.cursor.color}'></icon><icon class='secondary' style='background:${ronin.cursor.color_alt}'></icon></icon>`; ${ronin.brush.swatch.hint()}`;
} }
function distance_between(a,b) function distance_between(a,b)

View File

@ -11,7 +11,7 @@ function Keyboard()
{ {
ronin.keyboard.is_down[e.key] = true; ronin.keyboard.is_down[e.key] = true;
if(e.key == "Enter"){ if(ronin.commander.is_focused() && e.key == "Enter"){
e.preventDefault(); e.preventDefault();
ronin.commander.validate(); ronin.commander.validate();
} }

View File

@ -0,0 +1,31 @@
function Swatch()
{
this.index = 0;
this.colors = [];
this.start = function()
{
this.update();
}
this.update = function()
{
this.colors = [ronin.theme.active.f_high,ronin.theme.active.f_med,ronin.theme.active.f_low];
}
this.swap = function()
{
this.index += 1;
}
this.color = function(offset = 0)
{
return this.colors[(this.index + offset) % this.colors.length];
}
this.hint = function()
{
this.update();
return `<svg width="20px" height="20px" xmlns="http://www.w3.org/2000/svg" baseProfile="full" version="1.1" id='swatch' style='background-color:${this.color(1)}'><circle cx='10' cy='10' r='${ronin.cursor.size * 0.75}' fill='${this.color()}'/></svg>`;
}
}

View File

@ -3,6 +3,7 @@ function Brush()
Module.call(this,"brush"); Module.call(this,"brush");
this.speed = 0; this.speed = 0;
this.swatch = new Swatch();
this.pointers = [ this.pointers = [
new Pointer({offset:{x:0,y:0}}) new Pointer({offset:{x:0,y:0}})
@ -92,11 +93,6 @@ function Pointer(options)
return ronin.brush.thickness(line); return ronin.brush.thickness(line);
} }
this.color = function(line)
{
return ronin.cursor.color;
}
this.stroke = function(line,erase = false) this.stroke = function(line,erase = false)
{ {
var ctx = ronin.cursor.target.context(); var ctx = ronin.cursor.target.context();
@ -116,7 +112,7 @@ function Pointer(options)
ctx.lineTo((line.to.x * 2) + this.options.offset.x,(line.to.y * 2) + this.options.offset.y); ctx.lineTo((line.to.x * 2) + this.options.offset.x,(line.to.y * 2) + this.options.offset.y);
ctx.lineCap="round"; ctx.lineCap="round";
ctx.lineWidth = this.thickness(line); ctx.lineWidth = this.thickness(line);
ctx.strokeStyle = ronin.cursor.color; ctx.strokeStyle = ronin.brush.swatch.color();
ctx.stroke(); ctx.stroke();
ctx.closePath(); ctx.closePath();
} }

View File

@ -8,13 +8,12 @@ function Frame()
this.install = function() this.install = function()
{ {
ronin.el.appendChild(this.el); ronin.el.appendChild(this.el);
this.el.style.backgroundColor = this.background;
} }
this.methods.new = new Method("new","WxH","New Canvas",function(q){ this.methods.new = new Method("new","WxH","New Canvas",function(q){
ronin.layers.above.clear(); ronin.layers.above.clear();
ronin.layers.below.clear(); ronin.layers.below.clear();
ronin.frame.resize_to({width:930,height:540}); ronin.frame.resize_to({width:900,height:540});
}); });
this.width = 400; this.width = 400;

View File

@ -3,6 +3,7 @@ function Ronin()
this.el = document.createElement('yu'); this.el = document.createElement('yu');
this.el.id = "ronin"; this.el.id = "ronin";
this.theme = new Theme();
this.controller = new Controller(); this.controller = new Controller();
this.keyboard = new Keyboard(); this.keyboard = new Keyboard();
@ -41,6 +42,9 @@ function Ronin()
this.install = function() this.install = function()
{ {
this.theme.start();
this.brush.swatch.start();
document.body.appendChild(this.el); document.body.appendChild(this.el);
this.frame.width = window.innerWidth; this.frame.width = window.innerWidth;
@ -80,13 +84,21 @@ function Ronin()
this.controller.add("default","File","Save Images(PNGs)",() => { ronin.io.methods.save.run(); },"CmdOrCtrl+S"); this.controller.add("default","File","Save Images(PNGs)",() => { ronin.io.methods.save.run(); },"CmdOrCtrl+S");
this.controller.add("default","File","Export Image(JPG)",() => { ronin.io.methods.export.run(); },"CmdOrCtrl+E"); this.controller.add("default","File","Export Image(JPG)",() => { ronin.io.methods.export.run(); },"CmdOrCtrl+E");
this.controller.add_role("default","Edit","undo");
this.controller.add_role("default","Edit","redo");
this.controller.add_role("default","Edit","cut");
this.controller.add_role("default","Edit","copy");
this.controller.add_role("default","Edit","paste");
this.controller.add_role("default","Edit","delete");
this.controller.add_role("default","Edit","selectall");
this.controller.add("default","Layers","Above Layer",() => { ronin.cursor.select_layer(ronin.layers.above); },"c"); this.controller.add("default","Layers","Above Layer",() => { ronin.cursor.select_layer(ronin.layers.above); },"c");
this.controller.add("default","Layers","Below Layer",() => { ronin.cursor.select_layer(ronin.layers.below); },"z"); this.controller.add("default","Layers","Below Layer",() => { ronin.cursor.select_layer(ronin.layers.below); },"z");
this.controller.add("default","Layers","Toggle Layer",() => { ronin.cursor.swap_layer(); },"x"); this.controller.add("default","Layers","Toggle Layer",() => { ronin.cursor.brush.swatch.swap(); },"x");
this.controller.add("default","Brush","Inc Size",() => { ronin.brush.mod_size(1); },"]"); 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","Brush","Dec Size",() => { ronin.brush.mod_size(-1); },"[");
this.controller.add("default","Brush","Toggle Color",() => { ronin.cursor.swap_colors(); },"x"); this.controller.add("default","Brush","Toggle Color",() => { ronin.brush.swatch.swap(); },"x");
this.controller.add("default","Commander","Show",() => { ronin.commander.activate(); },"`"); this.controller.add("default","Commander","Show",() => { ronin.commander.activate(); },"`");
this.controller.add("default","Commander","Hide",() => { ronin.commander.deactivate(); },"Escape"); this.controller.add("default","Commander","Hide",() => { ronin.commander.deactivate(); },"Escape");
@ -115,11 +127,16 @@ function Ronin()
this.guide.update(); this.guide.update();
this.commander.update(); this.commander.update();
this.frame.resize_to({width:930,height:540}); this.frame.resize_to({width:900,height:540});
this.load(); this.load();
} }
this.reset = function()
{
this.theme.reset();
}
this.load = function(content = this.default()) this.load = function(content = this.default())
{ {

80
sources/scripts/theme.js Normal file
View File

@ -0,0 +1,80 @@
function Theme()
{
var app = this;
this.el = document.createElement("style");
this.el.type = 'text/css';
this.default = { background: "#222", f_high: "#fff", f_med: "#777", f_low: "#444", f_inv: "#000", b_high: "#000", b_med: "#affec7", b_low: "#000", b_inv: "#affec7" }
this.active = this.default;
this.start = function()
{
this.load(localStorage.theme ? localStorage.theme : this.default);
window.addEventListener('dragover',this.drag_enter);
window.addEventListener('drop', this.drag);
document.head.appendChild(this.el)
}
this.load = function(t)
{
var theme = is_json(t) ? JSON.parse(t) : t;
if(!theme.background){ return; }
var css = `
:root {
--background: ${theme.background};
--f_high: ${theme.f_high};
--f_med: ${theme.f_med};
--f_low: ${theme.f_low};
--f_inv: ${theme.f_inv};
--b_high: ${theme.b_high};
--b_med: ${theme.b_med};
--b_low: ${theme.b_low};
--b_inv: ${theme.b_inv};
}`;
this.active = theme;
this.el.textContent = css;
localStorage.setItem("theme", JSON.stringify(theme));
}
this.reset = function()
{
this.load(this.default);
}
this.drag_enter = function(e)
{
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
}
this.drag = function(e)
{
e.preventDefault();
e.stopPropagation();
var file = e.dataTransfer.files[0];
if(!file.name || !file.name.indexOf(".thm") < 0){ console.log("Theme","Not a theme"); return; }
var reader = new FileReader();
reader.onload = function(e){
app.load(e.target.result);
};
reader.readAsText(file);
}
function is_json(text)
{
try{
JSON.parse(text);
return true;
}
catch (error){
return false;
}
}
}