From b86162a58641741d6ee1373568e30567ea3a0c8a Mon Sep 17 00:00:00 2001 From: Vemulapalli Akshay Date: Tue, 24 Mar 2026 14:25:12 +0800 Subject: [PATCH 1/6] Fix HIGHLIGHTING --- src/features/cseMachine/CseMachineTypes.ts | 2 ++ .../cseMachine/components/ArrayUnit.tsx | 12 ++++++++++++ .../components/ControlItemComponent.tsx | 14 ++++++++++++++ src/features/cseMachine/components/Frame.tsx | 18 ++++++++++++++++++ .../components/StashItemComponent.tsx | 14 ++++++++++++++ src/features/cseMachine/components/Text.tsx | 8 ++++++++ src/features/cseMachine/components/Visible.tsx | 2 ++ .../components/arrows/GenericArrow.tsx | 5 +++++ .../cseMachine/components/values/ContValue.tsx | 17 +++++++++++++++++ .../cseMachine/components/values/FnValue.tsx | 17 +++++++++++++++++ .../components/values/GlobalFnValue.tsx | 17 +++++++++++++++++ 11 files changed, 126 insertions(+) diff --git a/src/features/cseMachine/CseMachineTypes.ts b/src/features/cseMachine/CseMachineTypes.ts index 7f0e4d672e..9841ec0e2b 100644 --- a/src/features/cseMachine/CseMachineTypes.ts +++ b/src/features/cseMachine/CseMachineTypes.ts @@ -40,6 +40,8 @@ export interface IVisible extends Drawable { height(): number; ref?: React.RefObject; + setArrowSourceHighlightedStyle?(): void; + setArrowSourceNormalStyle?(): void; } /** unassigned is internally represented as a symbol */ diff --git a/src/features/cseMachine/components/ArrayUnit.tsx b/src/features/cseMachine/components/ArrayUnit.tsx index 400b2e1399..256cfa7c59 100644 --- a/src/features/cseMachine/components/ArrayUnit.tsx +++ b/src/features/cseMachine/components/ArrayUnit.tsx @@ -60,6 +60,18 @@ export class ArrayUnit extends Visible { if (!CseMachine.getPrintableMode()) this.indexRef.current?.hide(); } + setArrowSourceHighlightedStyle(): void { + this.ref.current?.stroke(Config.HoverColor); + } + + setArrowSourceNormalStyle(): void { + this.ref.current?.stroke( + this.parent.isReferenced() && this.parent.isEnclosingFrameLive() + ? defaultStrokeColor() + : fadedStrokeColor() + ); + } + draw(): React.ReactNode { if (this.isDrawn()) return null; this._isDrawn = true; diff --git a/src/features/cseMachine/components/ControlItemComponent.tsx b/src/features/cseMachine/components/ControlItemComponent.tsx index b693b7cb12..fa8ae156e2 100644 --- a/src/features/cseMachine/components/ControlItemComponent.tsx +++ b/src/features/cseMachine/components/ControlItemComponent.tsx @@ -92,6 +92,20 @@ export class ControlItemComponent extends Visible implements IHoverable { this.ref.current.zIndex(this.zIndex); }; + setArrowSourceHighlightedStyle(): void { + const tag = this.ref.current?.getChildren?.()[0]; + const text = this.ref.current?.getChildren?.()[1]; + tag?.stroke(Config.HoverColor); + text?.fill(Config.HoverColor); + } + + setArrowSourceNormalStyle(): void { + const tag = this.ref.current?.getChildren?.()[0]; + const text = this.ref.current?.getChildren?.()[1]; + tag?.stroke(this.topItem ? defaultActiveColor() : defaultStrokeColor()); + text?.fill(defaultTextColor()); + } + destroy() { this.ref.current.destroyChildren(); } diff --git a/src/features/cseMachine/components/Frame.tsx b/src/features/cseMachine/components/Frame.tsx index 89d06788e5..8668e675bc 100644 --- a/src/features/cseMachine/components/Frame.tsx +++ b/src/features/cseMachine/components/Frame.tsx @@ -59,6 +59,7 @@ export class Frame extends Visible implements IHoverable { readonly bindings: Binding[] = []; /** name of this frame to display */ private _name!: Text; // removed readonly to allow reassignment for fixed layout + private readonly rectRef = React.createRef(); /** the level in which this frame resides */ readonly level: Level | undefined; /** environment associated with this frame */ @@ -260,6 +261,22 @@ export class Frame extends Visible implements IHoverable { onMouseLeave = () => {}; + setArrowSourceHighlightedStyle(): void { + this.rectRef.current?.stroke(Config.HoverColor); + this.name.setArrowSourceHighlightedStyle(); + } + + setArrowSourceNormalStyle(): void { + this.rectRef.current?.stroke( + CseMachine.getCurrentEnvId() === this.environment?.id + ? defaultActiveColor() + : this.isLive + ? defaultStrokeColor() + : fadedStrokeColor() + ); + this.name.setArrowSourceNormalStyle(); + } + draw(): React.ReactNode { return ( @@ -267,6 +284,7 @@ export class Frame extends Visible implements IHoverable { = React.createRef(); + setArrowSourceHighlightedStyle(): void {} + setArrowSourceNormalStyle(): void {} abstract draw(key?: number): React.ReactNode; } diff --git a/src/features/cseMachine/components/arrows/GenericArrow.tsx b/src/features/cseMachine/components/arrows/GenericArrow.tsx index 97c885e066..1ece2c4015 100644 --- a/src/features/cseMachine/components/arrows/GenericArrow.tsx +++ b/src/features/cseMachine/components/arrows/GenericArrow.tsx @@ -189,6 +189,7 @@ export class GenericArrow this.arrowHeadRef.current.pointerWidth(Config.ArrowHoveredHeadSize); this.arrowHeadRef.current.pointerLength(Config.ArrowHoveredHeadSize); } + this.source.setArrowSourceHighlightedStyle?.(); } public setNormalStyle() { @@ -202,6 +203,7 @@ export class GenericArrow this.arrowHeadRef.current.pointerWidth(Config.ArrowHeadSize); this.arrowHeadRef.current.pointerLength(Config.ArrowHeadSize); } + this.source.setArrowSourceNormalStyle?.(); } onClick = (e: KonvaEventObject) => { @@ -220,6 +222,9 @@ export class GenericArrow this.select(); // Update this arrow's visual state this.setHighlightedStyle(); + } else { + // If the arrow was already selected, deselect it and revert to normal style + this.setNormalStyle(); } // Force redraw entire layer to update all arrows diff --git a/src/features/cseMachine/components/values/ContValue.tsx b/src/features/cseMachine/components/values/ContValue.tsx index 9deadcdcad..f72bb2fdcd 100644 --- a/src/features/cseMachine/components/values/ContValue.tsx +++ b/src/features/cseMachine/components/values/ContValue.tsx @@ -128,6 +128,23 @@ export class ContValue extends Value implements IHoverable { this.labelRef.current?.hide(); }; + setArrowSourceHighlightedStyle(): void { + const shapes = this.ref.current?.getChildren?.() ?? []; + shapes.forEach((shape: any) => { + if (shape.attrs.stroke) shape.stroke(Config.HoverColor); + if (shape.attrs.fill) shape.fill(Config.HoverColor); + }); + } + + setArrowSourceNormalStyle(): void { + const strokeColor = this.isLive() ? defaultStrokeColor() : fadedStrokeColor(); + const shapes = this.ref.current?.getChildren?.() ?? []; + shapes.forEach((shape: any) => { + if (shape.attrs.stroke) shape.stroke(strokeColor); + if (shape.attrs.fill) shape.fill(strokeColor); + }); + } + draw(): React.ReactNode { if (this.enclosingFrame) { this._arrow = new ArrowFromFn(this).to(this.enclosingFrame) as ArrowFromFn; diff --git a/src/features/cseMachine/components/values/FnValue.tsx b/src/features/cseMachine/components/values/FnValue.tsx index e854a57d53..f1c4000168 100644 --- a/src/features/cseMachine/components/values/FnValue.tsx +++ b/src/features/cseMachine/components/values/FnValue.tsx @@ -169,6 +169,23 @@ export class FnValue extends Value implements IHoverable { currentTarget.getLayer()?.batchDraw(); }; + setArrowSourceHighlightedStyle(): void { + const shapes = this.ref.current?.getChildren?.() ?? []; + shapes.forEach((shape: any) => { + if (shape.attrs.stroke) shape.stroke(Config.HoverColor); + if (shape.attrs.fill) shape.fill(Config.HoverColor); + }); + } + + setArrowSourceNormalStyle(): void { + const strokeColor = this.isLive() ? defaultStrokeColor() : fadedStrokeColor(); + const shapes = this.ref.current?.getChildren?.() ?? []; + shapes.forEach((shape: any) => { + if (shape.attrs.stroke) shape.stroke(strokeColor); + if (shape.attrs.fill) shape.fill(strokeColor); + }); + } + isLive(): boolean { const id = (this.data as any).id; return id ? Layout.liveObjectIDs.has(id) : false; diff --git a/src/features/cseMachine/components/values/GlobalFnValue.tsx b/src/features/cseMachine/components/values/GlobalFnValue.tsx index 66cc1c9064..96941e0726 100644 --- a/src/features/cseMachine/components/values/GlobalFnValue.tsx +++ b/src/features/cseMachine/components/values/GlobalFnValue.tsx @@ -142,6 +142,23 @@ export class GlobalFnValue extends Value implements IHoverable { currentTarget.getLayer()?.batchDraw(); }; + setArrowSourceHighlightedStyle(): void { + const shapes = this.ref.current?.getChildren?.() ?? []; + shapes.forEach((shape: any) => { + if (shape.attrs.stroke) shape.stroke(Config.HoverColor); + if (shape.attrs.fill) shape.fill(Config.HoverColor); + }); + } + + setArrowSourceNormalStyle(): void { + const strokeColor = this.isReferenced() ? defaultStrokeColor() : fadedStrokeColor(); + const shapes = this.ref.current?.getChildren?.() ?? []; + shapes.forEach((shape: any) => { + if (shape.attrs.stroke) shape.stroke(strokeColor); + if (shape.attrs.fill) shape.fill(strokeColor); + }); + } + draw(): React.ReactNode { this._isDrawn = true; if (Layout.globalEnvNode.frame) { From 423f7bac6648d085408854569d5479dadc088fb7 Mon Sep 17 00:00:00 2001 From: Vemulapalli Akshay Date: Tue, 24 Mar 2026 15:04:52 +0800 Subject: [PATCH 2/6] Gemini suggestions --- .../cseMachine/components/ControlItemComponent.tsx | 14 ++++++-------- .../cseMachine/components/StashItemComponent.tsx | 14 ++++++-------- src/features/cseMachine/components/Visible.tsx | 13 +++++++++++++ .../cseMachine/components/values/ContValue.tsx | 12 ++---------- .../cseMachine/components/values/FnValue.tsx | 12 ++---------- .../cseMachine/components/values/GlobalFnValue.tsx | 12 ++---------- 6 files changed, 31 insertions(+), 46 deletions(-) diff --git a/src/features/cseMachine/components/ControlItemComponent.tsx b/src/features/cseMachine/components/ControlItemComponent.tsx index fa8ae156e2..617b10cbea 100644 --- a/src/features/cseMachine/components/ControlItemComponent.tsx +++ b/src/features/cseMachine/components/ControlItemComponent.tsx @@ -93,17 +93,15 @@ export class ControlItemComponent extends Visible implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - const tag = this.ref.current?.getChildren?.()[0]; - const text = this.ref.current?.getChildren?.()[1]; - tag?.stroke(Config.HoverColor); - text?.fill(Config.HoverColor); + this.resetStyle(); + this.tag?.stroke(Config.HoverColor); + this.secItem?.fill(Config.HoverColor); } setArrowSourceNormalStyle(): void { - const tag = this.ref.current?.getChildren?.()[0]; - const text = this.ref.current?.getChildren?.()[1]; - tag?.stroke(this.topItem ? defaultActiveColor() : defaultStrokeColor()); - text?.fill(defaultTextColor()); + this.resetStyle(); + this.tag?.stroke(this.topItem ? defaultActiveColor() : defaultStrokeColor()); + this.secItem?.fill(defaultTextColor()); } destroy() { diff --git a/src/features/cseMachine/components/StashItemComponent.tsx b/src/features/cseMachine/components/StashItemComponent.tsx index a044952727..49d7eac134 100644 --- a/src/features/cseMachine/components/StashItemComponent.tsx +++ b/src/features/cseMachine/components/StashItemComponent.tsx @@ -107,17 +107,15 @@ export class StashItemComponent extends Visible implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - const tag = this.ref.current?.getChildren?.()[0]; - const text = this.ref.current?.getChildren?.()[1]; - tag?.stroke(Config.HoverColor); - text?.fill(Config.HoverColor); + this.resetStyle(); + this.tag?.stroke(Config.HoverColor); + this.secItem?.fill(Config.HoverColor); } setArrowSourceNormalStyle(): void { - const tag = this.ref.current?.getChildren?.()[0]; - const text = this.ref.current?.getChildren?.()[1]; - tag?.stroke(isStashItemInDanger(this.index) ? defaultDangerColor() : defaultStrokeColor()); - text?.fill(defaultTextColor()); + this.resetStyle(); + this.tag?.stroke(isStashItemInDanger(this.index) ? defaultDangerColor() : defaultStrokeColor()); + this.secItem?.fill(defaultTextColor()); } destroy() { diff --git a/src/features/cseMachine/components/Visible.tsx b/src/features/cseMachine/components/Visible.tsx index 28116898a7..fd460a78ba 100644 --- a/src/features/cseMachine/components/Visible.tsx +++ b/src/features/cseMachine/components/Visible.tsx @@ -30,7 +30,20 @@ export abstract class Visible implements IVisible { reset(): void { this._isDrawn = false; } + setShapesStyle(color: string) { + const shapes = this.ref.current?.getChildren?.() ?? []; + shapes.forEach((shape: any) => { + if (shape.attrs.stroke) shape.stroke(color); + if (shape.attrs.fill) shape.fill(color); + }); + } public ref: RefObject = React.createRef(); + protected tag = this.ref.current?.getChildren?.()[0]; + protected secItem = this.ref.current?.getChildren?.()[1]; + resetStyle(): void { + this.tag = this.ref.current?.getChildren?.()[0]; + this.secItem = this.ref.current?.getChildren?.()[1]; + } setArrowSourceHighlightedStyle(): void {} setArrowSourceNormalStyle(): void {} abstract draw(key?: number): React.ReactNode; diff --git a/src/features/cseMachine/components/values/ContValue.tsx b/src/features/cseMachine/components/values/ContValue.tsx index f72bb2fdcd..2a6de79c8f 100644 --- a/src/features/cseMachine/components/values/ContValue.tsx +++ b/src/features/cseMachine/components/values/ContValue.tsx @@ -129,20 +129,12 @@ export class ContValue extends Value implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - const shapes = this.ref.current?.getChildren?.() ?? []; - shapes.forEach((shape: any) => { - if (shape.attrs.stroke) shape.stroke(Config.HoverColor); - if (shape.attrs.fill) shape.fill(Config.HoverColor); - }); + this.setShapesStyle(Config.HoverColor); } setArrowSourceNormalStyle(): void { const strokeColor = this.isLive() ? defaultStrokeColor() : fadedStrokeColor(); - const shapes = this.ref.current?.getChildren?.() ?? []; - shapes.forEach((shape: any) => { - if (shape.attrs.stroke) shape.stroke(strokeColor); - if (shape.attrs.fill) shape.fill(strokeColor); - }); + this.setShapesStyle(strokeColor); } draw(): React.ReactNode { diff --git a/src/features/cseMachine/components/values/FnValue.tsx b/src/features/cseMachine/components/values/FnValue.tsx index f1c4000168..a83f77903a 100644 --- a/src/features/cseMachine/components/values/FnValue.tsx +++ b/src/features/cseMachine/components/values/FnValue.tsx @@ -170,20 +170,12 @@ export class FnValue extends Value implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - const shapes = this.ref.current?.getChildren?.() ?? []; - shapes.forEach((shape: any) => { - if (shape.attrs.stroke) shape.stroke(Config.HoverColor); - if (shape.attrs.fill) shape.fill(Config.HoverColor); - }); + this.setShapesStyle(Config.HoverColor); } setArrowSourceNormalStyle(): void { const strokeColor = this.isLive() ? defaultStrokeColor() : fadedStrokeColor(); - const shapes = this.ref.current?.getChildren?.() ?? []; - shapes.forEach((shape: any) => { - if (shape.attrs.stroke) shape.stroke(strokeColor); - if (shape.attrs.fill) shape.fill(strokeColor); - }); + this.setShapesStyle(strokeColor); } isLive(): boolean { diff --git a/src/features/cseMachine/components/values/GlobalFnValue.tsx b/src/features/cseMachine/components/values/GlobalFnValue.tsx index 96941e0726..51bc6781d0 100644 --- a/src/features/cseMachine/components/values/GlobalFnValue.tsx +++ b/src/features/cseMachine/components/values/GlobalFnValue.tsx @@ -143,20 +143,12 @@ export class GlobalFnValue extends Value implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - const shapes = this.ref.current?.getChildren?.() ?? []; - shapes.forEach((shape: any) => { - if (shape.attrs.stroke) shape.stroke(Config.HoverColor); - if (shape.attrs.fill) shape.fill(Config.HoverColor); - }); + this.setShapesStyle(Config.HoverColor); } setArrowSourceNormalStyle(): void { const strokeColor = this.isReferenced() ? defaultStrokeColor() : fadedStrokeColor(); - const shapes = this.ref.current?.getChildren?.() ?? []; - shapes.forEach((shape: any) => { - if (shape.attrs.stroke) shape.stroke(strokeColor); - if (shape.attrs.fill) shape.fill(strokeColor); - }); + this.setShapesStyle(strokeColor); } draw(): React.ReactNode { From 22cb2aff63f9049bd874c7ca04bd5392f50e383d Mon Sep 17 00:00:00 2001 From: Vemulapalli Akshay Date: Wed, 25 Mar 2026 23:22:39 +0800 Subject: [PATCH 3/6] Fixed all suggestions from bots and Rick --- .../cseMachine/components/ControlItemComponent.tsx | 2 -- src/features/cseMachine/components/Frame.tsx | 3 ++- .../cseMachine/components/StashItemComponent.tsx | 2 -- src/features/cseMachine/components/Visible.tsx | 12 ++++++------ 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/features/cseMachine/components/ControlItemComponent.tsx b/src/features/cseMachine/components/ControlItemComponent.tsx index 617b10cbea..cc1bb37255 100644 --- a/src/features/cseMachine/components/ControlItemComponent.tsx +++ b/src/features/cseMachine/components/ControlItemComponent.tsx @@ -93,13 +93,11 @@ export class ControlItemComponent extends Visible implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - this.resetStyle(); this.tag?.stroke(Config.HoverColor); this.secItem?.fill(Config.HoverColor); } setArrowSourceNormalStyle(): void { - this.resetStyle(); this.tag?.stroke(this.topItem ? defaultActiveColor() : defaultStrokeColor()); this.secItem?.fill(defaultTextColor()); } diff --git a/src/features/cseMachine/components/Frame.tsx b/src/features/cseMachine/components/Frame.tsx index 8668e675bc..30cad7b680 100644 --- a/src/features/cseMachine/components/Frame.tsx +++ b/src/features/cseMachine/components/Frame.tsx @@ -1,3 +1,4 @@ +import { Rect as KonvaRect } from 'konva/lib/shapes/Rect'; import React from 'react'; import { Group, Rect } from 'react-konva'; @@ -59,7 +60,7 @@ export class Frame extends Visible implements IHoverable { readonly bindings: Binding[] = []; /** name of this frame to display */ private _name!: Text; // removed readonly to allow reassignment for fixed layout - private readonly rectRef = React.createRef(); + private readonly rectRef = React.createRef(); /** the level in which this frame resides */ readonly level: Level | undefined; /** environment associated with this frame */ diff --git a/src/features/cseMachine/components/StashItemComponent.tsx b/src/features/cseMachine/components/StashItemComponent.tsx index 49d7eac134..9c41c0fad0 100644 --- a/src/features/cseMachine/components/StashItemComponent.tsx +++ b/src/features/cseMachine/components/StashItemComponent.tsx @@ -107,13 +107,11 @@ export class StashItemComponent extends Visible implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - this.resetStyle(); this.tag?.stroke(Config.HoverColor); this.secItem?.fill(Config.HoverColor); } setArrowSourceNormalStyle(): void { - this.resetStyle(); this.tag?.stroke(isStashItemInDanger(this.index) ? defaultDangerColor() : defaultStrokeColor()); this.secItem?.fill(defaultTextColor()); } diff --git a/src/features/cseMachine/components/Visible.tsx b/src/features/cseMachine/components/Visible.tsx index fd460a78ba..dd2c17e323 100644 --- a/src/features/cseMachine/components/Visible.tsx +++ b/src/features/cseMachine/components/Visible.tsx @@ -30,7 +30,7 @@ export abstract class Visible implements IVisible { reset(): void { this._isDrawn = false; } - setShapesStyle(color: string) { + setShapesStyle(color: string): void { const shapes = this.ref.current?.getChildren?.() ?? []; shapes.forEach((shape: any) => { if (shape.attrs.stroke) shape.stroke(color); @@ -38,11 +38,11 @@ export abstract class Visible implements IVisible { }); } public ref: RefObject = React.createRef(); - protected tag = this.ref.current?.getChildren?.()[0]; - protected secItem = this.ref.current?.getChildren?.()[1]; - resetStyle(): void { - this.tag = this.ref.current?.getChildren?.()[0]; - this.secItem = this.ref.current?.getChildren?.()[1]; + protected get tag() { + return this.ref.current?.getChildren?.()[0]; + } + protected get secItem() { + return this.ref.current?.getChildren?.()[1]; } setArrowSourceHighlightedStyle(): void {} setArrowSourceNormalStyle(): void {} From fb3e1d3bec647fbe4f1ce23695d428ed2cf03afe Mon Sep 17 00:00:00 2001 From: Vemulapalli Akshay Date: Wed, 25 Mar 2026 23:35:33 +0800 Subject: [PATCH 4/6] Fixed Sentry bot error --- .../cseMachine/components/arrows/ArrowSelection.ts | 1 + src/features/cseMachine/components/arrows/GenericArrow.tsx | 7 +------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/features/cseMachine/components/arrows/ArrowSelection.ts b/src/features/cseMachine/components/arrows/ArrowSelection.ts index 7ca26b5e3f..bbbc7172fe 100644 --- a/src/features/cseMachine/components/arrows/ArrowSelection.ts +++ b/src/features/cseMachine/components/arrows/ArrowSelection.ts @@ -16,6 +16,7 @@ class ArrowSelectionManager { clearSelection(): GenericArrow | null { const oldArrow = this.selectedArrow; this.selectedArrow = null; + oldArrow?.setNormalStyle(); return oldArrow; } diff --git a/src/features/cseMachine/components/arrows/GenericArrow.tsx b/src/features/cseMachine/components/arrows/GenericArrow.tsx index 1ece2c4015..e8edb3347f 100644 --- a/src/features/cseMachine/components/arrows/GenericArrow.tsx +++ b/src/features/cseMachine/components/arrows/GenericArrow.tsx @@ -211,12 +211,7 @@ export class GenericArrow // Toggle selection - clear first, then select if it wasn't already selected const wasSelected = this.isSelected(); - const oldArrow = arrowSelection.clearSelection(); - - // Update old arrow's visual state - if (oldArrow && oldArrow !== this) { - oldArrow.setNormalStyle(); - } + arrowSelection.clearSelection(); if (!wasSelected) { this.select(); From 8a4dcba639bedad78363dfc377affeee55feacb1 Mon Sep 17 00:00:00 2001 From: Vemulapalli Akshay Date: Thu, 26 Mar 2026 13:49:33 +0800 Subject: [PATCH 5/6] New features added! Target now highlighed. Color added for identification of live vs dead while highlighting as well! --- src/features/cseMachine/CseMachineConfig.ts | 2 ++ src/features/cseMachine/components/ArrayUnit.tsx | 6 +++++- src/features/cseMachine/components/Frame.tsx | 6 +++++- src/features/cseMachine/components/Text.tsx | 6 +++++- .../cseMachine/components/arrows/GenericArrow.tsx | 5 +++-- src/features/cseMachine/components/values/ArrayValue.tsx | 8 ++++++++ src/features/cseMachine/components/values/ContValue.tsx | 6 +++++- src/features/cseMachine/components/values/FnValue.tsx | 6 +++++- .../cseMachine/components/values/GlobalFnValue.tsx | 6 +++++- 9 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/features/cseMachine/CseMachineConfig.ts b/src/features/cseMachine/CseMachineConfig.ts index d722459043..db1789bbc7 100644 --- a/src/features/cseMachine/CseMachineConfig.ts +++ b/src/features/cseMachine/CseMachineConfig.ts @@ -66,6 +66,7 @@ export const Config = Object.freeze({ PrintStrokeColor: '#777', PrintStrokeColorFaded: '#ccc', ArrowHighlightedColor: '#ffffff', + ArrowDeadHighlightedColor: '#787777', // Colors of different states ActiveColor: '#030fff', @@ -73,6 +74,7 @@ export const Config = Object.freeze({ DangerColor: '#ff1744', PrintDangerColor: '#f44336', HoverColor: '#25c225', + HoverDeadColor: '#127a12', PrintHoverColor: '#0dbf0d', // Colors for text hover background diff --git a/src/features/cseMachine/components/ArrayUnit.tsx b/src/features/cseMachine/components/ArrayUnit.tsx index 256cfa7c59..07ca195d15 100644 --- a/src/features/cseMachine/components/ArrayUnit.tsx +++ b/src/features/cseMachine/components/ArrayUnit.tsx @@ -61,7 +61,11 @@ export class ArrayUnit extends Visible { } setArrowSourceHighlightedStyle(): void { - this.ref.current?.stroke(Config.HoverColor); + if (this.parent.isLive()) { + this.ref.current?.stroke(Config.HoverColor); + } else { + this.ref.current?.stroke(Config.HoverDeadColor); + } } setArrowSourceNormalStyle(): void { diff --git a/src/features/cseMachine/components/Frame.tsx b/src/features/cseMachine/components/Frame.tsx index 30cad7b680..1fba618933 100644 --- a/src/features/cseMachine/components/Frame.tsx +++ b/src/features/cseMachine/components/Frame.tsx @@ -263,7 +263,11 @@ export class Frame extends Visible implements IHoverable { onMouseLeave = () => {}; setArrowSourceHighlightedStyle(): void { - this.rectRef.current?.stroke(Config.HoverColor); + if (this.isLive) { + this.rectRef.current?.stroke(Config.HoverColor); + } else { + this.rectRef.current?.stroke(Config.HoverDeadColor); + } this.name.setArrowSourceHighlightedStyle(); } diff --git a/src/features/cseMachine/components/Text.tsx b/src/features/cseMachine/components/Text.tsx index e5b56b8cd8..d4492c4a9c 100644 --- a/src/features/cseMachine/components/Text.tsx +++ b/src/features/cseMachine/components/Text.tsx @@ -96,7 +96,11 @@ export class Text extends Visible implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - this.ref.current?.fill(Config.HoverColor); + if (this.options.faded) { + this.ref.current?.fill(Config.HoverDeadColor); + } else { + this.ref.current?.fill(Config.HoverColor); + } } setArrowSourceNormalStyle(): void { diff --git a/src/features/cseMachine/components/arrows/GenericArrow.tsx b/src/features/cseMachine/components/arrows/GenericArrow.tsx index e8edb3347f..fd579dfb9a 100644 --- a/src/features/cseMachine/components/arrows/GenericArrow.tsx +++ b/src/features/cseMachine/components/arrows/GenericArrow.tsx @@ -146,7 +146,7 @@ export class GenericArrow * Subclasses can override this to provide custom hover colors. */ protected getHighlightedColor(): string { - return Config.ArrowHighlightedColor; + return this.isLive ? Config.ArrowHighlightedColor : Config.ArrowDeadHighlightedColor; } onMouseEnter = (e: KonvaEventObject) => { @@ -190,8 +190,8 @@ export class GenericArrow this.arrowHeadRef.current.pointerLength(Config.ArrowHoveredHeadSize); } this.source.setArrowSourceHighlightedStyle?.(); + this.target?.setArrowSourceHighlightedStyle?.(); } - public setNormalStyle() { const color = this.isLive ? defaultStrokeColor() : fadedStrokeColor(); if (this.pathRef.current) { @@ -204,6 +204,7 @@ export class GenericArrow this.arrowHeadRef.current.pointerLength(Config.ArrowHeadSize); } this.source.setArrowSourceNormalStyle?.(); + this.target?.setArrowSourceNormalStyle?.(); } onClick = (e: KonvaEventObject) => { diff --git a/src/features/cseMachine/components/values/ArrayValue.tsx b/src/features/cseMachine/components/values/ArrayValue.tsx index cb2de77a14..95aac8285e 100644 --- a/src/features/cseMachine/components/values/ArrayValue.tsx +++ b/src/features/cseMachine/components/values/ArrayValue.tsx @@ -109,6 +109,14 @@ export class ArrayValue extends Value implements IHoverable { } } + setArrowSourceHighlightedStyle(): void { + this.units.forEach(unit => unit.setArrowSourceHighlightedStyle()); + } + + setArrowSourceNormalStyle(): void { + this.units.forEach(unit => unit.setArrowSourceNormalStyle()); + } + isEnclosingFrameLive(): boolean { const id = (this.data as any).id; return id ? Layout.liveObjectIDs.has(id) : false; diff --git a/src/features/cseMachine/components/values/ContValue.tsx b/src/features/cseMachine/components/values/ContValue.tsx index 2a6de79c8f..83d0adf228 100644 --- a/src/features/cseMachine/components/values/ContValue.tsx +++ b/src/features/cseMachine/components/values/ContValue.tsx @@ -129,7 +129,11 @@ export class ContValue extends Value implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - this.setShapesStyle(Config.HoverColor); + if (this.isLive()) { + this.setShapesStyle(Config.HoverColor); + } else { + this.setShapesStyle(Config.HoverDeadColor); + } } setArrowSourceNormalStyle(): void { diff --git a/src/features/cseMachine/components/values/FnValue.tsx b/src/features/cseMachine/components/values/FnValue.tsx index a83f77903a..8d8845850a 100644 --- a/src/features/cseMachine/components/values/FnValue.tsx +++ b/src/features/cseMachine/components/values/FnValue.tsx @@ -170,7 +170,11 @@ export class FnValue extends Value implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - this.setShapesStyle(Config.HoverColor); + if (this.isLive()) { + this.setShapesStyle(Config.HoverColor); + } else { + this.setShapesStyle(Config.HoverDeadColor); + } } setArrowSourceNormalStyle(): void { diff --git a/src/features/cseMachine/components/values/GlobalFnValue.tsx b/src/features/cseMachine/components/values/GlobalFnValue.tsx index 51bc6781d0..1ab1d296d5 100644 --- a/src/features/cseMachine/components/values/GlobalFnValue.tsx +++ b/src/features/cseMachine/components/values/GlobalFnValue.tsx @@ -143,7 +143,11 @@ export class GlobalFnValue extends Value implements IHoverable { }; setArrowSourceHighlightedStyle(): void { - this.setShapesStyle(Config.HoverColor); + if (this.isReferenced()) { + this.setShapesStyle(Config.HoverColor); + } else { + this.setShapesStyle(Config.HoverDeadColor); + } } setArrowSourceNormalStyle(): void { From e4189342ad4f58798806c43fc7f6404cc6543d70 Mon Sep 17 00:00:00 2001 From: Vemulapalli Akshay Date: Thu, 26 Mar 2026 14:06:31 +0800 Subject: [PATCH 6/6] Fixed Gemini's suggestions --- src/features/cseMachine/components/Visible.tsx | 13 ++++++++++--- .../cseMachine/components/arrows/GenericArrow.tsx | 3 --- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/features/cseMachine/components/Visible.tsx b/src/features/cseMachine/components/Visible.tsx index dd2c17e323..24375a954b 100644 --- a/src/features/cseMachine/components/Visible.tsx +++ b/src/features/cseMachine/components/Visible.tsx @@ -1,3 +1,4 @@ +import Konva from 'konva'; import React from 'react'; import { RefObject } from 'react'; @@ -32,9 +33,15 @@ export abstract class Visible implements IVisible { } setShapesStyle(color: string): void { const shapes = this.ref.current?.getChildren?.() ?? []; - shapes.forEach((shape: any) => { - if (shape.attrs.stroke) shape.stroke(color); - if (shape.attrs.fill) shape.fill(color); + shapes.forEach((shape: Konva.Node) => { + if (shape instanceof Konva.Shape) { + if (shape.attrs.stroke) { + shape.stroke(color); + } + if (shape.attrs.fill) { + shape.fill(color); + } + } }); } public ref: RefObject = React.createRef(); diff --git a/src/features/cseMachine/components/arrows/GenericArrow.tsx b/src/features/cseMachine/components/arrows/GenericArrow.tsx index fd579dfb9a..fad79db90e 100644 --- a/src/features/cseMachine/components/arrows/GenericArrow.tsx +++ b/src/features/cseMachine/components/arrows/GenericArrow.tsx @@ -218,9 +218,6 @@ export class GenericArrow this.select(); // Update this arrow's visual state this.setHighlightedStyle(); - } else { - // If the arrow was already selected, deselect it and revert to normal style - this.setNormalStyle(); } // Force redraw entire layer to update all arrows