2018-10-03 19:27:40 -04:00
|
|
|
'use strict'
|
|
|
|
|
2019-02-06 23:06:55 -05:00
|
|
|
function Dotgrid () {
|
2019-01-09 16:00:52 -05:00
|
|
|
const defaultTheme = {
|
|
|
|
background: '#eee',
|
|
|
|
f_high: '#000',
|
|
|
|
f_med: '#999',
|
|
|
|
f_low: '#ccc',
|
|
|
|
f_inv: '#000',
|
|
|
|
b_high: '#000',
|
|
|
|
b_med: '#888',
|
|
|
|
b_low: '#aaa',
|
|
|
|
b_inv: '#ffb545'
|
|
|
|
}
|
2018-12-21 17:07:46 -05:00
|
|
|
|
2018-09-11 23:27:01 -04:00
|
|
|
// ISU
|
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
this.install = function (host) {
|
2019-04-21 20:28:31 -04:00
|
|
|
console.info('Dotgrid', 'Installing..')
|
2019-01-08 23:44:24 -05:00
|
|
|
this.theme = new Theme(defaultTheme)
|
|
|
|
this.history = new History()
|
2019-04-21 19:49:47 -04:00
|
|
|
|
|
|
|
this.source = new Source(this)
|
2019-01-08 22:09:20 -05:00
|
|
|
this.manager = new Manager(this)
|
2019-01-08 22:12:18 -05:00
|
|
|
this.renderer = new Renderer(this)
|
2019-01-08 22:49:34 -05:00
|
|
|
this.tool = new Tool(this)
|
2019-01-08 22:51:57 -05:00
|
|
|
this.interface = new Interface(this)
|
|
|
|
this.picker = new Picker(this)
|
|
|
|
this.cursor = new Cursor(this)
|
2019-01-11 22:02:29 -05:00
|
|
|
this.listener = new Listener(this)
|
2019-01-08 22:12:18 -05:00
|
|
|
|
|
|
|
host.appendChild(this.renderer.el)
|
2017-11-04 20:52:05 -04:00
|
|
|
|
2019-01-08 22:09:20 -05:00
|
|
|
this.manager.install()
|
2018-10-03 19:27:40 -04:00
|
|
|
this.interface.install(host)
|
2019-04-21 20:28:31 -04:00
|
|
|
this.theme.install(host, () => { this.update() })
|
2018-09-11 21:20:31 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
this.start = function () {
|
2019-04-21 20:28:31 -04:00
|
|
|
console.info('Dotgrid', 'Starting..')
|
2018-10-03 19:27:40 -04:00
|
|
|
this.theme.start()
|
|
|
|
this.tool.start()
|
2019-01-08 22:12:18 -05:00
|
|
|
this.renderer.start()
|
2018-10-03 19:27:40 -04:00
|
|
|
this.interface.start()
|
|
|
|
|
2019-04-21 20:28:31 -04:00
|
|
|
// Add events
|
2019-04-21 19:49:47 -04:00
|
|
|
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)
|
2019-04-21 20:45:21 -04:00
|
|
|
window.addEventListener('resize', function (e) { dotgrid.onResize() }, false)
|
2019-04-21 20:28:31 -04:00
|
|
|
window.addEventListener('dragover', function (e) { e.stopPropagation(); e.preventDefault(); e.dataTransfer.dropEffect = 'copy' })
|
2019-04-21 19:49:47 -04:00
|
|
|
window.addEventListener('drop', dotgrid.drag)
|
2018-10-03 19:27:40 -04:00
|
|
|
|
2019-04-21 19:49:47 -04:00
|
|
|
this.source.new()
|
2019-04-21 21:25:31 -04:00
|
|
|
this.onResize()
|
2018-10-03 19:27:40 -04:00
|
|
|
|
|
|
|
setTimeout(() => { document.body.className += ' ready' }, 250)
|
2018-09-11 23:27:01 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
this.update = function () {
|
2019-04-21 19:49:47 -04:00
|
|
|
this.manager.update()
|
|
|
|
this.interface.update()
|
|
|
|
this.renderer.update()
|
2016-12-31 12:18:01 -05:00
|
|
|
}
|
|
|
|
|
2019-01-09 16:00:52 -05:00
|
|
|
this.clear = function () {
|
|
|
|
this.history.clear()
|
|
|
|
this.tool.reset()
|
|
|
|
this.reset()
|
|
|
|
this.renderer.update()
|
|
|
|
this.interface.update(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
this.reset = function () {
|
|
|
|
this.tool.clear()
|
|
|
|
this.update()
|
|
|
|
}
|
|
|
|
|
2019-04-21 20:45:21 -04:00
|
|
|
// Methods
|
2018-07-07 20:15:35 -04:00
|
|
|
|
2019-04-21 20:45:21 -04:00
|
|
|
this.modZoom = function (mod = 0, set = false) {
|
|
|
|
try {
|
|
|
|
const { webFrame } = require('electron')
|
|
|
|
const currentZoomFactor = webFrame.getZoomFactor()
|
|
|
|
webFrame.setZoomFactor(set ? mod : currentZoomFactor + mod)
|
|
|
|
console.log(window.devicePixelRatio)
|
|
|
|
} catch (err) {
|
|
|
|
console.log('Cannot zoom')
|
2019-01-09 15:35:10 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-21 20:45:21 -04:00
|
|
|
this.setZoom = function (scale) {
|
2018-10-03 19:27:40 -04:00
|
|
|
try {
|
2019-04-21 20:45:21 -04:00
|
|
|
webFrame.setZoomFactor(scale)
|
2018-10-03 19:27:40 -04:00
|
|
|
} catch (err) {
|
2019-04-21 20:45:21 -04:00
|
|
|
console.log('Cannot zoom')
|
2018-08-17 15:58:01 -04:00
|
|
|
}
|
2017-11-04 19:59:11 -04:00
|
|
|
}
|
|
|
|
|
2019-04-21 20:45:21 -04:00
|
|
|
// Resize Tools
|
|
|
|
|
2019-04-21 20:34:48 -04:00
|
|
|
this.fitSize = function () {
|
2019-04-21 20:28:31 -04:00
|
|
|
if (this.requireResize() === false) { return }
|
|
|
|
console.log('Dotgrid', `Will resize to: ${printSize(this.getRequiredSize())}`)
|
2019-04-21 20:34:48 -04:00
|
|
|
this.setWindowSize(this.getRequiredSize())
|
2019-04-21 21:25:31 -04:00
|
|
|
this.update()
|
2019-04-21 20:28:31 -04:00
|
|
|
}
|
2018-08-17 15:58:01 -04:00
|
|
|
|
2019-04-21 20:28:31 -04:00
|
|
|
this.setWindowSize = function (size) {
|
2019-04-21 20:34:48 -04:00
|
|
|
console.log('Dotgrid', `Resizing to ${printSize(size)}`)
|
2019-04-21 20:28:31 -04:00
|
|
|
const win = require('electron').remote.getCurrentWindow()
|
|
|
|
win.setSize(size.width, size.height, false)
|
2019-04-21 20:45:21 -04:00
|
|
|
document.title = `Dotgrid — ${size.width}x${size.height}`
|
|
|
|
this.update()
|
|
|
|
}
|
|
|
|
|
|
|
|
this.getPadding = function () {
|
2019-04-21 21:09:42 -04:00
|
|
|
return { x: 60, y: 90 }
|
2019-04-21 20:28:31 -04:00
|
|
|
}
|
2018-09-11 23:27:01 -04:00
|
|
|
|
2019-04-21 20:28:31 -04:00
|
|
|
this.getWindowSize = function () {
|
|
|
|
return { width: window.innerWidth, height: window.innerHeight }
|
|
|
|
}
|
2018-10-03 19:27:40 -04:00
|
|
|
|
2019-04-21 20:28:31 -04:00
|
|
|
this.getProjectSize = function () {
|
|
|
|
return this.tool.settings.size
|
|
|
|
}
|
2018-08-17 15:58:01 -04:00
|
|
|
|
2019-04-21 20:28:31 -04:00
|
|
|
this.getPaddedSize = function () {
|
2019-04-21 20:34:48 -04:00
|
|
|
const rect = this.getWindowSize()
|
|
|
|
const pad = this.getPadding()
|
2019-04-21 20:45:21 -04:00
|
|
|
return { width: step(rect.width - pad.x, 15), height: step(rect.height - pad.y, 15) }
|
2019-04-21 20:28:31 -04:00
|
|
|
}
|
2018-08-17 15:58:01 -04:00
|
|
|
|
2019-04-21 20:28:31 -04:00
|
|
|
this.getRequiredSize = function () {
|
2019-04-21 20:34:48 -04:00
|
|
|
const rect = this.getProjectSize()
|
|
|
|
const pad = this.getPadding()
|
|
|
|
return { width: step(rect.width, 15) + pad.x, height: step(rect.height, 15) + pad.y }
|
2019-04-21 20:28:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
this.requireResize = function () {
|
2019-04-21 20:34:48 -04:00
|
|
|
const _window = this.getWindowSize()
|
2019-04-21 20:28:31 -04:00
|
|
|
const _required = this.getRequiredSize()
|
2019-04-21 21:00:32 -04:00
|
|
|
const offset = sizeOffset(_window, _required)
|
2019-04-21 20:28:31 -04:00
|
|
|
if (offset.width !== 0 || offset.height !== 0) {
|
2019-04-21 20:34:48 -04:00
|
|
|
console.log(`Dotgrid`, `Require ${printSize(_required)}, but window is ${printSize(_window)}(${printSize(offset)})`)
|
2019-04-21 20:28:31 -04:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
2018-08-17 15:58:01 -04:00
|
|
|
}
|
|
|
|
|
2019-04-21 20:45:21 -04:00
|
|
|
this.onResize = function () {
|
|
|
|
const _project = this.getProjectSize()
|
|
|
|
const _padded = this.getPaddedSize()
|
2019-04-21 21:00:32 -04:00
|
|
|
const offset = sizeOffset(_padded, _project)
|
2019-04-21 20:45:21 -04:00
|
|
|
if (offset.width !== 0 || offset.height !== 0) {
|
|
|
|
console.log(`Dotgrid`, `Resize project to ${printSize(_padded)}`)
|
|
|
|
this.tool.settings.size = _padded
|
2019-01-09 17:43:17 -05:00
|
|
|
}
|
2019-04-21 20:45:21 -04:00
|
|
|
this.update()
|
2019-01-09 17:43:17 -05:00
|
|
|
}
|
|
|
|
|
2019-01-09 16:00:52 -05:00
|
|
|
// Events
|
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
this.drag = function (e) {
|
|
|
|
e.preventDefault()
|
|
|
|
e.stopPropagation()
|
2018-07-07 20:15:35 -04:00
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
const file = e.dataTransfer.files[0]
|
2019-01-07 17:03:38 -05:00
|
|
|
const filename = file.path ? file.path : file.name ? file.name : ''
|
2018-01-11 22:22:50 -05:00
|
|
|
|
2019-01-07 17:03:38 -05:00
|
|
|
if (filename.indexOf('.grid') < 0) { console.warn('Dotgrid', 'Not a .grid file'); return }
|
2018-01-11 22:22:50 -05:00
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
const reader = new FileReader()
|
2019-01-07 17:03:38 -05:00
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
reader.onload = function (e) {
|
2019-01-07 17:03:38 -05:00
|
|
|
const data = e.target && e.target.result ? e.target.result : ''
|
2019-04-21 21:25:31 -04:00
|
|
|
dotgrid.source.load(filename, data)
|
2019-04-21 20:28:31 -04:00
|
|
|
dotgrid.fitSize()
|
2018-10-03 19:27:40 -04:00
|
|
|
}
|
|
|
|
reader.readAsText(file)
|
2018-01-11 22:22:50 -05:00
|
|
|
}
|
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
this.copy = function (e) {
|
2019-04-21 19:49:47 -04:00
|
|
|
dotgrid.renderer.update()
|
2018-01-13 15:11:57 -05:00
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
if (e.target !== this.picker.input) {
|
2019-04-21 19:49:47 -04:00
|
|
|
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.manager.el.outerHTML)
|
|
|
|
e.clipboardData.setData('text/svg+xml', dotgrid.manager.el.outerHTML)
|
2018-10-03 19:27:40 -04:00
|
|
|
e.preventDefault()
|
2018-07-26 02:56:06 -04:00
|
|
|
}
|
2018-02-07 01:44:18 -05:00
|
|
|
|
2019-04-21 19:49:47 -04:00
|
|
|
dotgrid.renderer.update()
|
2018-02-07 01:44:18 -05:00
|
|
|
}
|
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
this.cut = function (e) {
|
2019-04-21 19:49:47 -04:00
|
|
|
dotgrid.renderer.update()
|
2018-02-07 01:44:18 -05:00
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
if (e.target !== this.picker.input) {
|
2019-04-21 19:49:47 -04:00
|
|
|
e.clipboardData.setData('text/source', dotgrid.tool.export(dotgrid.tool.layer()))
|
|
|
|
e.clipboardData.setData('text/plain', dotgrid.tool.export(dotgrid.tool.layer()))
|
|
|
|
e.clipboardData.setData('text/html', dotgrid.manager.el.outerHTML)
|
|
|
|
e.clipboardData.setData('text/svg+xml', dotgrid.manager.el.outerHTML)
|
|
|
|
dotgrid.tool.layers[dotgrid.tool.index] = []
|
2018-10-03 19:27:40 -04:00
|
|
|
e.preventDefault()
|
2018-07-26 02:56:06 -04:00
|
|
|
}
|
2018-02-07 01:44:18 -05:00
|
|
|
|
2019-04-21 19:49:47 -04:00
|
|
|
dotgrid.renderer.update()
|
2017-11-21 16:24:25 -05:00
|
|
|
}
|
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
this.paste = function (e) {
|
|
|
|
if (e.target !== this.picker.el) {
|
2018-10-03 19:38:53 -04:00
|
|
|
let data = e.clipboardData.getData('text/source')
|
2019-01-07 17:03:38 -05:00
|
|
|
if (isJson(data)) {
|
2018-10-03 19:27:40 -04:00
|
|
|
data = JSON.parse(data.trim())
|
2019-04-21 19:49:47 -04:00
|
|
|
dotgrid.tool.import(data)
|
2018-07-26 02:56:06 -04:00
|
|
|
}
|
2018-10-03 19:27:40 -04:00
|
|
|
e.preventDefault()
|
2018-05-07 21:32:06 -04:00
|
|
|
}
|
2018-07-07 20:15:35 -04:00
|
|
|
|
2019-04-21 19:49:47 -04:00
|
|
|
dotgrid.renderer.update()
|
2017-11-21 16:24:25 -05:00
|
|
|
}
|
2017-11-05 23:35:29 -05:00
|
|
|
}
|
2017-11-06 21:10:09 -05:00
|
|
|
|
2018-10-03 19:27:40 -04:00
|
|
|
String.prototype.capitalize = function () {
|
|
|
|
return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase()
|
2018-05-09 03:22:00 -04:00
|
|
|
}
|
2018-07-17 20:52:23 -04:00
|
|
|
|
2019-04-21 21:00:32 -04:00
|
|
|
function sizeOffset (a, b) { return { width: a.width - b.width, height: a.height - b.height } }
|
2019-04-21 20:28:31 -04:00
|
|
|
function printSize (size) { return `${size.width}x${size.height}` }
|
2019-01-07 17:03:38 -05:00
|
|
|
function isJson (text) { try { JSON.parse(text); return true } catch (error) { return false } }
|
2019-04-21 19:36:12 -04:00
|
|
|
function isEqual (a, b) { return a && b && a.x === b.x && a.y === b.y }
|
2018-10-03 19:27:40 -04:00
|
|
|
function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
|
|
|
|
function step (v, s) { return Math.round(v / s) * s }
|