-
Notifications
You must be signed in to change notification settings - Fork 143
GSoC 2025 Week 4-5: feat(Masonry): Complete Brick Tower Rendering System Implementation #443
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
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
1d6fa11
fix(masonry): path generation for compound bricks is fixed
saumyashahi 8ff5887
feat(masonry): add text measurement utility and dynamic label width c…
saumyashahi 400dba7
feat(masonry): add origin calculation logic for nested and argumnent …
saumyashahi 829bcf9
feat(masonry): add brick tree rendereing system for connection types
saumyashahi 68bd13a
feat(masonry): add test story for argument positioning with different…
saumyashahi 062f33b
feat(masonry): add argument brick management with dynamic positioning
saumyashahi a95bf7b
feat(masonry): add brick factory for creating different brick types w…
saumyashahi f2b309d
feat(masonry): add TreeView stories for different brick layouts and c…
saumyashahi 6ffaf38
chore(masonry): remove debug statements and clean up code comments
saumyashahi 6461ec7
fix(masonry): all linting errors and warnings across masonry module
saumyashahi 2271109
refactor(masonry): [brick] seperate text measurement utility
Karan-Palan 0f51edf
chore(masonry): [tree] fix story filename typo
Karan-Palan 84ba115
feat(masonry): [brick] create wrapper compoenent
Karan-Palan 723bea0
feat(masonry): [brick] update other compoenents to reuse wrapper comp…
Karan-Palan 9321df1
refactor(masonry): move @types to /src and update imports
Karan-Palan 702bed0
refactor(masonry): [tower] refactor tree into tower and workspace man…
Karan-Palan 051d754
feat(masonry): [tower] seperate tower logic (one connected stack), si…
Karan-Palan 648fbb3
feat(masonry): [workspace] create Workspace manager which perfroms CR…
Karan-Palan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| /** A simple Cartesian point */ | ||
| export type TPoint = { x: number; y: number }; | ||
|
|
||
| /** All supported physical notch pairings */ | ||
| export type TNotchType = 'top-bottom' | 'right-left' | 'left-right' | 'nested'; | ||
|
|
||
| /** A single connection‑point centroid */ | ||
| export type TConnectionPoint = { x: number; y: number }; | ||
|
|
||
| /** One logical connection between two bricks */ | ||
| export type TBrickConnection = { | ||
| from: string; // uuid of source brick | ||
| to: string; // uuid of destination brick | ||
| fromNotchId: string; // e.g. "right_0" | ||
| toNotchId: string; // e.g. "left" | ||
| type: TNotchType; | ||
| }; | ||
|
|
||
| /** Validation result for attempted connections */ | ||
| export type TConnectionValidation = { | ||
| isValid: boolean; | ||
| reason?: string; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| // brickFactory.ts | ||
| import { SimpleBrick, ExpressionBrick } from '../model/model'; | ||
| import CompoundBrick from '../model/model'; | ||
| import type { TBrickType, TColor, TExtent } from '../../@types/brick'; | ||
|
|
||
| let idCounter = 0; | ||
| function generateUUID(prefix: string): string { | ||
| return `${prefix}_${++idCounter}`; | ||
| } | ||
|
|
||
| // Default colors | ||
| const defaultColors = { | ||
| simple: { | ||
| colorBg: '#bbdefb' as TColor, | ||
| colorFg: '#222' as TColor, | ||
| strokeColor: '#1976d2' as TColor, | ||
| }, | ||
| expression: { | ||
| colorBg: '#b2fab4' as TColor, | ||
| colorFg: '#222' as TColor, | ||
| strokeColor: '#2e7d32' as TColor, | ||
| }, | ||
| compound: { | ||
| colorBg: '#b9f6ca' as TColor, | ||
| colorFg: '#222' as TColor, | ||
| strokeColor: '#43a047' as TColor, | ||
| }, | ||
| }; | ||
|
|
||
| const defaultLabelType = 'text' as const; | ||
| const defaultScale = 1; | ||
| const defaultBBoxArgs: TExtent[] = [{ w: 40, h: 20 }]; | ||
|
|
||
| export function createSimpleBrick( | ||
| overrides: Partial<ConstructorParameters<typeof SimpleBrick>[0]> = {}, | ||
| ) { | ||
| const idx = idCounter + 1; | ||
| // By default, SimpleBrick has two argument slots (for arguments/inputs) | ||
| return new SimpleBrick({ | ||
| uuid: generateUUID('simple'), | ||
| name: overrides.name ?? `Simple${idx}`, | ||
| label: overrides.label ?? `Simple${idx}`, | ||
| labelType: overrides.labelType ?? defaultLabelType, | ||
| colorBg: overrides.colorBg ?? defaultColors.simple.colorBg, | ||
| colorFg: overrides.colorFg ?? defaultColors.simple.colorFg, | ||
| strokeColor: overrides.strokeColor ?? defaultColors.simple.strokeColor, | ||
| shadow: overrides.shadow ?? false, | ||
| scale: overrides.scale ?? defaultScale, | ||
| bboxArgs: overrides.bboxArgs ?? [ | ||
| { w: 40, h: 20 }, | ||
| { w: 40, h: 20 }, | ||
| ], | ||
| topNotch: overrides.topNotch ?? true, | ||
| bottomNotch: overrides.bottomNotch ?? true, | ||
| tooltip: overrides.tooltip, | ||
| ...overrides, | ||
| }); | ||
| } | ||
|
|
||
| // ExpressionBrick is used as an argument value, not as an argument-receiving brick | ||
| export function createExpressionBrick( | ||
| overrides: Partial<ConstructorParameters<typeof ExpressionBrick>[0]> = {}, | ||
| ) { | ||
| const idx = idCounter + 1; | ||
| return new ExpressionBrick({ | ||
| uuid: generateUUID('expr'), | ||
| name: overrides.name ?? `Expr${idx}`, | ||
| label: overrides.label ?? `Expr${idx}`, | ||
| labelType: overrides.labelType ?? defaultLabelType, | ||
| colorBg: overrides.colorBg ?? defaultColors.expression.colorBg, | ||
| colorFg: overrides.colorFg ?? defaultColors.expression.colorFg, | ||
| strokeColor: overrides.strokeColor ?? defaultColors.expression.strokeColor, | ||
| shadow: overrides.shadow ?? false, | ||
| scale: overrides.scale ?? defaultScale, | ||
| bboxArgs: overrides.bboxArgs ?? [{ w: 40, h: 20 }], | ||
| value: overrides.value, | ||
| isValueSelectOpen: overrides.isValueSelectOpen ?? false, | ||
| tooltip: overrides.tooltip, | ||
| ...overrides, | ||
| }); | ||
| } | ||
|
|
||
| export function createCompoundBrick( | ||
| overrides: Partial<ConstructorParameters<typeof CompoundBrick>[0]> = {}, | ||
| ) { | ||
| const idx = idCounter + 1; | ||
| return new CompoundBrick({ | ||
| uuid: generateUUID('compound'), | ||
| name: overrides.name ?? `Compound${idx}`, | ||
| label: overrides.label ?? `Compound${idx}`, | ||
| labelType: overrides.labelType ?? defaultLabelType, | ||
| colorBg: overrides.colorBg ?? defaultColors.compound.colorBg, | ||
| colorFg: overrides.colorFg ?? defaultColors.compound.colorFg, | ||
| strokeColor: overrides.strokeColor ?? defaultColors.compound.strokeColor, | ||
| shadow: overrides.shadow ?? false, | ||
| scale: overrides.scale ?? defaultScale, | ||
| bboxArgs: overrides.bboxArgs ?? defaultBBoxArgs, | ||
| bboxNest: overrides.bboxNest ?? [], | ||
| topNotch: overrides.topNotch ?? true, | ||
| bottomNotch: overrides.bottomNotch ?? true, | ||
| isFolded: overrides.isFolded ?? false, | ||
| tooltip: overrides.tooltip, | ||
| ...overrides, | ||
| }); | ||
| } | ||
|
|
||
| export function resetFactoryCounter() { | ||
| idCounter = 0; | ||
| } | ||
|
|
||
| export function getFactoryCounter() { | ||
| return idCounter; | ||
| } | ||
|
|
||
| export function createBrick( | ||
| type: TBrickType, | ||
| overrides: Partial< | ||
| | ConstructorParameters<typeof SimpleBrick>[0] | ||
| | ConstructorParameters<typeof ExpressionBrick>[0] | ||
| | ConstructorParameters<typeof CompoundBrick>[0] | ||
| > = {}, | ||
| ) { | ||
| switch (type) { | ||
| case 'Simple': | ||
| return createSimpleBrick(overrides); | ||
| case 'Expression': | ||
| return createExpressionBrick(overrides); | ||
| case 'Compound': | ||
| return createCompoundBrick(overrides); | ||
| default: | ||
| throw new Error(`Unsupported brick type: ${type}`); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| export { | ||
| createSimpleBrick, | ||
| createExpressionBrick, | ||
| createCompoundBrick, | ||
| createBrick, | ||
| resetFactoryCounter, | ||
| getFactoryCounter, | ||
| } from './brickFactory'; | ||
| export { generateBrickData } from './path'; | ||
| export type { TInputUnion } from './path'; | ||
| export { | ||
| measureTextWidth, | ||
| estimateTextWidth, | ||
| getLabelWidth, | ||
| measureLabel, | ||
| } from './textMeasurement'; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is temporary to render stuff right now, will be updated later, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I figured the previous method to determine the label width in justin's model wasn't rendering correct, so I used this one, we can enhance this further in time as required. Right now for rendering in storybooks this method works fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The model does not decide the label length, the component does
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was no function in the model to determine the label width. That was done by the react component itself. The model is only responsible to determine and pass down the props and has no connection(functions related to) to rendering the brick.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had temporarily added
estimateTextWidth(label)inside the model just to visually unblock layout issues in Storybook for now. But yes, this is something we can definitely clean up by moving all layout-related measurements (like label width) to the React view layerThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initially the label widths were being calculated in a fixed way for all label width, no function in the model to determine the label width hence it did not return correct bounding boxes and the position for the origin of the argument bricks for short and long labels did not render correctly. So I made a function to calculate label width
Now it is working correctly .