Skip to content

Commit

Permalink
feat: Highlight a shape hovered in the tree panel
Browse files Browse the repository at this point in the history
  • Loading branch information
miyanokomiya committed Nov 20, 2024
1 parent 031557c commit b5c3a40
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
31 changes: 28 additions & 3 deletions src/components/shapeTreePanel/ShapeTreePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ export const ShapeTreePanel: React.FC = () => {
const { handleEvent } = useContext(AppStateMachineContext);
const getCtx = useContext(GetAppStateContext);

const handleNodeHover = useCallback(
(id: string) => {
handleEvent({
type: "shape-highlight",
data: { id, meta: { type: "outline" } },
});
},
[handleEvent],
);

const handleNodeSelect = useCallback(
(id: string, multi = false, range = false) => {
const ctx = getCtx();
Expand Down Expand Up @@ -150,7 +160,13 @@ export const ShapeTreePanel: React.FC = () => {
<ul className="relative flex flex-col items-start" style={{ gap: 1 }}>
{rootNodeProps.map((n) => (
<li key={n.id} className="w-full">
<UITreeNode {...n} dropTo={dropTo} onSelect={handleNodeSelect} onDragStart={handleStartDragging} />
<UITreeNode
{...n}
dropTo={dropTo}
onHover={handleNodeHover}
onSelect={handleNodeSelect}
onDragStart={handleStartDragging}
/>
</li>
))}
{draggingTarget ? (
Expand All @@ -176,6 +192,7 @@ interface UITreeNodeProps {
primeSibling: boolean;
draggable: boolean;
dropTo?: [string, DropOperation];
onHover?: (id: string) => void;
onSelect?: (id: string, multi?: boolean, range?: boolean) => void;
onDragStart?: (e: React.PointerEvent, id: string) => void;
renderShape: (id: string, canvas: HTMLCanvasElement | null) => void;
Expand All @@ -191,6 +208,7 @@ const UITreeNode: React.FC<UITreeNodeProps> = ({
primeSibling,
draggable,
dropTo,
onHover,
onSelect,
onDragStart,
renderShape,
Expand Down Expand Up @@ -222,6 +240,10 @@ const UITreeNode: React.FC<UITreeNodeProps> = ({
onSelect?.(id, true);
}, [id, onSelect]);

const handleNodePointerEnter = useCallback(() => {
onHover?.(id);
}, [id, onHover]);

const rootRef = useRef<HTMLDivElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);

Expand Down Expand Up @@ -258,8 +280,11 @@ const UITreeNode: React.FC<UITreeNodeProps> = ({
<div className={"ml-1 w-2 border-gray-400 " + (draggable ? "border-t-2" : "border-2 h-2 rounded-full")} />
<button
type="button"
className={"px-1 rounded w-full flex items-center gap-2 select-none touch-none" + selectedClass}
className={
"px-1 rounded w-full flex items-center gap-2 select-none touch-none hover:bg-gray-200" + selectedClass
}
onPointerDown={handleNodeDown}
onPointerEnter={handleNodePointerEnter}
>
<div className="border rounded" style={{ backgroundColor: sheetColor, padding: 2 }}>
<canvas ref={canvasRef} width="24" height="24" />
Expand All @@ -280,7 +305,7 @@ const UITreeNode: React.FC<UITreeNodeProps> = ({
>
{childNode.map((c) => (
<li key={c.id} className="w-full">
<UITreeNode {...c} dropTo={dropTo} onSelect={onSelect} onDragStart={onDragStart} />
<UITreeNode {...c} dropTo={dropTo} onHover={onHover} onSelect={onSelect} onDragStart={onDragStart} />
</li>
))}
<div className="absolute left-0 right-0 bottom-0 border-t border-gray-400" />
Expand Down
10 changes: 9 additions & 1 deletion src/composables/states/appCanvas/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,15 @@ export interface ShapeHighlightEvent extends ModeStateEventBase {
};
}

export type HighlightShapeMeta = HighlightLineVertexMeta | HighlightLineSegmentMeta | HighlightLineBezierMeta;
export type HighlightShapeMeta =
| HighlightOutline
| HighlightLineVertexMeta
| HighlightLineSegmentMeta
| HighlightLineBezierMeta;

export type HighlightOutline = {
type: "outline";
};

export type HighlightLineVertexMeta = {
type: "vertex";
Expand Down
14 changes: 13 additions & 1 deletion src/composables/states/appCanvas/intransientState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ export function defineIntransientState<A extends any[]>(
}
break;
}
case "shape-highlight": {
switch (event.data.meta.type) {
case "outline": {
const shapeComposite = ctx.getShapeComposite();
hoveredShape = shapeComposite.shapeMap[event.data.id];
ctx.redraw();
return;
}
default:
return;
}
}
}

return src.handleEvent(ctx, event);
Expand All @@ -72,7 +84,7 @@ export function defineIntransientState<A extends any[]>(

applyStrokeStyle(renderCtx, {
color: ctx.getStyleScheme().selectionSecondaly,
width: 2 * ctx.getScale(),
width: 3 * ctx.getScale(),
dash: "short",
});
renderCtx.stroke();
Expand Down

0 comments on commit b5c3a40

Please sign in to comment.