diff --git a/src/css/settings-application.css b/src/css/settings-application.css new file mode 100644 index 00000000..50184416 --- /dev/null +++ b/src/css/settings-application.css @@ -0,0 +1,3 @@ +.tiled-preview-checkbox { + vertical-align: -2px; +} \ No newline at end of file diff --git a/src/js/controller/AnimatedPreviewController.js b/src/js/controller/AnimatedPreviewController.js index 7045aa19..25a5019f 100644 --- a/src/js/controller/AnimatedPreviewController.js +++ b/src/js/controller/AnimatedPreviewController.js @@ -27,6 +27,7 @@ // the oninput event won't work on IE10 unfortunately, but at least will provide a // consistent behavior across all other browsers that support the input type range // see https://bugzilla.mozilla.org/show_bug.cgi?id=853670 + this.fpsRangeInput.on('input change', this.onFPSSliderChange.bind(this)); document.querySelector('.right-column').style.width = Constants.ANIMATED_PREVIEW_WIDTH + 'px'; @@ -43,12 +44,15 @@ this.updateZoom_(); this.updateOnionSkinPreview_(); + this.updateMaxFPS_(); this.updateContainerDimensions_(); }; ns.AnimatedPreviewController.prototype.onUserSettingsChange_ = function (evt, name, value) { if (name == pskl.UserSettings.ONION_SKIN) { this.updateOnionSkinPreview_(); + } else if (name == pskl.UserSettings.MAX_FPS) { + this.updateMaxFPS_(); } else { this.updateZoom_(); this.updateContainerDimensions_(); @@ -64,6 +68,12 @@ } }; + ns.AnimatedPreviewController.prototype.updateMaxFPS_ = function () { + var maxFps = pskl.UserSettings.get(pskl.UserSettings.MAX_FPS); + this.fpsRangeInput.get(0).setAttribute('max', maxFps); + this.setFPS(Math.min(this.fps, maxFps)); + }; + ns.AnimatedPreviewController.prototype.updateZoom_ = function () { var isTiled = pskl.UserSettings.get(pskl.UserSettings.TILED_PREVIEW); var zoom = isTiled ? 1 : this.calculateZoom_(); @@ -93,7 +103,10 @@ ns.AnimatedPreviewController.prototype.setFPS = function (fps) { if (typeof fps === 'number') { this.fps = fps; - this.fpsRangeInput.val(this.fps); + // reset + this.fpsRangeInput.get(0).value = 0; + // set proper value + this.fpsRangeInput.get(0).value = this.fps; this.fpsRangeInput.blur(); this.fpsCounterDisplay.html(this.fps + ' FPS'); } diff --git a/src/js/controller/settings/ApplicationSettingsController.js b/src/js/controller/settings/ApplicationSettingsController.js index 4364005f..9f1bc563 100644 --- a/src/js/controller/settings/ApplicationSettingsController.js +++ b/src/js/controller/settings/ApplicationSettingsController.js @@ -3,38 +3,75 @@ ns.ApplicationSettingsController = function () {}; - /** - * @public - */ ns.ApplicationSettingsController.prototype.init = function() { - // Highlight selected background picker: - var backgroundClass = pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND); - $('#background-picker-wrapper') - .find('.background-picker[data-background-class=' + backgroundClass + ']') - .addClass('selected'); + this.backgroundContainer = document.querySelector('.background-picker-wrapper'); + pskl.utils.Event.addEventListener(this.backgroundContainer, 'click', this.onBackgroundClick_, this); + + // Highlight selected background : + var background = pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND); + var selectedBackground = this.backgroundContainer.querySelector('[data-background=' + background + ']'); + if (selectedBackground) { + selectedBackground.classList.add('selected'); + } // Grid display and size var gridWidth = pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH); - $('#grid-width').val(gridWidth); - $('#grid-width').change(this.onGridWidthChange.bind(this)); + var gridSelect = document.querySelector('.grid-width-select'); + var selectedOption = gridSelect.querySelector('option[value="'+gridWidth+'"]'); + if (selectedOption) { + selectedOption.setAttribute('selected', 'selected'); + } - // Handle canvas background changes: - $('#background-picker-wrapper').click(this.onBackgroundClick.bind(this)); + pskl.utils.Event.addEventListener(gridSelect, 'change', this.onGridWidthChange_, this); + + // Tiled preview + var tiledPreview = pskl.UserSettings.get(pskl.UserSettings.TILED_PREVIEW); + var tiledPreviewCheckbox = document.querySelector('.tiled-preview-checkbox'); + if (tiledPreview) { + tiledPreviewCheckbox.setAttribute('checked', true); + } + pskl.utils.Event.addEventListener(tiledPreviewCheckbox, 'change', this.onTiledPreviewChange_, this); + + // Max FPS + var maxFpsInput = document.querySelector('.max-fps-input'); + maxFpsInput.value = pskl.UserSettings.get(pskl.UserSettings.MAX_FPS); + pskl.utils.Event.addEventListener(maxFpsInput, 'change', this.onMaxFpsChange_, this); }; - ns.ApplicationSettingsController.prototype.onGridWidthChange = function (evt) { - var width = $('#grid-width').val(); - pskl.UserSettings.set(pskl.UserSettings.GRID_WIDTH, parseInt(width, 10)); + ns.ApplicationSettingsController.prototype.destroy = function () { + pskl.utils.Event.removeAllEventListeners(this); + this.backgroundContainer = null; }; - ns.ApplicationSettingsController.prototype.onBackgroundClick = function (evt) { - var target = $(evt.target).closest('.background-picker'); - if (target.length) { - var backgroundClass = target.data('background-class'); - pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, backgroundClass); + ns.ApplicationSettingsController.prototype.onGridWidthChange_ = function (evt) { + var width = parseInt(evt.target.value, 10); + pskl.UserSettings.set(pskl.UserSettings.GRID_WIDTH, width); + }; - $('.background-picker').removeClass('selected'); - target.addClass('selected'); + ns.ApplicationSettingsController.prototype.onTiledPreviewChange_ = function (evt) { + pskl.UserSettings.set(pskl.UserSettings.TILED_PREVIEW, evt.currentTarget.checked); + }; + + ns.ApplicationSettingsController.prototype.onBackgroundClick_ = function (evt) { + var target = evt.target; + var background = target.dataset.background; + if (background) { + pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, background); + var selected = this.backgroundContainer.querySelector('.selected'); + if (selected) { + selected.classList.remove('selected'); + } + target.classList.add('selected'); + } + }; + + ns.ApplicationSettingsController.prototype.onMaxFpsChange_ = function (evt) { + var target = evt.target; + var fps = parseInt(target.value, 10); + if (fps && !isNaN(fps)) { + pskl.UserSettings.set(pskl.UserSettings.MAX_FPS, fps); + } else { + target.value = pskl.UserSettings.get(pskl.UserSettings.MAX_FPS); } }; diff --git a/src/js/controller/settings/SettingsController.js b/src/js/controller/settings/SettingsController.js index 16babfae..625461bc 100644 --- a/src/js/controller/settings/SettingsController.js +++ b/src/js/controller/settings/SettingsController.js @@ -73,8 +73,15 @@ }; ns.SettingsController.prototype.loadSetting = function (setting) { + if (this.currentController && this.currentController.destroy) { + this.currentController.destroy(); + } + this.drawerContainer.innerHTML = pskl.utils.Template.get(settings[setting].template); - (new settings[setting].controller(this.piskelController)).init(); + + this.currentSetting = setting; + this.currentController = new settings[setting].controller(this.piskelController); + this.currentController.init(); this.settingsContainer.addClass(EXP_DRAWER_CLS); @@ -82,7 +89,6 @@ $('[data-setting='+setting+']').addClass(SEL_SETTING_CLS); this.isExpanded = true; - this.currentSetting = setting; }; ns.SettingsController.prototype.closeDrawer = function () { diff --git a/src/js/utils/Event.js b/src/js/utils/Event.js new file mode 100644 index 00000000..58849ce7 --- /dev/null +++ b/src/js/utils/Event.js @@ -0,0 +1,42 @@ +(function () { + var ns = $.namespace('pskl.utils'); + + ns.Event = {}; + + ns.Event.addEventListener = function (el, type, callback, scope, args) { + var listener = { + el : el, + type : type, + callback : callback, + handler : args ? callback.bind(scope, args) : callback.bind(scope) + }; + + scope.__pskl_listeners = scope.__pskl_listeners || []; + scope.__pskl_listeners.push(listener); + el.addEventListener(type, listener.handler); + }; + + ns.Event.removeEventListener = function (el, type, callback, scope) { + if (scope && scope.__pskl_listeners) { + var listeners = scope.__pskl_listeners; + for (var i = 0 ; i < listeners.length ; i++) { + if (listeners[i].callback === callback) { + el.removeEventListener(type, listeners[i].handler); + listeners.slice(i, 1); + break; + } + } + } + }; + + ns.Event.removeAllEventListeners = function (scope) { + if (scope && scope.__pskl_listeners) { + var listeners = scope.__pskl_listeners; + for (var i = 0 ; i < listeners.length ; i++) { + var listener = listeners[i]; + listener.el.removeEventListener(listener.type, listener.handler); + } + scope.__pskl_listeners = []; + } + }; +})(); \ No newline at end of file diff --git a/src/js/utils/UserSettings.js b/src/js/utils/UserSettings.js index d603b1de..3114c683 100644 --- a/src/js/utils/UserSettings.js +++ b/src/js/utils/UserSettings.js @@ -3,6 +3,7 @@ ns.UserSettings = { GRID_WIDTH : 'GRID_WIDTH', + MAX_FPS : 'MAX_FPS', CANVAS_BACKGROUND : 'CANVAS_BACKGROUND', SELECTED_PALETTE : 'SELECTED_PALETTE', TILED_PREVIEW : 'TILED_PREVIEW', @@ -11,6 +12,7 @@ KEY_TO_DEFAULT_VALUE_MAP_ : { 'GRID_WIDTH' : 0, + 'MAX_FPS' : 24, 'CANVAS_BACKGROUND' : 'lowcont-dark-canvas-background', 'SELECTED_PALETTE' : Constants.CURRENT_COLORS_PALETTE_ID, 'TILED_PREVIEW' : false, diff --git a/src/piskel-script-list.js b/src/piskel-script-list.js index 86d26d65..dea5c4f9 100644 --- a/src/piskel-script-list.js +++ b/src/piskel-script-list.js @@ -17,6 +17,7 @@ "js/utils/CanvasUtils.js", "js/utils/DateUtils.js", "js/utils/Dom.js", + "js/utils/Event.js", "js/utils/Math.js", "js/utils/FileUtils.js", "js/utils/FrameTransform.js", diff --git a/src/templates/settings/application.html b/src/templates/settings/application.html index 8138604b..11643bd2 100644 --- a/src/templates/settings/application.html +++ b/src/templates/settings/application.html @@ -1,38 +1,51 @@
- Preferences: + General
-
-
+
-
-
-
- - - - - + + + +
- - +
+ +
+
+ Preview +
+ +
+ +
+ +
+ + +