Skip to content
This repository was archived by the owner on Oct 22, 2021. It is now read-only.

Commit 8d0c44d

Browse files
committed
✨ GUI settings editor
Fuck yeah! Open with Ctrl+Shift+S or by clicking on the settings.json file in the filesystem display.
1 parent b2b766e commit 8d0c44d

File tree

4 files changed

+263
-6
lines changed

4 files changed

+263
-6
lines changed

src/_renderer.js

Lines changed: 186 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ function initGreeter() {
422422
};
423423
// Prevent losing hardware keyboard focus on the terminal when using touch keyboard
424424
window.onmouseup = (e) => {
425-
window.term[window.currentTerm].term.focus();
425+
if (window.keyboard.linkedToTerm) window.term[window.currentTerm].term.focus();
426426
};
427427
window.term[0].term.writeln("\033[1m"+`Welcome to eDEX-UI v${electron.remote.app.getVersion()} - Electron v${process.versions.electron}`+"\033[0m");
428428

@@ -515,6 +515,184 @@ window.focusShellTab = (number) => {
515515
}
516516
};
517517

518+
// Settings editor
519+
window.openSettings = () => {
520+
// Build lists of available keyboards, themes, monitors
521+
let keyboards, themes, monitors;
522+
fs.readdirSync(keyboardsDir).forEach(kb => {
523+
if (!kb.endsWith(".json")) return;
524+
kb = kb.replace(".json", "");
525+
if (kb === window.settings.keyboard) return;
526+
keyboards += `<option>${kb}</option>`;
527+
});
528+
fs.readdirSync(themesDir).forEach(th => {
529+
if (!th.endsWith(".json")) return;
530+
th = th.replace(".json", "");
531+
if (th === window.settings.theme) return;
532+
themes += `<option>${th}</option>`;
533+
});
534+
for (let i = 0; i < electron.remote.screen.getAllDisplays().length; i++) {
535+
if (i !== window.settings.monitor) monitors += `<option>${i}</option>`;
536+
}
537+
538+
// Unlink the tactile keyboard from the terminal emulator to allow filling in the settings fields
539+
window.keyboard.detach();
540+
541+
new Modal({
542+
type: "custom",
543+
title: `Settings <i>(v${electron.remote.app.getVersion()})</i>`,
544+
html: `<table id="settingsEditor">
545+
<tr>
546+
<th>Key</th>
547+
<th>Description</th>
548+
<th>Value</th>
549+
</tr>
550+
<tr>
551+
<td>shell</td>
552+
<td>The program to run as a terminal emulator</td>
553+
<td><input type="text" id="settingsEditor-shell" value="${window.settings.shell}"></td>
554+
</tr>
555+
<tr>
556+
<td>cwd</td>
557+
<td>Working Directory to start in</td>
558+
<td><input type="text" id="settingsEditor-cwd" value="${window.settings.cwd}"></td>
559+
</tr>
560+
<tr>
561+
<td>env</td>
562+
<td>Custom shell environment override</td>
563+
<td><input type="text" id="settingsEditor-env" value="${window.settings.env}"></td>
564+
</tr>
565+
<tr>
566+
<td>keyboard</td>
567+
<td>On-screen keyboard layout code</td>
568+
<td><select id="settingsEditor-keyboard">
569+
<option>${window.settings.keyboard}</option>
570+
${keyboards}
571+
</select></td>
572+
</tr>
573+
<tr>
574+
<td>theme</td>
575+
<td>Name of the theme to load</td>
576+
<td><select id="settingsEditor-theme">
577+
<option>${window.settings.theme}</option>
578+
${themes}
579+
</select></td>
580+
</tr>
581+
<tr>
582+
<td>audio</td>
583+
<td>Activate audio sound effects</td>
584+
<td><select id="settingsEditor-audio">
585+
<option>${window.settings.audio}</option>
586+
<option>${!window.settings.audio}</option>
587+
</select></td>
588+
</tr>
589+
<tr>
590+
<td>extraAudio</td>
591+
<td>Enable extra audio FX (requires audio: true)</td>
592+
<td><select id="settingsEditor-extraAudio">
593+
<option>${window.settings.extraAudio}</option>
594+
<option>${!window.settings.extraAudio}</option>
595+
</select></td>
596+
</tr>
597+
<tr>
598+
<td>port</td>
599+
<td>Local port to use for UI-shell connection</td>
600+
<td><input type="number" id="settingsEditor-port" value="${window.settings.port}"></td>
601+
</tr>
602+
<tr>
603+
<td>pingAddr</td>
604+
<td>IPv4 address to test Internet connectivity</td>
605+
<td><input type="text" id="settingsEditor-pingAddr" value="${window.settings.pingAddr || "1.1.1.1"}"></td>
606+
</tr>
607+
<tr>
608+
<td>monitor</td>
609+
<td>Which monitor to spawn the UI in (defaults to primary display)</td>
610+
<td><select id="settingsEditor-monitor">
611+
${(typeof window.settings.monitor !== "undefined") ? "<option>"+window.settings.monitor+"</option>" : ""}
612+
${monitors}
613+
</select></td>
614+
</tr>
615+
<tr>
616+
<td>nointro</td>
617+
<td>Skip the intro boot log and logo</td>
618+
<td><select id="settingsEditor-nointro">
619+
<option>${window.settings.nointro}</option>
620+
<option>${!window.settings.nointro}</option>
621+
</select></td>
622+
</tr>
623+
<tr>
624+
<td>iface</td>
625+
<td>Override the interface used for network monitoring</td>
626+
<td><input type="text" id="settingsEditor-iface" value="${window.settings.iface}"></td>
627+
</tr>
628+
<tr>
629+
<td>allowWindowed</td>
630+
<td>Allow using F11 key to set the UI in windowed mode</td>
631+
<td><select id="settingsEditor-allowWindowed">
632+
<option>${window.settings.allowWindowed}</option>
633+
<option>${!window.settings.allowWindowed}</option>
634+
</select></td>
635+
</tr>
636+
<tr>
637+
<td>excludeSelfFromToplist</td>
638+
<td>Exclude eDEX from top processes monitoring</td>
639+
<td><select id="settingsEditor-excludeSelfFromToplist">
640+
<option>${window.settings.excludeSelfFromToplist}</option>
641+
<option>${!window.settings.excludeSelfFromToplist}</option>
642+
</select></td>
643+
</tr>
644+
<tr>
645+
<td>experimentalFeatures</td>
646+
<td>Toggle Chrome's experimental web features (DANGEROUS)</td>
647+
<td><select id="settingsEditor-experimentalFeatures">
648+
<option>${window.settings.experimentalFeatures}</option>
649+
<option>${!window.settings.experimentalFeatures}</option>
650+
</select></td>
651+
</tr>
652+
</table>
653+
<h6 id="settingsEditorStatus">Loaded values from memory</h6>
654+
<br>`,
655+
buttons: [
656+
{label: "Open in External Editor", action:`electron.shell.openExternal('file://${settingsFile}')`},
657+
{label: "Save to Disk", action: "window.writeSettingsFile()"},
658+
{label: "Reload UI", action: "window.location.reload(true);"},
659+
{label: "Restart eDEX", action: "electron.remote.app.relaunch();electron.remote.app.quit();"}
660+
]
661+
}, () => {
662+
// Link the keyboard back to the terminal
663+
window.keyboard.attach();
664+
});
665+
};
666+
667+
window.writeSettingsFile = () => {
668+
window.settings = {
669+
shell: document.getElementById("settingsEditor-shell").value || window.settings.shell,
670+
cwd: document.getElementById("settingsEditor-cwd").value || window.settings.cwd,
671+
env: document.getElementById("settingsEditor-env").value || window.settings.env,
672+
keyboard: document.getElementById("settingsEditor-keyboard").value || window.settings.keyboard,
673+
theme: document.getElementById("settingsEditor-theme").value || window.settings.theme,
674+
audio: Boolean(document.getElementById("settingsEditor-audio").value) || window.settings.audio,
675+
extraAudio: Boolean(document.getElementById("settingsEditor-extraAudio").value) || window.settings.extraAudio,
676+
pingAddr: document.getElementById("settingsEditor-pingAddr").value || window.settings.pingAddr,
677+
port: Number(document.getElementById("settingsEditor-port").value) || window.settings.port,
678+
monitor: Number(document.getElementById("settingsEditor-monitor").value) || window.settings.monitor,
679+
nointro: Boolean(document.getElementById("settingsEditor-nointro").value) || window.settings.nointro,
680+
iface: document.getElementById("settingsEditor-iface").value || window.settings.iface,
681+
allowWindowed: Boolean(document.getElementById("settingsEditor-allowWindowed").value) || window.settings.allowWindowed,
682+
excludeSelfFromToplist: Boolean(document.getElementById("settingsEditor-excludeSelfFromToplist").value) || window.settings.excludeSelfFromToplist,
683+
experimentalFeatures: Boolean(document.getElementById("settingsEditor-experimentalFeatures").value) || window.settings.experimentalFeatures
684+
};
685+
686+
Object.keys(window.settings).forEach(key => {
687+
if (window.settings[key] === "undefined") {
688+
delete window.settings[key];
689+
}
690+
});
691+
692+
fs.writeFileSync(settingsFile, JSON.stringify(window.settings, "", 4));
693+
document.getElementById("settingsEditorStatus").innerText = "New values written to settings.json file at "+new Date().toTimeString();
694+
};
695+
518696
// Global keyboard shortcuts
519697
const globalShortcut = electron.remote.globalShortcut;
520698
globalShortcut.unregisterAll();
@@ -525,6 +703,13 @@ function registerKeyboardShortcuts() {
525703
electron.remote.getCurrentWindow().webContents.toggleDevTools();
526704
});
527705

