Merge branch 'click_to_move' into 'master'

Click to move

See merge request openflexure/openflexure-microscope-jsclient!47
This commit is contained in:
Joel Collins 2020-04-14 10:36:56 +00:00
commit 7fc202aea1
5 changed files with 206 additions and 18 deletions

41
package-lock.json generated
View file

@ -8876,7 +8876,8 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -8897,12 +8898,14 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -8917,17 +8920,20 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -9044,7 +9050,8 @@
"inherits": { "inherits": {
"version": "2.0.4", "version": "2.0.4",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -9056,6 +9063,7 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -9070,6 +9078,7 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -9077,12 +9086,14 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.9.0", "version": "2.9.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -9101,6 +9112,7 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -9190,7 +9202,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -9202,6 +9215,7 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -9287,7 +9301,8 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -9323,6 +9338,7 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -9342,6 +9358,7 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -9385,12 +9402,14 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.1.1", "version": "3.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
} }
} }
}, },

View file

@ -172,7 +172,8 @@ export default {
isAutofocusing: 0, isAutofocusing: 0,
moveLock: false, moveLock: false,
fastAutofocusUri: null, fastAutofocusUri: null,
normalAutofocusUri: null normalAutofocusUri: null,
moveInImageCoordinatesUri: null
}; };
}, },
@ -196,6 +197,10 @@ export default {
this.$root.$on("globalMoveEvent", (x, y, z, absolute) => { this.$root.$on("globalMoveEvent", (x, y, z, absolute) => {
this.moveRequest(x, y, z, absolute); this.moveRequest(x, y, z, absolute);
}); });
// A global signal listener to perform a move action in pixels
this.$root.$on("globalMoveInImageCoordinatesEvent", (x, y, absolute) => {
this.moveInImageCoordinatesRequest(x, y, absolute);
});
this.$root.$on("globalMoveStepEvent", (x_steps, y_steps, z_steps) => { this.$root.$on("globalMoveStepEvent", (x_steps, y_steps, z_steps) => {
this.moveRequest( this.moveRequest(
x_steps * this.stepXy, x_steps * this.stepXy,
@ -208,6 +213,7 @@ export default {
this.updatePosition(); this.updatePosition();
// Look for autofocus plugin // Look for autofocus plugin
this.updateAutofocusUri(); this.updateAutofocusUri();
this.updateMoveInImageCoordinatesUri();
}, },
beforeDestroy() { beforeDestroy() {
@ -252,6 +258,35 @@ export default {
} }
}, },
moveInImageCoordinatesRequest: function(x, y) {
console.log(`Sending move request in image coordinates: ${x}, ${y}`);
// If not movement-locked
if (!this.moveLock) {
// Lock move requests
this.moveLock = true;
if (!this.moveInImageCoordinatesUri){
this.modalError("Moving in image coordinates is not supported - you will need to upgrade your microscope's software.");
}
// Send move request
axios
.post(this.moveInImageCoordinatesUri, {
x: y, // NB the coordinates are numpy/PIL style, meaning X and Y are swapped.
y: x,
})
.then(() => {
this.updatePosition(); // Update the position in text boxes
})
.catch(error => {
this.modalError(error); // Let mixin handle error
})
.then(() => {
this.moveLock = false; // Release the move lock
});
}
},
zeroRequest: function() { zeroRequest: function() {
// Send move request // Send move request
axios axios
@ -293,6 +328,24 @@ export default {
.catch(error => { .catch(error => {
this.modalError(error); // Let mixin handle error this.modalError(error); // Let mixin handle error
}); });
},
updateMoveInImageCoordinatesUri: 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.camera_stage_mapping"
);
if (foundExtension) {
// Get plugin action link
this.moveInImageCoordinatesUri = foundExtension.links.move_in_image_coordinates.href;
}
})
.catch(error => {
this.modalError(error); // Let mixin handle error
});
} }
} }
}; };

View file

