From 6a353ccbd366adf93b75681468fba3e57efec489 Mon Sep 17 00:00:00 2001 From: Richard Date: Sat, 29 May 2021 13:06:13 +0100 Subject: [PATCH] Added UI controls to enable ImJoy and gallery There are now tick boxes in "features" settings to enable/disable ImJoy and the gallery. These persist in local storage. --- .../api/static/src/components/appContent.vue | 156 +++++++++--------- .../settingsComponents/featuresSettings.vue | 48 ++++++ .../api/static/src/store.js | 10 +- 3 files changed, 133 insertions(+), 81 deletions(-) diff --git a/openflexure_microscope/api/static/src/components/appContent.vue b/openflexure_microscope/api/static/src/components/appContent.vue index 6b270fcb..44f37085 100644 --- a/openflexure_microscope/api/static/src/components/appContent.vue +++ b/openflexure_microscope/api/static/src/components/appContent.vue @@ -28,7 +28,14 @@ :class="item.class" @set-tab="setTab" > - {{ item.icon }} + + + {{ item.icon }} +
@@ -48,20 +55,6 @@ {{ plugin.icon || "extension" }} - - - - - - - - + import( + /* webpackChunkName: "gallery") */ "./tabContentComponents/galleryContent.vue" + ); +const imjoyContent = () => + import( + /* webpackChunkName: "imjoy" */ "./tabContentComponents/imjoyContent.vue" + ); // Import modal components for device initialisation import calibrationModal from "./modalComponents/calibrationModal.vue"; import TabIcon from "./genericComponents/tabIcon.vue"; -import { mapState } from "vuex"; - // Export main app export default { name: "AppContent", @@ -214,37 +204,12 @@ export default { aboutContent, loggingContent, TabIcon, - ImJoyContent: () => import(/* webpackChunkName: "imjoy" */"./tabContentComponents/imjoyContent.vue") + imjoyContent }, data: function() { return { plugins: [], currentTab: "view", - unwatchStoreFunction: null, - topTabs: [ - { - id: "view", - icon: "visibility", - component: viewContent - }, - { - id: "gallery", - icon: "photo_library", - component: galleryContent, - divide: true // Add a divider after this tab icon - }, - { - id: "navigate", - icon: "gamepad", - component: navigateContent - }, - { - id: "capture", - icon: "camera_alt", - component: captureContent, - divide: true // Add a divider after this tab icon - } - ], bottomTabs: [ { id: "settings", @@ -296,32 +261,76 @@ export default { return ind; }, + topTabs: function() { + let tabs = [ + { + id: "view", + icon: "visibility", + component: viewContent + }, + { + id: "gallery", + icon: "photo_library", + component: galleryContent, + divide: true // Add a divider after this tab icon + }, + { + id: "navigate", + icon: "gamepad", + component: navigateContent + }, + { + id: "capture", + icon: "camera_alt", + component: captureContent, + divide: true // Add a divider after this tab icon + } + ]; + if (!this.$store.state.galleryEnabled) { + tabs = tabs.filter(tab => tab.id != "gallery"); + } + if (this.$store.state.IHIEnabled) { + tabs.push({ + id: "slidescan", + icon: "settings_overscan", + component: slideScanContent, + divide: true + }); + } + if (this.$store.state.imjoyEnabled) { + tabs.push({ + id: "imjoy", + iconURL: "https://imjoy.io/static/img/imjoy-icon.svg", + component: imjoyContent, + divide: true + }); + } + return tabs; + }, + currentTabIndex: function() { return this.tabOrder.indexOf(this.currentTab); }, imjoyEnabled: function() { - return process.env.VUE_APP_ENABLE_IMJOY === "true"; + // Enable the ImJoy tab (and associated code) only if it is + // enabled client-side, and at build time. + // This means that the medical version of the microscope can + // disable the plugin architecture by setting the environment + // variable VUE_APP_ENABLE_IMJOY=false + if (process.env.VUE_APP_ENABLE_IMJOY === "true") { + return this.$store.state.imjoyEnabled; + } else { + return false; + } }, // Map the tabs from ImJoy's store module so we can display them - ...mapState("imjoy", { imjoyTabs: "tabs" }), - - // Map the setting for IHI's interface so we can watch it - ...mapState(["IHIEnabled"]) - }, - - watch: { - // Update the interface when the IHI interface is enabled/disabled - IHIEnabled: function(newValue) { - this.updateTopTabs(newValue); - } + ...mapState("imjoy", { imjoyTabs: "tabs" }) }, created: function() { if (this.$store.getters.ready) { - // Update top tabs - this.updateTopTabs(this.$store.state.IHIEnabled); // Update plugins this.updatePlugins().then(() => { // Start initialisation modals @@ -346,19 +355,6 @@ export default { }, methods: { - updateTopTabs: function(IHIEnabled) { - if (IHIEnabled) { - this.topTabs.push({ - id: "slidescan", - icon: "settings_overscan", - component: slideScanContent, - divide: true - }); - } else { - // If the connection is now disconnected, empty capture list - this.topTabs = this.topTabs.filter(tab => tab.id != "slidescan"); - } - }, updatePlugins: function() { return axios .get(this.pluginsUri) diff --git a/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/featuresSettings.vue b/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/featuresSettings.vue index 581d7c0f..14636010 100644 --- a/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/featuresSettings.vue +++ b/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/featuresSettings.vue @@ -14,6 +14,28 @@ for use in clinics acquiring blood smear samples using a 100x oil-immersion objective, with a Raspberry Pi Camera v2.

