Merge branch 'v2.1.0-dev' into 'master'

V2.1.0 dev

See merge request openflexure/openflexure-microscope-jsclient!45
This commit is contained in:
Joel Collins 2020-03-26 11:53:36 +00:00
commit 2af671f2d5
28 changed files with 560 additions and 240 deletions

14
package-lock.json generated
View file

@ -8586,14 +8586,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -8613,8 +8611,7 @@
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
@ -8762,7 +8759,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -16021,6 +16017,12 @@
}
}
},
"vue-plugin-load-script": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/vue-plugin-load-script/-/vue-plugin-load-script-1.2.0.tgz",
"integrity": "sha512-QbWjZSFRToSP6S0nZFsH618PsTlZgSg8m8Xv602vezznLTHYd0wAXEw0jlYND7L6BMe0KcA7cvUwLROyfBlQ4w==",
"dev": true
},
"vue-style-loader": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",

View file

@ -1,6 +1,6 @@
{
"name": "openflexure-ev",
"version": "2.0.0",
"version": "2.1.0-alpha",
"private": true,
"description": "An electron-based user client for the OpenFlexure Microscope Server",
"author": "OpenFlexure <contact@openflexure.org> (https://www.openflexure.org)",
@ -52,6 +52,7 @@
"mdns-js": "^1.0.3",
"uikit": "^3.3.3",
"vue": "^2.6.11",
"vue-plugin-load-script": "^1.2.0",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.1.2"
},

View file

