Skip to content
Open
59 changes: 39 additions & 20 deletions src/components/field/svg/FieldOverlayRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ class FieldOverlayRoot extends Component<Props, State> {
<FieldImage2024 />
</>
)}


{layers[ViewLayers.Grid] && <FieldGrid></FieldGrid>}
{/* Waypoint mouse capture*/}

Expand Down Expand Up @@ -304,7 +306,6 @@ class FieldOverlayRoot extends Component<Props, State> {
</div>
</Popover>
)}

{layers[ViewLayers.Waypoints] &&
uiState.isNavbarWaypointSelected() && (
<circle
Expand All @@ -326,6 +327,43 @@ class FieldOverlayRoot extends Component<Props, State> {
{layers[ViewLayers.Samples] && layers[ViewLayers.Trajectory] && (
<FieldGeneratedWaypoints></FieldGeneratedWaypoints>
)}
{/* Display field zones */}
{layers[ViewLayers.Zones] &&
doc.pathlist.activePath.params.constraints
.filter((c) => c.enabled)
.map((c) => {
return (
<FieldConstraintDisplayLayer
points={doc.pathlist.activePath.params.waypoints}
constraint={c as IConstraintStoreKeyed<ConstraintKey>}
lineColor={c.selected ? "var(--select-yellow)":"transparent"}
clickable= {c.selected || !(uiState.layers[ViewLayers.Waypoints] &&
uiState.isNavbarWaypointSelected())}
></FieldConstraintDisplayLayer>
);
})}

{!layers[ViewLayers.Zones] && doc.isSidebarConstraintSelected && (
<FieldConstraintDisplayLayer
points={doc.pathlist.activePath.params.waypoints}
constraint={
doc.selectedSidebarItem as IConstraintStoreKeyed<ConstraintKey>
}
lineColor="var(--select-yellow)"
clickable={true}
></FieldConstraintDisplayLayer>
)}
{!doc.isSidebarConstraintSelected &&
doc.isSidebarConstraintHovered && (
<FieldConstraintDisplayLayer
points={doc.pathlist.activePath.params.waypoints}
constraint={
doc.hoveredSidebarItem as IConstraintStoreKeyed<ConstraintKey>
}
lineColor="white"
clickable={false}
></FieldConstraintDisplayLayer>
)}
<FieldEventMarkers></FieldEventMarkers>
{layers[ViewLayers.Waypoints] &&
doc.pathlist.activePath.params.waypoints
Expand Down Expand Up @@ -364,26 +402,7 @@ class FieldOverlayRoot extends Component<Props, State> {
{eventMarkerSelected && (
<FieldEventMarkerAddLayer></FieldEventMarkerAddLayer>
)}
{doc.isSidebarConstraintSelected && (
<FieldConstraintDisplayLayer
points={doc.pathlist.activePath.params.waypoints}
constraint={
doc.selectedSidebarItem as IConstraintStoreKeyed<ConstraintKey>
}
lineColor="var(--select-yellow)"
></FieldConstraintDisplayLayer>
)}

{!doc.isSidebarConstraintSelected &&
doc.isSidebarConstraintHovered && (
<FieldConstraintDisplayLayer
points={doc.pathlist.activePath.params.waypoints}
constraint={
doc.hoveredSidebarItem as IConstraintStoreKeyed<ConstraintKey>
}
lineColor="white"
></FieldConstraintDisplayLayer>
)}
{layers[ViewLayers.Trajectory] && (
<InterpolatedRobot
timestamp={uiState.pathAnimationTimestamp}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,23 @@
import KeepOutCircleOverlay from "./KeepOutCircleOverlay";
import { IHolonomicWaypointStore } from "../../../../document/HolonomicWaypointStore";
import KeepInLaneOverlay from "./KeepInLaneOverlay";
import { IConstraintDataStore } from "../../../../document/ConstraintDataStore";

export type OverlayProps<K extends keyof ConstraintDataTypeMap> = {
data: IConstraintStoreKeyed<K>;
start: IHolonomicWaypointStore;
end: IHolonomicWaypointStore;
lineColor: string;
select: ()=>void;
clickable: boolean;
};
export type OverlayElementProps<K extends keyof ConstraintDataTypeMap> = {
data: IConstraintDataStore<K>;
start?: IHolonomicWaypointStore;
end?: IHolonomicWaypointStore;
selected: boolean;
select: ()=>void;
clickable: boolean;
};
const overlays = {
PointAt: (props: OverlayProps<"PointAt">) => (
Expand All @@ -26,37 +37,49 @@
start={props.start}
end={props.end}
lineColor={props.lineColor}
selected={props.data.selected}
select={()=>{props.data.setSelected(true)}}
clickable={props.clickable}
></PointAtOverlay>
),
KeepInCircle: (props: OverlayProps<"KeepInCircle">) => (
<KeepInCircleOverlay
data={props.data.data}
start={props.start}
end={props.end}
lineColor={props.lineColor}
selected={props.data.selected}
select={()=>{props.data.setSelected(true)}}
clickable={props.clickable}
></KeepInCircleOverlay>
),
KeepInRectangle: (props: OverlayProps<"KeepInRectangle">) => (
<KeepInRectangleOverlay
data={props.data.data}
start={props.start}
end={props.end}
lineColor={props.lineColor}
selected={props.data.selected}
select={()=>{props.data.setSelected(true)}}
clickable={props.clickable}
></KeepInRectangleOverlay>
),
KeepInLane: (props: OverlayProps<"KeepInLane">) => (
<KeepInLaneOverlay
data={props.data.data}
start={props.start}
end={props.end}
selected={props.data.selected}
select={()=>{props.data.setSelected(true)}}
clickable={props.clickable}
></KeepInLaneOverlay>
),
KeepOutCircle: (props: OverlayProps<"KeepOutCircle">) => (
<KeepOutCircleOverlay
data={props.data.data}
start={props.start}
end={props.end}
lineColor={props.lineColor}
selected={props.data.selected}
select={()=>{props.data.setSelected(true)}}
clickable={props.clickable}
></KeepOutCircleOverlay>
),
StopPoint: () => <></>,
Expand All @@ -70,6 +93,7 @@
constraint?: IConstraintStoreKeyed<ConstraintKey>;
points: IHolonomicWaypointStore[];
lineColor: string;
clickable: boolean;
};
function FieldConstraintDisplayLayer(props: Props) {
const constraint = props.constraint;
Expand All @@ -82,19 +106,20 @@
data: constraint,
start: constraint.getStartWaypoint(props.points),
end: constraint.getEndWaypoint(props.points),
lineColor: props.lineColor
lineColor: props.lineColor,
clickable: props.clickable
};
if (startIndex === undefined) {
return <></>;
}
return (
<g>
<g key={props.constraint?.uuid ?? "undef"} style={{zIndex: constraint.selected ? "999" : undefined}}>
<FieldConstraintRangeLayer
points={doc.pathlist.activePath.params.waypoints}
start={startIndex}
end={endIndex}
lineColor={props.lineColor}
id="display"
id={"display"+props.constraint?.uuid ?? "undef"}

Check failure on line 122 in src/components/field/svg/constraintDisplay/FieldConstraintDisplayLayer.tsx

View workflow job for this annotation

GitHub Actions / TypeScript compiler

Right operand of ?? is unreachable because the left operand is never nullish.
></FieldConstraintRangeLayer>
{overlays[constraint.data.type](
// @ts-expect-error can't cast the constraint as the proper type.
Expand Down
65 changes: 39 additions & 26 deletions src/components/field/svg/constraintDisplay/KeepInCircleOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import * as d3 from "d3";
import { observer } from "mobx-react";
import React, { Component } from "react";
import { IConstraintDataStore } from "../../../../document/ConstraintDataStore";

Check failure on line 4 in src/components/field/svg/constraintDisplay/KeepInCircleOverlay.tsx

View workflow job for this annotation

GitHub Actions / Format

'IConstraintDataStore' is defined but never used. Allowed unused vars must match /^_/u
import {
ConstraintKey,

Check failure on line 6 in src/components/field/svg/constraintDisplay/KeepInCircleOverlay.tsx

View workflow job for this annotation

GitHub Actions / Format

'ConstraintKey' is defined but never used. Allowed unused vars must match /^_/u
DataMap
} from "../../../../document/ConstraintDefinitions";
import { doc } from "../../../../document/DocumentManager";
import { doc, uiState } from "../../../../document/DocumentManager";

Check failure on line 9 in src/components/field/svg/constraintDisplay/KeepInCircleOverlay.tsx

View workflow job for this annotation

GitHub Actions / Format

'uiState' is defined but never used. Allowed unused vars must match /^_/u
import { IHolonomicWaypointStore } from "../../../../document/HolonomicWaypointStore";

Check failure on line 10 in src/components/field/svg/constraintDisplay/KeepInCircleOverlay.tsx

View workflow job for this annotation

GitHub Actions / Format

'IHolonomicWaypointStore' is defined but never used. Allowed unused vars must match /^_/u
import { ViewLayers } from "../../../../document/UIData";

Check failure on line 11 in src/components/field/svg/constraintDisplay/KeepInCircleOverlay.tsx

View workflow job for this annotation

GitHub Actions / Format

'ViewLayers' is defined but never used. Allowed unused vars must match /^_/u
import { OverlayElementProps } from "./FieldConstraintDisplayLayer";

const STROKE = 0.1;
const DOT = 0.1;
const SELECT_COLOR = "var(--select-yellow)";
const MOVABLE_COLOR = "green";
const IMMOVABLE_COLOR = "darkseagreen";

type Props<K extends ConstraintKey> = {
data: IConstraintDataStore<K>;
start?: IHolonomicWaypointStore;
end?: IHolonomicWaypointStore;
lineColor: string;
};
class KeepInCircleOverlay extends Component<Props<"KeepInCircle">, object> {
class KeepInCircleOverlay extends Component<OverlayElementProps<"KeepInCircle">, object> {
id = crypto.randomUUID();
rootRef: React.RefObject<SVGGElement> = React.createRef<SVGGElement>();
componentDidMount() {
if (this.rootRef.current) {
Expand All @@ -27,66 +27,79 @@
.on("drag", (event) => this.dragPointTranslate(event))
.on("start", () => {
doc.history.startGroup(() => {});
this.props.select()
})
.on("end", (_event) => doc.history.stopGroup())
.container(this.rootRef.current);
d3.select<SVGCircleElement, undefined>(`#dragTarget-keepInCircle`).call(
dragHandleDrag
);
d3.select<SVGCircleElement, undefined>(
`#dragTarget-keepInCircleDot`
`#dragTarget-keepInCircle` + this.id
).call(dragHandleDrag);
d3.select<SVGCircleElement, undefined>(
`#dragTarget-keepInCircleDot` + this.id
).call(dragHandleDrag);
const radiusHandleDrag = d3
.drag<SVGCircleElement, undefined>()
.on("drag", (event) => this.dragPointRadius(event))
.on("start", () => {
doc.history.startGroup(() => {});
this.props.select();
})
.on("end", (_event) => doc.history.stopGroup())
.container(this.rootRef.current);
d3.select<SVGCircleElement, undefined>(
`#dragRadiusTarget-keepInCircle`
`#dragRadiusTarget-keepInCircle` + this.id
).call(radiusHandleDrag);
}
}

dragPointTranslate(event: any) {
this.props.data.x.set(this.props.data.serialize.props.x.val + event.dx);
this.props.data.y.set(this.props.data.serialize.props.y.val + event.dy);
this.props.data.x.set(this.props.data.serialize.props.x.val + event.dx);
this.props.data.y.set(this.props.data.serialize.props.y.val + event.dy);
}

dragPointRadius(event: any) {
const dx = event.x - this.props.data.serialize.props.x.val;
const dy = event.y - this.props.data.serialize.props.y.val;
const r = Math.sqrt(dx * dx + dy * dy);
const dx = event.x - this.props.data.serialize.props.x.val;
const dy = event.y - this.props.data.serialize.props.y.val;
const r = Math.sqrt(dx * dx + dy * dy);

this.props.data.r.set(r);
this.props.data.r.set(r);
}

getColor() : string {
if (this.props.selected) return SELECT_COLOR;
if (this.props.clickable) return MOVABLE_COLOR;
return IMMOVABLE_COLOR;
}
render() {
const data = this.props.data.serialize as DataMap["KeepInCircle"];
const x = data.props.x.val;
const y = data.props.y.val;
const r = data.props.r.val;
const color = this.getColor();
return (
<g ref={this.rootRef}>
<g ref={this.rootRef} onClick={
() => {
if (this.props.clickable) this.props.select();
}}>
{/* Main Circle */}
<circle
cx={x}
cy={y}
r={r - STROKE / 2}
fill={"green"}
fill={color}
fillOpacity={0.1}
id="dragTarget-keepInCircle"
id={"dragTarget-keepInCircle" + this.id}
pointerEvents={"visibleStroke"}
></circle>
{/* Center Dot */}
<circle
cx={x}
cy={y}
r={r < DOT * 2 ? 0.0 : DOT}
fill={"green"}
fill={color}
fillOpacity={1.0}
id="dragTarget-keepInCircleDot"
id={"dragTarget-keepInCircleDot" + this.id}
pointerEvents={"visible"}
></circle>
{/* Radius Handle */}
<circle
Expand All @@ -95,10 +108,10 @@
r={r - STROKE / 2}
fill={"transparent"}
pointerEvents={"visibleStroke"}
stroke={"green"}
stroke={color}
strokeWidth={STROKE}
strokeOpacity={1.0}
id="dragRadiusTarget-keepInCircle"
id={"dragRadiusTarget-keepInCircle" + this.id}
></circle>
</g>
);
Expand Down
Loading
Loading