Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 16 additions & 27 deletions src/pages/edit/Editor/components/NodePinPropertyEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CCConnectionStore } from "../../../../store/connection";
import { IntrinsicComponentDefinition } from "../../../../store/intrinsics/base";
import { CCNodePinStore } from "../../../../store/nodePin";
import { useStore } from "../../../../store/react";
import getCCComponentEditorRendererNodeGeometry from "../renderer/Node/geometry";
import { getCCComponentEditorRendererNodeGeometry } from "../renderer/Node/geometry";
import { useComponentEditorStore } from "../store";

export function CCComponentEditorNodePinPropertyEditor() {
Expand Down Expand Up @@ -123,33 +123,22 @@ export function CCComponentEditorNodePinPropertyEditor() {
nodePin.id,
);
for (const connection of connections) {
const anotherNodePinId =
connection.from === nodePin.id
? connection.to
: connection.from;
const fromNodePinId =
connection.from === nodePin.id
? nodePin.id
: anotherNodePinId;
const toNodePinId =
connection.from === nodePin.id
? anotherNodePinId
: nodePin.id;
const from = connection.from;
const to = connection.to;
const parentComponentId = connection.parentComponentId;
store.connections.unregister([connection.id]);
if (
store.nodePins.isConnectable(nodePin.id, anotherNodePinId)
) {
// reconnect if still connectable after bit width change
store.connections.register(
CCConnectionStore.create({
parentComponentId,
from: fromNodePinId,
to: toNodePinId,
bentPortion: 0.5,
}),
);
}
store.connections.unregister([connection.id]).then(() => {
if (store.nodePins.isConnectable(from, to)) {
// reconnect if still connectable after bit width change
store.connections.register(
CCConnectionStore.create({
parentComponentId,
from,
to,
bentPortion: 0.5,
}),
);
}
});
}
}
continue;
Expand Down
6 changes: 6 additions & 0 deletions src/pages/edit/Editor/components/ViewModeSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { Edit, PlayArrow } from "@mui/icons-material";
import { Fab } from "@mui/material";
import { isEachInputPinConnected } from "../../../../store/component";
import { useStore } from "../../../../store/react";
import { useComponentEditorStore } from "../store";

export default function CCComponentEditorViewModeSwitcher() {
const componentEditorState = useComponentEditorStore()();
const { store } = useStore();

return (
<Fab
Expand All @@ -15,6 +18,9 @@ export default function CCComponentEditorViewModeSwitcher() {
);
componentEditorState.setTimeStep(0);
}}
disabled={
!isEachInputPinConnected(store, componentEditorState.componentId)
}
>
{componentEditorState.editorMode === "edit" ? <PlayArrow /> : <Edit />}
</Fab>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/edit/Editor/renderer/ComponentPin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useStore } from "../../../../../store/react";
import { wrappingIncrementSimulationValue } from "../../../../../store/simulation";
import { useComponentEditorStore } from "../../store";
import { stringifySimulationValue } from "../../store/slices/core";
import getCCComponentEditorRendererNodeGeometry from "./../Node/geometry";
import { getCCComponentEditorRendererNodeGeometry } from "./../Node/geometry";
export type CCComponentEditorRendererComponentPinProps = {
nodePinId: CCNodePinId;
};
Expand Down
2 changes: 1 addition & 1 deletion src/pages/edit/Editor/renderer/Connection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import ensureStoreItem from "../../../../../store/react/error";
import { useNode } from "../../../../../store/react/selectors";
import { useComponentEditorStore } from "../../store";
import { stringifySimulationValue } from "../../store/slices/core/index";
import getCCComponentEditorRendererNodeGeometry from "../Node/geometry";
import { getCCComponentEditorRendererNodeGeometry } from "../Node/geometry";

