Skip to content

Commit

Permalink
[shared-ui] Improve drag connector visibility and behaviors (#3982)
Browse files Browse the repository at this point in the history
  • Loading branch information
paullewis authored Dec 11, 2024
1 parent 02c4353 commit 3967bec
Show file tree
Hide file tree
Showing 19 changed files with 455 additions and 162 deletions.
6 changes: 6 additions & 0 deletions .changeset/kind-ducks-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@breadboard-ai/visual-editor": patch
"@breadboard-ai/shared-ui": patch
---

Improve reference drag and drop
53 changes: 29 additions & 24 deletions packages/shared-ui/src/elements/drag-connector/drag-connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
* Copyright 2024 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { LitElement, html, css, nothing, PropertyValues, svg } from "lit";
import { LitElement, html, css, nothing, PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { DragConnectorReceiver } from "../../types/types";
import { GraphIdentifier } from "@breadboard-ai/types";
import { NodeCreateReferenceEvent } from "../../events/events";
import {
DragConnectorCancelledEvent,
NodeCreateReferenceEvent,
} from "../../events/events";
import { getSubItemColor } from "../../utils/subgraph-color";

const documentStyles = getComputedStyle(document.documentElement);
Expand Down Expand Up @@ -95,6 +98,7 @@ export class DragConnector extends LitElement {
}

#onPointerUp(evt: MouseEvent) {
let foundTarget = false;
for (const el of evt.composedPath()) {
if (!this.#isDragConnectorReceiver(el)) {
continue;
Expand All @@ -112,13 +116,18 @@ export class DragConnector extends LitElement {
break;
}

foundTarget = true;
this.dispatchEvent(
new NodeCreateReferenceEvent(graphId, nodeId, portId, this.source)
);
break;
}
}

if (!foundTarget) {
this.dispatchEvent(new DragConnectorCancelledEvent());
}

this.start = null;
this.end = null;
document.body.classList.remove("boards-highlight");
Expand Down Expand Up @@ -148,7 +157,6 @@ export class DragConnector extends LitElement {
return nothing;
}

const bgColor = getGlobalColor("--bb-neutral-0");
const fillColor = this.isOnTarget
? `#${getGlobalColor("--bb-joiner-500").toString(16).padStart(2)}`
: getSubItemColor<string>(
Expand All @@ -165,28 +173,25 @@ export class DragConnector extends LitElement {
<circle
cx="${this.end.x}"
cy="${this.end.y}"
r="8"
fill="#${bgColor.toString(16).padStart(2)}"
stroke="${fillColor}"
stroke-width="1"
r="10"
fill="${fillColor}"
/>
<line
x1="${this.end.x - 5}"
y1="${this.end.y}"
x2="${this.end.x + 5}"
y2="${this.end.y}"
stroke="white"
stroke-width="2"
/>
<line
x1="${this.end.x}"
y1="${this.end.y - 5}"
x2="${this.end.x}"
y2="${this.end.y + 5}"
stroke="white"
stroke-width="2"
/>
<circle cx="${this.end.x}" cy="${this.end.y}" r="5" fill="${fillColor}" />
${this.isOnTarget
? svg`<line
x1="${this.end.x - 3}"
y1="${this.end.y}"
x2="${this.end.x + 3}"
y2="${this.end.y}"
stroke="white"
stroke-width="2" />
<line
x1="${this.end.x}"
y1="${this.end.y - 3}"
x2="${this.end.x}"
y2="${this.end.y + 3}"
stroke="white"
stroke-width="2" />`
: nothing}
</svg>`;
}
}
8 changes: 7 additions & 1 deletion packages/shared-ui/src/elements/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ export class Editor extends LitElement implements DragConnectorReceiver {
@property()
isShowingBoardActivityOverlay = false;

@property()
showBoardReferenceMarkers = false;

@state()
showOverflowMenu = false;

Expand Down Expand Up @@ -462,7 +465,9 @@ export class Editor extends LitElement implements DragConnectorReceiver {

return {
url,
title: selectedGraph.raw().title ?? "Untitled Board",
title: subGraphId
? (selectedGraph.raw().title ?? "Untitled Board")
: "Main",
subGraphId,
minimized: (selectedGraph.metadata() || {}).visual?.minimized ?? false,
showNodeTypeDescriptions: this.showNodeTypeDescriptions,
Expand Down Expand Up @@ -1095,6 +1100,7 @@ export class Editor extends LitElement implements DragConnectorReceiver {
.showSubgraphsInline=${this.showSubgraphsInline}
.selectionChangeId=${this.selectionState?.selectionChangeId}
.moveToSelection=${this.selectionState?.moveToSelection}
.showBoardReferenceMarkers=${this.showBoardReferenceMarkers}
></bb-graph-renderer>
</div>`;

Expand Down
4 changes: 4 additions & 0 deletions packages/shared-ui/src/elements/editor/graph-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import * as PIXI from "pixi.js";

const ASSET_LIST = new Map([
["code-blocks", "/third_party/icons/graph/code-blocks-48px.svg"],
[
"drag-click-inverted",
"/third_party/icons/graph/drag-click-inverted-48px.svg",
],
["edit", "/third_party/icons/graph/edit-48px.svg"],
["fetch", "/third_party/icons/graph/fetch-48px.svg"],
["google-drive", "/third_party/icons/graph/google-drive-48px.svg"],
Expand Down
27 changes: 27 additions & 0 deletions packages/shared-ui/src/elements/editor/graph-node-port.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { GraphNodePortType } from "./types.js";
import { PortStatus } from "@google-labs/breadboard";
import { getGlobalColor } from "./utils.js";

const boardReferenceColor = getGlobalColor("--bb-joiner-500");

const connectedColor = getGlobalColor("--bb-inputs-200");
const danglingColor = getGlobalColor("--bb-warning-300");
const indeterminateColor = getGlobalColor("--bb-neutral-300");
Expand Down Expand Up @@ -46,6 +48,7 @@ export class GraphNodePort extends PIXI.Graphics {
};
#overrideStatus: PortStatus | null = null;
#readOnly = false;
#showBoardReferenceMarker = false;

constructor(public type: GraphNodePortType) {
super();
Expand Down Expand Up @@ -86,6 +89,19 @@ export class GraphNodePort extends PIXI.Graphics {
return this.#radius;
}

set showBoardReferenceMarker(showBoardReferenceMarker: boolean) {
if (showBoardReferenceMarker === this.#showBoardReferenceMarker) {
return;
}

this.#showBoardReferenceMarker = showBoardReferenceMarker;
this.#isDirty = true;
}

get showBoardReferenceMarker() {
return this.#showBoardReferenceMarker;
}

set configured(configured: boolean) {
if (configured === this.#configured) {
return;
Expand Down Expand Up @@ -152,6 +168,17 @@ export class GraphNodePort extends PIXI.Graphics {
this.stroke();
this.closePath();

if (this.#showBoardReferenceMarker) {
const ratio = 1 / this.worldTransform.a;
this.beginPath();
this.circle(0, 0, 10 * ratio);
this.stroke({
color: boardReferenceColor,
width: Math.round(4 * ratio),
});
this.closePath();
}

this.eventMode = "static";
this.cursor = this.#readOnly ? undefined : "pointer";
}
Expand Down
16 changes: 16 additions & 0 deletions packages/shared-ui/src/elements/editor/graph-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ export class GraphNode extends PIXI.Container {
#showNodePreviewValues = false;
#showNodeTypeDescriptions = false;
#showNodeRunnerButton = false;
#showBoardReferenceMarkers = false;

#overflowMenu = new GraphOverflowMenu();
#headerInPort = new GraphNodePort(GraphNodePortType.IN);
#headerOutPort = new GraphNodePort(GraphNodePortType.OUT);
Expand Down Expand Up @@ -471,6 +473,15 @@ export class GraphNode extends PIXI.Container {
this.#isDirty = true;
}

set showBoardReferenceMarkers(showBoardReferenceMarkers: boolean) {
this.#showBoardReferenceMarkers = showBoardReferenceMarkers;
this.#isDirty = true;
}

get showBoardReferenceMarkers() {
return this.#showBoardReferenceMarkers;
}

get references() {
return this.#references;
}
Expand Down Expand Up @@ -1348,6 +1359,11 @@ export class GraphNode extends PIXI.Container {
nodePort.configured = port.configured && port.edges.length === 0;
nodePort.visible = true;

const isBoard =
isBoardBehavior(port.schema) || isBoardArrayBehavior(port.schema);
nodePort.showBoardReferenceMarker =
isBoard && this.#showBoardReferenceMarkers;

this.#inPortLocations.set(port.name, nodePort.position);

label.x = this.#padding;
Expand Down
44 changes: 43 additions & 1 deletion packages/shared-ui/src/elements/editor/graph-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { styleMap } from "lit/directives/style-map.js";
import {
computeNextExpansionState,
emptySelectionState,
emptyWorkspaceSelectionState,
getGlobalColor,
inspectableEdgeToString,
} from "./utils.js";
Expand All @@ -68,6 +69,7 @@ import {
import { MAIN_BOARD_ID } from "../../constants/constants.js";
import { GraphComment } from "./graph-comment.js";
import { isBoardArrayBehavior, isBoardBehavior } from "../../utils/index.js";
import { ModuleIdentifier } from "@breadboard-ai/types";

const backgroundColor = getGlobalColor("--bb-ui-50");
const backgroundGridColor = getGlobalColor("--bb-ui-100");
Expand Down Expand Up @@ -103,6 +105,9 @@ export class GraphRenderer extends LitElement {
@property()
showSubgraphsInline = false;

@property()
showMainGraphBorder = true;

@property()
assetPrefix = "";

Expand Down Expand Up @@ -134,13 +139,24 @@ export class GraphRenderer extends LitElement {
@property()
padding = 100;

@property()
set showBoardReferenceMarkers(showBoardReferenceMarkers: boolean) {
this.#showBoardReferenceMarkers = showBoardReferenceMarkers;
this.#toggleToolBoardMarkersOnGraphs();
}

get showBoardReferenceMarkers() {
return this.#showBoardReferenceMarkers;
}

#app = new PIXI.Application();
#appInitialized = false;
#configChanged = false;
#lastSelectionChangeId: WorkspaceSelectionChangeId | null = null;
#selectionHasChanged = false;
#topGraphUrlChanged = false;
#graphsRendered = false;
#showBoardReferenceMarkers = false;

#overflowEditNode: Ref<HTMLButtonElement> = createRef();
#overflowDeleteNode: Ref<HTMLButtonElement> = createRef();
Expand Down Expand Up @@ -732,6 +748,16 @@ export class GraphRenderer extends LitElement {
}
}

#toggleToolBoardMarkersOnGraphs() {
for (const graph of this.#container.children) {
if (!(graph instanceof Graph)) {
continue;
}

graph.showBoardReferenceMarkers = this.#showBoardReferenceMarkers;
}
}

#emitGraphVisualInformation() {
const visualStates: WorkspaceVisualState = new Map<
GraphIdentifier,
Expand Down Expand Up @@ -1926,6 +1952,21 @@ export class GraphRenderer extends LitElement {
}
);

graph.on(GRAPH_OPERATIONS.MODULE_SELECTED, (moduleId: ModuleIdentifier) => {
const selectionChangeId = this.#selectionChangeId();
const selectionState = emptyWorkspaceSelectionState();
selectionState.modules.add(moduleId);

this.dispatchEvent(
new WorkspaceSelectionStateEvent(
selectionChangeId,
selectionState,
true,
"immediate"
)
);
});

graph.on(GRAPH_OPERATIONS.GRAPH_REFERENCE_LOAD, (reference) => {
this.dispatchEvent(new StartEvent(reference));
});
Expand Down Expand Up @@ -2338,7 +2379,8 @@ export class GraphRenderer extends LitElement {
}

graph.subGraphId = subGraphId;
graph.subGraphTitle = opts.title ?? null;
graph.graphTitle = opts.title ?? null;
graph.graphOutlineVisible = subGraphId !== null || this.showMainGraphBorder;

return true;
}
Expand Down
Loading

0 comments on commit 3967bec

Please sign in to comment.