Skip to content

Commit 29cc1ba

Browse files
committed
whiteboard: make it so you can select multiple items (via xxx-click); can't do anything with them yet...
1 parent e744f9d commit 29cc1ba

File tree

8 files changed

+65
-28
lines changed

8 files changed

+65
-28
lines changed

src/packages/frontend/frame-editors/whiteboard-editor/actions.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,38 @@ export class Actions extends BaseActions<State> {
7979
this._syncstring.delete({ id });
8080
}
8181

82-
public setFocusedElement(frameId: string, focusedId: string): void {
82+
public clearSelection(frameId: string): void {
8383
const node = this._get_frame_node(frameId);
8484
if (node == null) return;
85-
this.set_frame_tree({ id: frameId, focusedId });
85+
this.set_frame_tree({ id: frameId, selection: [] });
86+
}
87+
88+
public setSelection(
89+
frameId: string,
90+
id: string,
91+
type: "add" | "remove" | "only" | "toggle" = "only"
92+
): void {
93+
const node = this._get_frame_node(frameId);
94+
if (node == null) return;
95+
let selection = node.get("selection")?.toJS() ?? [];
96+
if (type == "toggle") {
97+
const i = selection.indexOf(id);
98+
if (i == -1) {
99+
selection.push(id);
100+
} else {
101+
selection.splice(i, 1);
102+
}
103+
} else if (type == "add") {
104+
if (selection.includes(id)) return;
105+
selection.push(id);
106+
} else if (type == "remove") {
107+
const i = selection.indexOf(id);
108+
if (i == -1) return;
109+
selection.splice(i, 1);
110+
} else if (type == "only") {
111+
selection = [id];
112+
}
113+
this.set_frame_tree({ id: frameId, selection });
86114
}
87115

88116
public setSelectedTool(frameId: string, selectedTool: Tool): void {

src/packages/frontend/frame-editors/whiteboard-editor/canvas.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
import { Element, Point } from "./types";
1818
import { Tool, TOOLS } from "./tools/spec";
1919
import RenderElement from "./elements/render";
20-
import Focused, { FOCUSED_BORDER_COLOR } from "./focused";
20+
import Focused, { SELECTED_BORDER_COLOR } from "./focused";
2121
import NotFocused from "./not-focused";
2222
import Position from "./position";
2323
import { useFrameContext } from "./hooks";
@@ -43,7 +43,7 @@ interface Props {
4343
elements: Element[];
4444
font_size?: number;
4545
scale?: number; // use this if passed in; otherwise, deduce from font_size.
46-
focusedId?: string;
46+
selection?: Set<string>;
4747
selectedTool?: Tool;
4848
margin?: number;
4949
readOnly?: boolean;
@@ -57,7 +57,7 @@ export default function Canvas({
5757
elements,
5858
font_size,
5959
scale,
60-
focusedId,
60+
selection,
6161
margin,
6262
readOnly,
6363
selectedTool,
@@ -194,23 +194,26 @@ export default function Canvas({
194194
}
195195
*/
196196

197-
const focused = id == focusedId;
197+
const selected = selection?.has(id);
198+
const focused = !!(selected && selection?.size === 1);
198199
let elt = (
199200
<RenderElement
200201
element={element}
201202
focused={focused}
202203
canvasScale={canvasScale}
203204
/>
204205
);
205-
if (!isNavRectangle && (element.style || focused || isNavigator)) {
206+
if (!isNavRectangle && (element.style || selected || isNavigator)) {
206207
elt = (
207208
<div
208209
style={{
209210
...element.style,
210-
...(focused
211+
...(selected
211212
? {
212213
cursor: "text",
213-
border: `${2 / canvasScale}px dashed ${FOCUSED_BORDER_COLOR}`,
214+
border: `${
215+
2 / canvasScale
216+
}px dashed ${SELECTED_BORDER_COLOR}`,
214217
marginLeft: `-${2 / canvasScale}px`,
215218
marginTop: `-${2 / canvasScale}px`,
216219
}
@@ -361,8 +364,7 @@ export default function Canvas({
361364
if (selectedTool == "select") {
362365
if (e.target == gridDivRef.current) {
363366
// clear selection
364-
// unfocus, because nothing got clicked on.
365-
frame.actions.setFocusedElement(frame.id, "");
367+
frame.actions.clearSelection(frame.id);
366368
} else {
367369
// clicked on an element on the canvas; either stay selected or let
368370
// it handle selecting it.
@@ -392,7 +394,7 @@ export default function Canvas({
392394

393395
const { id } = frame.actions.createElement(element, true);
394396
frame.actions.setSelectedTool(frame.id, "select");
395-
frame.actions.setFocusedElement(frame.id, id);
397+
frame.actions.setSelection(frame.id, id);
396398
}
397399
}
398400

src/packages/frontend/frame-editors/whiteboard-editor/elements/text.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ interface Props {
1414
export default function Text({ element, focused }: Props) {
1515
const [value, setValue] = useState<string>(element.str ?? "");
1616
const frame = useFrameContext();
17+
useEffect(() => {
18+
// should really be a 3-way merge...
19+
setValue(element.str ?? "");
20+
}, [element.str]);
21+
1722

1823
if (!focused) {
1924
return (
@@ -26,11 +31,6 @@ export default function Text({ element, focused }: Props) {
2631
);
2732
}
2833

29-
useEffect(() => {
30-
// should really be a 3-way merge...
31-
setValue(element.str ?? "");
32-
}, [element.str]);
33-
3434
return (
3535
<div>
3636
<Popover

src/packages/frontend/frame-editors/whiteboard-editor/focused.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Displays focused element with a border around it.
2+
Displays selected element with a border around it.
33
44
NOTE that this is HTML and border width must be at least 1px.
55
Given our CSS scale before this, if the scale is bigger than 2
@@ -19,7 +19,7 @@ import DragHandle from "./focused-resize";
1919
import Position from "./position";
2020

2121
const thickness = 2;
22-
export const FOCUSED_BORDER_COLOR = "#40a9ff";
22+
export const SELECTED_BORDER_COLOR = "#40a9ff";
2323
const OFFSET = 50;
2424
const rotateEps = 0.07;
2525
const rotationSnaps: number[] = [];
@@ -225,7 +225,7 @@ export default function Focused({
225225
? {
226226
border: `${
227227
thickness / canvasScale
228-
}px dashed ${FOCUSED_BORDER_COLOR}`,
228+
}px dashed ${SELECTED_BORDER_COLOR}`,
229229
marginLeft: `${-thickness / canvasScale + offset.x}px`,
230230
marginTop: `${-thickness / canvasScale + offset.y}px`,
231231
}

src/packages/frontend/frame-editors/whiteboard-editor/not-focused.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,13 @@ export default function NotFocused({
2222
!readOnly && selectable
2323
? (e) => {
2424
e.stopPropagation();
25-
console.log(e);
26-
frame.actions.setFocusedElement(frame.id, id);
25+
frame.actions.setSelection(
26+
frame.id,
27+
id,
28+
e.altKey || e.metaKey || e.ctrlKey || e.shiftKey
29+
? "toggle"
30+
: "only"
31+
);
2732
}
2833
: undefined
2934
}

src/packages/frontend/frame-editors/whiteboard-editor/tools/edit-bar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ function OtherOperations({ actions, elements }: ButtonProps) {
238238
z += 1;
239239
}
240240
actions.syncstring_commit();
241-
actions.setFocusedElement(frame.id, "");
241+
actions.clearSelection(frame.id);
242242
} else if (key == "send-to-back") {
243243
const { zMin } = getPageSpan(elements);
244244
let z = zMin - 1;
@@ -248,7 +248,7 @@ function OtherOperations({ actions, elements }: ButtonProps) {
248248
z -= 1;
249249
}
250250
actions.syncstring_commit();
251-
actions.setFocusedElement(frame.id, "");
251+
actions.clearSelection(frame.id);
252252
return;
253253
}
254254
}}

src/packages/frontend/frame-editors/whiteboard-editor/tools/navigation.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { PANEL_STYLE } from "./panel";
1616
import Canvas from "../canvas";
1717
import { Element } from "../types";
1818
import Draggable from "react-draggable";
19-
import { FOCUSED_BORDER_COLOR } from "../focused";
19+
import { SELECTED_BORDER_COLOR } from "../focused";
2020

2121
const TOOLS = {
2222
map: {
@@ -125,7 +125,7 @@ export default function Navigation({ fontSize, elements }: Props) {
125125
height: `${BAR_HEIGHT + height + resize.y}px`,
126126
opacity: "0.5",
127127
background: "lightblue",
128-
border: `2px dashed ${FOCUSED_BORDER_COLOR}`,
128+
border: `2px dashed ${SELECTED_BORDER_COLOR}`,
129129
zIndex: 1005,
130130
}}
131131
></div>

src/packages/frontend/frame-editors/whiteboard-editor/whiteboard.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ export default function Whiteboard({
7070
<Canvas
7171
elements={x}
7272
font_size={font_size}
73-
focusedId={
74-
selectedTool == "select" ? desc.get("focusedId") : undefined
73+
selection={
74+
selectedTool == "select"
75+
? new Set(desc.get("selection")?.toJS() ?? [])
76+
: undefined
7577
}
7678
selectedTool={selectedTool}
7779
fitToScreen={desc.get("fitToScreen")}

0 commit comments

Comments
 (0)