export type CCComponentEditorRendererConnectionEndpoint = {
direction: CCComponentPinType;
Expand Down
71 changes: 31 additions & 40 deletions src/pages/edit/Editor/renderer/Node/components/Default/geometry.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
import { type Vector2, vector2 } from "../../../../../../../common/vector2";
import type { Vector2 } from "../../../../../../../common/vector2";
import type { CCNodePinId } from "../../../../../../../store/nodePin";
import type {
CCComponentEditorRendererNodeGeometryCalculator,
CCComponentEditorRendererNodeGeometrySource,
CCComponentEditorRendererNodeLayout,
CCComponentEditorRendererNodeLayoutSource,
} from "../../types";

const width = 100;
const gapY = 20;
const paddingY = 15;

export const ccComponentRendererNodeDefaultGeometryCalculator: CCComponentEditorRendererNodeGeometryCalculator =
(source: CCComponentEditorRendererNodeGeometrySource) => {
const size: Vector2 = {
x: width,
y:
gapY *
Math.max(
source.inputNodePinIds.length,
source.outputNodePinIds.length,
) +
paddingY * 2,
};
export function ccComponentRendererNodeDefaultLayoutCalculator(
source: CCComponentEditorRendererNodeLayoutSource,
): CCComponentEditorRendererNodeLayout {
const size: Vector2 = {
x: width,
y:
gapY *
Math.max(
source.inputNodePinIds.length,
source.outputNodePinIds.length,
) +
paddingY * 2,
};

const nodePinPositionById = new Map<CCNodePinId, Vector2>();
for (const [index, nodePinId] of source.inputNodePinIds.entries()) {
nodePinPositionById.set(nodePinId, {
x: source.position.x - size.x / 2,
y:
source.position.y +
gapY * (index - source.inputNodePinIds.length / 2 + 0.5),
});
}
for (const [index, nodePinId] of source.outputNodePinIds.entries()) {
nodePinPositionById.set(nodePinId, {
x: source.position.x + size.x / 2,
y:
source.position.y +
gapY * (index - source.outputNodePinIds.length / 2 + 0.5),
});
}
const nodePinOffsetById = new Map<CCNodePinId, Vector2>();

return {
rect: {
position: vector2.sub(source.position, vector2.div(size, 2)),
size,
},
nodePinPositionById,
};
};
const startYIn =
size.y / 2 - (gapY * (source.inputNodePinIds.length - 1)) / 2;
for (const [index, pinId] of source.inputNodePinIds.entries()) {
nodePinOffsetById.set(pinId, { x: 0, y: startYIn + gapY * index });
}

const startYOut =
size.y / 2 - (gapY * (source.outputNodePinIds.length - 1)) / 2;
for (const [index, pinId] of source.outputNodePinIds.entries()) {
nodePinOffsetById.set(pinId, { x: size.x, y: startYOut + gapY * index });
}

return { size, nodePinOffsetById };
}
12 changes: 6 additions & 6 deletions src/pages/edit/Editor/renderer/Node/components/Default/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ export function CCComponentEditorRendererNodeDefaultRenderer(
<>
<text
fill={theme.palette.textPrimary}
x={props.geometry.rect.position.x}
y={props.geometry.rect.position.y - 5}
x={0}
y={-5}
textAnchor="start"
fontSize={12}
>
{props.component.name}
</text>
<rect
x={props.geometry.rect.position.x}
y={props.geometry.rect.position.y}
width={props.geometry.rect.size.x}
height={props.geometry.rect.size.y}
x={0}
y={0}
width="100%"
height="100%"
fill={theme.palette.white}
stroke={
props.nodeState.isSelected
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { SettingsOutlined } from "@mui/icons-material";
import { IconButton } from "@mui/material";
import type { CCNodeId } from "../../../../../../../store/node";
import type { CCComponentEditorRendererNodeGeometry } from "../../types";

type Props = {
nodeId: CCNodeId;
geometry: CCComponentEditorRendererNodeGeometry;
};

export function CCComponentEditorRendererNodeDisplayRendererConfigSettingButton(
_props: Props,
) {
return (
<IconButton
sx={{ width: "20px", height: "20px" }}
onPointerDown={(e) => {
e.stopPropagation();
}}
disableTouchRipple
disableFocusRipple
>
<SettingsOutlined sx={{ width: "12px", height: "12px" }} />
</IconButton>
);
}
51 changes: 26 additions & 25 deletions src/pages/edit/Editor/renderer/Node/components/Display/geometry.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
import nullthrows from "nullthrows";
import { type Vector2, vector2 } from "../../../../../../../common/vector2";
import type { CCIntrinsicComponentDisplaySpec } from "../../../../../../../store/intrinsics/types";
import type { CCNodePinId } from "../../../../../../../store/nodePin";
import type {
CCComponentEditorRendererNodeGeometryCalculator,
CCComponentEditorRendererNodeGeometrySource,
CCComponentEditorRendererNodeLayout,
CCComponentEditorRendererNodeLayoutSource,
} from "../../types";

const width = 320;
const height = 200;
const size = { x: 320, y: 200 };

export const ccComponentRendererNodeDisplayGeometryCalculator: CCComponentEditorRendererNodeGeometryCalculator =
(source: CCComponentEditorRendererNodeGeometrySource) => {
const size: Vector2 = {
x: width,
y: height,
};
export const ccComponentEditorRendererNodeDisplayLayoutConstants = {
padding: 8,
gridSize: 12,
gridSizeDisplayWidth: 60,
};

return {
rect: {
position: vector2.sub(source.position, vector2.div(size, 2)),
size,
},
nodePinPositionById: new Map<CCNodePinId, Vector2>(
source.inputNodePinIds.map(
(id) =>
[
id,
vector2.create(source.position.x - size.x / 2, source.position.y),
] as const,
),
),
};
export function ccComponentRendererNodeDisplayLayoutCalculator(
source: CCComponentEditorRendererNodeLayoutSource,
): CCComponentEditorRendererNodeLayout {
const { padding, gridSize, gridSizeDisplayWidth } =
ccComponentEditorRendererNodeDisplayLayoutConstants;
const config = source.config as CCIntrinsicComponentDisplaySpec["config"];

return {
size: {
x: gridSizeDisplayWidth + gridSize * config.resolution.x + padding * 2,
y: gridSize * config.resolution.y + padding * 2,
},
nodePinOffsetById: new Map<CCNodePinId, Vector2>([
[nullthrows(source.inputNodePinIds[0]), vector2.create(0, size.y / 2)],
]),
};
}
48 changes: 20 additions & 28 deletions src/pages/edit/Editor/renderer/Node/components/Display/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import type { CCIntrinsicComponentDisplaySpec } from "../../../../../../../store
import { useStore } from "../../../../../../../store/react";
import { useComponentEditorStore } from "../../../../store";
import type { CCComponentEditorRendererNodeRendererProps } from "../../types";
import { CCComponentEditorRendererNodeDefaultRenderer } from "../Default";
import { CCComponentEditorRendererNodeDisplayRendererConfigSettingButton } from "./ConfigSettingButton";
import { ccComponentEditorRendererNodeDisplayLayoutConstants } from "./geometry";

export function CCComponentEditorRendererNodeDisplayRenderer(
props: CCComponentEditorRendererNodeRendererProps,
Expand All @@ -23,38 +26,27 @@ export function CCComponentEditorRendererNodeDisplayRenderer(
? editorState.getNodePinValue(inputNodePin.id)
: undefined;

const { padding, gridSize, gridSizeDisplayWidth } =
ccComponentEditorRendererNodeDisplayLayoutConstants;

return (
<>
<rect
x={props.geometry.rect.position.x}
y={props.geometry.rect.position.y}
width={props.geometry.rect.size.x}
height={props.geometry.rect.size.y}
fill={theme.palette.white}
stroke={
props.nodeState.isSelected
? theme.palette.primary
: theme.palette.textPrimary
}
strokeWidth={2}
rx={2}
/>
<text
x={props.geometry.rect.position.x + 8}
y={props.geometry.rect.position.y + 20}
fontSize={12}
fill={theme.palette.textPrimary}
>
Display
</text>
<CCComponentEditorRendererNodeDefaultRenderer {...props} />
<text
x={props.geometry.rect.position.x + 8}
y={props.geometry.rect.position.y + 40}
x={padding}
y={padding}
fontSize={16}
fill={theme.palette.textPrimary}
dominantBaseline="hanging"
>
{config.resolution.x}x{config.resolution.y}
</text>
<foreignObject x={padding / 2} y={padding + 16} width={32} height={32}>
<CCComponentEditorRendererNodeDisplayRendererConfigSettingButton
nodeId={props.node.id}
geometry={props.geometry}
/>
</foreignObject>
{Array(config.resolution.y)
.keys()
.map((y) =>
Expand All @@ -63,10 +55,10 @@ export function CCComponentEditorRendererNodeDisplayRenderer(
.map((x) => (
<rect
key={`${x}-${y}`}
x={props.geometry.rect.position.x + 64 + x * 12}
y={props.geometry.rect.position.y + 8 + y * 12}
width={12}
height={12}
x={padding + gridSizeDisplayWidth + x * gridSize}
y={padding + y * gridSize}
width={gridSize}
height={gridSize}
fill={
inputValue?.[
config.resolution.x * config.resolution.y -
Expand Down
Loading
Loading