diff --git a/app.js b/app.js new file mode 100644 index 0000000..5c1daab --- /dev/null +++ b/app.js @@ -0,0 +1,34 @@ +var app = module.exports = require('appjs'); + +app.serveFilesFrom(__dirname + '/content'); + +var window = app.createWindow( +{ + width : 1280, + height : 720, + icons : __dirname + '/content/icons' +}); + +window.on('create', function() +{ + window.frame.show(); + window.frame.center(); +}); + +window.on('ready', function() +{ + window.require = require; + window.process = process; + window.module = module; + + function F12(e) { return e.keyIdentifier === 'F12' } + function Command_Option_J(e) { return e.keyCode === 74 && e.metaKey && e.altKey } + + window.addEventListener('keydown', function(e) + { + if (F12(e) || Command_Option_J(e)) + window.frame.openDevTools(); + }); + + window.dispatchEvent(new window.Event('app-ready')); +}); diff --git a/dialogger.js b/dialogger.js new file mode 100644 index 0000000..e641f8b --- /dev/null +++ b/dialogger.js @@ -0,0 +1,830 @@ +var fs = null; +addEventListener('app-ready', function(e) +{ + // We're running inside app.js + fs = require('fs'); + $('#import').hide(); + $('#export').hide(); + $('#export-game').hide(); +}); + +var graph = new joint.dia.Graph(); + +var defaultLink = new joint.dia.Link( +{ + attrs: + { + '.marker-target': { d: 'M 10 0 L 0 5 L 10 10 z', }, + '.link-tools .tool-remove circle, .marker-vertex': { r: 8 }, + }, +}); +defaultLink.set('smooth', true); + +var allowableConnections = +[ + ['dialogue.Text', 'dialogue.Text'], + ['dialogue.Text', 'dialogue.Node'], + ['dialogue.Text', 'dialogue.Choice'], + ['dialogue.Text', 'dialogue.Set'], + ['dialogue.Text', 'dialogue.Branch'], + ['dialogue.Node', 'dialogue.Text'], + ['dialogue.Node', 'dialogue.Node'], + ['dialogue.Node', 'dialogue.Choice'], + ['dialogue.Node', 'dialogue.Set'], + ['dialogue.Node', 'dialogue.Branch'], + ['dialogue.Choice', 'dialogue.Text'], + ['dialogue.Choice', 'dialogue.Node'], + ['dialogue.Choice', 'dialogue.Set'], + ['dialogue.Choice', 'dialogue.Branch'], + ['dialogue.Set', 'dialogue.Text'], + ['dialogue.Set', 'dialogue.Node'], + ['dialogue.Set', 'dialogue.Set'], + ['dialogue.Set', 'dialogue.Branch'], + ['dialogue.Branch', 'dialogue.Text'], + ['dialogue.Branch', 'dialogue.Node'], + ['dialogue.Branch', 'dialogue.Set'], + ['dialogue.Branch', 'dialogue.Branch'], +]; + +function validateConnection(cellViewS, magnetS, cellViewT, magnetT, end, linkView) +{ + // Prevent loop linking + if (magnetS == magnetT) + return false; + + if (cellViewS == cellViewT) + return false; + + if (magnetT.attributes.magnet.nodeValue !== 'passive') // Can't connect to an output port + return false; + + var sourceType = cellViewS.model.attributes.type; + var targetType = cellViewT.model.attributes.type; + var valid = false; + for (var i = 0; i < allowableConnections.length; i++) + { + var rule = allowableConnections[i]; + if (sourceType == rule[0] && targetType == rule[1]) + { + valid = true; + break; + } + } + if (!valid) + return false; + + var links = graph.getConnectedLinks(cellViewS.model); + for (var i = 0; i < links.length; i++) + { + var link = links[i]; + if (link.attributes.source.id === cellViewS.model.id && link.attributes.source.port === magnetS.attributes.port.nodeValue && link.attributes.target.id) + { + var targetCell = graph.getCell(link.attributes.target.id); + if (targetCell.attributes.type !== targetType) + return false; // We can only connect to multiple targets of the same type + if (targetCell == cellViewT.model) + return false; // Already connected + } + } + + return true; +} + +function validateMagnet(cellView, magnet) +{ + if (magnet.getAttribute('magnet') === 'passive') + return false; + + // If unlimited connections attribute is null, we can only ever connect to one object + // If it is not null, it is an array of type strings which are allowed to have unlimited connections + var unlimitedConnections = magnet.getAttribute('unlimitedConnections'); + var links = graph.getConnectedLinks(cellView.model); + for (var i = 0; i < links.length; i++) + { + var link = links[i]; + if (link.attributes.source.id === cellView.model.id && link.attributes.source.port === magnet.attributes.port.nodeValue) + { + // This port already has a connection + if (unlimitedConnections && link.attributes.target.id) + { + var targetCell = graph.getCell(link.attributes.target.id); + if (unlimitedConnections.indexOf(targetCell.attributes.type) !== -1) + return true; // It's okay because this target type has unlimited connections + } + return false; + } + } + + return true; +} + +joint.shapes.dialogue = {}; +joint.shapes.dialogue.Base = joint.shapes.devs.Model.extend( +{ + defaults: joint.util.deepSupplement + ( + { + type: 'dialogue.Base', + size: { width: 200, height: 64 }, + name: '', + attrs: + { + rect: { stroke: 'none', 'fill-opacity': 0 }, + text: { display: 'none' }, + '.inPorts circle': { magnet: 'passive' }, + '.outPorts circle': { magnet: true, }, + }, + }, + joint.shapes.devs.Model.prototype.defaults + ), +}); + +joint.shapes.dialogue.BaseView = joint.shapes.devs.ModelView.extend( +{ + template: + [ + '