This commit is contained in:
Richard Bowman 2023-11-02 20:30:54 +00:00
parent 79752a2a4c
commit c5c02eb029
9 changed files with 235 additions and 227 deletions

View file

@ -351,9 +351,9 @@ export default {
.catch(error => { .catch(error => {
this.modalError(error); // Let mixin handle error this.modalError(error); // Let mixin handle error
});*/ });*/
return new Promise((resolve) => { return new Promise(resolve => {
resolve({}); resolve({});
}); });
}, },
setTab: function(event, tab) { setTab: function(event, tab) {
if (!(this.currentTab == tab)) { if (!(this.currentTab == tab)) {

View file

@ -4,10 +4,10 @@
<div class="input-and-buttons-container"> <div class="input-and-buttons-container">
<input <input
v-for="(_v, key) in value" v-for="(_v, key) in value"
:key="key"
v-model="value[key]"
class="uk-form-small numeric-setting-line-input" class="uk-form-small numeric-setting-line-input"
type="number" type="number"
v-model="value[key]"
:key="key"
@focusin="focusIn" @focusin="focusIn"
@focusout="focusOut" @focusout="focusOut"
@keydown="keyDown" @keydown="keyDown"
@ -18,87 +18,89 @@
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import axios from "axios"; import axios from "axios";
export default { export default {
name: "MultiNumericSettingLine", name: "MultiNumericSettingLine",
props: { props: {
label: { label: {
type: String, type: String,
required: true required: true
}, },
propertyUrl: { propertyUrl: {
type: String, type: String,
required: true required: true
}, },
readBackDelay: { readBackDelay: {
type: Number, type: Number,
default: undefined, default: undefined,
required: false required: false
}, }
}, },
data: () => { data: () => {
return { return {
value: {}, value: {},
valueOnEnter: undefined valueOnEnter: undefined
} };
}, },
computed: { computed: {
readBack: function() { readBack: function() {
return this.readBackDelay !== undefined; return this.readBackDelay !== undefined;
} }
}, },
mounted() { mounted() {
this.readProperty(); this.readProperty();
}, },
methods: { methods: {
readProperty: async function() { readProperty: async function() {
let response = await axios.get(this.propertyUrl) let response = await axios.get(this.propertyUrl);
this.value = response.data this.value = response.data;
console.log("Read property", this.propertyUrl, response.data) console.log("Read property", this.propertyUrl, response.data);
return response.data return response.data;
}, },
writeProperty: async function() { writeProperty: async function() {
try { try {
let requestedValue = Number(this.value) let requestedValue = Number(this.value);
await axios.post(this.propertyUrl, requestedValue) await axios.post(this.propertyUrl, requestedValue);
if(this.readBack) { if (this.readBack) {
await new Promise(r => setTimeout(r, this.readBackDelay)) await new Promise(r => setTimeout(r, this.readBackDelay));
let newVal = await this.readProperty() let newVal = await this.readProperty();
if(newVal == requestedValue) { if (newVal == requestedValue) {
await this.modalNotify(`Set ${this.label} to ${newVal}.`) await this.modalNotify(`Set ${this.label} to ${newVal}.`);
} else { } else {
await this.modalNotify(`Set ${this.label} to ${newVal} (requested ${requestedValue}).`) await this.modalNotify(
} `Set ${this.label} to ${newVal} (requested ${requestedValue}).`
} else { );
await this.modalNotify(`Set ${this.label} to ${this.value}.`); }
} } else {
} catch(error) { await this.modalNotify(`Set ${this.label} to ${this.value}.`);
this.modalError(error); // Let mixin handle error
} }
} catch (error) {
this.modalError(error); // Let mixin handle error
}
}, },
focusIn: function(event) { focusIn: function(event) {
this.valueOnEnter = event.target.value; this.valueOnEnter = event.target.value;
}, },
focusOut: function(event) { focusOut: function(event) {
if (this.valueOnEnter != event.target.value) { if (this.valueOnEnter != event.target.value) {
this.writeProperty(event.target.value); this.writeProperty(event.target.value);
} }
}, },
keyDown: function(event) { keyDown: function(event) {
// Pressing enter should set the property, whether or not we think it's changed. // Pressing enter should set the property, whether or not we think it's changed.
if (event.keyCode == 13) { if (event.keyCode == 13) {
this.writeProperty(); this.writeProperty();
} }
} }
} }
}; };
</script> </script>
@ -109,7 +111,7 @@ methods: {
} }
.numeric-setting-line-input { .numeric-setting-line-input {
display: table-cell; display: table-cell;
width:100%; width: 100%;
} }
.button-next-to-input { .button-next-to-input {
display: table-cell; display: table-cell;

View file

@ -4,10 +4,10 @@
<div class="input-and-buttons-container"> <div class="input-and-buttons-container">
<input <input
v-for="i in value.length" v-for="i in value.length"
:key="i"
v-model="value[i - 1]"
class="uk-form-small numeric-setting-line-input" class="uk-form-small numeric-setting-line-input"
type="number" type="number"
v-model="value[i - 1]"
:key="i"
@focusin="focusIn" @focusin="focusIn"
@focusout="focusOut" @focusout="focusOut"
@keydown="keyDown" @keydown="keyDown"
@ -18,87 +18,89 @@
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import axios from "axios"; import axios from "axios";
export default { export default {
name: "NumericArraySettingLine", name: "NumericArraySettingLine",
props: { props: {
label: { label: {
type: String, type: String,
required: true required: true
}, },
propertyUrl: { propertyUrl: {
type: String, type: String,
required: true required: true
}, },
readBackDelay: { readBackDelay: {
type: Number, type: Number,
default: undefined, default: undefined,
required: false required: false
}, }
}, },
data: () => { data: () => {
return { return {
value: {}, value: {},
valueOnEnter: undefined valueOnEnter: undefined
} };
}, },
computed: { computed: {
readBack: function() { readBack: function() {
return this.readBackDelay !== undefined; return this.readBackDelay !== undefined;
} }
}, },
mounted() { mounted() {
this.readProperty(); this.readProperty();
}, },
methods: { methods: {
readProperty: async function() { readProperty: async function() {
let response = await axios.get(this.propertyUrl) let response = await axios.get(this.propertyUrl);
this.value = response.data this.value = response.data;
console.log("Read property", this.propertyUrl, response.data) console.log("Read property", this.propertyUrl, response.data);
return response.data return response.data;
}, },
writeProperty: async function() { writeProperty: async function() {
try { try {
let requestedValue = this.value let requestedValue = this.value;
await axios.post(this.propertyUrl, requestedValue) await axios.post(this.propertyUrl, requestedValue);
if(this.readBack) { if (this.readBack) {
await new Promise(r => setTimeout(r, this.readBackDelay)) await new Promise(r => setTimeout(r, this.readBackDelay));
let newVal = await this.readProperty() let newVal = await this.readProperty();
if(newVal == requestedValue) { if (newVal == requestedValue) {
await this.modalNotify(`Set ${this.label} to ${newVal}.`) await this.modalNotify(`Set ${this.label} to ${newVal}.`);
} else { } else {
await this.modalNotify(`Set ${this.label} to ${newVal} (requested ${requestedValue}).`) await this.modalNotify(
} `Set ${this.label} to ${newVal} (requested ${requestedValue}).`
} else { );
await this.modalNotify(`Set ${this.label} to ${this.value}.`); }
} } else {
} catch(error) { await this.modalNotify(`Set ${this.label} to ${this.value}.`);
this.modalError(error); // Let mixin handle error
} }
} catch (error) {
this.modalError(error); // Let mixin handle error
}
}, },
focusIn: function(event) { focusIn: function(event) {
this.valueOnEnter = event.target.value; this.valueOnEnter = event.target.value;
}, },
focusOut: function(event) { focusOut: function(event) {
if (this.valueOnEnter != event.target.value) { if (this.valueOnEnter != event.target.value) {
this.writeProperty(event.target.value); this.writeProperty(event.target.value);
} }
}, },
keyDown: function(event) { keyDown: function(event) {
// Pressing enter should set the property, whether or not we think it's changed. // Pressing enter should set the property, whether or not we think it's changed.
if (event.keyCode == 13) { if (event.keyCode == 13) {
this.writeProperty(); this.writeProperty();
} }
} }
} }
}; };
</script> </script>
@ -112,10 +114,10 @@ methods: {
width: 100%; width: 100%;
} }
.numeric-setting-line-input { .numeric-setting-line-input {
flex-grow: 1; flex-grow: 1;
margin-left: 5px; margin-left: 5px;
margin-right: 5px; margin-right: 5px;
width: 6em; width: 6em;
} }
.button-next-to-input { .button-next-to-input {
flex-grow: 0; flex-grow: 0;

View file

@ -3,9 +3,9 @@
<label class="uk-form-label">{{ label }}</label> <label class="uk-form-label">{{ label }}</label>
<div class="input-and-buttons-container"> <div class="input-and-buttons-container">
<input <input
v-model="value"
class="uk-form-small numeric-setting-line-input" class="uk-form-small numeric-setting-line-input"
type="number" type="number"
v-model="value"
@focusin="focusIn" @focusin="focusIn"
@focusout="focusOut" @focusout="focusOut"
@keydown="keyDown" @keydown="keyDown"
@ -16,87 +16,89 @@
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import axios from "axios"; import axios from "axios";
export default { export default {
name: "NumericSettingLine", name: "NumericSettingLine",
props: { props: {
label: { label: {
type: String, type: String,
required: true required: true
}, },
propertyUrl: { propertyUrl: {
type: String, type: String,
required: true required: true
}, },
readBackDelay: { readBackDelay: {
type: Number, type: Number,
default: undefined, default: undefined,
required: false required: false
} }
}, },
data: () => { data: () => {
return { return {
value: undefined, value: undefined,
valueOnEnter: undefined valueOnEnter: undefined
} };
}, },
computed: { computed: {
readBack: function() { readBack: function() {
return this.readBackDelay !== undefined; return this.readBackDelay !== undefined;
} }
}, },
mounted() { mounted() {
this.readProperty(); this.readProperty();
}, },
methods: { methods: {
readProperty: async function() { readProperty: async function() {
let response = await axios.get(this.propertyUrl) let response = await axios.get(this.propertyUrl);
this.value = response.data this.value = response.data;
console.log("Read property", this.propertyUrl, response.data) console.log("Read property", this.propertyUrl, response.data);
return response.data return response.data;
}, },
writeProperty: async function() { writeProperty: async function() {
try { try {
let requestedValue = Number(this.value) let requestedValue = Number(this.value);
await axios.post(this.propertyUrl, requestedValue) await axios.post(this.propertyUrl, requestedValue);
if(this.readBack) { if (this.readBack) {
await new Promise(r => setTimeout(r, this.readBackDelay)) await new Promise(r => setTimeout(r, this.readBackDelay));
let newVal = await this.readProperty() let newVal = await this.readProperty();
if(newVal == requestedValue) { if (newVal == requestedValue) {
await this.modalNotify(`Set ${this.label} to ${newVal}.`) await this.modalNotify(`Set ${this.label} to ${newVal}.`);
} else { } else {
await this.modalNotify(`Set ${this.label} to ${newVal} (requested ${requestedValue}).`) await this.modalNotify(
} `Set ${this.label} to ${newVal} (requested ${requestedValue}).`
} else { );
await this.modalNotify(`Set ${this.label} to ${this.value}.`); }
} } else {
} catch(error) { await this.modalNotify(`Set ${this.label} to ${this.value}.`);
this.modalError(error); // Let mixin handle error
} }
} catch (error) {
this.modalError(error); // Let mixin handle error
}
}, },
focusIn: function(event) { focusIn: function(event) {
this.valueOnEnter = event.target.value; this.valueOnEnter = event.target.value;
}, },
focusOut: function(event) { focusOut: function(event) {
if (this.valueOnEnter != event.target.value) { if (this.valueOnEnter != event.target.value) {
this.writeProperty(event.target.value); this.writeProperty(event.target.value);
} }
}, },
keyDown: function(event) { keyDown: function(event) {
// Pressing enter should set the property, whether or not we think it's changed. // Pressing enter should set the property, whether or not we think it's changed.
if (event.keyCode == 13) { if (event.keyCode == 13) {
this.writeProperty(); this.writeProperty();
} }
} }
} }
}; };
</script> </script>
@ -110,10 +112,10 @@ methods: {
width: 100%; width: 100%;
} }
.numeric-setting-line-input { .numeric-setting-line-input {
flex-grow: 1; flex-grow: 1;
margin-left: 5px; margin-left: 5px;
margin-right: 5px; margin-right: 5px;
width: 6em; width: 6em;
} }
.button-next-to-input { .button-next-to-input {
flex-grow: 0; flex-grow: 0;

View file

@ -142,7 +142,10 @@ export default {
if (task.status == "pending" || task.status == "running") { if (task.status == "pending" || task.status == "running") {
this.taskStarted = true; this.taskStarted = true;
this.$emit("taskStarted", this.taskId); this.$emit("taskStarted", this.taskId);
this.startPolling(task.id, task.links.find(t => t.rel==self).href); this.startPolling(
task.id,
task.links.find(t => t.rel == self).href
);
} }
} }
}); });
@ -219,33 +222,32 @@ export default {
var checkCondition = (resolve, reject) => { var checkCondition = (resolve, reject) => {
// If the condition is met, we're done! // If the condition is met, we're done!
axios.get( axios
this.taskUrl, .get(this.taskUrl, { baseURL: this.$store.getters.baseUri })
{baseURL: this.$store.getters.baseUri} .then(response => {
).then(response => { var result = response.data.status;
var result = response.data.status; // If the task ends with success
// If the task ends with success if (result == "completed") {
if (result == "completed") { resolve(response.data);
resolve(response.data); }
} // If task ends with an error
// If task ends with an error else if (result == "error") {
else if (result == "error") { // Pass the error string back with reject
// Pass the error string back with reject
reject(new Error(response.data.output)); reject(new Error(response.data.output));
} }
// If task ends with termination // If task ends with termination
else if (result == "cancelled") { else if (result == "cancelled") {
// Pass a generic termination error back with reject // Pass a generic termination error back with reject
reject(new Error("Task cancelled")); reject(new Error("Task cancelled"));
} else { } else {
// Since the task is still running, we can update the progress bar // Since the task is still running, we can update the progress bar
this.progress = response.data.progress; this.progress = response.data.progress;
// Check again after timeout // Check again after timeout
setTimeout(checkCondition, interval, resolve, reject); setTimeout(checkCondition, interval, resolve, reject);
} }
}); });
}; };
return new Promise(checkCondition); return new Promise(checkCondition);

View file

@ -221,7 +221,10 @@
</select> </select>
</div> </div>
<div class="uk-margin-small uk-margin-remove-bottom" v-if="backgroundDetectUri"> <div
v-if="backgroundDetectUri"
class="uk-margin-small uk-margin-remove-bottom"
>
<label class="uk-form-label" for="form-stacked-text"> <label class="uk-form-label" for="form-stacked-text">
<input <input
v-model="detectEmptyFieldsAndSkipAutofocus" v-model="detectEmptyFieldsAndSkipAutofocus"
@ -475,7 +478,8 @@ export default {
namemode: this.namingStyle.toLowerCase(), namemode: this.namingStyle.toLowerCase(),
autofocus_dz: afDeltas[this.scanDeltaZ], autofocus_dz: afDeltas[this.scanDeltaZ],
fast_autofocus: this.scanDeltaZ == "Fast", fast_autofocus: this.scanDeltaZ == "Fast",
detect_empty_fields_and_skip_autofocus: this.detectEmptyFieldsAndSkipAutofocus detect_empty_fields_and_skip_autofocus: this
.detectEmptyFieldsAndSkipAutofocus
}; };
}, },
smartScanPayload: function() { smartScanPayload: function() {
@ -568,7 +572,8 @@ export default {
); );
if (foundExtension) { if (foundExtension) {
// Get plugin action link // Get plugin action link
this.backgroundDetectUri = foundExtension.links.grab_and_classify_image.href; this.backgroundDetectUri =
foundExtension.links.grab_and_classify_image.href;
} }
}) })
.catch(error => { .catch(error => {

View file

@ -3,7 +3,7 @@
<div class="uk-grid uk-grid-divider uk-child-width-expand" uk-grid> <div class="uk-grid uk-grid-divider uk-child-width-expand" uk-grid>
<div class="uk-width-large"> <div class="uk-width-large">
<h3>Automatic calibration</h3> <h3>Automatic calibration</h3>
<cameraCalibrationSettings :camera-uri="cameraUri"/> <cameraCalibrationSettings :camera-uri="cameraUri" />
<h3>Manual camera settings</h3> <h3>Manual camera settings</h3>
<form @submit.prevent="applySettingsRequest"> <form @submit.prevent="applySettingsRequest">
@ -39,7 +39,7 @@
/> />
<NumericArraySettingLine <NumericArraySettingLine
label="MJPEG stream resolution" label="MJPEG stream resolution"
:property-url="cameraUri +'stream_resolution'" :property-url="cameraUri + 'stream_resolution'"
:read-back-delay="100" :read-back-delay="100"
/> />
</div> </div>
@ -104,7 +104,7 @@ export default {
miniStreamDisplay, miniStreamDisplay,
NumericSettingLine, NumericSettingLine,
NumericArraySettingLine NumericArraySettingLine
}, },
data: function() { data: function() {
return { return {

View file

@ -15,10 +15,7 @@
> >
</taskSubmitter> </taskSubmitter>
</div> </div>
<div <div v-if="'auto_expose_from_minimum' in actions" class="uk-margin-small">
v-if="'auto_expose_from_minimum' in actions"
class="uk-margin-small"
>
<taskSubmitter <taskSubmitter
:can-terminate="false" :can-terminate="false"
:requires-confirmation="false" :requires-confirmation="false"
@ -29,10 +26,7 @@
> >
</taskSubmitter> </taskSubmitter>
</div> </div>
<div <div v-if="'calibrate_white_balance' in actions" class="uk-margin-small">
v-if="'calibrate_white_balance' in actions"
class="uk-margin-small"
>
<taskSubmitter <taskSubmitter
:can-terminate="false" :can-terminate="false"
:requires-confirmation="false" :requires-confirmation="false"
@ -43,10 +37,7 @@
> >
</taskSubmitter> </taskSubmitter>
</div> </div>
<div <div v-if="'calibrate_lens_shading' in actions" class="uk-margin-small">
v-if="'calibrate_lens_shading' in actions"
class="uk-margin-small"
>
<taskSubmitter <taskSubmitter
:can-terminate="false" :can-terminate="false"
:requires-confirmation="true" :requires-confirmation="true"
@ -62,7 +53,7 @@
</taskSubmitter> </taskSubmitter>
</div> </div>
<div <div
v-show="showExtraSettings" v-show="showExtraSettings"
v-if="'flatten_lens_shading_table' in actions" v-if="'flatten_lens_shading_table' in actions"
class="uk-child-width-expand" class="uk-child-width-expand"
@ -77,11 +68,12 @@
> >
</taskSubmitter> </taskSubmitter>
</div> </div>
<div <div
v-show="showExtraSettings" v-show="showExtraSettings"
v-if="'reset_lens_shading' in actions" v-if="'reset_lens_shading' in actions"
class="uk-child-width-expand" class="uk-child-width-expand"
> <taskSubmitter >
<taskSubmitter
:can-terminate="false" :can-terminate="false"
:requires-confirmation="false" :requires-confirmation="false"
:submit-url="cameraUri + 'reset_lens_shading'" :submit-url="cameraUri + 'reset_lens_shading'"
@ -132,13 +124,16 @@ export default {
methods: { methods: {
updateActions: async function() { updateActions: async function() {
try{ try {
let response = await axios.get(this.cameraUri) // Get the thing description let response = await axios.get(this.cameraUri); // Get the thing description
let td = response.data let td = response.data;
this.actions = td.actions this.actions = td.actions;
console.log("full auto calibrate in actions", 'full_auto_calibrate' in this.actions) console.log(
} catch(error) { "full auto calibrate in actions",
this.modalError(error) // Let mixin handle error "full_auto_calibrate" in this.actions
);
} catch (error) {
this.modalError(error); // Let mixin handle error
} }
}, },

View file

@ -1,3 +1,3 @@
module.exports = { module.exports = {
outputDir: '../openflexure_microscope/api/static/dist', outputDir: "../openflexure_microscope/api/static/dist"
}; };