From 923083cf4da4abd05cb075ee7de5ec8613fed5a7 Mon Sep 17 00:00:00 2001 From: Tamoor Shahid Date: Tue, 20 Jan 2026 15:32:30 +0000 Subject: [PATCH 1/3] Made focus tab responsive and edited grid tags --- src/screens/OavMover/OAVMoveController.tsx | 9 ++- src/screens/OavMover/OAVSideBar.tsx | 12 +-- src/screens/OavMover/OAVStageController.tsx | 87 ++++++++++++--------- 3 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/screens/OavMover/OAVMoveController.tsx b/src/screens/OavMover/OAVMoveController.tsx index 2344426..be72572 100644 --- a/src/screens/OavMover/OAVMoveController.tsx +++ b/src/screens/OavMover/OAVMoveController.tsx @@ -221,7 +221,11 @@ function FocusMove(props: TabPanelProps) { return ( + <>
-
+ ); } diff --git a/src/screens/OavMover/OAVStageController.tsx b/src/screens/OavMover/OAVStageController.tsx index 4853258..81ff672 100644 --- a/src/screens/OavMover/OAVStageController.tsx +++ b/src/screens/OavMover/OAVStageController.tsx @@ -1,4 +1,4 @@ -import { Box, Grid2, useTheme } from "@mui/material"; +import { Grid2, useTheme } from "@mui/material"; import { OAVSideBar } from "./OAVSideBar"; import { submitAndRunPlanImmediately } from "#/blueapi/blueapi.ts"; import { readVisitFromPv, parseInstrumentSession } from "#/blueapi/visit.ts"; @@ -48,43 +48,60 @@ export function OavMover() { const fullVisit = readVisitFromPv(); return ( -
- - - - { - const [x_um, y_um] = [x / pixelsPerMicron, y / pixelsPerMicron]; + + + { + const [x_um, y_um] = [x / pixelsPerMicron, y / pixelsPerMicron]; + console.log( + `Clicked on position (${x}, ${y}) (px relative to beam centre) in original stream. Relative position in um (${x_um}, ${y_um}). Submitting to BlueAPI...`, + ); + const [x_int, y_int] = [Math.round(x), Math.round(y)]; + if (Number.isNaN(x_um) || Number.isNaN(y_um)) { + console.log("Not submitting plan while disconnected from PVs!"); + } else { + // This is an example but not useful for actual production use. + submitAndRunPlanImmediately({ + planName: "gui_gonio_move_on_click", + planParams: { position_px: [x_int, y_int] }, + instrumentSession: parseInstrumentSession(fullVisit), + }).catch((error) => { console.log( - `Clicked on position (${x}, ${y}) (px relative to beam centre) in original stream. Relative position in um (${x_um}, ${y_um}). Submitting to BlueAPI...`, + `Failed to run plan gui_gonio_move_on_click, see console and logs for full error. Reason: ${error}`, ); - const [x_int, y_int] = [Math.round(x), Math.round(y)]; - if (Number.isNaN(x_um) || Number.isNaN(y_um)) { - console.log( - "Not submitting plan while disconnected from PVs!", - ); - } else { - // This is an example but not useful for actual production use. - submitAndRunPlanImmediately({ - planName: "gui_gonio_move_on_click", - planParams: { position_px: [x_int, y_int] }, - instrumentSession: parseInstrumentSession(fullVisit), - }).catch((error) => { - console.log( - `Failed to run plan gui_gonio_move_on_click, see console and logs for full error. Reason: ${error}`, - ); - }); - } - }} - /> - - + }); + } + }} + /> + + + -
+ ); } + +/* + +xs, sm, md, lg, xl + +Anything below lg (1200px) will be one column. +Lg and above will have a side bar. +Lg will still have a compact side bar like focus tab being 2x2 grid. +XL can afford to be normal like 4 button wide focus tab. +Anything larger will just have to deal with it for now. + +*/ From 8ab3961c19334b321993cb5aae8dbba0742299d9 Mon Sep 17 00:00:00 2001 From: Tamoor Shahid Date: Fri, 20 Feb 2026 16:56:53 +0000 Subject: [PATCH 2/3] Changed dialog box to not scroll anymore --- src/screens/OavMover/OAVCoordinateSystem.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/screens/OavMover/OAVCoordinateSystem.tsx b/src/screens/OavMover/OAVCoordinateSystem.tsx index 62c58c6..16b37a5 100644 --- a/src/screens/OavMover/OAVCoordinateSystem.tsx +++ b/src/screens/OavMover/OAVCoordinateSystem.tsx @@ -119,6 +119,8 @@ export function CoordinateSystem() { onClose={handleClose} aria-labelledby="customized-dialog-title" open={open} + maxWidth="md" + scroll="body" > How to use Co-ordinate System Setup From 0db08d2a7686f04cf63df4815068fd3b254accc1 Mon Sep 17 00:00:00 2001 From: Tamoor Shahid Date: Tue, 24 Feb 2026 11:16:36 +0000 Subject: [PATCH 3/3] Refactored and improved layout --- src/screens/OavMover/OAVCoordinateSystem.tsx | 173 ++++++++++--------- src/screens/OavMover/OAVMoveController.tsx | 55 +++--- src/screens/OavMover/OAVMover.test.tsx | 5 +- src/screens/OavMover/OAVPresetDrawer.tsx | 97 ++++++----- src/screens/OavMover/OAVSideBar.tsx | 8 +- 5 files changed, 173 insertions(+), 165 deletions(-) diff --git a/src/screens/OavMover/OAVCoordinateSystem.tsx b/src/screens/OavMover/OAVCoordinateSystem.tsx index 16b37a5..0bcb041 100644 --- a/src/screens/OavMover/OAVCoordinateSystem.tsx +++ b/src/screens/OavMover/OAVCoordinateSystem.tsx @@ -1,19 +1,65 @@ import { Help, Close } from "@mui/icons-material"; import { - Box, Grid2, Dialog, DialogTitle, IconButton, DialogContent, Typography, + Divider, + Stack, } from "@mui/material"; import React from "react"; import oxfordChipDiagram from "#/assets/Oxford Chip Diagram.excalidraw.svg"; import { containedButtonStyles } from "#/blueapi/BlueapiComponentsStyling.ts"; import { RunPlanButton } from "#/blueapi/BlueapiComponents.tsx"; +type PlanButton = { + label: string; + planName: string; + planParams?: Record; + title: string; +}; + export function CoordinateSystem() { + const coordinateSystemSetup: PlanButton[] = [ + { + label: "Go to origin", + planName: "moveto", + planParams: { place: "zero" }, + title: "Go to Fiducial 0", + }, + { + label: "Go to Fiducial1", + planName: "moveto", + planParams: { place: "f1" }, + title: "Go to Fiducial 1", + }, + { + label: "Go to Fiducial2", + planName: "moveto", + planParams: { place: "f2" }, + title: "Go to Fiducial 2", + }, + { + label: "Set Fiducial0", + planName: "gui_set_fiducial_0", + title: "Set Fiducial 0", + }, + { + label: "Set Fiducial1", + planName: "fiducial", + planParams: { point: "1" }, + title: "Set Fiducial 1", + }, + { + label: "Set Fiducial2", + planName: "fiducial", + planParams: { point: "2" }, + title: "Set Fiducial 2", + }, + ]; + const [open, setOpen] = React.useState(false); const handleClickOpen = () => { @@ -25,96 +71,50 @@ export function CoordinateSystem() { return ( <> - - - - Co-ordinate System Setup - - - - - - - - - - - - - - - - - - - + + + Co-ordinate System Setup + + + + + {coordinateSystemSetup.map((button) => ( - - - - - - + ))} + + + + + + - + - + Oxford Chip Fiducial Alignment Diagram Fiducial alignment for an Oxford type chip. Fiducial 0 is the origin, the top left corner. Fiducial 1 is the top right corner and diff --git a/src/screens/OavMover/OAVMoveController.tsx b/src/screens/OavMover/OAVMoveController.tsx index be72572..4d4c041 100644 --- a/src/screens/OavMover/OAVMoveController.tsx +++ b/src/screens/OavMover/OAVMoveController.tsx @@ -9,7 +9,7 @@ import { KeyboardArrowDown, KeyboardDoubleArrowDown, } from "@mui/icons-material"; -import { Box, Tabs, Tab, useTheme } from "@mui/material"; +import { Box, Tabs, Tab, useTheme, useMediaQuery } from "@mui/material"; import { useState } from "react"; interface TabPanelProps { @@ -28,11 +28,12 @@ const arrowsBoxStyle = { const arrowsScreenSizing = { minWidth: { + md: "16px", lg: "32px", xl: "64px", }, width: { - lg: "32px", + md: "32px", }, }; @@ -218,6 +219,12 @@ function WindowMove(props: TabPanelProps) { function FocusMove(props: TabPanelProps) { if (props.value !== props.index) return null; + const focus_move = [ + { direction: "in", size_of_move: "big", label: "IN x3" }, + { direction: "in", size_of_move: "small", label: "IN" }, + { direction: "out", size_of_move: "small", label: "OUT" }, + { direction: "out", size_of_move: "big", label: "OUT x3" }, + ]; return ( - - - - + {focus_move.map((move) => ( + + ))} ); } @@ -259,6 +254,7 @@ export function MoveArrows() { const theme = useTheme(); const [value, setValue] = useState(0); + const isSmall = useMediaQuery(theme.breakpoints.down("xl")); const handleChange = (_event: React.SyntheticEvent, newValue: number) => { setValue(newValue); @@ -276,13 +272,18 @@ export function MoveArrows() { value={value} onChange={handleChange} sx={{ + "& .MuiTabs-flexContainer": { + flexWrap: isSmall ? "wrap" : "nowrap", + }, "& .MuiTab-root": { - minWidth: { xs: 80, sm: 120 }, + minWidth: isSmall ? "50%" : "25%", + maxWidth: isSmall ? "50%" : "none", }, "& .MuiTab-root.Mui-selected": { color: theme.palette.secondary.main, }, "& .MuiTabs-indicator": { + display: isSmall ? "none" : "block", backgroundColor: theme.palette.secondary.dark, }, }} diff --git a/src/screens/OavMover/OAVMover.test.tsx b/src/screens/OavMover/OAVMover.test.tsx index 9da6367..bb7a2ad 100644 --- a/src/screens/OavMover/OAVMover.test.tsx +++ b/src/screens/OavMover/OAVMover.test.tsx @@ -53,10 +53,11 @@ describe("OavMover Components", () => { }); it("should render side drawer", async () => { - expect(screen.getByText("Preset Positions")).toBeInTheDocument(); + screen.debug(); const presetButton = screen.getByRole("button", { - name: "Preset Positions", + name: /Preset Positions/i, }); + expect(presetButton).toBeInTheDocument(); await userEvent.click(presetButton); expect(screen.getByRole("presentation")).toBeInTheDocument(); expect( diff --git a/src/screens/OavMover/OAVPresetDrawer.tsx b/src/screens/OavMover/OAVPresetDrawer.tsx index 513721b..f0faafc 100644 --- a/src/screens/OavMover/OAVPresetDrawer.tsx +++ b/src/screens/OavMover/OAVPresetDrawer.tsx @@ -1,42 +1,44 @@ import { RunPlanButton } from "#/blueapi/BlueapiComponents.tsx"; import { containedButtonStyles } from "#/blueapi/BlueapiComponentsStyling.ts"; -import { Box, Stack, Button, Drawer } from "@mui/material"; +import { Box, Stack, Button, Drawer, Tooltip, Typography } from "@mui/material"; import { useState } from "react"; export function PresetMovements() { + const presetPositions = [ + { + label: "Collect Position", + place: "collect_position", + title: "Move into position for collection", + }, + { + label: "Load Position", + place: "load_position", + title: "Move hardware for sample loading", + }, + { + label: "Microdrop align", + place: "microdrop_position", + title: "Align microdrop", + }, + ]; + return ( - -

- Preset Positions -

- - - - + + + Preset Positions + + + {presetPositions.map((position) => ( + + ))} ); @@ -44,23 +46,24 @@ export function PresetMovements() { export function PresetPositionsSideDrawer() { const [open, setOpen] = useState(false); - const toggleDrawer = (newOpen: boolean) => () => { - setOpen(newOpen); - }; + const toggleDrawer = (newOpen: boolean) => () => setOpen(newOpen); return ( <> - + + + diff --git a/src/screens/OavMover/OAVSideBar.tsx b/src/screens/OavMover/OAVSideBar.tsx index af91ee5..a81fcf1 100644 --- a/src/screens/OavMover/OAVSideBar.tsx +++ b/src/screens/OavMover/OAVSideBar.tsx @@ -1,4 +1,4 @@ -import { Grid2 } from "@mui/material"; +import { Divider } from "@mui/material"; import { CoordinateSystem } from "./OAVCoordinateSystem"; import { PresetPositionsSideDrawer } from "./OAVPresetDrawer"; import { MoveArrows } from "./OAVMoveController"; @@ -7,8 +7,9 @@ import { BacklightControl, ZoomControl } from "./OAVDeviceSettings"; export function OAVSideBar() { return ( <> + OAV Movement Controller - + OAV Stats -
-
+ Preset Positions );