706+
// Open settings
707+
globalShortcut.register("CommandOrControl+Shift+s", () => {
708+
if (!document.getElementById("settingsEditor")) {
709+
window.openSettings();
710+
}
711+
});
712+
528713
// Copy and paste shortcuts
529714

530715
if (process.platform === "darwin") {

src/assets/css/modal.css

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ div.modal_popup > h1 {
3636
margin-bottom: 2vh;
3737
}
3838

39+
div.modal_popup > h1 i {
40+
font-size: 2.3vh;
41+
opacity: 0.6;
42+
font-style: normal;
43+
}
44+
3945
div.modal_popup > h5 {
4046
font-size: 2vh;
4147
font-weight: normal;
@@ -74,3 +80,58 @@ div.modal_popup button {
7480
padding-bottom: 0.7vh;
7581
cursor: pointer;
7682
}
83+
84+
div.modal_popup button:hover {
85+
background: rgba(var(--color_r), var(--color_g), var(--color_b), 0.5)
86+
}
87+
88+
/* Settings editor modal */
89+
table#settingsEditor, table#settingsEditor th, table#settingsEditor td {
90+
border: 0.15vh solid rgb(var(--color_r), var(--color_g), var(--color_b));
91+
border-collapse: collapse;
92+
}
93+
94+
table#settingsEditor th, table#settingsEditor td {
95+
padding: 0.3vh;
96+
}
97+
98+
table#settingsEditor th {
99+
font-size: 2vh;
100+
}
101+
102+
table#settingsEditor td {
103+
font-size: 1.7vh;
104+
}
105+
106+
table#settingsEditor td input {
107+
width: 100%;
108+
background: var(--color_light_black);
109+
color: rgb(var(--color_r), var(--color_g), var(--color_b));
110+
border: 0.15vh solid rgb(var(--color_r), var(--color_g), var(--color_b));
111+
padding: 0.4vh 0.2vh;
112+
font-size: 1.4vh;
113+
box-sizing: border-box;
114+
}
115+
116+
table#settingsEditor td input:active, table#settingsEditor td input:focus {
117+
outline: none !important;
118+
background: rgb(var(--color_r), var(--color_g), var(--color_b));
119+
color: var(--color_light_black);
120+
}
121+
122+
table#settingsEditor td select {
123+
cursor: pointer;
124+
width: 100%;
125+
background: var(--color_light_black);
126+
color: rgb(var(--color_r), var(--color_g), var(--color_b));
127+
border: 0.15vh solid rgb(var(--color_r), var(--color_g), var(--color_b));
128+
padding: 0.4vh;
129+
font-size: 1.4vh;
130+
}
131+
132+
h6#settingsEditorStatus {
133+
margin: 0;
134+
margin-top: 1vh;
135+
font-size: 1.5vh;
136+
font-style: italic;
137+
}

