From c13cd8b8596a538f27203b0fdfca7ba27cddb68f Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 9 Feb 2016 17:38:53 +0000 Subject: [PATCH] Fix settings dialog close actions If the Esc key or the Cancel button are used to exit the Settings dialog, any changes will be discarded. If the Apply button is used, the dialog only closes if the inputs are all valid, then saves the settings in the dialog. --- src/gui/html/js/dom.js | 36 +++++++++++++-------- src/gui/html/js/events.js | 67 ++++++++++++++++++++++----------------- src/gui/html/js/init.js | 14 +++++--- 3 files changed, 71 insertions(+), 46 deletions(-) diff --git a/src/gui/html/js/dom.js b/src/gui/html/js/dom.js index 3df6fbd5..291c3b10 100644 --- a/src/gui/html/js/dom.js +++ b/src/gui/html/js/dom.js @@ -52,27 +52,40 @@ } }, - updateSettingsDialog(settings, installedGames, gameFolder) { - const gameSelect = document.getElementById('defaultGameSelect'); + createGameItem(game) { + const menuItem = document.createElement('paper-item'); + menuItem.setAttribute('value', game.folder); + menuItem.textContent = game.name; + + return menuItem; + }, + + setGameMenuItems(games) { const gameMenu = document.getElementById('gameMenu'); + + /* First make sure game listing elements don't have any existing entries. */ + while (gameMenu.firstElementChild) { + gameMenu.removeChild(gameMenu.firstElementChild); + } + + games.forEach((game) => { + gameMenu.appendChild(this.createGameItem(game)); + }); + }, + + updateSettingsDialog(settings) { + const gameSelect = document.getElementById('defaultGameSelect'); const gameTable = document.getElementById('gameTable'); /* First make sure game listing elements don't have any existing entries. */ while (gameSelect.children.length > 1) { gameSelect.removeChild(gameSelect.lastElementChild); } - while (gameMenu.firstElementChild) { - gameMenu.removeChild(gameMenu.firstElementChild); - } gameTable.clear(); /* Now fill with new values. */ settings.games.forEach((game) => { - const menuItem = document.createElement('paper-item'); - menuItem.setAttribute('value', game.folder); - menuItem.textContent = game.name; - gameMenu.appendChild(menuItem); - gameSelect.appendChild(menuItem.cloneNode(true)); + gameSelect.appendChild(this.createGameItem(game)); const row = gameTable.addRow(game); gameTable.setReadOnly(row, ['name', 'folder', 'type']); @@ -82,9 +95,6 @@ document.getElementById('languageSelect').value = settings.language; document.getElementById('enableDebugLogging').checked = settings.enableDebugLogging; document.getElementById('updateMasterlist').checked = settings.updateMasterlist; - - this.updateEnabledGames(installedGames); - this.updateSelectedGame(gameFolder); }, }; })); diff --git a/src/gui/html/js/events.js b/src/gui/html/js/events.js index 808ec37c..3cab21aa 100644 --- a/src/gui/html/js/events.js +++ b/src/gui/html/js/events.js @@ -365,36 +365,45 @@ function onSidebarClick(evt) { function areSettingsValid() { return document.getElementById('gameTable').validate(); } -function onCloseSettingsDialog(evt) { - if (evt.target.classList.contains('accept')) { - if (!areSettingsValid()) { - return; - } - - /* Update the JS variable values. */ - const settings = { - enableDebugLogging: document.getElementById('enableDebugLogging').checked, - game: document.getElementById('defaultGameSelect').value, - games: document.getElementById('gameTable').getRowsData(false), - language: document.getElementById('languageSelect').value, - lastGame: loot.settings.lastGame, - updateMasterlist: document.getElementById('updateMasterlist').checked, - filters: loot.settings.filters, - }; - - /* Send the settings back to the C++ side. */ - loot.query('closeSettings', settings).then(JSON.parse).then((installedGames) => { - loot.installedGames = installedGames; - loot.dom.updateEnabledGames(installedGames); - }).catch(handlePromiseError).then(() => { - loot.settings = settings; - loot.dom.updateSettingsDialog(loot.settings, loot.installedGames, loot.game.folder); - }).catch(handlePromiseError); - } else { - /* Re-apply the existing settings to the settings dialog elements. */ - loot.dom.updateSettingsDialog(loot.settings, loot.installedGames, loot.game.folder); +function onApplySettings(evt) { + if (!areSettingsValid()) { + evt.stopPropagation(); } - evt.target.parentElement.parentElement.close(); +} +function onCloseSettingsDialog(evt) { + if (evt.target.id !== 'settingsDialog') { + /* The event can be fired by dropdowns in the settings dialog, so ignore + any events that don't come from the dialog itself. */ + return; + } + if (!evt.detail.confirmed) { + /* Re-apply the existing settings to the settings dialog elements. */ + loot.dom.updateSettingsDialog(loot.settings); + return; + } + + /* Update the JS variable values. */ + const settings = { + enableDebugLogging: document.getElementById('enableDebugLogging').checked, + game: document.getElementById('defaultGameSelect').value, + games: document.getElementById('gameTable').getRowsData(false), + language: document.getElementById('languageSelect').value, + lastGame: loot.settings.lastGame, + updateMasterlist: document.getElementById('updateMasterlist').checked, + filters: loot.settings.filters, + }; + + /* Send the settings back to the C++ side. */ + loot.query('closeSettings', settings).then(JSON.parse).then((installedGames) => { + loot.installedGames = installedGames; + loot.dom.updateEnabledGames(installedGames); + }).catch(handlePromiseError).then(() => { + loot.settings = settings; + loot.dom.updateSettingsDialog(loot.settings); + loot.dom.setGameMenuItems(loot.settings.games); + loot.dom.updateEnabledGames(loot.installedGames); + loot.dom.updateSelectedGame(loot.game.folder); + }).catch(handlePromiseError); } function onShowSettingsDialog() { document.getElementById('settingsDialog').open(); diff --git a/src/gui/html/js/init.js b/src/gui/html/js/init.js index 25e9128c..4f72d5a7 100644 --- a/src/gui/html/js/init.js +++ b/src/gui/html/js/init.js @@ -82,8 +82,8 @@ /* Set up event handlers for settings dialog. */ const settings = document.getElementById('settingsDialog'); - settings.getElementsByClassName('accept')[0].addEventListener('click', onCloseSettingsDialog); - settings.getElementsByClassName('cancel')[0].addEventListener('click', onCloseSettingsDialog); + settings.addEventListener('iron-overlay-closed', onCloseSettingsDialog); + settings.querySelector('[dialog-confirm]').addEventListener('tap', onApplySettings); /* Set up handler for opening and closing editors. */ document.body.addEventListener('loot-editor-open', onEditorOpen); @@ -214,7 +214,10 @@ function setSettings(appData) { return query('getSettings').then(JSON.parse).then((result) => { appData.settings = result; - dom.updateSettingsDialog(appData.settings, appData.installedGames, appData.game.folder); + dom.updateSettingsDialog(appData.settings); + loot.dom.setGameMenuItems(appData.settings.games); + loot.dom.updateEnabledGames(appData.installedGames); + loot.dom.updateSelectedGame(appData.game.folder); }); } @@ -260,7 +263,10 @@ loot.filters = new Filters(loot.l10n); translateStaticText(loot.l10n); /* Also need to update the settings UI. */ - dom.updateSettingsDialog(loot.settings, loot.installedGames, loot.game.folder); + dom.updateSettingsDialog(loot.settings); + loot.dom.setGameMenuItems(loot.settings.games); + loot.dom.updateEnabledGames(loot.installedGames); + loot.dom.updateSelectedGame(loot.game.folder); }).then(() => { return displayInitErrors(); }).then((result) => {