Skip to content

Commit

Permalink
moved XYZ widgets to main window, with state inheritance to children #2
Browse files Browse the repository at this point in the history
  • Loading branch information
hcwinsemius committed Jan 24, 2025
1 parent aff580a commit 5a953f1
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 60 deletions.
8 changes: 6 additions & 2 deletions dashboard/src/views/calibration.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
display: flex;
flex-direction: column;
align-items: stretch;

}

.tabbed-layout {
display: flex;
border: 1px solid #ccc;
margin-bottom: 10px;
}

.tabs-column {
Expand All @@ -26,6 +28,7 @@
cursor: pointer;
border-bottom: 1px solid #ccc;
font-size: 16px;
width: 100%; // button span over the entire width of the
}

.tabs-column button.active-tab {
Expand All @@ -36,11 +39,12 @@

.tab-content {
flex: 1;
padding: 20px;
padding: 0px;
}

.img-calibration {
width: 100%;
height: auto;
cursor: crosshair;
pointer-events: auto !important;
pointer-events: auto !important; // necessary to ensure that styling and click events are picked up within a transform view
}
72 changes: 71 additions & 1 deletion dashboard/src/views/calibration.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import React, { useState } from 'react';
import VideoTab from './calibrationTabs/videoTab'
import XYZWidget from './calibrationTabs/XyzWidget';

import './calibration.css'; // Ensure the styles reflect the updated layout.

const Calibration = () => {
const [activeTab, setActiveTab] = useState('video');
const [widgets, setWidgets] = useState([]);
const [selectedWidgetId, setSelectedWidgetId] = useState(null); // To track which widget is being updated
const [nextId, setNextId] = useState(1); // widget ids increment automatically
const [dots, setDots] = useState([]); // Array of { x, y, id } objects

const [formData, setFormData] = useState({
video: '',
controlPoints: '',
Expand All @@ -24,9 +31,38 @@ const Calibration = () => {
const handleSubmit = (e) => {
e.preventDefault();
console.log('Form submitted:', formData);
alert('Form submitted successfully!');
};

const addWidget = () => {
setWidgets((prevWidgets) => [
...prevWidgets,
{ id: nextId, coordinates: { x: '', y: '', z: '', row: '', col: '' } },
]);
setNextId((prevId) => prevId + 1); // increment the unique id for the next widget
};

const updateWidget = (id, updatedCoordinates) => {
setWidgets((prevWidgets) =>
prevWidgets.map((widget) =>
widget.id === id ? { ...widget, coordinates: updatedCoordinates } : widget
)
);
};

const deleteWidget = (id) => {
setWidgets((prevWidgets) => prevWidgets.filter((widget) => widget.id !== id));
console.log(dots.filter);
// also delete the dot
setDots((prevDots) => {
// Copy the previous state object
const newDots = { ...prevDots };
delete newDots[id];
return newDots;
});

};


return (
<div className="tabbed-form-container">
<h1>Camera calibration</h1>
Expand Down Expand Up @@ -68,6 +104,11 @@ const Calibration = () => {
<div className="tab-content">
{activeTab === 'video' && (
<VideoTab
widgets={widgets}
selectedWidgetId={selectedWidgetId}
updateWidget={updateWidget}
dots={dots}
setDots={setDots}
/>
)}
{activeTab === 'threed' && (
Expand All @@ -92,6 +133,35 @@ const Calibration = () => {
</div>
)}
</div>
<div className="tabs-column" style={{width:"300px"}}>
<div style={{ flex: 1 }}>
<button onClick={addWidget} className="active-tab">Add GCP</button>
{widgets.map((widget) => (
<div key={widget.id} onClick={(event) =>
setSelectedWidgetId(widget.id)
}
style={{
border: selectedWidgetId === widget.id ? '4px solid red' : '1px solid black',
marginTop: '10px',
marginBottom: '10px',
padding: '5px',
color: 'white',
cursor: 'pointer',
}}
>
<XYZWidget
id={widget.id}
coordinates={widget.coordinates}
onUpdate={(id, coordinates) => updateWidget(id, coordinates)}
onDelete={deleteWidget}
/>
</div>
))}
</div>

</div>


</form>

{/* Submit button section */}
Expand Down
7 changes: 2 additions & 5 deletions dashboard/src/views/calibrationTabs/photoComponent.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { useState, useRef } from 'react';
import { TransformComponent, useTransformEffect, useTransformInit } from 'react-zoom-pan-pinch';

const PhotoComponent = ({imageRef, selectedWidgetId, updateWidget, widgets, scale}) => {
const PhotoComponent = ({imageRef, selectedWidgetId, updateWidget, widgets, scale, dots, setDots}) => {
const [transformState, setTransformState] = useState(null); // state of zoom is stored here
const [dots, setDots] = useState([]); // Array of { x, y, id } objects

useTransformInit(({state, instance}) => {
// ensure the zoom/pan state is stored in a react state at the mounting of the photo element
Expand Down Expand Up @@ -45,7 +44,7 @@ const PhotoComponent = ({imageRef, selectedWidgetId, updateWidget, widgets, scal
// Calculate the row and column on the **original image** (as percentages)
const originalRow = Math.round(normalizedY * originalHeight * 100) / 100;
const originalCol = Math.round(normalizedX * originalWidth * 100) / 100;

console.log(widgets);
// Add the new dot to the state with the ID of the associated widget
if (!selectedWidgetId) {
alert("Please select a widget to update its row/column.");
Expand Down Expand Up @@ -76,8 +75,6 @@ const PhotoComponent = ({imageRef, selectedWidgetId, updateWidget, widgets, scal
{/* Render colored dots */}
{Object.entries(dots).map(([widgetId, dot]) => {
const imgElement = imageRef.current;
const boundingBox = imgElement.getBoundingClientRect();
// console.log(boundingBox);
return (
<div
key={widgetId}
Expand Down
57 changes: 5 additions & 52 deletions dashboard/src/views/calibrationTabs/videoTab.jsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,15 @@
import React, { useState, useRef, useEffect } from 'react';
import { TransformWrapper, TransformComponent, useTransformEffect, useTransformInit } from 'react-zoom-pan-pinch';
import XYZWidget from './XyzWidget';
import PhotoComponent from './photoComponent';

const VideoTab = () => {
const [widgets, setWidgets] = useState([]);
const [nextId, setNextId] = useState(1); // widget ids increment automatically
const [selectedWidgetId, setSelectedWidgetId] = useState(null); // To track which widget is being updated
const VideoTab = ({widgets, selectedWidgetId, updateWidget, dots, setDots}) => {
const [scale, setScale] = useState(1);
const imageRef = useRef(null); // Reference to image within TransFormWrapper

const addWidget = () => {
setWidgets((prevWidgets) => [
...prevWidgets,
{ id: nextId, coordinates: { x: '', y: '', z: '', row: '', col: '' } },
]);
setNextId((prevId) => prevId + 1); // increment the unique id for the next widget
};

const updateWidget = (id, updatedCoordinates) => {
setWidgets((prevWidgets) =>
prevWidgets.map((widget) =>
widget.id === id ? { ...widget, coordinates: updatedCoordinates } : widget
)
);
};

const deleteWidget = (id) => {
setWidgets((prevWidgets) => prevWidgets.filter((widget) => widget.id !== id));
// also delete the dot
};

return (
<div>
<div style={{ display: 'flex', margin: '20px' }}>
<div style={{ flex: 1, border: '1px solid black', marginRight: '20px', position: 'relative' }}>
<div style={{ display: 'flex', margin: '5px' }}>
<div style={{ flex: 1, border: '1px solid black', position: 'relative' }}>
<TransformWrapper
// ensure the scale is tracked all the time
onTransformed={(e) => {
Expand All @@ -47,37 +22,15 @@ const VideoTab = () => {
updateWidget={updateWidget}
widgets={widgets}
scale={scale}
dots={dots}
setDots={setDots}
/>
</TransformWrapper>
<div style={{ textAlign: 'center', marginTop: '10px', color: '#555' }}>
Click on the photo to select row/column
</div>
</div>
<div>
<div style={{ flex: 1 }}>
<button onClick={addWidget} className="btn">Add Widget</button>
{widgets.map((widget) => (
<div key={widget.id} onClick={(event) =>
setSelectedWidgetId(widget.id)
}
style={{
border: selectedWidgetId === widget.id ? '4px solid red' : '1px solid black',
marginTop: '10px',
marginBottom: '10px',
padding: '5px',
color: 'white',
cursor: 'pointer',
}}
>
<XYZWidget
id={widget.id}
coordinates={widget.coordinates}
onUpdate={(id, coordinates) => updateWidget(id, coordinates)}
onDelete={deleteWidget}
/>
</div>
))}
</div>
</div>
</div>
<h2>Current Coordinates:</h2>
Expand Down

0 comments on commit 5a953f1

Please sign in to comment.