src/classes/filesystem.class.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ class FilesystemDisplay {
288288
if (e.type === "edex-kblayout") {
289289
cmd = `window.remakeKeyboard('${e.name.slice(0, -5)}')`;
290290
}
291-
if (e.type === "edex-settings" && process.env.editor) {
292-
cmd = `window.term[window.currentTerm].writelr('${process.env.editor} \\'${e.name.slice(0, -5)}\\'')`;
291+
if (e.type === "edex-settings") {
292+
cmd = `window.openSettings()`;
293293
}
294294

295295
let icon = "";
@@ -384,7 +384,7 @@ class FilesystemDisplay {
384384

385385
// Automatically start indexing supposed beginning CWD
386386
// See #365
387-
this.readFS(window.settings.cwd);
387+
this.readFS(window.term[window.currentTerm].cwd || window.settings.cwd);
388388
}
389389
}
390390

src/classes/modal.class.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
window.modals = [];
22

33
class Modal {
4-
constructor(options) {
4+
constructor(options, onclose) {
55
if (!options || !options.type) throw "Missing parameters";
66

77
this.type = options.type;
88
this.id = window.modals.length;
99
this.title = options.title || options.type || "Modal window";
1010
this.message = options.message || "Lorem ipsum dolor sit amet.";
11+
this.onclose = onclose;
1112
let classes = "modal_popup";
1213
let buttons = [];
1314
let zindex = 0;
@@ -26,6 +27,12 @@ class Modal {
2627
zindex = 1000;
2728
buttons.push({label:"OK", action:"window.modals["+this.id+"].close();"});
2829
break;
30+
case "custom":
31+
classes += " info custom";
32+
zindex = 500;
33+
buttons = options.buttons;
34+
buttons.push({label:"Close", action:"window.modals["+this.id+"].close();"});
35+
break;
2936
default:
3037
classes += " info";
3138
zindex = 500;
@@ -35,7 +42,7 @@ class Modal {
3542

3643
let DOMstring = `<div id="modal_${this.id}" class="${classes}" style="z-index:${zindex+this.id};">
3744
<h1>${this.title}</h1>
38-
<h5>${this.message}</h5>
45+
${this.type === "custom" ? options.html : "<h5>"+this.message+"</h5>"}
3946
<div>`;
4047
buttons.forEach((b) => {
4148
DOMstring += `<button onclick="${b.action}">${b.label}</button>`;
@@ -50,6 +57,10 @@ class Modal {
5057
setTimeout(() => {
5158
modalElement.remove();
5259
}, 100);
60+
61+
if (typeof this.onclose === "function") {
62+
this.onclose();
63+
}
5364
};
5465

5566
let tmp = document.createElement("div");

0 commit comments

Comments
 (0)