Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GSoC 2023: Niloy #394

Merged
merged 48 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
199063b
feat(code-builder): implement `_getBBoxBrick` method for the path
niloysikdar Jul 5, 2023
1c9035f
feat(code-builder): implement `_getBBoxNotchArg` method for the path
niloysikdar Jul 12, 2023
c91c546
fix(code-builder): calculation for `_getBBoxNotchInsTop` method for t…
niloysikdar Jul 12, 2023
9626024
fix(code-builder): calculation for `_getBBoxNotchInsBot` method for t…
niloysikdar Jul 12, 2023
6a1d9bd
fix(code-builder): calculation for `_getBBoxNotchInsNestTop` method f…
niloysikdar Jul 12, 2023
1cddeef
feat(code-builder): implement `_getBBoxArgs` method for the path
niloysikdar Jul 12, 2023
e73dc5f
fix(code-builder): remove `hasNotchNest` for generatePath inside `Bri…
niloysikdar Jul 12, 2023
bb6b2b6
fix(code-builder): `extent` and `coords` calculation in `path.ts`
niloysikdar Jul 13, 2023
62d32f8
chore(path): print results in DEV mode
niloysikdar Jul 13, 2023
7061c19
feat(code-builder): implement missing getters for `BrickBlock`
niloysikdar Jul 13, 2023
aa1b79d
fix(bricks): types for bricks
niloysikdar Jul 13, 2023
3e20bbf
refactor(bricks): define `bBoxArgs` getter to get extent and coords
niloysikdar Jul 13, 2023
3dc48d8
refactor(bricks): change `bBoxArgs` to make it more flexible
niloysikdar Jul 13, 2023
7fa3927
feat(bricks): add `bBoxBrick` getter
niloysikdar Jul 13, 2023
45c4deb
fix(bricks): convert `SVGpaths` getter to `SVGpath`
niloysikdar Jul 13, 2023
905eb1a
feat(storybook): show visual indicators
niloysikdar Jul 13, 2023
345f102
chore(storybook): remove `No Args` story for `Expression Brick`
niloysikdar Jul 13, 2023
8f2c502
fix(generatePath): `_getBBoxArgs` coords calculation
niloysikdar Jul 13, 2023
23e07bd
feat(bricks): change the model add `bBoxNotchArg` getter
niloysikdar Jul 14, 2023
e896c52
docs(storybook): add bounding box for notch to `BrickBlock` story
niloysikdar Jul 14, 2023
40f477f
feat(bricks): change the model add `bBoxNotchInsTop` getter
niloysikdar Jul 14, 2023
25319dd
docs(storybook): add bounding box for top ins notch to `BrickBlock` s…
niloysikdar Jul 14, 2023
d3afc52
feat(bricks): change the model add `bBoxNotchInsBot` getter
niloysikdar Jul 14, 2023
e35807e
docs(storybook): add bounding box for bottom ins notch to `BrickBlock…
niloysikdar Jul 14, 2023
b63724d
feat(bricks): change the model to add `bBoxNotchInsNestTop` getter
niloysikdar Jul 14, 2023
328e989
docs(storybook): add bounding box for top ins notch inside nesting to…
niloysikdar Jul 14, 2023
8fcbb0f
fix(bricks): change `BrickData` model to adapt the new type
niloysikdar Jul 14, 2023
8012d80
docs(storybook): add notch visualization to the `BrickData` stories
niloysikdar Jul 14, 2023
d10d1b2
fix(bricks): change `BrickExpression` model to adapt the new type
niloysikdar Jul 14, 2023
3ea7584
docs(storybook): add notch and args visualization to the `BrickExpres…
niloysikdar Jul 14, 2023
5985d03
fix(bricks): change `BrickStatement` model to adapt the new type
niloysikdar Jul 14, 2023
edcbc4c
docs(storybook): add notch and args visualization to the `BrickStatem…
niloysikdar Jul 14, 2023
0234f48
fix(bricks-path): coords(x) calculation for `_getBBoxArgs`
niloysikdar Jul 14, 2023
8a7e7d7
docs(storybook): show overall bounding box of the bricks
niloysikdar Jul 14, 2023
5260a5d
refactor(code-builder): [brick] coalesce notch interfaces
meganindya Jul 16, 2023
af59fcc
refactor(code-builder): [brick] draw visual indicators only in storybook
meganindya Jul 16, 2023
dda9e98
chore(code-builder): remove DEV mode logs from `path.ts`
niloysikdar Jul 17, 2023
778180b
test(code-builder): add missing todo tests for `path.spec.ts`
niloysikdar Jul 17, 2023
440365b
chore(playground): add dummy workspace data
niloysikdar Jul 19, 2023
3c9d8bd
fix(bricks): fix brick components to accept coords
niloysikdar Jul 19, 2023
4301c8e
feat(playground): add workspace page and functionality into playground
niloysikdar Jul 19, 2023
5505352
feat(playground): initialize and configure brick store
niloysikdar Aug 11, 2023
86bac1e
feat(bricks): modify bricks ho handle drag state
niloysikdar Aug 11, 2023
5a2b103
feat(playground): render bricks and drag them
niloysikdar Aug 11, 2023
da683cd
feat(playground): refactor bricks to encapsulate drag logic
niloysikdar Aug 11, 2023
ea72582
feat(playground): recursive function to get below brick IDs
niloysikdar Aug 18, 2023
9e633e5
feat(playground): detect and update positions of collision areas for …
niloysikdar Aug 30, 2023
12d2b23
hack(singer): disable erroneous lines
meganindya Mar 20, 2024
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
4 changes: 3 additions & 1 deletion modules/code-builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"react-dom": "~18.x"
},
"dependencies": {
"@sugarlabs/musicblocks-v4-lib": "^0.2.0"
"@sugarlabs/musicblocks-v4-lib": "^0.2.0",
"react-aria": "^3.26.0",
"zustand": "^4.3.9"
}
}
5 changes: 5 additions & 0 deletions modules/code-builder/playground/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ import { createRoot } from 'react-dom/client';
import { createBrowserRouter, Navigate, RouterProvider } from 'react-router-dom';