@ -1,28 +1,22 @@
<template>
<div id="app" :class="handleTheme">
<!-- Grid managing whole app -->
<div
uk-grid
class="uk-height-1-1 uk-margin-remove uk-padding-remove"
margin="0"
>
<panelLeft />
<panelRight />
</div>
<div
id="app"
class="uk-height-1-1 uk-margin-remove uk-padding-remove"
:class="handleTheme"
>
<panelLeft />
</div>
</template>
<script>
// Import components
import panelLeft from "./components/panelLeft.vue";
import panelRight from "./components/panelRight.vue";
// Export main app
export default {
name: "App",
components: {
panelRight,
panelLeft
},
@ -131,4 +125,23 @@ html {
pointer-events: none;
opacity: 0.4;
}
.control-component {
overflow-y: auto;
overflow-x: hidden;
width: 300px;
height: 100%;
padding: 0;
background-color: rgba(180, 180, 180, 0.055);
border-width: 0 1px 0 0;
border-style: solid;
border-color: rgba(180, 180, 180, 0.25);
}
.view-component {
overflow-y: auto;
overflow-x: hidden;
height: 100%;
padding: 0;
}
</style>

View file

@ -1,5 +1,5 @@
<template>
<div id="paneCapture">
<div id="paneCapture" class="uk-padding-small">
<div>
<label class="uk-form-label" for="form-stacked-text">Filename</label>
<input

View file

@ -1,5 +1,5 @@
<template>
<div id="paneNavigate">
<div id="paneNavigate" class="uk-padding-small">
<div v-if="setPosition">
<ul uk-accordion="multiple: true; animation: false">
<li>

View file

@ -1,17 +0,0 @@
<template>
<div id="panePlugins">
<h3>Plugins</h3>
<div class="uk-placeholder uk-text-center">
Plugin support coming soon...
</div>
</div>
</template>
<script>
// Export main app
export default {
name: "PanePlugins"
};
</script>
<style lang="less"></style>

View file

@ -1,43 +0,0 @@
<template>
<div id="paneSettings">
<appSettings />
<ul uk-accordion="multiple: true; animation: false">
<li>
<a class="uk-accordion-title" href="#">Stream settings</a>
<div class="uk-accordion-content"><streamSettings /></div>
</li>
<li v-if="$store.getters.ready">
<a class="uk-accordion-title" href="#">Camera settings</a>
<div class="uk-accordion-content"><cameraSettings /></div>
</li>
<li v-if="$store.getters.ready">
<a class="uk-accordion-title" href="#">Microscope settings</a>
<div class="uk-accordion-content"><microscopeSettings /></div>
</li>
</ul>
</div>
</template>
<script>
import streamSettings from "./settingsComponents/streamSettings.vue";
import microscopeSettings from "./settingsComponents/microscopeSettings.vue";
import cameraSettings from "./settingsComponents/cameraSettings.vue";
import appSettings from "./settingsComponents/appSettings.vue";
// Export main app
export default {
name: "PaneSettings",
components: {
streamSettings,
cameraSettings,
microscopeSettings,
appSettings
}
};
</script>
<style lang="less"></style>

View file

@ -1,5 +1,5 @@
<template>
<div class="host-input">
<div class="host-input uk-padding-small">
<div v-if="configuration && $store.getters.ready">
<div>
<div class="uk-margin-small-bottom">

View file

@ -2,9 +2,8 @@
<div
v-if="!(requireConnection && !$store.getters.ready)"
:hidden="currentTab != id"
class="uk-width-expand"
class="uk-width-expand uk-height-1-1"
>
<div class="section-heading">{{ id }}</div>
<div class="section-content"><slot></slot></div>
</div>
</template>
@ -39,8 +38,8 @@ export default {
cursor: default;
}
.section-content,
.section-heading {
padding: 9px 10px;
.section-content {
padding: 0;
height: 100%;
}
</style>

View file

@ -10,13 +10,25 @@
class="uk-flex uk-flex-column uk-padding-remove uk-width-auto uk-height-1-1 uk-text-center"
>
<tabIcon
id="status"
v-show="!liteMode"
id="connect"
:require-connection="false"
:current-tab="currentTab"
@set-tab="setTab"
>
<i class="material-icons">bug_report</i>
</tabIcon>
<tabIcon
id="gallery"
:require-connection="true"
:current-tab="currentTab"
@set-tab="setTab"
>
<i class="material-icons">photo_library</i>
</tabIcon>
<hr />
<tabIcon
id="navigate"
:require-connection="true"
@ -61,69 +73,58 @@
<!-- Corresponding vertical tab content -->
<div
id="container-left"
:hidden="!showControlBar"
class="uk-padding-remove uk-height-1-1 uk-width-expand"
>
<div
id="component-left"
class="uk-padding-remove uk-flex uk-flex-1 panel-content"
<tabContent
id="connect"
:require-connection="false"
:current-tab="currentTab"
>
<tabContent
id="status"
:require-connection="false"
:current-tab="currentTab"
>
<paneStatus />
</tabContent>
<tabContent
id="navigate"
:require-connection="true"
:current-tab="currentTab"
>
<paneNavigate />
</tabContent>
<tabContent
id="capture"
:require-connection="true"
:current-tab="currentTab"
>
<paneCapture />
</tabContent>
<tabContent
id="settings"
:require-connection="false"
:current-tab="currentTab"
>
<paneSettings />
</tabContent>
<connectContent />
</tabContent>
<tabContent
id="gallery"
:require-connection="false"
:current-tab="currentTab"
>
<galleryContent />
</tabContent>
<tabContent
id="navigate"
:require-connection="true"
:current-tab="currentTab"
>
<navigateContent />
</tabContent>
<tabContent
id="capture"
:require-connection="true"
:current-tab="currentTab"
>
<captureContent />
</tabContent>
<tabContent
id="settings"
:require-connection="false"
:current-tab="currentTab"
>
<settingsContent />
</tabContent>
<tabContent
v-for="plugin in pluginsGuiList"
:id="plugin.id"
:key="plugin.id"
:require-connection="plugin.requiresConnection"
:current-tab="currentTab"
>
<div
v-for="form in plugin.forms"
:key="
`${form.route}/${form.name}`.replace(/\s+/g, '-').toLowerCase()
"
class="uk-flex uk-flex-column"
>
<JsonForm
:name="form.name"
:route="form.route"
:is-task="form.isTask"
:submit-label="form.submitLabel"
:schema="form.schema"
:emit-on-response="form.emitOnResponse"
@reloadForms="updatePlugins()"
/>
<hr />
</div>
</tabContent>
</div>
<tabContent
v-for="plugin in pluginsGuiList"
:id="plugin.id"
:key="plugin.id"
:require-connection="plugin.requiresConnection"
:current-tab="currentTab"
>
<extensionContent
:forms="plugin.forms"
:web-component="plugin.wc"
:view-panel="plugin.viewPanel"
@reloadForms="updatePlugins()"
/>
</tabContent>
</div>
</div>
</template>
@ -135,14 +136,13 @@ import axios from "axios";
import tabIcon from "./genericComponents/tabIcon";
import tabContent from "./genericComponents/tabContent";
// Import pane components
import paneStatus from "./controlComponents/paneStatus";
import paneNavigate from "./controlComponents/paneNavigate";
import paneCapture from "./controlComponents/paneCapture";
import paneSettings from "./controlComponents/paneSettings";
// Import plugin components
import JsonForm from "./pluginComponents/JsonForm";
// Import new content components
import connectContent from "./tabContentComponents/connectContent.vue";
import navigateContent from "./tabContentComponents/navigateContent.vue";
import captureContent from "./tabContentComponents/captureContent.vue";
import settingsContent from "./tabContentComponents/settingsContent.vue";
import galleryContent from "./tabContentComponents/galleryContent.vue";
import extensionContent from "./tabContentComponents/extensionContent.vue";
// Export main app
export default {
@ -151,19 +151,20 @@ export default {
components: {
tabIcon,
tabContent,
paneStatus,
paneNavigate,
paneCapture,
paneSettings,
JsonForm
connectContent,
navigateContent,
captureContent,
settingsContent,
galleryContent,
extensionContent
},
data: function() {
return {
plugins: [],
currentTab: "status",
showControlBar: true,
unwatchStoreFunction: null
currentTab: "connect",
unwatchStoreFunction: null,
liteMode: process.env.VUE_APP_LITEMODE == "true" ? true : false
};
},
@ -197,7 +198,7 @@ export default {
console.log("Left panel now ready");
} else {
console.log("Right panel now disabled");
this.currentTab = "status";
this.currentTab = "connect";
}
}
);
@ -225,11 +226,7 @@ export default {
});
},
setTab: function(event, tab) {
if (this.currentTab == tab) {
this.showControlBar = !this.showControlBar;
this.currentTab = "none";
} else {
this.showControlBar = true;
if (!(this.currentTab == tab)) {
this.currentTab = tab;
}
}
@ -239,15 +236,17 @@ export default {
<style scoped lang="less">
#component-left {
width: 300px;
width: 100%;
height: 100%;
}
#container-left {
overflow: hidden auto;
overflow: hidden;
background-color: rgba(180, 180, 180, 0.025);
width: 100%;
height: 100%;
}
#container-left,
#switcher-left {
border-width: 0 1px 0 0;
border-style: solid;

