diff --git a/src/css/settings-application.css b/src/css/settings-application.css index e100e72b..a2407055 100644 --- a/src/css/settings-application.css +++ b/src/css/settings-application.css @@ -62,6 +62,11 @@ text-align: center; } +.settings-item-grid-size { + display: flex; + align-items: center; +} + .grid-width-select, .color-format-select { margin: 5px 5px 0 5px; diff --git a/src/css/pensize.css b/src/css/widgets-size-picker.css similarity index 55% rename from src/css/pensize.css rename to src/css/widgets-size-picker.css index 4fc85931..715d65ed 100644 --- a/src/css/pensize.css +++ b/src/css/widgets-size-picker.css @@ -1,9 +1,13 @@ -.pen-size-container { +/***********************/ +/* SIZE PICKER WIDGET */ +/***********************/ + +.size-picker-container { overflow: hidden; padding: 5px 5px; } -.pen-size-option { +.size-picker-option { float: left; box-sizing: border-box; width: 20px; @@ -15,20 +19,20 @@ cursor: pointer; } -.pen-size-option[data-size='1'] { +.size-picker-option[data-size='1'] { padding: 5px; } -.pen-size-option[data-size='2'] { +.size-picker-option[data-size='2'] { padding: 4px; } -.pen-size-option[data-size='3'] { +.size-picker-option[data-size='3'] { padding: 3px; } -.pen-size-option[data-size='4'] { +.size-picker-option[data-size='4'] { padding: 2px; } -.pen-size-option:before { +.size-picker-option:before { content: ''; width: 100%; height: 100%; @@ -39,19 +43,19 @@ font-size: 90%; } -.pen-size-option:hover { +.size-picker-option:hover { border-color: #888; } -.pen-size-option.selected:before { +.size-picker-option.selected:before { background-color: var(--highlight-color); } -.pen-size-option.selected { +.size-picker-option.selected { border-color: var(--highlight-color); } -.pen-size-option.labeled:before { - content: attr(real-pen-size); +.size-picker-option.labeled:before { + content: attr(real-size); color: black; } diff --git a/src/js/app.js b/src/js/app.js index 33098bf5..e38a4692 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -10,6 +10,9 @@ ns.app = { init : function () { + // Run preferences migration scripts for version v0.12.0 + pskl.UserSettings.migrate_to_v0_12(); + /** * When started from APP Engine, appEngineToken_ (Boolean) should be set on window.pskl */ diff --git a/src/js/controller/PenSizeController.js b/src/js/controller/PenSizeController.js index 324e4cf6..41e619be 100644 --- a/src/js/controller/PenSizeController.js +++ b/src/js/controller/PenSizeController.js @@ -1,23 +1,19 @@ (function () { var ns = $.namespace('pskl.controller'); - ns.PenSizeController = function () {}; + ns.PenSizeController = function () { + this.sizePicker = new pskl.widgets.SizePicker(this.onSizePickerChanged_.bind(this)); + }; ns.PenSizeController.prototype.init = function () { - this.container = document.querySelector('.pen-size-container'); - pskl.utils.Event.addEventListener(this.container, 'click', this.onPenSizeOptionClick_, this); + this.sizePicker.init(document.querySelector('.pen-size-container')); $.subscribe(Events.PEN_SIZE_CHANGED, this.onPenSizeChanged_.bind(this)); - this.updateSelectedOption_(); }; - ns.PenSizeController.prototype.onPenSizeOptionClick_ = function (e) { - var size = e.target.dataset.size; - if (!isNaN(size)) { - size = parseInt(size, 10); - pskl.app.penSizeService.setPenSize(size); - } + ns.PenSizeController.prototype.onSizePickerChanged_ = function (size) { + pskl.app.penSizeService.setPenSize(size); }; ns.PenSizeController.prototype.onPenSizeChanged_ = function (e) { @@ -25,19 +21,7 @@ }; ns.PenSizeController.prototype.updateSelectedOption_ = function () { - pskl.utils.Dom.removeClass('labeled', this.container); - pskl.utils.Dom.removeClass('selected', this.container); var size = pskl.app.penSizeService.getPenSize(); - var selectedOption; - if (size <= 4) { - selectedOption = this.container.querySelector('[data-size="' + size + '"]'); - } else { - selectedOption = this.container.querySelector('[data-size="4"]'); - selectedOption.classList.add('labeled'); - selectedOption.setAttribute('real-pen-size', size); - } - if (selectedOption) { - selectedOption.classList.add('selected'); - } + this.sizePicker.setSize(size); }; })(); diff --git a/src/js/controller/settings/application/GridApplicationController.js b/src/js/controller/settings/application/GridApplicationController.js index 91ba09a7..edc29edb 100644 --- a/src/js/controller/settings/application/GridApplicationController.js +++ b/src/js/controller/settings/application/GridApplicationController.js @@ -4,23 +4,35 @@ ns.GridApplicationController = function (piskelController, applicationController) { this.piskelController = piskelController; this.applicationController = applicationController; + this.sizePicker = new pskl.widgets.SizePicker(this.onSizePickerChanged_.bind(this)); }; pskl.utils.inherit(ns.GridApplicationController, pskl.controller.settings.AbstractSettingController); ns.GridApplicationController.prototype.init = function () { - // Grid display and size - var gridWidth = pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH); - var gridSelect = document.querySelector('.grid-width-select'); - var selectedOption = gridSelect.querySelector('option[value="' + gridWidth + '"]'); - if (selectedOption) { - selectedOption.setAttribute('selected', 'selected'); + var isEnabled = pskl.UserSettings.get(pskl.UserSettings.GRID_ENABLED); + var enableGridCheckbox = document.querySelector('.enable-grid-checkbox'); + if (isEnabled) { + enableGridCheckbox.setAttribute('checked', 'true'); } - this.addEventListener(gridSelect, 'change', this.onGridWidthChange_); + this.addEventListener(enableGridCheckbox, 'change', this.onEnableGridChange_); + + // Grid size + var gridWidth = pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH); + this.sizePicker.init(document.querySelector('.grid-size-container')); + this.sizePicker.setSize(gridWidth); }; - ns.GridApplicationController.prototype.onGridWidthChange_ = function (evt) { - var width = parseInt(evt.target.value, 10); - pskl.UserSettings.set(pskl.UserSettings.GRID_WIDTH, width); + ns.GridApplicationController.prototype.destroy = function () { + this.sizePicker.destroy(); + this.superclass.destroy.call(this); + }; + + ns.GridApplicationController.prototype.onSizePickerChanged_ = function (size) { + pskl.UserSettings.set(pskl.UserSettings.GRID_WIDTH, size); + }; + + ns.GridApplicationController.prototype.onEnableGridChange_ = function (evt) { + pskl.UserSettings.set(pskl.UserSettings.GRID_ENABLED, evt.currentTarget.checked); }; })(); diff --git a/src/js/rendering/frame/FrameRenderer.js b/src/js/rendering/frame/FrameRenderer.js index 1a802d49..0a48130a 100644 --- a/src/js/rendering/frame/FrameRenderer.js +++ b/src/js/rendering/frame/FrameRenderer.js @@ -55,7 +55,7 @@ this.displayCanvas = null; this.setDisplaySize(renderingOptions.width, renderingOptions.height); - this.setGridWidth(pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH)); + this.setGridWidth(this.getUserGridWidth_()); $.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this)); }; @@ -180,11 +180,18 @@ }; ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) { - if (settingName == pskl.UserSettings.GRID_WIDTH) { - this.setGridWidth(settingValue); + var settings = pskl.UserSettings; + if (settingName == settings.GRID_WIDTH || settingName == settings.GRID_ENABLED) { + this.setGridWidth(this.getUserGridWidth_()); } }; + ns.FrameRenderer.prototype.getUserGridWidth_ = function () { + var gridEnabled = pskl.UserSettings.get(pskl.UserSettings.GRID_ENABLED); + var width = pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH); + return gridEnabled ? width : 0; + }; + /** * Transform a screen pixel-based coordinate (relative to the top-left corner of the rendered * frame) into a sprite coordinate in column and row. diff --git a/src/js/utils/UserSettings.js b/src/js/utils/UserSettings.js index b1af51bd..1ca0e8da 100644 --- a/src/js/utils/UserSettings.js +++ b/src/js/utils/UserSettings.js @@ -2,6 +2,7 @@ var ns = $.namespace('pskl'); ns.UserSettings = { + GRID_ENABLED : 'GRID_ENABLED', GRID_WIDTH : 'GRID_WIDTH', MAX_FPS : 'MAX_FPS', DEFAULT_SIZE : 'DEFAULT_SIZE', @@ -21,7 +22,8 @@ TRANSFORM_SHOW_MORE: 'TRANSFORM_SHOW_MORE', APPLICATION_SETTINGS_TAB: 'APPLICATION_SETTINGS_TAB', KEY_TO_DEFAULT_VALUE_MAP_ : { - 'GRID_WIDTH' : 0, + 'GRID_ENABLED' : false, + 'GRID_WIDTH' : 1, 'MAX_FPS' : 24, 'DEFAULT_SIZE' : { width : Constants.DEFAULT.WIDTH, @@ -81,7 +83,7 @@ /** * @private */ - readFromLocalStorage_ : function(key) { + readFromLocalStorage_ : function (key) { var value = window.localStorage[key]; if (typeof value != 'undefined') { value = JSON.parse(value); @@ -92,7 +94,7 @@ /** * @private */ - writeToLocalStorage_ : function(key, value) { + writeToLocalStorage_ : function (key, value) { // TODO(grosbouddha): Catch storage exception here. window.localStorage[key] = JSON.stringify(value); }, @@ -107,7 +109,7 @@ /** * @private */ - checkKeyValidity_ : function(key) { + checkKeyValidity_ : function (key) { if (key.indexOf(pskl.service.keyboard.Shortcut.USER_SETTINGS_PREFIX) === 0) { return true; } @@ -118,4 +120,20 @@ } } }; + + // Migration script for version 11 to version 12. Initialize the GRID_ENABLED pref from + // the current GRID_WIDTH and update the stored grid width to 1 if it was set to 0. + // SHOULD BE REMOVED FOR RELEASE 13. + ns.UserSettings.migrate_to_v0_12 = function () { + var storedGridEnabled = ns.UserSettings.readFromLocalStorage_('GRID_ENABLED'); + if (typeof storedGridEnabled === 'undefined' || storedGridEnabled === null) { + var gridWidth = ns.UserSettings.get('GRID_WIDTH'); + ns.UserSettings.writeToLocalStorage_('GRID_ENABLED', gridWidth > 0); + } + + var storedGridWidth = ns.UserSettings.readFromLocalStorage_('GRID_WIDTH'); + if (storedGridWidth === 0) { + ns.UserSettings.writeToLocalStorage_('GRID_WIDTH', 1); + } + }; })(); diff --git a/src/js/widgets/SizePicker.js b/src/js/widgets/SizePicker.js new file mode 100644 index 00000000..6550c5f2 --- /dev/null +++ b/src/js/widgets/SizePicker.js @@ -0,0 +1,50 @@ +(function () { + var ns = $.namespace('pskl.widgets'); + + ns.SizePicker = function (onChange) { + this.onChange = onChange; + }; + + ns.SizePicker.prototype.init = function (container) { + this.container = container; + pskl.utils.Event.addEventListener(this.container, 'click', this.onSizeOptionClick_, this); + }; + + ns.SizePicker.prototype.destroy = function () { + pskl.utils.Event.removeAllEventListeners(this); + }; + + ns.SizePicker.prototype.getSize = function () { + var selectedOption = this.container.querySelector('.selected'); + return selectedOption ? selectedOption.dataset.size : null; + }; + + ns.SizePicker.prototype.setSize = function (size) { + if (this.getSize() === size) { + return; + } + + pskl.utils.Dom.removeClass('labeled', this.container); + pskl.utils.Dom.removeClass('selected', this.container); + var selectedOption; + if (size <= 4) { + selectedOption = this.container.querySelector('[data-size="' + size + '"]'); + } else { + selectedOption = this.container.querySelector('[data-size="4"]'); + selectedOption.classList.add('labeled'); + selectedOption.setAttribute('real-size', size); + } + if (selectedOption) { + selectedOption.classList.add('selected'); + } + }; + + ns.SizePicker.prototype.onSizeOptionClick_ = function (e) { + var size = e.target.dataset.size; + if (!isNaN(size)) { + size = parseInt(size, 10); + this.onChange(size); + this.setSize(size); + } + }; +})(); diff --git a/src/js/widgets/Tabs.js b/src/js/widgets/Tabs.js index dd4c7fab..b0ecec7f 100644 --- a/src/js/widgets/Tabs.js +++ b/src/js/widgets/Tabs.js @@ -1,19 +1,6 @@ (function () { var ns = $.namespace('pskl.widgets'); - /** - * Simple layout widget to display one step element (DOM Element) at a time. - * When switching to another step, the new step element will slide over the - * current step element. When going back to the previous step, the current - * step element will slide out from the container to reveal the previous one. - * - * @param {Object} steps map of step descriptions with the step name as the key. - * Each step description contains: - * - el {Element} the DOM Element corresponding to this step - * - name {String} the name of the step (redundant with the key) - * @param {Element} container the DOM Element in which the wizard should be - * displayed. - */ ns.Tabs = function (tabs, parentController, settingsName) { this.tabs = tabs; this.parentController = parentController; diff --git a/src/piskel-script-list.js b/src/piskel-script-list.js index fceedccd..2c4b21a4 100644 --- a/src/piskel-script-list.js +++ b/src/piskel-script-list.js @@ -162,6 +162,7 @@ "js/widgets/FramePicker.js", "js/widgets/HslRgbColorPicker.js", "js/widgets/SizeInput.js", + "js/widgets/SizePicker.js", "js/widgets/SynchronizedInputs.js", "js/widgets/Tabs.js", "js/widgets/Wizard.js", diff --git a/src/piskel-style-list.js b/src/piskel-style-list.js index 6594a9e9..3760668c 100644 --- a/src/piskel-style-list.js +++ b/src/piskel-style-list.js @@ -15,7 +15,6 @@ "css/settings-resize.css", "css/settings-save.css", "css/tools.css", - "css/pensize.css", "css/icons.css", "css/color-picker-slider.css", "css/dialogs.css", @@ -39,6 +38,7 @@ "css/minimap.css", "css/widgets-anchor.css", "css/widgets-frame-picker.css", + "css/widgets-size-picker.css", "css/widgets-tabs.css", "css/widgets-wizard.css" ]; \ No newline at end of file diff --git a/src/templates/drawing-tools.html b/src/templates/drawing-tools.html index 62c174b8..6d792a96 100644 --- a/src/templates/drawing-tools.html +++ b/src/templates/drawing-tools.html @@ -1,11 +1,11 @@
-
-
-
-
-
+
+
+
+
+
    diff --git a/src/templates/settings/application/grid.html b/src/templates/settings/application/grid.html index f6cd6cec..8b2bf5b8 100644 --- a/src/templates/settings/application/grid.html +++ b/src/templates/settings/application/grid.html @@ -1,13 +1,31 @@