2018-10-04 11:27:40 +12:00
'use strict'
function Dotgrid ( width , height , grid _x , grid _y , block _x , block _y ) {
this . controller = null
this . theme = new Theme ( )
this . interface = new Interface ( )
this . history = new History ( )
this . guide = new Guide ( )
this . renderer = new Renderer ( )
this . tool = new Tool ( )
this . picker = new Picker ( )
this . cursor = new Cursor ( )
this . grid _x = grid _x
this . grid _y = grid _y
this . block _x = block _x
this . block _y = block _y
2016-12-31 14:35:14 -07:00
2018-09-12 15:27:01 +12:00
// ISU
2018-10-04 11:27:40 +12:00
this . install = function ( host ) {
host . appendChild ( this . guide . el )
2017-11-05 14:52:05 +14:00
2018-10-04 11:27:40 +12:00
this . interface . install ( host )
this . theme . install ( host , this . update )
2018-09-12 13:20:31 +12:00
}
2018-10-04 11:27:40 +12:00
this . start = function ( ) {
this . theme . start ( )
this . tool . start ( )
this . guide . start ( )
this . interface . start ( )
document . addEventListener ( 'mousedown' , function ( e ) { dotgrid . cursor . down ( e ) } , false )
document . addEventListener ( 'mousemove' , function ( e ) { dotgrid . cursor . move ( e ) } , false )
document . addEventListener ( 'contextmenu' , function ( e ) { dotgrid . cursor . alt ( e ) } , false )
document . addEventListener ( 'mouseup' , function ( e ) { dotgrid . cursor . up ( e ) } , false )
document . addEventListener ( 'copy' , function ( e ) { dotgrid . copy ( e ) } , false )
document . addEventListener ( 'cut' , function ( e ) { dotgrid . cut ( e ) } , false )
document . addEventListener ( 'paste' , function ( e ) { dotgrid . paste ( e ) } , false )
window . addEventListener ( 'drop' , dotgrid . drag )
this . new ( )
setTimeout ( ( ) => { document . body . className += ' ready' } , 250 )
2018-09-12 15:27:01 +12:00
}
2018-10-04 11:27:40 +12:00
this . update = function ( ) {
dotgrid . resize ( )
dotgrid . interface . update ( )
dotgrid . guide . update ( )
2016-12-31 10:18:01 -07:00
}
2018-05-07 17:03:35 +12:00
// File
2018-01-12 21:46:09 +13:00
2018-10-04 11:27:40 +12:00
this . new = function ( ) {
2018-07-18 12:52:23 +12:00
this . set _zoom ( 1.0 )
2018-10-04 11:27:40 +12:00
this . set _size ( { width : 300 , height : 300 } )
this . history . push ( this . tool . layers )
this . clear ( )
2018-01-12 21:09:26 +13:00
}
2018-10-04 11:27:40 +12:00
this . open = function ( ) {
if ( ! dialog ) { return }
2018-08-27 07:39:15 +12:00
2018-10-04 11:27:40 +12:00
const paths = dialog . showOpenDialog ( { properties : [ 'openFile' ] , filters : [ { name : 'Dotgrid Image' , extensions : [ 'dot' , 'grid' ] } ] } )
2018-05-11 09:57:14 +12:00
2018-10-04 11:27:40 +12:00
if ( ! paths ) { console . warn ( 'Nothing to load' ) ; return }
2018-05-11 09:57:14 +12:00
fs . readFile ( paths [ 0 ] , 'utf-8' , ( err , data ) => {
2018-10-04 11:27:40 +12:00
if ( err ) { alert ( 'An error ocurred reading the file :' + err . message ) ; return }
this . tool . replace ( JSON . parse ( data . toString ( ) . trim ( ) ) )
this . guide . update ( )
} )
2018-05-11 09:57:14 +12:00
}
2018-10-04 11:27:40 +12:00
this . save = function ( content = this . tool . export ( ) ) {
if ( dotgrid . tool . length ( ) < 1 ) { console . warn ( 'Nothing to save' ) ; return }
2018-08-04 15:55:08 +12:00
2018-10-04 11:27:40 +12:00
if ( ! dialog ) { this . save _web ( content ) ; return }
2018-08-18 09:34:24 +12:00
2018-10-04 11:27:40 +12:00
dialog . showSaveDialog ( { title : 'Save to .grid' , filters : [ { name : 'Dotgrid Format' , extensions : [ 'grid' , 'dot' ] } ] } , ( fileName ) => {
if ( fileName === undefined ) { return }
fileName = fileName . substr ( - 5 , 5 ) != '.grid' ? fileName + '.grid' : fileName
fs . writeFileSync ( fileName , content )
2018-09-12 13:20:31 +12:00
dotgrid . guide . update ( )
2018-10-04 11:27:40 +12:00
} )
2018-01-12 21:09:26 +13:00
}
2018-10-04 11:27:40 +12:00
this . save _web = function ( content ) {
console . info ( 'Web Save' )
const win = window . open ( '' , 'Save' , ` toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=640,height=480,top= ${ screen . height - 200 } ,left= ${ screen . width - 640 } ` )
win . document . body . innerHTML = ` <style>body { background: ${ dotgrid . theme . active . background } ; color: ${ dotgrid . theme . active . f _med } } pre { color: ${ dotgrid . theme . active . f _high } }</style><p>To save: Copy this into a .grid file.<br />To load: Drag the .grid onto the browser window.</p><pre> ${ content } </pre> `
2018-08-18 09:34:24 +12:00
}
2018-10-04 11:27:40 +12:00
this . render = function ( content = this . renderer . to _png ( { width : dotgrid . tool . settings . size . width * 2 , height : dotgrid . tool . settings . size . height * 2 } ) , ready = null , size = null ) {
if ( ! ready ) { return }
if ( dotgrid . tool . length ( ) < 1 ) { console . warn ( 'Nothing to render' ) ; return }
2018-05-11 10:37:10 +12:00
2018-10-04 11:27:40 +12:00
if ( ! dialog ) { dotgrid . render _web ( content ) ; return }
2018-08-18 09:34:24 +12:00
2018-10-04 11:27:40 +12:00
dialog . showSaveDialog ( { title : 'Save to .png' , filters : [ { name : 'Image Format' , extensions : [ 'png' ] } ] } , ( fileName ) => {
if ( fileName === undefined ) { return }
fileName = fileName . substr ( - 4 , 4 ) != '.png' ? fileName + '.png' : fileName
2018-05-11 11:08:51 +12:00
console . log ( ` Rendered ${ size . width } x ${ size . height } ` )
2018-10-04 11:27:40 +12:00
fs . writeFileSync ( fileName , ready )
} )
2018-05-11 09:57:14 +12:00
}
2018-01-12 21:09:26 +13:00
2018-10-04 11:27:40 +12:00
this . render _web = function ( content , window ) {
2018-08-18 09:34:24 +12:00
// Handled in Renderer
2018-10-04 11:27:40 +12:00
console . info ( 'Web Render' )
2018-08-18 09:34:24 +12:00
}
2018-10-04 11:27:40 +12:00
this . export = function ( content = this . renderer . to _svg ( ) ) {
if ( dotgrid . tool . length ( ) < 1 ) { console . warn ( 'Nothing to export' ) ; return }
2018-08-04 15:55:08 +12:00
2018-10-04 11:27:40 +12:00
if ( ! dialog ) { this . export _web ( content ) ; return }
2018-08-18 09:34:24 +12:00
2018-10-04 11:27:40 +12:00
dialog . showSaveDialog ( { title : 'Save to .svg' , filters : [ { name : 'Vector Format' , extensions : [ 'svg' ] } ] } , ( fileName ) => {
if ( fileName === undefined ) { return }
fileName = fileName . substr ( - 4 , 4 ) != '.svg' ? fileName + '.svg' : fileName
fs . writeFileSync ( fileName , content )
2018-09-12 13:20:31 +12:00
this . guide . update ( )
2018-10-04 11:27:40 +12:00
} )
2018-01-12 21:09:26 +13:00
}
2018-10-04 11:27:40 +12:00
this . export _web = function ( content ) {
console . info ( 'Web Export' )
const win = window . open ( '' , 'Save' , ` toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=640,height=480,top= ${ screen . height - 200 } ,left= ${ screen . width - 640 } ` )
win . document . body . innerHTML = ` <style>body { background: ${ dotgrid . theme . active . background } }</style> ${ dotgrid . renderer . to _svg ( ) } `
2018-08-18 09:34:24 +12:00
}
2018-05-07 17:03:35 +12:00
// Basics
2018-07-07 17:15:35 -07:00
2018-10-04 11:27:40 +12:00
this . set _size = function ( size = { width : 300 , height : 300 } , ui = true , scale = 1 ) {
size = { width : clamp ( step ( size . width , 15 ) , 105 , 1080 ) , height : clamp ( step ( size . height , 15 ) , 120 , 1080 ) }
2018-05-07 11:15:23 +12:00
2018-05-08 10:47:09 +12:00
this . tool . settings . size . width = size . width
this . tool . settings . size . height = size . height
2018-05-10 20:01:31 +12:00
2018-10-04 11:27:40 +12:00
try {
const win = require ( 'electron' ) . remote . getCurrentWindow ( )
win . setSize ( ( size . width + 100 ) * scale , ( size . height + 100 + ( ui ? 10 : 0 ) ) * scale , true )
} catch ( err ) {
console . log ( 'No window' )
2018-08-18 07:58:01 +12:00
}
2018-05-07 16:24:01 +12:00
2018-10-04 11:27:40 +12:00
this . grid _x = size . width / 15
this . grid _y = size . height / 15
this . grid _width = this . tool . settings . size . width / this . grid _x
this . grid _height = this . tool . settings . size . height / this . grid _y
2018-05-07 16:51:58 +12:00
2018-10-04 11:27:40 +12:00
dotgrid . guide . resize ( size )
2018-05-11 09:13:01 +12:00
2018-10-04 11:27:40 +12:00
this . interface . update ( )
dotgrid . guide . update ( )
2017-11-05 13:59:11 +14:00
}
2018-10-04 11:27:40 +12:00
this . set _zoom = function ( scale ) {
this . set _size ( { width : this . tool . settings . size . width , height : this . tool . settings . size . height } , true , scale )
2018-08-18 07:58:01 +12:00
2018-10-04 11:27:40 +12:00
try {
webFrame . setZoomFactor ( scale )
} catch ( err ) {
console . log ( 'Cannot zoom' )
2018-08-18 07:58:01 +12:00
}
2018-05-13 09:50:19 +12:00
}
2016-12-31 10:18:01 -07:00
// Draw
2018-07-07 17:15:35 -07:00
2018-10-04 11:27:40 +12:00
this . reset = function ( ) {
this . tool . clear ( )
this . update ( )
2016-12-31 10:18:01 -07:00
}
2018-10-04 11:27:40 +12:00
this . clear = function ( ) {
this . history . clear ( )
this . tool . reset ( )
this . reset ( )
dotgrid . guide . update ( )
dotgrid . interface . update ( true )
2017-11-08 10:40:13 +13:00
}
2018-10-04 11:27:40 +12:00
this . resize = function ( ) {
const size = { width : step ( window . innerWidth - 90 , 15 ) , height : step ( window . innerHeight - 120 , 15 ) }
2018-08-18 07:58:01 +12:00
2018-10-04 11:27:40 +12:00
if ( size . width == dotgrid . tool . settings . size . width && size . height == dotgrid . tool . settings . size . height ) {
return
2018-09-12 15:27:01 +12:00
}
console . log ( ` Resized: ${ size . width } x ${ size . height } ` )
2018-10-04 11:27:40 +12:00
2018-08-18 07:58:01 +12:00
dotgrid . tool . settings . size . width = size . width
dotgrid . tool . settings . size . height = size . height
2018-10-04 11:27:40 +12:00
dotgrid . grid _x = size . width / 15
dotgrid . grid _y = size . height / 15
2018-08-18 07:58:01 +12:00
2018-10-04 11:27:40 +12:00
dotgrid . grid _width = dotgrid . tool . settings . size . width / dotgrid . grid _x
dotgrid . grid _height = dotgrid . tool . settings . size . height / dotgrid . grid _y
2018-08-18 07:58:01 +12:00
2018-10-04 11:27:40 +12:00
dotgrid . guide . resize ( size )
2018-08-18 07:58:01 +12:00
2018-08-18 09:34:24 +12:00
document . title = ` Dotgrid — ${ size . width } x ${ size . height } `
2018-08-18 07:58:01 +12:00
}
2018-10-04 11:27:40 +12:00
this . drag = function ( e ) {
e . preventDefault ( )
e . stopPropagation ( )
2018-07-07 17:15:35 -07:00
2018-10-04 11:27:40 +12:00
const file = e . dataTransfer . files [ 0 ]
2018-01-12 16:22:50 +13:00
2018-10-04 11:27:40 +12:00
if ( ! file || ! file . path || file . path . indexOf ( '.dot' ) < 0 && file . path . indexOf ( '.grid' ) < 0 ) { console . warn ( 'Dotgrid' , 'Not a dot file' ) ; return }
2018-01-12 16:22:50 +13:00
2018-10-04 11:27:40 +12:00
const reader = new FileReader ( )
reader . onload = function ( e ) {
dotgrid . tool . replace ( JSON . parse ( e . target . result . toString ( ) . trim ( ) ) )
dotgrid . guide . update ( )
}
reader . readAsText ( file )
2018-01-12 16:22:50 +13:00
}
2018-10-04 11:27:40 +12:00
this . copy = function ( e ) {
dotgrid . guide . update ( )
2018-01-14 09:11:57 +13:00
2018-10-04 11:27:40 +12:00
if ( e . target !== this . picker . input ) {
e . clipboardData . setData ( 'text/source' , dotgrid . tool . export ( dotgrid . tool . layer ( ) ) )
e . clipboardData . setData ( 'text/plain' , dotgrid . tool . path ( ) )
e . clipboardData . setData ( 'text/html' , dotgrid . renderer . to _svg ( ) )
e . clipboardData . setData ( 'text/svg+xml' , dotgrid . renderer . to _svg ( ) )
e . preventDefault ( )
2018-07-25 23:56:06 -07:00
}
2018-02-07 19:44:18 +13:00
2018-10-04 11:27:40 +12:00
dotgrid . guide . update ( )
2018-02-07 19:44:18 +13:00
}
2018-10-04 11:27:40 +12:00
this . cut = function ( e ) {
dotgrid . guide . update ( )
2018-02-07 19:44:18 +13:00
2018-10-04 11:27:40 +12:00
if ( e . target !== this . picker . input ) {
e . clipboardData . setData ( 'text/plain' , dotgrid . tool . export ( dotgrid . tool . layer ( ) ) )
e . clipboardData . setData ( 'text/html' , dotgrid . renderer . to _svg ( ) )
e . clipboardData . setData ( 'text/svg+xml' , dotgrid . renderer . to _svg ( ) )
dotgrid . tool . layers [ dotgrid . tool . index ] = [ ]
e . preventDefault ( )
2018-07-25 23:56:06 -07:00
}
2018-02-07 19:44:18 +13:00
2018-10-04 11:27:40 +12:00
dotgrid . guide . update ( )
2017-11-21 22:24:25 +01:00
}
2018-10-04 11:27:40 +12:00
this . paste = function ( e ) {
if ( e . target !== this . picker . el ) {
2018-10-04 11:38:53 +12:00
let data = e . clipboardData . getData ( 'text/source' )
2018-07-25 23:56:06 -07:00
if ( is _json ( data ) ) {
2018-10-04 11:27:40 +12:00
data = JSON . parse ( data . trim ( ) )
dotgrid . tool . import ( data )
2018-07-25 23:56:06 -07:00
}
2018-10-04 11:27:40 +12:00
e . preventDefault ( )
2018-05-08 13:32:06 +12:00
}
2018-07-07 17:15:35 -07:00
2018-10-04 11:27:40 +12:00
dotgrid . guide . update ( )
2017-11-21 22:24:25 +01:00
}
2017-11-05 22:35:29 -06:00
}
2017-11-07 15:10:09 +13:00
2018-10-04 11:27:40 +12:00
window . addEventListener ( 'resize' , function ( e ) {
dotgrid . update ( )
} , false )
window . addEventListener ( 'dragover' , function ( e ) {
e . stopPropagation ( )
e . preventDefault ( )
e . dataTransfer . dropEffect = 'copy'
} )
String . prototype . capitalize = function ( ) {
return this . charAt ( 0 ) . toUpperCase ( ) + this . slice ( 1 ) . toLowerCase ( )
2018-05-08 21:22:00 -10:00
}
2018-07-18 12:52:23 +12:00
2018-10-04 11:27:40 +12:00
function is _json ( text ) { try { JSON . parse ( text ) ; return true } catch ( error ) { return false } }
function pos _is _equal ( a , b ) { return a && b && a . x == b . x && a . y == b . y }
function clamp ( v , min , max ) { return v < min ? min : v > max ? max : v }
function step ( v , s ) { return Math . round ( v / s ) * s }