View file

@ -1,5 +1,5 @@
<template>
<div>
<div class="uk-padding-small">
<div class="uk-flex">
<div class="uk-text-bold uk-text-uppercase uk-width-expand">
{{ name }}
@ -203,6 +203,7 @@ export default {
updateForm() {
// Trigger a plugin form update
console.log("Emitting reloadForms");
this.$emit("reloadForms");
},

View file

@ -0,0 +1,61 @@
<template>
<div>
<div v-if="error" class="uk-padding-small uk-text-danger">
<b>{{ error }}</b>
</div>
<component
:is="componentName"
v-if="ready"
:component-base-u-r-l="ApiRootURL"
></component>
</div>
</template>
<script>
export default {
name: "WebComponentLoader",
props: {
componentURL: {
type: String,
required: true
},
componentName: {
type: String,
required: true
}
},
data: function() {
return {
ready: false,
error: null
};
},
computed: {
ApiRootURL: function() {
return `${this.$store.getters.baseUri}/api/v2`;
}
},
mounted() {
// Method 2
this.$loadScript(this.componentURL)
.then(() => {
const el = customElements.get(this.componentName);
if (el) {
this.ready = true;
} else {
this.error = `Error: No component ${this.componentName} found.`;
}
this.ready = true;
})
.catch(() => {
this.ready = false;
});
}
};
</script>
<style scoped></style>

View file

@ -0,0 +1,25 @@
<template>
<!-- Grid managing tab content -->
<div uk-grid class="uk-height-1-1 uk-margin-remove uk-padding-remove">
<div class="control-component">
<paneCapture />
</div>
<div class="view-component uk-width-expand">
<streamDisplay />
</div>
</div>
</template>
<script>
import paneCapture from "../controlComponents/paneCapture";
import streamDisplay from "../viewComponents/streamDisplay.vue";
export default {
name: "NavigateContent",
components: {
paneCapture,
streamDisplay
}
};
</script>

View file

@ -0,0 +1,27 @@
<template>
<!-- Grid managing tab content -->
<div uk-grid class="uk-height-1-1 uk-margin-remove uk-padding-remove">
<div class="view-component uk-width-expand">
<connectDisplayLite v-if="liteMode" />
<connectDisplay v-else />
</div>
</div>
</template>
<script>
import connectDisplay from "../viewComponents/connectDisplay.vue";
export default {
name: "ConnectContent",
components: {
connectDisplay
},
data: function() {
return {
liteMode: process.env.VUE_APP_LITEMODE == "true" ? true : false
};
}
};
</script>

View file

@ -0,0 +1,72 @@
<template>
<!-- Grid managing tab content -->
<div uk-grid class="uk-height-1-1 uk-margin-remove uk-padding-remove">
<div class="control-component">
<div v-if="webComponent">
<WebComponentLoader
:component-u-r-l="webComponent.href"
:component-name="webComponent.name"
/>
</div>
<!-- Handle OpenFlexure eV Forms -->
<div
v-for="form in forms"
:key="`${form.route}/${form.name}`.replace(/\s+/g, '-').toLowerCase()"
class="uk-height-1-1 uk-width-1-1"
>
<JsonForm
:name="form.name"
:route="form.route"
:is-task="form.isTask"
:submit-label="form.submitLabel"
:schema="form.schema"
:emit-on-response="form.emitOnResponse"
v-on="$listeners"
/>
</div>
</div>
<div class="view-component uk-width-expand">
<galleryDisplay v-if="viewPanel == 'gallery'" />
<settingsDisplay v-else-if="viewPanel == 'settings'" />
<streamDisplay v-else />
</div>
</div>
</template>
<script>
import JsonForm from "../pluginComponents/JsonForm";
import WebComponentLoader from "../pluginComponents/WebComponentLoader";
import streamDisplay from "../viewComponents/streamDisplay.vue";
import galleryDisplay from "../viewComponents/galleryDisplay.vue";
import settingsDisplay from "../viewComponents/settingsDisplay.vue";
export default {
name: "ExtensionContent",
components: {
JsonForm,
WebComponentLoader,
streamDisplay,
galleryDisplay,
settingsDisplay
},
props: {
forms: {
type: Array,
required: false,
default: () => []
},
webComponent: {
type: Object,
required: false,
default: null
},
viewPanel: {
type: String,
required: false,
default: "stream"
}
}
};
</script>

View file

@ -0,0 +1,19 @@
<template>
<!-- Grid managing tab content -->
<div class="view-component uk-height-1-1 uk-width-expand">
<galleryDisplay />
</div>
</template>
<script>
import galleryDisplay from "../viewComponents/galleryDisplay.vue";
export default {
name: "NavigateContent",
components: {
galleryDisplay
}
};
</script>

View file

@ -0,0 +1,25 @@
<template>
<!-- Grid managing tab content -->
<div uk-grid class="uk-height-1-1 uk-margin-remove uk-padding-remove">
<div class="control-component">
<paneNavigate />
</div>
<div class="view-component uk-width-expand">
<streamDisplay />
</div>
</div>
</template>
<script>
import paneNavigate from "../controlComponents/paneNavigate";
import streamDisplay from "../viewComponents/streamDisplay.vue";
export default {
name: "NavigateContent",
components: {
paneNavigate,
streamDisplay
}
};
</script>

View file

@ -0,0 +1,25 @@
<template>
<!-- Grid managing tab content -->
<div uk-grid class="uk-height-1-1 uk-margin-remove uk-padding-remove">
<div class="control-component">
<paneStatus />
</div>
<div class="view-component uk-width-expand uk-padding-small">
<settingsDisplay />
</div>
</div>
</template>
<script>
import paneStatus from "../controlComponents/paneStatus";
import settingsDisplay from "../viewComponents/settingsDisplay.vue";
export default {
name: "NavigateContent",
components: {
paneStatus,
settingsDisplay
}
};
</script>

View file

@ -1,6 +1,6 @@
<template>
<div
class="captureCard uk-card uk-card-default uk-card-hover uk-padding-remove uk-width-medium"
class="capture-card uk-card uk-card-default uk-card-hover uk-padding-remove uk-width-medium"
:class="{ 'uk-card-secondary': $store.state.globalSettings.darkMode }"
>
<div class="uk-card-media-top">

View file

@ -1,6 +1,6 @@
<template>
<div
class="captureCard uk-card uk-card-primary uk-card-hover uk-padding-remove uk-width-medium"
class="capture-card uk-card uk-card-primary uk-card-hover uk-padding-remove uk-width-medium"
>
<div class="uk-card-media-top">
<a href="#">

View file

@ -63,29 +63,49 @@ export default {
}
},
mounted() {
mounted: function() {
this.updateZipperUri();
},
created: function() {
// Watch for host 'ready', then update status
this.unwatchStoreFunction = this.$store.watch(
(state, getters) => {
return getters.ready;
},
ready => {
if (ready) {
// If the connection is now ready, update zipper URL
this.updateZipperUri();
}
}
);
},
methods: {
updateZipperUri: function() {
axios
.get(this.pluginsUri) // Get a list of plugins
.then(response => {
var plugins = response.data;
var foundExtension = plugins.find(
e => e.title === "org.openflexure.zipbuilder"
);
// if ZipBuilderPlugin is enabled
if (foundExtension) {
// Get plugin action links
this.zipBuilderUri = foundExtension.links.build.href;
this.zipGetterUri = foundExtension.links.get.href;
}
})
.catch(error => {
this.modalError(error); // Let mixin handle error
});
if (this.$store.state.available) {
axios
.get(this.pluginsUri) // Get a list of plugins
.then(response => {
var plugins = response.data;
var foundExtension = plugins.find(
e => e.title === "org.openflexure.zipbuilder"
);
// if ZipBuilderPlugin is enabled
if (foundExtension) {
// Get plugin action links
this.zipBuilderUri = foundExtension.links.build.href;
this.zipGetterUri = foundExtension.links.get.href;
}
})
.catch(error => {
this.modalError(error); // Let mixin handle error
});
} else {
this.zipBuilderUri = null;
this.zipGetterUri = null;
}
},
resetZipper: function() {

View file

@ -1,22 +1,24 @@
<template>
<div class="galleryDisplay uk-padding uk-padding-remove-top">
<!-- Gallery nav bar -->
<nav
class="uk-navbar-container uk-navbar-transparent navbar"
class="gallery-navbar uk-navbar-container uk-navbar-transparent"
uk-navbar="mode: click"
>
<!-- Left side controls -->
<div
class="uk-navbar-left uk-padding-remove-top uk-padding-remove-bottom"
>
<ul class="uk-navbar-nav">
<li :class="[sortDescending ? 'uk-active' : '']">
<a class="uk-icon" href="#" @click="sortDescending = true"
><i class="material-icons">keyboard_arrow_down</i></a
>
<a class="uk-icon" href="#" @click="sortDescending = true">
<i class="material-icons">keyboard_arrow_down</i>
</a>
</li>
<li :class="[!sortDescending ? 'uk-active' : '']">
<a class="uk-icon" href="#" @click="sortDescending = false"
><i class="material-icons">keyboard_arrow_up</i></a
>
<a class="uk-icon" href="#" @click="sortDescending = false">
<i class="material-icons">keyboard_arrow_up</i>
</a>
</li>
<li>
<a href="#">Filter</a>
@ -34,8 +36,8 @@
:key="tag"
class="uk-margin-small"
>
<label
><input
<label>
<input
:id="tag"
v-model="checkedTags"
class="uk-checkbox"
@ -43,8 +45,8 @@
:value="tag"
checked
/>
{{ tag }}</label
>
{{ tag }}
</label>
</div>
</form>
</ul>
@ -53,6 +55,7 @@
</ul>
</div>
<!-- Right side buttons -->
<div class="uk-navbar-right">
<div class="uk-grid">
<div>
@ -71,26 +74,34 @@
</div>
</nav>
<!-- Gallery -->
<div
v-if="$store.getters.ready"
class="uk-padding-remove-top"
uk-lightbox="toggle: .lightbox-link"
>
<!-- Folder heading -->
<div
v-if="galleryFolder"
class="uk-flex uk-flex-middle uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom"
class="gallery-folder-heading uk-flex uk-flex-middle"
>
<a href="#" class="uk-icon uk-margin-remove" @click="galleryFolder = ''"
><i class="material-icons">arrow_back</i></a
<a
href="#"
class="uk-icon uk-margin-remove"
@click="galleryFolder = ''"
>
<i class="material-icons">arrow_back</i>
</a>
<div class="uk-margin-left">
<h3 class="uk-margin-remove uk-margin-left">
<b>SCAN</b> {{ allScans[galleryFolder].metadata.image.name }}
<b>SCAN</b>
{{ allScans[galleryFolder].metadata.image.name }}
</h3>
</div>
</div>
<div class="uk-grid-medium uk-grid-match uk-margin-top" uk-grid>
<!-- Gallery capture cards -->
<div class="gallery-grid">
<div v-for="item in sortedItems" :key="item.metadata.id">
<scanCard
v-if="'isScan' in item"
@ -267,6 +278,8 @@ export default {
},
mounted() {
// Update on mount (does nothing if not connected)
this.updateCaptures();
// A global signal listener to perform a gallery refresh
this.$root.$on("globalUpdateCaptures", () => {
this.updateCaptures();
@ -309,15 +322,19 @@ export default {
methods: {
updateCaptures: function() {
console.log("Updating capture list...");
axios
.get(this.capturesUri)
.then(response => {
this.captures = response.data;
})
.catch(error => {
this.modalError(error); // Let mixin handle error
});
if (this.$store.state.available) {
console.log("Updating capture list...");
axios
.get(this.capturesUri)
.then(response => {
this.captures = response.data;
})
.catch(error => {
this.modalError(error); // Let mixin handle error
});
} else {
console.log("Delaying capture update until connection is available");
}
},
filterCaptures: function(list, filterTags) {
@ -363,9 +380,29 @@ export default {
</script>
<style scoped lang="less">
.navbar {
.gallery-navbar {
border-width: 0 0 1px 0;
border-style: solid;
border-color: rgba(180, 180, 180, 0.25);
}
.gallery-navbar,
.gallery-folder-heading {
margin-bottom: 30px;
}
.gallery-grid {
display: grid;
grid-template-columns: repeat(auto-fill, 320px);
justify-content: center;
}
.gallery-grid > div {
display: inline-block;
margin-bottom: 20px;
}
/deep/ .capture-card {
width: 300px;
height: 100%; // Used to have all cards in a row match their heights
margin-left: auto;
margin-right: auto;
}
</style>

View file

@ -1,8 +1,6 @@
<template>
<div v-if="settings" id="microscopeSettings">
<form @submit.prevent="applyConfigRequest">
<h4>Stage</h4>
<label class="uk-form-label" for="form-stacked-text"
>Backlash compensation</label
>
@ -41,7 +39,7 @@
</div>
</div>
<h4>Microscope</h4>
<br />
<div>
<label class="uk-form-label" for="form-stacked-text"
@ -55,6 +53,8 @@
/>
</div>
<br />
<button
type="submit"
class="uk-button uk-button-primary uk-form-small uk-float-right uk-margin-small uk-width-1-1"

View file

@ -7,24 +7,20 @@
>
</p>
<div class="uk-child-width-1-2" uk-grid>
<p>
<label :class="[{ 'uk-disabled': !this.$store.getters.ready }]"
><input
v-model="autoGpuPreview"
class="uk-checkbox"
type="checkbox"
/>
GPU preview</label
>
</p>
<p>
<label :class="[{ 'uk-disabled': !this.$store.getters.ready }]"
><input v-model="trackWindow" class="uk-checkbox" type="checkbox" />
Track window</label
>
</p>
</div>
<hr />
<p>
<label :class="[{ 'uk-disabled': !this.$store.getters.ready }]"
><input v-model="autoGpuPreview" class="uk-checkbox" type="checkbox" />
GPU preview</label
>
</p>
<p>
<label :class="[{ 'uk-disabled': !this.$store.getters.ready }]"
><input v-model="trackWindow" class="uk-checkbox" type="checkbox" />
Track window</label
>
</p>
</div>
</template>

View file

@ -0,0 +1,54 @@
<template>
<div id="settingsDisplay" class="uk-padding uk-height-1-1">
<div class="uk-height-1-1 uk-child-width-expand@m" uk-grid>
<div class="uk-padding-remove">
<div class="settings-pane uk-padding-small">
<h3>System settings</h3>
<appSettings />
<hr />
<streamSettings />
</div>
</div>
<div class="uk-padding-remove">
<div v-if="$store.getters.ready" class="settings-pane uk-padding-small">
<h3>Camera settings</h3>
<cameraSettings />
</div>
</div>
<div class="uk-padding-remove">
<div v-if="$store.getters.ready" class="settings-pane uk-padding-small">
<h3>Microscope settings</h3>
<microscopeSettings />
</div>
</div>
</div>
</div>
</template>
<script>
import streamSettings from "./settingsComponents/streamSettings.vue";
import microscopeSettings from "./settingsComponents/microscopeSettings.vue";
import cameraSettings from "./settingsComponents/cameraSettings.vue";
import appSettings from "./settingsComponents/appSettings.vue";
// Export main app
export default {
name: "SettingsDisplay",
components: {
streamSettings,
cameraSettings,
microscopeSettings,
appSettings
}
};
</script>
<style lang="less">
.settings-pane {
border-width: 0 1px 0 0;
border-style: solid;
border-color: rgba(180, 180, 180, 0.25);
min-height: 100%;
}
</style>

View file

@ -7,6 +7,10 @@ import UIkit from "uikit";
// Import MD icons
import "material-design-icons/iconfont/material-icons.css";
// Import load-script module
import LoadScript from "vue-plugin-load-script";
Vue.use(LoadScript);
Vue.config.productionTip = false;
Vue.mixin({