@ -0,0 +1,111 @@
<template>
<div id="cameraStageMappingSettings">
<form @submit.prevent="applyConfigRequest">
<!--Show auto calibrate if default plugin is enabled-->
<div v-if="'calibrate_xy' in recalibrationLinks" class="uk-margin-small">
<taskSubmitter
:can-terminate="false"
:requires-confirmation="true"
:confirmation-message="
'Start recalibration of the stage to the camera? This may take a while, and the microscope will be locked during this time.'
"
:submit-url="recalibrationLinks.calibrate_xy.href"
:submit-label="'Auto-Calibrate using camera'"
@response="onRecalibrateResponse"
@error="onRecalibrateError"
>
</taskSubmitter>
</div>
</form>
</div>
</template>
<script>
import axios from "axios";
import taskSubmitter from "../../genericComponents/taskSubmitter";
// Export main app
export default {
name: "CameraStageMappingSettings",
components: {
taskSubmitter
},
data: function() {
return {
settings: null,
recalibrationLinks: {},
isCalibrating: false
};
},
computed: {
settingsUri: function() {
return `${this.$store.getters.baseUri}/api/v2/instrument/settings`;
},
pluginsUri: function() {
return `${this.$store.getters.baseUri}/api/v2/extensions`;
}
},
mounted() {
this.updateSettings();
this.updateRecalibrationLinks();
},
methods: {
updateSettings: function() {
axios
.get(this.settingsUri)
.then(response => {
this.settings = response.data.extensions['org.openflexure.camera_stage_mapping'];
})
.catch(error => {
this.modalError(error); // Let mixin handle error
this.settings = {};
});
},
updateRecalibrationLinks: 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.camera_stage_mapping"
);
// if camera-stage mapping extension is enabled
if (foundExtension) {
// Get plugin action link
this.recalibrationLinks = foundExtension.links;
} else {
this.recalibrationLinks = {}
}
})
.catch(error => {
this.modalError(error); // Let mixin handle error
});
},
onRecalibrateResponse: function() {
this.modalNotify("Finished stage-to-camera calibration.");
// Update local settings
this.updateSettings();
},
onRecalibrateError: function(error) {
this.modalError(error); // Let mixin handle error
}
}
};
</script>
<style lang="less">
.center-spinner {
margin-left: auto;
margin-right: auto;
}
</style>

View file

@ -15,6 +15,12 @@
<cameraSettings /> <cameraSettings />
</div> </div>
</div> </div>
<div class="uk-padding-remove">
<div v-if="$store.getters.ready" class="settings-pane uk-padding-small">
<h3>Camera/stage mapping settings</h3>
<cameraStageMappingSettings />
</div>
</div>
<div class="uk-padding-remove"> <div class="uk-padding-remove">
<div v-if="$store.getters.ready" class="settings-pane uk-padding-small"> <div v-if="$store.getters.ready" class="settings-pane uk-padding-small">
<h3>Microscope settings</h3> <h3>Microscope settings</h3>
@ -30,6 +36,7 @@ import streamSettings from "./settingsComponents/streamSettings.vue";
import microscopeSettings from "./settingsComponents/microscopeSettings.vue"; import microscopeSettings from "./settingsComponents/microscopeSettings.vue";
import cameraSettings from "./settingsComponents/cameraSettings.vue"; import cameraSettings from "./settingsComponents/cameraSettings.vue";
import appSettings from "./settingsComponents/appSettings.vue"; import appSettings from "./settingsComponents/appSettings.vue";
import cameraStageMappingSettings from "./settingsComponents/cameraStageMappingSettings.vue";
// Export main app // Export main app
export default { export default {
@ -39,6 +46,7 @@ export default {
streamSettings, streamSettings,
cameraSettings, cameraSettings,
microscopeSettings, microscopeSettings,
cameraStageMappingSettings,
appSettings appSettings
} }
}; };

View file

@ -123,16 +123,13 @@ export default {
let xRelative = let xRelative =
(0.5 * event.target.offsetWidth - xCoordinate) / (0.5 * event.target.offsetWidth - xCoordinate) /
event.target.offsetWidth; event.target.offsetWidth * event.target.naturalWidth;
let yRelative = let yRelative =
(0.5 * event.target.offsetHeight - yCoordinate) / (0.5 * event.target.offsetHeight - yCoordinate) /
event.target.offsetHeight; event.target.offsetHeight * event.target.naturalHeight;
let xSteps = xRelative * this.fov[0];
let ySteps = yRelative * this.fov[1];
// Emit a signal to move, acted on by panelNavigate.vue // Emit a signal to move, acted on by panelNavigate.vue
this.$root.$emit("globalMoveEvent", xSteps, ySteps, 0, false); this.$root.$emit("globalMoveInImageCoordinatesEvent", -xRelative, -yRelative);
}, },
handleResize: function() { handleResize: function() {