import PageCollision from './pages/Collision';
import WorkSpace from './pages/WorkSpace';

const router = createBrowserRouter([
{
path: '/collision',
element: <PageCollision />,
},
{
path: '/workspace',
element: <WorkSpace />,
},
{
path: '/',
element: <Navigate to="/collision" />,
Expand Down
185 changes: 185 additions & 0 deletions modules/code-builder/playground/pages/WorkSpace/BrickFactory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { useState } from 'react';
import { useMove } from 'react-aria';
import { BrickBlock, BrickData, BrickExpression, BrickStatement } from '@/brick';
import { useBricksCoords } from './BricksCoordsStore';
import { WORKSPACES_DATA } from './data';
import type { Brick } from './data';
import { getBelowBricksIds } from './utils';

const BrickFactory = ({ brickData }: { brickData: Brick }) => {
const CONTAINER_SIZE_X = 800;
const CONTAINER_SIZE_Y = 700;
const BRICK_HEIGHT = brickData.instance.bBoxBrick.extent.height;
const BRICK_WIDTH = brickData.instance.bBoxBrick.extent.width;
const { getCoords, setCoords } = useBricksCoords();
const brickCoords = getCoords(brickData.id)!;
const [color, setColor] = useState(brickData.instance.colorBg as string);

const clampX = (pos: number) => Math.min(Math.max(pos, 0), CONTAINER_SIZE_X - BRICK_WIDTH * 2);
const clampY = (pos: number) => Math.min(Math.max(pos, 0), CONTAINER_SIZE_Y - BRICK_HEIGHT * 2);

const { moveProps } = useMove({
onMoveStart(e) {
console.log(`move start with pointerType = ${e.pointerType}`);
setColor('white');
},
onMove(e) {
const newX = brickCoords.x + e.deltaX;
const newY = brickCoords.y + e.deltaY;
setCoords(brickData.id, { x: clampX(newX), y: clampY(newY) });

brickData.childBricks.forEach((childBrick) => {
const childBrickCoords = getCoords(childBrick)!;
setCoords(childBrick, {
x: childBrickCoords.x + e.deltaX,
y: childBrickCoords.y + e.deltaY,
});
});

const belowBrickIds = getBelowBricksIds(WORKSPACES_DATA[0].data, brickData.id);
belowBrickIds.forEach((belowBrickId) => {
const belowBrickCoords = getCoords(belowBrickId)!;
setCoords(belowBrickId, {
x: belowBrickCoords.x + e.deltaX,
y: belowBrickCoords.y + e.deltaY,
});
});

// Normally, we want to allow the user to continue
// dragging outside the box such that they need to
// drag back over the ball again before it moves.
// This is handled below by clamping during render.
// If using the keyboard, however, we need to clamp
// here so that dragging outside the container and
// then using the arrow keys works as expected.
// if (e.pointerType === 'keyboard') {
// x = clamp(x);
// y = clamp(y);
// }

// setEvents((events) => [
// `move with pointerType = ${e.pointerType}, deltaX = ${e.deltaX}, deltaY = ${e.deltaY}`,
// ...events,
// ]);
},
onMoveEnd(e) {
console.log(`move end with pointerType = ${e.pointerType}`);
setColor(brickData.instance.colorBg as string);
},
});

const VisualIndicators = () => (
<>
{/* Right args bounding box */}
{'bBoxArgs' in brickData.instance && (
<>
{Object.keys(brickData.instance.bBoxArgs).map((name, i) => {
if ('bBoxArgs' in brickData.instance) {
const arg = brickData.instance.bBoxArgs[name];

return (
<rect
key={i}
x={brickCoords.x + arg?.coords.x}
y={brickCoords.y + arg?.coords.y}
height={arg?.extent.height}
width={arg?.extent.width}
fill="green"
opacity={0.8}
/>
);
}
})}
</>
)}

{/* Top instruction notch bounding box */}
{'bBoxNotchInsTop' in brickData.instance && (
<rect
x={brickCoords.x + brickData.instance.bBoxNotchInsTop?.coords.x}
y={brickCoords.y + brickData.instance.bBoxNotchInsTop?.coords.y}
height={brickData.instance.bBoxNotchInsTop?.extent.height}
width={brickData.instance.bBoxNotchInsTop?.extent.width}
fill="green"
opacity={0.9}
/>
)}

{/* Bottom instruction notch bounding box */}
{'bBoxNotchInsBot' in brickData.instance && (
<rect
x={brickCoords.x + brickData.instance.bBoxNotchInsBot?.coords.x}
y={brickCoords.y + brickData.instance.bBoxNotchInsBot?.coords.y}
height={brickData.instance.bBoxNotchInsBot?.extent.height}
width={brickData.instance.bBoxNotchInsBot?.extent.width}
fill="green"
opacity={0.9}
/>
)}

{/* Top instruction notch inside nesting bounding box */}
{'bBoxNotchInsNestTop' in brickData.instance && (
<rect
x={brickCoords.x + brickData.instance.bBoxNotchInsNestTop?.coords.x}
y={brickCoords.y + brickData.instance.bBoxNotchInsNestTop?.coords.y}
height={brickData.instance.bBoxNotchInsNestTop?.extent.height}
width={brickData.instance.bBoxNotchInsNestTop?.extent.width}
fill="green"
opacity={0.9}
/>
)}
</>
);

const getBrick = () => {
switch (brickData.type) {
case 'data':
return (
<BrickData
brickData={brickData}
moveProps={moveProps}
coords={brickCoords}
color={color}
/>
);
case 'expression':
return (
<BrickExpression
brickData={brickData}
moveProps={moveProps}
coords={brickCoords}
color={color}
/>
);
case 'statement':
return (
<BrickStatement
brickData={brickData}
moveProps={moveProps}
coords={brickCoords}
color={color}
/>
);
case 'block':
return (
<BrickBlock
brickData={brickData}
moveProps={moveProps}
coords={brickCoords}
color={color}
/>
);
default:
return <></>;
}
};

return (
<>
<VisualIndicators />
{/* {getBrick()} */}
</>
);
};

export default BrickFactory;
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { create } from 'zustand';

type CoordsState = {
allCoords: {
brickId: string;
coords: {
x: number;
y: number;
};
}[];
setCoords: (brickId: string, coords: { x: number; y: number }) => void;
getCoords: (brickId: string) => { x: number; y: number } | undefined;
};

const useBricksCoordsStore = create<CoordsState>((set, get) => ({
allCoords: [
{ brickId: '1', coords: { x: 50, y: 50 } },
{ brickId: '2', coords: { x: 68, y: 92 } },
{ brickId: '3', coords: { x: 68, y: 134 } },
{ brickId: '4', coords: { x: 68, y: 176 } },
{ brickId: '5', coords: { x: 86, y: 218 } },
{ brickId: '6', coords: { x: 68, y: 302 } },
],
setCoords: (brickId: string, coords: { x: number; y: number }) =>
set(
(state: {
allCoords: {
brickId: string;
coords: {
x: number;
y: number;
};
}[];
}) => ({
allCoords: state.allCoords.map((item) =>
item.brickId === brickId ? { brickId, coords } : item,
),
}),
),
getCoords: (brickId: string) =>
get().allCoords.find((item) => item.brickId === brickId)?.coords,
}));

export const useBricksCoords = () => {
const allCoords = useBricksCoordsStore((state) => state.allCoords);
const setCoords = useBricksCoordsStore((state) => state.setCoords);
const getCoords = useBricksCoordsStore((state) => state.getCoords);

return { allCoords, setCoords, getCoords };
};
Loading
Loading