diff --git a/src/js/app.js b/src/js/app.js index 3aa24f55..7a490acd 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -24,6 +24,9 @@ this.shortcutService = new pskl.service.keyboard.ShortcutService(); this.shortcutService.init(); + this.inputService = new pskl.service.keyboard.InputService(); + this.inputService.init(); + var size = pskl.UserSettings.get(pskl.UserSettings.DEFAULT_SIZE); var fps = Constants.DEFAULT.FPS; var descriptor = new pskl.model.piskel.Descriptor('New Piskel', ''); diff --git a/src/js/controller/DrawingController.js b/src/js/controller/DrawingController.js index d59a9282..b18e75c8 100644 --- a/src/js/controller/DrawingController.js +++ b/src/js/controller/DrawingController.js @@ -44,6 +44,7 @@ // State of drawing controller: this.isClicked = false; this.previousMousemoveTime = 0; + this.lastUpdateInputs_ = 0; this.currentToolBehavior = null; }; @@ -64,11 +65,17 @@ pskl.app.shortcutService.registerShortcut(shortcuts.MISC.RESET_ZOOM, this.resetZoom_.bind(this)); pskl.app.shortcutService.registerShortcut(shortcuts.MISC.INCREASE_ZOOM, this.updateZoom_.bind(this, 1)); pskl.app.shortcutService.registerShortcut(shortcuts.MISC.DECREASE_ZOOM, this.updateZoom_.bind(this, -1)); + pskl.app.shortcutService.registerShortcut(shortcuts.MISC.OFFSET_UP, this.updateOffset_.bind(this, 'up')); pskl.app.shortcutService.registerShortcut(shortcuts.MISC.OFFSET_RIGHT, this.updateOffset_.bind(this, 'right')); pskl.app.shortcutService.registerShortcut(shortcuts.MISC.OFFSET_DOWN, this.updateOffset_.bind(this, 'down')); pskl.app.shortcutService.registerShortcut(shortcuts.MISC.OFFSET_LEFT, this.updateOffset_.bind(this, 'left')); + pskl.app.shortcutService.registerShortcut(shortcuts.MISC.CURSOR_UP, this.updateCursor_.bind(this, 'up')); + pskl.app.shortcutService.registerShortcut(shortcuts.MISC.CURSOR_RIGHT, this.updateCursor_.bind(this, 'right')); + pskl.app.shortcutService.registerShortcut(shortcuts.MISC.CURSOR_DOWN, this.updateCursor_.bind(this, 'down')); + pskl.app.shortcutService.registerShortcut(shortcuts.MISC.CURSOR_LEFT, this.updateCursor_.bind(this, 'left')); + window.setTimeout(function () { this.afterWindowResize_(); this.resetZoom_(); @@ -156,6 +163,10 @@ * @private */ ns.DrawingController.prototype.onMousedown_ = function (event) { + if (this.isClicked) { + return; + } + $.publish(Events.MOUSE_EVENT, [event, this]); var frame = this.piskelController.getCurrentFrame(); var coords = this.getSpriteCoordinates(event.clientX, event.clientY); @@ -290,6 +301,83 @@ ); }; + /** + * Update the current viewport offset of 1 pixel in the provided direction. + * Direction can be one of 'up', 'right', 'down', 'left'. + * Callback for the OFFSET_${DIR} shortcuts. + */ + ns.DrawingController.prototype.updateCursor_ = function (dir) { + var x = this.currentX || 0; + var y = this.currentY || 0; + if (dir === 'up') { + y -= 1; + } else if (dir === 'right') { + x += 1; + } else if (dir === 'down') { + y += 1; + } else if (dir === 'left') { + x -= 1; + } + + this.currentX = x; + this.currentY = y; + + var screenCoordinates = this.getScreenCoordinates(x, y); + + var event = { + 'type': 'mousemove', + 'button': 0, + 'shiftKey': false, + 'altKey': false, + 'ctrlKey': false + }; + + event.clientX = screenCoordinates.x; + event.clientY = screenCoordinates.y; + + this.onMousemove_(event); + }; + + ns.DrawingController.prototype.clickCursor_ = function () { + var x = this.currentX || 0; + var y = this.currentY || 0; + + var screenCoordinates = this.getScreenCoordinates(x, y); + + var event = { + 'type': 'mousedown', + 'button': 0, + 'shiftKey': false, + 'altKey': false, + 'ctrlKey': false + }; + + event.clientX = screenCoordinates.x; + event.clientY = screenCoordinates.y; + + this.onMousedown_(event); + }; + + ns.DrawingController.prototype.releaseCursor_ = function () { + var x = this.currentX || 0; + var y = this.currentY || 0; + + var screenCoordinates = this.getScreenCoordinates(x, y); + + var event = { + 'type': 'mouseup', + 'button': 0, + 'shiftKey': false, + 'altKey': false, + 'ctrlKey': false + }; + + event.clientX = screenCoordinates.x; + event.clientY = screenCoordinates.y; + + this.onMouseup_(event); + }; + /** * Update the current zoom level by a given multiplier. * @@ -429,6 +517,20 @@ this.renderer.render(currentFrame); this.overlayRenderer.render(this.overlayFrame); + + this.updateInputs_(); + }; + + ns.DrawingController.prototype.updateInputs_ = function () { + var shortcuts = pskl.service.keyboard.Shortcuts; + + if (pskl.app.inputService.isKeyPressed(shortcuts.MISC.CURSOR_CLICK)) { + this.clickCursor_(); + this.isClickingCursor_ = true; + } else if (this.isClickingCursor_) { + this.releaseCursor_(); + this.isClickingCursor_ = false; + } }; /** diff --git a/src/js/service/keyboard/InputService.js b/src/js/service/keyboard/InputService.js new file mode 100644 index 00000000..8f0aa212 --- /dev/null +++ b/src/js/service/keyboard/InputService.js @@ -0,0 +1,48 @@ +(function () { + var ns = $.namespace('pskl.service.keyboard'); + + ns.InputService = function () { + this.activeShortcuts_ = {}; + }; + + /** + * @public + */ + ns.InputService.prototype.init = function() { + $(document.body).keydown($.proxy(this.onKeyDown_, this)); + $(document.body).keyup($.proxy(this.onKeyUp_, this)); + }; + + ns.InputService.prototype.isKeyPressed = function (shortcut) { + return shortcut.getKeys().some(function (key) { + return this.activeShortcuts_[key]; + }.bind(this)); + }; + + /** + * @private + */ + ns.InputService.prototype.onKeyDown_ = function(evt) { + var eventKey = ns.KeyUtils.createKeyFromEvent(evt); + if (this.isInInput_(evt) || !eventKey) { + return; + } + + this.activeShortcuts_[ns.KeyUtils.stringify(eventKey)] = true; + }; + + ns.InputService.prototype.onKeyUp_ = function(evt) { + var eventKey = ns.KeyUtils.createKeyFromEvent(evt); + if (this.isInInput_(evt) || !eventKey) { + return; + } + + this.activeShortcuts_[ns.KeyUtils.stringify(eventKey)] = false; + }; + + ns.InputService.prototype.isInInput_ = function (evt) { + var targetTagName = evt.target.nodeName.toUpperCase(); + return targetTagName === 'INPUT' || targetTagName === 'TEXTAREA'; + }; + +})(); diff --git a/src/js/service/keyboard/Shortcuts.js b/src/js/service/keyboard/Shortcuts.js index 2c26f623..58fb432c 100644 --- a/src/js/service/keyboard/Shortcuts.js +++ b/src/js/service/keyboard/Shortcuts.js @@ -66,6 +66,11 @@ OFFSET_RIGHT : createShortcut('move-right', 'Move viewport right', 'shift+right'), OFFSET_DOWN : createShortcut('move-down', 'Move viewport down', 'shift+down'), OFFSET_LEFT : createShortcut('move-left', 'Move viewport left', 'shift+left'), + CURSOR_UP : createShortcut('cursor-up', 'Move cursor up', 'alt+up'), + CURSOR_RIGHT : createShortcut('cursor-right', 'Move cursor right', 'alt+right'), + CURSOR_DOWN : createShortcut('cursor-down', 'Move cursor down', 'alt+down'), + CURSOR_LEFT : createShortcut('cursor-left', 'Move cursor left', 'alt+left'), + CURSOR_CLICK : createShortcut('cursor-click', 'Click cursor', 'SPACE'), }, STORAGE : { diff --git a/src/piskel-script-list.js b/src/piskel-script-list.js index 8c286b35..eb4b0804 100644 --- a/src/piskel-script-list.js +++ b/src/piskel-script-list.js @@ -197,6 +197,7 @@ "js/service/palette/PaletteImportService.js", "js/service/pensize/PenSizeService.js", "js/service/SavedStatusService.js", + "js/service/keyboard/InputService.js", "js/service/keyboard/KeycodeTranslator.js", "js/service/keyboard/KeyUtils.js", "js/service/keyboard/Shortcut.js",