+

+ +

+

+ ImJoy enables integration with a wide + variety of microscopy and image analysis applications, including ImageJ.JS + and Kaibu. Support for ImJoy within the OFM software is currently + experimental, and it may slow down loading of the application. +

+

+ +

+

+ The "gallery" tab can cause performance issues; un-tick the box above to + disable it. +

@@ -34,18 +56,44 @@ export default { set(value) { this.$store.commit("changeIHIEnabled", value); } + }, + imjoyEnabled: { + get() { + return this.$store.state.imjoyEnabled; + }, + set(value) { + this.$store.commit("changeImjoyEnabled", value); + } + }, + galleryEnabled: { + get() { + return this.$store.state.galleryEnabled; + }, + set(value) { + this.$store.commit("changeGalleryEnabled", value); + } } }, watch: { IHIEnabled: function() { this.setLocalStorageObj("IHIEnabled", this.IHIEnabled); + }, + imjoyEnabled: function() { + this.setLocalStorageObj("imjoyEnabled", this.imjoyEnabled); + }, + galleryEnabled: function() { + this.setLocalStorageObj("galleryEnabled", this.galleryEnabled); } }, mounted() { // Try loading settings from localStorage. If null, don't change. this.IHIEnabled = this.getLocalStorageObj("IHIEnabled") || this.IHIEnabled; + this.imjoyEnabled = + this.getLocalStorageObj("imjoyEnabled") || this.imjoyEnabled; + this.galleryEnabled = + this.getLocalStorageObj("galleryEnabled") || this.galleryEnabled; } }; diff --git a/openflexure_microscope/api/static/src/store.js b/openflexure_microscope/api/static/src/store.js index 8023b829..c9965d3e 100644 --- a/openflexure_microscope/api/static/src/store.js +++ b/openflexure_microscope/api/static/src/store.js @@ -39,7 +39,7 @@ const moduleImjoy = { }, /** * Set a parameter on the tab with a given id - * + * * Payload should contain: * tab: ID of the tab to modify (not window_id) * key: name of the property to add/change @@ -87,6 +87,8 @@ export default new Vuex.Store({ autoGpuPreview: false, trackWindow: true, IHIEnabled: false, + imjoyEnabled: false, + galleryEnabled: true, appTheme: "system", activeStreams: {} }, @@ -113,6 +115,12 @@ export default new Vuex.Store({ changeIHIEnabled(state, enabled) { state.IHIEnabled = enabled; }, + changeImjoyEnabled(state, enabled) { + state.imjoyEnabled = enabled; + }, + changeGalleryEnabled(state, enabled) { + state.galleryEnabled = enabled; + }, resetState(state) { state.waiting = false; state.available = false;