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.
This commit is contained in:
parent
dac1c9a748
commit
6a353ccbd3
3 changed files with 133 additions and 81 deletions
|
|
@ -28,7 +28,14 @@
|
||||||
:class="item.class"
|
:class="item.class"
|
||||||
@set-tab="setTab"
|
@set-tab="setTab"
|
||||||
>
|
>
|
||||||
<i class="material-icons">{{ item.icon }}</i>
|
<img
|
||||||
|
v-if="item.iconURL"
|
||||||
|
style="filter: grayscale(100%);width: 22px;margin-top: 5px;margin-bottom: 8px;"
|
||||||
|
:src="item.iconURL"
|
||||||
|
/>
|
||||||
|
<i v-if="!item.iconURL" class="material-icons">
|
||||||
|
{{ item.icon }}
|
||||||
|
</i>
|
||||||
</tabIcon>
|
</tabIcon>
|
||||||
<!-- Add a divider if item.divide is true -->
|
<!-- Add a divider if item.divide is true -->
|
||||||
<hr v-if="item.divide" :key="'tab-divider-' + index" />
|
<hr v-if="item.divide" :key="'tab-divider-' + index" />
|
||||||
|
|
@ -48,20 +55,6 @@
|
||||||
<i class="material-icons">{{ plugin.icon || "extension" }}</i>
|
<i class="material-icons">{{ plugin.icon || "extension" }}</i>
|
||||||
</tabIcon>
|
</tabIcon>
|
||||||
|
|
||||||
<tabIcon
|
|
||||||
v-if="imjoyEnabled"
|
|
||||||
tab-i-d="ImJoy"
|
|
||||||
title="ImJoy"
|
|
||||||
:require-connection="false"
|
|
||||||
:current-tab="currentTab"
|
|
||||||
@set-tab="setTab"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style="filter: grayscale(100%);width: 22px;margin-top: 5px;margin-bottom: 8px;"
|
|
||||||
src="https://imjoy.io/static/img/imjoy-icon.svg"
|
|
||||||
/>
|
|
||||||
</tabIcon>
|
|
||||||
|
|
||||||
<tabIcon
|
<tabIcon
|
||||||
v-for="imjoyTab in imjoyTabs"
|
v-for="imjoyTab in imjoyTabs"
|
||||||
:key="imjoyTab.id"
|
:key="imjoyTab.id"
|
||||||
|
|
@ -137,15 +130,6 @@
|
||||||
/>
|
/>
|
||||||
</tabContent>
|
</tabContent>
|
||||||
|
|
||||||
<tabContent
|
|
||||||
v-if="imjoyEnabled"
|
|
||||||
tab-i-d="ImJoy"
|
|
||||||
:require-connection="false"
|
|
||||||
:current-tab="currentTab"
|
|
||||||
>
|
|
||||||
<ImJoyContent />
|
|
||||||
</tabContent>
|
|
||||||
|
|
||||||
<tabContent
|
<tabContent
|
||||||
v-for="imjoyTab in imjoyTabs"
|
v-for="imjoyTab in imjoyTabs"
|
||||||
:key="imjoyTab.id"
|
:key="imjoyTab.id"
|
||||||
|
|
@ -185,17 +169,23 @@ import captureContent from "./tabContentComponents/captureContent.vue";
|
||||||
import slideScanContent from "./tabContentComponents/slideScanContent.vue";
|
import slideScanContent from "./tabContentComponents/slideScanContent.vue";
|
||||||
import viewContent from "./tabContentComponents/viewContent.vue";
|
import viewContent from "./tabContentComponents/viewContent.vue";
|
||||||
import settingsContent from "./tabContentComponents/settingsContent.vue";
|
import settingsContent from "./tabContentComponents/settingsContent.vue";
|
||||||
import galleryContent from "./tabContentComponents/galleryContent.vue";
|
|
||||||
import extensionContent from "./tabContentComponents/extensionContent.vue";
|
import extensionContent from "./tabContentComponents/extensionContent.vue";
|
||||||
import aboutContent from "./tabContentComponents/aboutContent.vue";
|
import aboutContent from "./tabContentComponents/aboutContent.vue";
|
||||||
import loggingContent from "./tabContentComponents/loggingContent.vue";
|
import loggingContent from "./tabContentComponents/loggingContent.vue";
|
||||||
|
// ImJoy and the gallery are loaded asynchronously to allow them to be disabled if needed
|
||||||
|
const galleryContent = () =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "gallery") */ "./tabContentComponents/galleryContent.vue"
|
||||||
|
);
|
||||||
|
const imjoyContent = () =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "imjoy" */ "./tabContentComponents/imjoyContent.vue"
|
||||||
|
);
|
||||||
|
|
||||||
// Import modal components for device initialisation
|
// Import modal components for device initialisation
|
||||||
import calibrationModal from "./modalComponents/calibrationModal.vue";
|
import calibrationModal from "./modalComponents/calibrationModal.vue";
|
||||||
import TabIcon from "./genericComponents/tabIcon.vue";
|
import TabIcon from "./genericComponents/tabIcon.vue";
|
||||||
|
|
||||||
import { mapState } from "vuex";
|
|
||||||
|
|
||||||
// Export main app
|
// Export main app
|
||||||
export default {
|
export default {
|
||||||
name: "AppContent",
|
name: "AppContent",
|
||||||
|
|
@ -214,37 +204,12 @@ export default {
|
||||||
aboutContent,
|
aboutContent,
|
||||||
loggingContent,
|
loggingContent,
|
||||||
TabIcon,
|
TabIcon,
|
||||||
ImJoyContent: () => import(/* webpackChunkName: "imjoy" */"./tabContentComponents/imjoyContent.vue")
|
imjoyContent
|
||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
plugins: [],
|
plugins: [],
|
||||||
currentTab: "view",
|
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: [
|
bottomTabs: [
|
||||||
{
|
{
|
||||||
id: "settings",
|
id: "settings",
|
||||||
|
|
@ -296,32 +261,76 @@ export default {
|
||||||
return ind;
|
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() {
|
currentTabIndex: function() {
|
||||||
return this.tabOrder.indexOf(this.currentTab);
|
return this.tabOrder.indexOf(this.currentTab);
|
||||||
},
|
},
|
||||||
|
|
||||||
imjoyEnabled: function() {
|
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
|
// Map the tabs from ImJoy's store module so we can display them
|
||||||
...mapState("imjoy", { imjoyTabs: "tabs" }),
|
...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);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
created: function() {
|
created: function() {
|
||||||
if (this.$store.getters.ready) {
|
if (this.$store.getters.ready) {
|
||||||
// Update top tabs
|
|
||||||
this.updateTopTabs(this.$store.state.IHIEnabled);
|
|
||||||
// Update plugins
|
// Update plugins
|
||||||
this.updatePlugins().then(() => {
|
this.updatePlugins().then(() => {
|
||||||
// Start initialisation modals
|
// Start initialisation modals
|
||||||
|
|
@ -346,19 +355,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
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() {
|
updatePlugins: function() {
|
||||||
return axios
|
return axios
|
||||||
.get(this.pluginsUri)
|
.get(this.pluginsUri)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,28 @@
|
||||||
for use in clinics acquiring blood smear samples using a 100x
|
for use in clinics acquiring blood smear samples using a 100x
|
||||||
oil-immersion objective, with a Raspberry Pi Camera v2.
|
oil-immersion objective, with a Raspberry Pi Camera v2.
|
||||||
</p>
|
</p>
|
||||||
|
<p class="uk-margin-small">
|
||||||
|
<label
|
||||||
|
><input v-model="imjoyEnabled" class="uk-checkbox" type="checkbox" />
|
||||||
|
Enable ImJoy plugin engine</label
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p class="uk-margin-small">
|
||||||
|
<a href="https://imjoy.io/">ImJoy</a> 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.
|
||||||
|
</p>
|
||||||
|
<p class="uk-margin-small">
|
||||||
|
<label
|
||||||
|
><input v-model="galleryEnabled" class="uk-checkbox" type="checkbox" />
|
||||||
|
Enable Gallery</label
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p class="uk-margin-small">
|
||||||
|
The "gallery" tab can cause performance issues; un-tick the box above to
|
||||||
|
disable it.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -34,18 +56,44 @@ export default {
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit("changeIHIEnabled", 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: {
|
watch: {
|
||||||
IHIEnabled: function() {
|
IHIEnabled: function() {
|
||||||
this.setLocalStorageObj("IHIEnabled", this.IHIEnabled);
|
this.setLocalStorageObj("IHIEnabled", this.IHIEnabled);
|
||||||
|
},
|
||||||
|
imjoyEnabled: function() {
|
||||||
|
this.setLocalStorageObj("imjoyEnabled", this.imjoyEnabled);
|
||||||
|
},
|
||||||
|
galleryEnabled: function() {
|
||||||
|
this.setLocalStorageObj("galleryEnabled", this.galleryEnabled);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
// Try loading settings from localStorage. If null, don't change.
|
// Try loading settings from localStorage. If null, don't change.
|
||||||
this.IHIEnabled = this.getLocalStorageObj("IHIEnabled") || this.IHIEnabled;
|
this.IHIEnabled = this.getLocalStorageObj("IHIEnabled") || this.IHIEnabled;
|
||||||
|
this.imjoyEnabled =
|
||||||
|
this.getLocalStorageObj("imjoyEnabled") || this.imjoyEnabled;
|
||||||
|
this.galleryEnabled =
|
||||||
|
this.getLocalStorageObj("galleryEnabled") || this.galleryEnabled;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ const moduleImjoy = {
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Set a parameter on the tab with a given id
|
* Set a parameter on the tab with a given id
|
||||||
*
|
*
|
||||||
* Payload should contain:
|
* Payload should contain:
|
||||||
* tab: ID of the tab to modify (not window_id)
|
* tab: ID of the tab to modify (not window_id)
|
||||||
* key: name of the property to add/change
|
* key: name of the property to add/change
|
||||||
|
|
@ -87,6 +87,8 @@ export default new Vuex.Store({
|
||||||
autoGpuPreview: false,
|
autoGpuPreview: false,
|
||||||
trackWindow: true,
|
trackWindow: true,
|
||||||
IHIEnabled: false,
|
IHIEnabled: false,
|
||||||
|
imjoyEnabled: false,
|
||||||
|
galleryEnabled: true,
|
||||||
appTheme: "system",
|
appTheme: "system",
|
||||||
activeStreams: {}
|
activeStreams: {}
|
||||||
},
|
},
|
||||||
|
|
@ -113,6 +115,12 @@ export default new Vuex.Store({
|
||||||
changeIHIEnabled(state, enabled) {
|
changeIHIEnabled(state, enabled) {
|
||||||
state.IHIEnabled = enabled;
|
state.IHIEnabled = enabled;
|
||||||
},
|
},
|
||||||
|
changeImjoyEnabled(state, enabled) {
|
||||||
|
state.imjoyEnabled = enabled;
|
||||||
|
},
|
||||||
|
changeGalleryEnabled(state, enabled) {
|
||||||
|
state.galleryEnabled = enabled;
|
||||||
|
},
|
||||||
resetState(state) {
|
resetState(state) {
|
||||||
state.waiting = false;
|
state.waiting = false;
|
||||||
state.available = false;
|
state.available = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue