From 8d70bd75076f3abd10acb241de75c1f52622d42f Mon Sep 17 00:00:00 2001 From: Shachar Itzhaky <corwin.amber@gmail.com> Date: Sat, 15 May 2021 01:54:54 +0300 Subject: [PATCH] [feature] [ui] Attached light switch. --- ui-js/cm-provider.js | 6 +++++ ui-js/coq-layout-classic.js | 31 +++++++++++++++++-------- ui-js/coq-manager.js | 24 ++++++++++++++++---- ui-js/settings.js | 45 ++++++++++++++++++++++++++++++++----- 4 files changed, 88 insertions(+), 18 deletions(-) diff --git a/ui-js/cm-provider.js b/ui-js/cm-provider.js index 00a9130b..e9ba54fa 100644 --- a/ui-js/cm-provider.js +++ b/ui-js/cm-provider.js @@ -106,6 +106,12 @@ class CmCoqProvider { return editor; } + configure(options) { + if (options.theme) { + this.editor.setOption('theme', options.theme); + } + } + trackLineCount() { this.lineCount = this.editor.lineCount(); this.editor.on('change', ev => { diff --git a/ui-js/coq-layout-classic.js b/ui-js/coq-layout-classic.js index f817c664..8c2e2663 100644 --- a/ui-js/coq-layout-classic.js +++ b/ui-js/coq-layout-classic.js @@ -101,8 +101,7 @@ class CoqLayoutClassic { this.panel.id = 'panel-wrapper'; this.panel.innerHTML = this.html({base_path: options.base_path, ...params}); - if (options.theme) - this.panel.classList.add(`jscoq-theme-${options.theme}`); + this.configure(options); this.ide.appendChild(this.panel); @@ -135,9 +134,21 @@ class CoqLayoutClassic { .on('change', ev => this.filterLog(parseInt(ev.target.value))); this.filterLog(3); // Info + this._setupSettings(); this._preloadImages(); } + /** + * Configure or re-configure UI based on CoqManager options. + * @param {object} options + */ + configure(options) { + if (options.theme) { + this.panel.classList.remove(...this.panel.classList); + this.panel.classList.add(`jscoq-theme-${options.theme}`); + } + } + show() { this.ide.classList.add('goals-active'); this.ide.classList.remove('toggled'); @@ -191,13 +202,6 @@ class CoqLayoutClassic { return this.outline = outline_pane[0]; } - createOutline() { - var outline_pane = $('<div>').attr('id', 'outline-pane'); - $(this.ide).prepend(outline_pane); - requestAnimationFrame(() => $(this.ide).addClass('outline-active')); - return this.outline = outline_pane[0]; - } - /** * Shows a notice in the main goal pane (reserved for important messages, * such as during startup). @@ -340,6 +344,15 @@ class CoqLayoutClassic { } } + /** + * Set up hooks for when user changes settings. + */ + _setupSettings() { + this.settings.model.theme.observe(theme => { + this.configure({theme}); + }); + } + /** * Auxiliary function to improve UX by preloading images. */ diff --git a/ui-js/coq-manager.js b/ui-js/coq-manager.js index 527d812a..1e588ae2 100644 --- a/ui-js/coq-manager.js +++ b/ui-js/coq-manager.js @@ -148,6 +148,11 @@ class ProviderContainer { return new Promise(resolve => setTimeout(resolve, 0)); } + configure(options) { + for (let snippet of this.snippets) + snippet.configure(options); + } + // Get the next candidate and mark it. getNext(prev, until) { @@ -294,7 +299,7 @@ class CoqManager { } // Setup the Coq statement provider. - this.provider = this.setupProvider(elems); + this.provider = this._setupProvider(elems); // Setup the Panel UI. this.layout = new CoqLayoutClassic(this.options, {kb: this.keyTooltips()}); @@ -306,7 +311,8 @@ class CoqManager { if (this.coq) this.layout.onToggle = () => {}; }; - this.setupDragDrop(); + this._setupSettings(); + this._setupDragDrop(); // Setup pretty printer for feedback and goals this.pprint = new FormatPrettyPrint(); @@ -351,7 +357,7 @@ class CoqManager { } // Provider setup - setupProvider(elems) { + _setupProvider(elems) { var provider = new ProviderContainer(elems, this.options); @@ -394,7 +400,17 @@ class CoqManager { return provider; } - setupDragDrop() { + /** + * Set up hooks for when user changes settings. + */ + _setupSettings() { + const editorThemes = {'light': 'default', 'dark': 'blackboard'}; + this.layout.settings.model.theme.observe(theme => { + this.provider.configure({theme: editorThemes[theme]}); + }); + } + + _setupDragDrop() { $(this.layout.ide).on('dragover', (evt) => { evt.preventDefault(); evt.originalEvent.dataTransfer.dropEffect = 'link'; diff --git a/ui-js/settings.js b/ui-js/settings.js index d4412ac2..7f199b9e 100644 --- a/ui-js/settings.js +++ b/ui-js/settings.js @@ -7,7 +7,7 @@ class SettingsPanel { <label for="settings--theme"> <div class="setting"> Light switch</label> - <input id="settings--theme" type="checkbox" class="switch"> + <input id="settings--theme" type="checkbox" checked class="switch"> </div> </label> <label for="settings--company"> @@ -25,8 +25,16 @@ class SettingsPanel { `; } - constructor() { + constructor(model) { this.el = $(this.html()); + this.model = model || new CoqSettings(); + + this.el.find('#settings--theme').on('change', ev => { + this.model.theme.value = ev.target.checked ? 'light' : 'dark'; + }); + this.el.find('#settings--company').on('change', ev => { + this.model.company.value = ev.target.checked; + }); } show() { @@ -38,12 +46,39 @@ class SettingsPanel { } toggle() { - if (this.isShown()) this.hide(); + if (this.isVisible()) this.hide(); else this.show(); - return this.isShown(); + return this.isVisible(); } - isShown() { + isVisible() { return this.el.parent().length > 0; } +} + + +class CoqSettings { + constructor() { + this.theme = new ReactiveVar('light'); + this.company = new ReactiveVar(true); + } +} + +class ReactiveVar { + constructor(value) { + this._value = value; + this.observers = []; + } + + get value() { return this._value; } + set value(val) { + this._value = val; + for (let o of this.observers) { + o(val); + } + } + + observe(callback) { + this.observers.push(callback); + } } \ No newline at end of file -- GitLab