mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Settings dialog improvements.
* Game name, type and folder are read-only to prevent issues identifying a game and with desync of behaviours. * Cancelling the dialog resets the its controls' values. * Applying the dialog updates the JS settings vars, and sends them to C++. It also updates the game menu contents. * The current game can no longer be deleted. * Added masterlist update setting control.
This commit is contained in:
@@ -178,7 +178,7 @@ var pluginCardProto = Object.create(HTMLElement.prototype, {
|
||||
|
||||
var tables = this.shadowRoot.getElementsByTagName('table');
|
||||
for (var j = 0; j < tables.length; ++j) {
|
||||
var rowsData = tables[j].getWritableRowData();
|
||||
var rowsData = tables[j].getRowsData(true);
|
||||
if (rowsData.length > 0) {
|
||||
if (tables[j].id == 'loadAfter') {
|
||||
plugin.userlist.after = rowsData;
|
||||
@@ -729,15 +729,14 @@ var MessageDialog = document.registerElement('message-dialog', {
|
||||
/* Create a <editable-table> element type that extends from <table>. */
|
||||
var EditableTableProto = Object.create(HTMLTableElement.prototype, {
|
||||
|
||||
getWritableRowData: {
|
||||
value: function() {
|
||||
getRowsData: {
|
||||
value: function(writableOnly) {
|
||||
var writableRows = [];
|
||||
var rows = this.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
|
||||
|
||||
for (var i = 0; i < rows.length; ++i) {
|
||||
var trash = rows[i].getElementsByClassName('fa-trash-o');
|
||||
|
||||
if (trash.length > 0 && !trash[0].classList.contains('hidden')) {
|
||||
if (trash.length > 0 && (!writableOnly || !trash[0].classList.contains('hidden'))) {
|
||||
var rowData = {};
|
||||
|
||||
var inputs = rows[i].getElementsByTagName('input');
|
||||
@@ -759,17 +758,49 @@ var EditableTableProto = Object.create(HTMLTableElement.prototype, {
|
||||
},
|
||||
|
||||
setReadOnly: {
|
||||
value: function(row) {
|
||||
row.getElementsByClassName('fa-trash-o')[0].classList.toggle('hidden');
|
||||
value: function(row, classMask, readOnly) {
|
||||
if (readOnly == undefined) {
|
||||
readOnly = true;
|
||||
}
|
||||
|
||||
var trash = row.getElementsByClassName('fa-trash-o')[0];
|
||||
if (classMask) {
|
||||
for (var i = 0; i < classMask.length; ++i) {
|
||||
if (trash.classList.contains(classMask[i])) {
|
||||
trash.classList.toggle('hidden', readOnly);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trash.classList.toggle('hidden', readOnly);
|
||||
}
|
||||
|
||||
var inputs = row.getElementsByTagName('input');
|
||||
for (var i = 0; i < inputs.length; ++i) {
|
||||
inputs[i].setAttribute('readonly', true);
|
||||
if (classMask) {
|
||||
for (var j = 0; j < classMask.length; ++j) {
|
||||
if (inputs[i].classList.contains(classMask[j])) {
|
||||
inputs[i].setAttribute('readonly', readOnly);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
inputs[i].setAttribute('readonly', readOnly);
|
||||
}
|
||||
}
|
||||
|
||||
var selects = row.getElementsByTagName('select');
|
||||
for (var i = 0; i < selects.length; ++i) {
|
||||
selects[i].setAttribute('disabled', true);
|
||||
if (classMask) {
|
||||
for (var j = 0; j < classMask.length; ++j) {
|
||||
if (selects[i].classList.contains(classMask[j])) {
|
||||
selects[i].setAttribute('disabled', readOnly);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
selects[i].setAttribute('disabled', readOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -230,6 +230,18 @@ function updateSelectedGame() {
|
||||
} else {
|
||||
document.getElementById('redatePluginsButton').classList.toggle('disabled', true);
|
||||
}
|
||||
|
||||
/* Also disable deletion of the game's row in the settings dialog. */
|
||||
var rows = document.getElementById('gameTable').getElementsByTagName('tbody')[0].getElementsByTagName('tr');
|
||||
for (var i = 0; i < rows.length; ++i) {
|
||||
if (rows[i].getElementsByClassName('folder').length > 0) {
|
||||
if (rows[i].getElementsByClassName('folder')[0].value == loot.game.folder) {
|
||||
document.getElementById('gameTable').setReadOnly(rows[i], ['fa-trash-o']);
|
||||
} else {
|
||||
document.getElementById('gameTable').setReadOnly(rows[i], ['fa-trash-o'], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function changeGame(evt) {
|
||||
/* First store current game info in loot.games object.
|
||||
@@ -501,17 +513,90 @@ function closeAboutDialog(evt) {
|
||||
function showAboutDialog(evt) {
|
||||
document.getElementById('about').showModal();
|
||||
}
|
||||
function updateSettingsUI() {
|
||||
var gameSelect = document.getElementById('defaultGameSelect');
|
||||
var gameMenu = document.getElementById('gameMenu').firstElementChild;
|
||||
var gameTable = document.getElementById('gameTable');
|
||||
|
||||
/* First make sure game listing elements don't have any existing entries. */
|
||||
while (gameSelect.firstElementChild) {
|
||||
gameSelect.removeChild(gameSelect.firstElementChild);
|
||||
}
|
||||
while (gameMenu.firstElementChild) {
|
||||
gameMenu.removeChild(gameMenu.firstElementChild);
|
||||
}
|
||||
gameTable.clear();
|
||||
|
||||
/* Now fill with new values. */
|
||||
for (var i = 0; i < loot.settings.games.length; ++i) {
|
||||
var option = document.createElement('option');
|
||||
option.value = loot.settings.games[i].folder;
|
||||
option.textContent = loot.settings.games[i].name;
|
||||
gameSelect.appendChild(option);
|
||||
|
||||
var li = document.createElement('li');
|
||||
li.setAttribute('data-action', 'change-game');
|
||||
li.setAttribute('data-target', loot.settings.games[i].folder);
|
||||
|
||||
if (loot.installedGames.indexOf(loot.settings.games[i].folder) == -1) {
|
||||
li.classList.toggle('disabled', true);
|
||||
}
|
||||
|
||||
var icon = document.createElement('span');
|
||||
icon.className = 'fa fa-fw';
|
||||
li.appendChild(icon);
|
||||
|
||||
var text = document.createElement('span');
|
||||
text.textContent = loot.settings.games[i].name;
|
||||
li.appendChild(text);
|
||||
|
||||
gameMenu.appendChild(li);
|
||||
|
||||
var row = gameTable.addRow(loot.settings.games[i]);
|
||||
gameTable.setReadOnly(row, ['name','folder','type']);
|
||||
}
|
||||
|
||||
/* Highlight game in menu. */
|
||||
updateSelectedGame();
|
||||
|
||||
gameSelect.value = loot.settings.game;
|
||||
document.getElementById('languageSelect').value = loot.settings.language;
|
||||
document.getElementById('debugVerbositySelect').value = loot.settings.debugVerbosity;
|
||||
document.getElementById('updateMasterlist').checked = loot.settings.updateMasterlist;
|
||||
}
|
||||
function closeSettingsDialog(evt) {
|
||||
if (!areSettingsValid()) {
|
||||
evt.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.target.returnValue == 'true') {
|
||||
var dialog = evt.target.parentElement.parentElement;
|
||||
if (evt.target.classList.contains('accept')) {
|
||||
/* Update the JS variable values. */
|
||||
var settings = {
|
||||
debugVerbosity: document.getElementById('debugVerbositySelect').value,
|
||||
game: document.getElementById('defaultGameSelect').value,
|
||||
games: document.getElementById('gameTable').getRowsData(false),
|
||||
language: document.getElementById('languageSelect').value,
|
||||
lastGame: loot.game.folder,
|
||||
updateMasterlist: document.getElementById('updateMasterlist').value,
|
||||
};
|
||||
|
||||
/* Send the settings back to the C++ side. */
|
||||
var request = JSON.stringify({
|
||||
name: 'closeSettings',
|
||||
args: [
|
||||
settings
|
||||
]
|
||||
});
|
||||
loot.query(request).catch(processCefError);
|
||||
|
||||
loot.settings = settings;
|
||||
|
||||
} else {
|
||||
|
||||
/* Re-apply the existing settings to the settings dialog elements. */
|
||||
updateSettingsUI();
|
||||
}
|
||||
dialog.close();
|
||||
}
|
||||
|
||||
function showSettingsDialog(evt) {
|
||||
@@ -623,18 +708,10 @@ function setupEventHandlers() {
|
||||
|
||||
/* Set up event handlers for settings dialog. */
|
||||
var settings = document.getElementById('settings');
|
||||
settings.addEventListener('close', closeSettingsDialog, false);
|
||||
settings.addEventListener('cancel', closeSettingsDialog, false);
|
||||
|
||||
settings.getElementsByClassName('accept')[0].addEventListener('click', function(evt){
|
||||
evt.target.parentElement.parentElement.close(true);
|
||||
}, false);
|
||||
settings.getElementsByClassName('cancel')[0].addEventListener('click', function(evt){
|
||||
evt.target.parentElement.parentElement.close(false);
|
||||
}, false);
|
||||
settings.getElementsByClassName('accept')[0].addEventListener('click', closeSettingsDialog, false);
|
||||
settings.getElementsByClassName('cancel')[0].addEventListener('click', closeSettingsDialog, false);
|
||||
|
||||
/* Set up about dialog handlers. */
|
||||
|
||||
document.getElementById('about').getElementsByTagName('button')[0].addEventListener('click', closeAboutDialog, false);
|
||||
|
||||
|
||||
@@ -727,43 +804,7 @@ function initVars() {
|
||||
console.log('getSettings response: ' + results[3]);
|
||||
}
|
||||
|
||||
/* Now fill game lists/table. */
|
||||
var gameSelect = document.getElementById('defaultGameSelect');
|
||||
var gameMenu = document.getElementById('gameMenu').firstElementChild;
|
||||
var gameTable = document.getElementById('gameTable');
|
||||
for (var i = 0; i < loot.settings.games.length; ++i) {
|
||||
var option = document.createElement('option');
|
||||
option.value = loot.settings.games[i].folder;
|
||||
option.textContent = loot.settings.games[i].name;
|
||||
gameSelect.appendChild(option);
|
||||
|
||||
var li = document.createElement('li');
|
||||
li.setAttribute('data-action', 'change-game');
|
||||
li.setAttribute('data-target', loot.settings.games[i].folder);
|
||||
|
||||
if (loot.installedGames.indexOf(loot.settings.games[i].folder) == -1) {
|
||||
li.classList.toggle('disabled', true);
|
||||
}
|
||||
|
||||
var icon = document.createElement('span');
|
||||
icon.className = 'fa fa-fw';
|
||||
li.appendChild(icon);
|
||||
|
||||
var text = document.createElement('span');
|
||||
text.textContent = loot.settings.games[i].name;
|
||||
li.appendChild(text);
|
||||
|
||||
gameMenu.appendChild(li);
|
||||
|
||||
gameTable.addRow(loot.settings.games[i]);
|
||||
}
|
||||
|
||||
/* Highlight game in menu. */
|
||||
updateSelectedGame();
|
||||
|
||||
gameSelect.value = loot.settings.game;
|
||||
document.getElementById('languageSelect').value = loot.settings.language;
|
||||
document.getElementById('debugVerbositySelect').value = loot.settings.debugVerbosity;
|
||||
updateSettingsUI();
|
||||
}).catch(processCefError);
|
||||
}
|
||||
|
||||
|
||||
@@ -530,7 +530,8 @@ along with LOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
<!-- Game rows go here. -->
|
||||
<tr><td colspan="4">Add new row...</td><td></td></tr>
|
||||
</table>
|
||||
<p>Language and game changes will be applied after LOOT is restarted.
|
||||
<p><input type="checkbox" id="updateMasterlist"><label for="updateMasterlist">Update masterlist before sorting</label>
|
||||
<p>Language changes will be applied after LOOT is restarted.
|
||||
<hr>
|
||||
<div class="buttons">
|
||||
<button class="accept">Apply</button>
|
||||
|
||||
Reference in New Issue
Block a user