Files
pointvec/desktop/sources/scripts/dotgrid.js

239 lines
7.1 KiB
JavaScript
Raw Normal View History

2018-10-04 11:27:40 +12:00
'use strict'
2019-02-07 16:06:55 +12:00
function Dotgrid () {
2019-01-10 09:00:52 +12: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-22 10:07:46 +12:00
2018-09-12 15:27:01 +12:00
// ISU
2018-10-04 11:27:40 +12:00
this.install = function (host) {
2019-04-22 09:28:31 +09:00
console.info('Dotgrid', 'Installing..')
2019-01-09 16:44:24 +12:00
this.theme = new Theme(defaultTheme)
this.history = new History()
2019-04-22 08:49:47 +09:00
this.source = new Source(this)
2019-01-09 15:09:20 +12:00
this.manager = new Manager(this)
2019-01-09 15:12:18 +12:00
this.renderer = new Renderer(this)
2019-01-09 15:49:34 +12:00
this.tool = new Tool(this)
2019-01-09 15:51:57 +12:00
this.interface = new Interface(this)
this.picker = new Picker(this)
this.cursor = new Cursor(this)
2019-01-12 15:02:29 +12:00
this.listener = new Listener(this)
2019-01-09 15:12:18 +12:00
host.appendChild(this.renderer.el)
2017-11-05 14:52:05 +14:00
2019-01-09 15:09:20 +12:00
this.manager.install()
2018-10-04 11:27:40 +12:00
this.interface.install(host)
2019-04-22 09:28:31 +09:00
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 () {
2019-04-22 09:28:31 +09:00
console.info('Dotgrid', 'Starting..')
2018-10-04 11:27:40 +12:00
this.theme.start()
this.tool.start()
2019-01-09 15:12:18 +12:00
this.renderer.start()
2018-10-04 11:27:40 +12:00
this.interface.start()
2019-04-22 09:28:31 +09:00
// Add events
2019-04-22 08:49:47 +09: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-22 09:45:21 +09:00
window.addEventListener('resize', function (e) { dotgrid.onResize() }, false)
2019-04-22 09:28:31 +09:00
window.addEventListener('dragover', function (e) { e.stopPropagation(); e.preventDefault(); e.dataTransfer.dropEffect = 'copy' })
2019-04-22 08:49:47 +09:00
window.addEventListener('drop', dotgrid.drag)
2018-10-04 11:27:40 +12:00
2019-04-22 08:49:47 +09:00
this.source.new()
2018-10-04 11:27:40 +12:00
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 () {
2019-04-22 08:49:47 +09:00
this.manager.update()
this.interface.update()
this.renderer.update()
2016-12-31 10:18:01 -07:00
}
2019-01-10 09:00:52 +12: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-22 09:45:21 +09:00
// Methods
2019-04-22 09:45:21 +09: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-10 08:35:10 +12:00
}
}
2019-04-22 09:45:21 +09:00
this.setZoom = function (scale) {
2018-10-04 11:27:40 +12:00
try {
2019-04-22 09:45:21 +09:00
webFrame.setZoomFactor(scale)
2018-10-04 11:27:40 +12:00
} catch (err) {
2019-04-22 09:45:21 +09:00
console.log('Cannot zoom')
2018-08-18 07:58:01 +12:00
}
2017-11-05 13:59:11 +14:00
}
2019-04-22 09:45:21 +09:00
// Resize Tools
2019-04-22 09:34:48 +09:00
this.fitSize = function () {
2019-04-22 09:28:31 +09:00
if (this.requireResize() === false) { return }
console.log('Dotgrid', `Will resize to: ${printSize(this.getRequiredSize())}`)
2019-04-22 09:34:48 +09:00
this.setWindowSize(this.getRequiredSize())
2019-04-22 09:28:31 +09:00
}
2018-08-18 07:58:01 +12:00
2019-04-22 09:28:31 +09:00
this.setWindowSize = function (size) {
2019-04-22 09:34:48 +09:00
console.log('Dotgrid', `Resizing to ${printSize(size)}`)
2019-04-22 09:28:31 +09:00
const win = require('electron').remote.getCurrentWindow()
win.setSize(size.width, size.height, false)
2019-04-22 09:45:21 +09:00
document.title = `Dotgrid — ${size.width}x${size.height}`
this.update()
}
this.getPadding = function () {
return { x: 90, y: 120 }
2019-04-22 09:28:31 +09:00
}
2018-09-12 15:27:01 +12:00
2019-04-22 09:28:31 +09:00
this.getWindowSize = function () {
return { width: window.innerWidth, height: window.innerHeight }
}
2018-10-04 11:27:40 +12:00
2019-04-22 09:28:31 +09:00
this.getProjectSize = function () {
return this.tool.settings.size
}
2018-08-18 07:58:01 +12:00
2019-04-22 09:28:31 +09:00
this.getPaddedSize = function () {
2019-04-22 09:34:48 +09:00
const rect = this.getWindowSize()
const pad = this.getPadding()
2019-04-22 09:45:21 +09:00
return { width: step(rect.width - pad.x, 15), height: step(rect.height - pad.y, 15) }
2019-04-22 09:28:31 +09:00
}
2018-08-18 07:58:01 +12:00
2019-04-22 09:28:31 +09:00
this.getRequiredSize = function () {
2019-04-22 09:34:48 +09: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-22 09:28:31 +09:00
}
this.requireResize = function () {
2019-04-22 09:34:48 +09:00
const _window = this.getWindowSize()
2019-04-22 09:28:31 +09:00
const _required = this.getRequiredSize()
2019-04-22 09:34:48 +09:00
const offset = { width: _window.width - _required.width, height: _window.height - _required.height }
2019-04-22 09:28:31 +09:00
if (offset.width !== 0 || offset.height !== 0) {
2019-04-22 09:34:48 +09:00
console.log(`Dotgrid`, `Require ${printSize(_required)}, but window is ${printSize(_window)}(${printSize(offset)})`)
2019-04-22 09:28:31 +09:00
return true
}
return false
2018-08-18 07:58:01 +12:00
}
2019-04-22 09:45:21 +09:00
this.onResize = function () {
const _project = this.getProjectSize()
const _padded = this.getPaddedSize()
const offset = { width: _padded.width - _project.width, height: _padded.height - _project.height }
if (offset.width !== 0 || offset.height !== 0) {
console.log(`Dotgrid`, `Resize project to ${printSize(_padded)}`)
this.tool.settings.size = _padded
2019-01-10 10:43:17 +12:00
}
2019-04-22 09:45:21 +09:00
this.update()
2019-01-10 10:43:17 +12:00
}
2019-01-10 09:00:52 +12:00
// Events
2018-10-04 11:27:40 +12:00
this.drag = function (e) {
e.preventDefault()
e.stopPropagation()
2018-10-04 11:27:40 +12:00
const file = e.dataTransfer.files[0]
2019-01-08 10:03:38 +12:00
const filename = file.path ? file.path : file.name ? file.name : ''
2018-01-12 16:22:50 +13:00
2019-01-08 10:03:38 +12:00
if (filename.indexOf('.grid') < 0) { console.warn('Dotgrid', 'Not a .grid file'); return }
2018-01-12 16:22:50 +13:00
2018-10-04 11:27:40 +12:00
const reader = new FileReader()
2019-01-08 10:03:38 +12:00
2018-10-04 11:27:40 +12:00
reader.onload = function (e) {
2019-01-08 10:03:38 +12:00
const data = e.target && e.target.result ? e.target.result : ''
if (data && !isJson(data)) { return }
2019-04-22 08:49:47 +09:00
dotgrid.tool.replace(JSON.parse(`${data}`))
2019-04-22 09:28:31 +09:00
dotgrid.fitSize()
2018-10-04 11:27:40 +12:00
}
reader.readAsText(file)
2018-01-12 16:22:50 +13:00
}
2018-10-04 11:27:40 +12:00
this.copy = function (e) {
2019-04-22 08:49:47 +09:00
dotgrid.renderer.update()
2018-01-14 09:11:57 +13:00
2018-10-04 11:27:40 +12:00
if (e.target !== this.picker.input) {
2019-04-22 08:49:47 +09: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-04 11:27:40 +12:00
e.preventDefault()
}
2018-02-07 19:44:18 +13:00
2019-04-22 08:49:47 +09:00
dotgrid.renderer.update()
2018-02-07 19:44:18 +13:00
}
2018-10-04 11:27:40 +12:00
this.cut = function (e) {
2019-04-22 08:49:47 +09:00
dotgrid.renderer.update()
2018-02-07 19:44:18 +13:00
2018-10-04 11:27:40 +12:00
if (e.target !== this.picker.input) {
2019-04-22 08:49:47 +09: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-04 11:27:40 +12:00
e.preventDefault()
}
2018-02-07 19:44:18 +13:00
2019-04-22 08:49:47 +09:00
dotgrid.renderer.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')
2019-01-08 10:03:38 +12:00
if (isJson(data)) {
2018-10-04 11:27:40 +12:00
data = JSON.parse(data.trim())
2019-04-22 08:49:47 +09:00
dotgrid.tool.import(data)
}
2018-10-04 11:27:40 +12:00
e.preventDefault()
2018-05-08 13:32:06 +12:00
}
2019-04-22 08:49:47 +09:00
dotgrid.renderer.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
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
2019-04-22 09:28:31 +09:00
function printSize (size) { return `${size.width}x${size.height}` }
2019-01-08 10:03:38 +12:00
function isJson (text) { try { JSON.parse(text); return true } catch (error) { return false } }
2019-04-22 08:36:12 +09:00
function isEqual (a, b) { return a && b && a.x === b.x && a.y === b.y }
2018-10-04 11:27:40 +12:00
function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
function step (v, s) { return Math.round(v / s) * s }