canvu-react 0.4.53 → 0.4.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/native.cjs +631 -54
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +19 -0
- package/dist/native.d.ts +19 -0
- package/dist/native.js +631 -54
- package/dist/native.js.map +1 -1
- package/package.json +1 -1
package/dist/native.js
CHANGED
|
@@ -1193,6 +1193,9 @@ function cloneVectorSceneItemWithNewId(item) {
|
|
|
1193
1193
|
}
|
|
1194
1194
|
return next;
|
|
1195
1195
|
}
|
|
1196
|
+
function cloneVectorSceneItemsWithNewIds(items) {
|
|
1197
|
+
return items.map(cloneVectorSceneItemWithNewId);
|
|
1198
|
+
}
|
|
1196
1199
|
|
|
1197
1200
|
// src/scene/managed-images.ts
|
|
1198
1201
|
var MANAGED_KEY = "managed";
|
|
@@ -1256,8 +1259,68 @@ function rotateManagedImage(items, id) {
|
|
|
1256
1259
|
function deleteManagedImage(items, id) {
|
|
1257
1260
|
return restackManagedImages(items.filter((i) => i.id !== id));
|
|
1258
1261
|
}
|
|
1262
|
+
function reorderManagedImages(items, orderedManagedIds) {
|
|
1263
|
+
const managedSlots = [];
|
|
1264
|
+
for (let i = 0; i < items.length; i++) {
|
|
1265
|
+
const item = items[i];
|
|
1266
|
+
if (item && isManagedImage(item)) managedSlots.push(i);
|
|
1267
|
+
}
|
|
1268
|
+
if (managedSlots.length !== orderedManagedIds.length) {
|
|
1269
|
+
return [...items];
|
|
1270
|
+
}
|
|
1271
|
+
const byId = new Map(items.map((i) => [i.id, i]));
|
|
1272
|
+
const next = [...items];
|
|
1273
|
+
managedSlots.forEach((slot, k) => {
|
|
1274
|
+
const orderedId = orderedManagedIds[k];
|
|
1275
|
+
if (orderedId === void 0) return;
|
|
1276
|
+
const replacement = byId.get(orderedId);
|
|
1277
|
+
if (replacement) next[slot] = replacement;
|
|
1278
|
+
});
|
|
1279
|
+
return restackManagedImages(next);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
// src/native/native-images-menu-reorder.ts
|
|
1283
|
+
function moveNativeManagedImageId(managedIds, fromIndex, toIndex) {
|
|
1284
|
+
const next = [...managedIds];
|
|
1285
|
+
if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0 || fromIndex >= next.length || toIndex >= next.length) {
|
|
1286
|
+
return next;
|
|
1287
|
+
}
|
|
1288
|
+
const [item] = next.splice(fromIndex, 1);
|
|
1289
|
+
if (item === void 0) return next;
|
|
1290
|
+
next.splice(toIndex, 0, item);
|
|
1291
|
+
return next;
|
|
1292
|
+
}
|
|
1293
|
+
function getNativeImagesMenuReorderIndex({
|
|
1294
|
+
activeId,
|
|
1295
|
+
managedIds,
|
|
1296
|
+
rowLayouts,
|
|
1297
|
+
dragDeltaY
|
|
1298
|
+
}) {
|
|
1299
|
+
const currentIndex = managedIds.indexOf(activeId);
|
|
1300
|
+
if (currentIndex < 0) return -1;
|
|
1301
|
+
const layoutById = new Map(rowLayouts.map((layout) => [layout.id, layout]));
|
|
1302
|
+
const activeLayout = layoutById.get(activeId);
|
|
1303
|
+
if (!activeLayout) return currentIndex;
|
|
1304
|
+
const activeCenterY = activeLayout.y + activeLayout.height / 2 + dragDeltaY;
|
|
1305
|
+
let nextIndex = currentIndex;
|
|
1306
|
+
let closestDistance = Infinity;
|
|
1307
|
+
for (let index = 0; index < managedIds.length; index++) {
|
|
1308
|
+
const id = managedIds[index];
|
|
1309
|
+
if (id === void 0) continue;
|
|
1310
|
+
const layout = layoutById.get(id);
|
|
1311
|
+
if (!layout) continue;
|
|
1312
|
+
const centerY = layout.y + layout.height / 2;
|
|
1313
|
+
const distance = Math.abs(activeCenterY - centerY);
|
|
1314
|
+
if (distance < closestDistance) {
|
|
1315
|
+
closestDistance = distance;
|
|
1316
|
+
nextIndex = index;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
return nextIndex;
|
|
1320
|
+
}
|
|
1259
1321
|
var defaultLabels = {
|
|
1260
1322
|
title: "Images",
|
|
1323
|
+
dragHandle: "Drag to reorder",
|
|
1261
1324
|
focus: "Focus on canvas",
|
|
1262
1325
|
duplicate: "Duplicate",
|
|
1263
1326
|
rotate: "Rotate",
|
|
@@ -1329,61 +1392,110 @@ function NativeImagesMenuRow({
|
|
|
1329
1392
|
item,
|
|
1330
1393
|
items,
|
|
1331
1394
|
labels,
|
|
1395
|
+
isDragging,
|
|
1396
|
+
isDropTarget,
|
|
1397
|
+
dragDeltaY,
|
|
1332
1398
|
onItemsChange,
|
|
1333
1399
|
onFocusItem,
|
|
1400
|
+
onDragStart,
|
|
1401
|
+
onDragMove,
|
|
1402
|
+
onDragEnd,
|
|
1403
|
+
onRowLayout,
|
|
1334
1404
|
getImageUri,
|
|
1335
1405
|
renderThumbnail,
|
|
1336
1406
|
rowStyle,
|
|
1337
1407
|
actionButtonStyle
|
|
1338
1408
|
}) {
|
|
1339
1409
|
const imageUri = getImageUri(item);
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1410
|
+
const panResponder = useMemo(
|
|
1411
|
+
() => PanResponder.create({
|
|
1412
|
+
onStartShouldSetPanResponder: () => true,
|
|
1413
|
+
onMoveShouldSetPanResponder: () => true,
|
|
1414
|
+
onPanResponderGrant: () => onDragStart(item.id),
|
|
1415
|
+
onPanResponderMove: (_event, gestureState) => onDragMove(item.id, gestureState.dy),
|
|
1416
|
+
onPanResponderRelease: (_event, gestureState) => onDragEnd(item.id, gestureState.dy),
|
|
1417
|
+
onPanResponderTerminate: (_event, gestureState) => onDragEnd(item.id, gestureState.dy),
|
|
1418
|
+
onPanResponderTerminationRequest: () => false,
|
|
1419
|
+
onShouldBlockNativeResponder: () => true
|
|
1420
|
+
}),
|
|
1421
|
+
[item.id, onDragEnd, onDragMove, onDragStart]
|
|
1422
|
+
);
|
|
1423
|
+
const onLayout = useCallback(
|
|
1424
|
+
(event) => {
|
|
1425
|
+
const { height, y } = event.nativeEvent.layout;
|
|
1426
|
+
onRowLayout({ id: item.id, y, height });
|
|
1427
|
+
},
|
|
1428
|
+
[item.id, onRowLayout]
|
|
1429
|
+
);
|
|
1430
|
+
return /* @__PURE__ */ jsxs(
|
|
1431
|
+
View,
|
|
1432
|
+
{
|
|
1433
|
+
onLayout,
|
|
1434
|
+
style: [
|
|
1435
|
+
styles.row,
|
|
1436
|
+
rowStyle,
|
|
1437
|
+
isDropTarget && styles.dropTargetRow,
|
|
1438
|
+
isDragging && styles.draggingRow,
|
|
1439
|
+
isDragging && { transform: [{ translateY: dragDeltaY }] }
|
|
1440
|
+
],
|
|
1441
|
+
children: [
|
|
1442
|
+
/* @__PURE__ */ jsx(
|
|
1443
|
+
View,
|
|
1444
|
+
{
|
|
1445
|
+
accessibilityRole: "button",
|
|
1446
|
+
accessibilityLabel: labels.dragHandle,
|
|
1447
|
+
style: [styles.handle, isDragging && styles.handleDragging],
|
|
1448
|
+
...panResponder.panHandlers,
|
|
1449
|
+
children: /* @__PURE__ */ jsx(NativeImagesMenuIcon, { name: "grip", color: "#94a3b8" })
|
|
1450
|
+
}
|
|
1451
|
+
),
|
|
1452
|
+
/* @__PURE__ */ jsx(
|
|
1453
|
+
Pressable,
|
|
1454
|
+
{
|
|
1455
|
+
accessibilityRole: "button",
|
|
1456
|
+
accessibilityLabel: labels.focus,
|
|
1457
|
+
disabled: !onFocusItem,
|
|
1458
|
+
onPress: () => onFocusItem?.(item),
|
|
1459
|
+
style: styles.thumbnailButton,
|
|
1460
|
+
children: /* @__PURE__ */ jsxs(View, { style: styles.thumbnailBox, children: [
|
|
1461
|
+
renderThumbnail ? renderThumbnail(item) : null,
|
|
1462
|
+
!renderThumbnail && imageUri ? /* @__PURE__ */ jsx(Image$1, { source: { uri: imageUri }, style: styles.thumbnailImage }) : null
|
|
1463
|
+
] })
|
|
1464
|
+
}
|
|
1465
|
+
),
|
|
1466
|
+
/* @__PURE__ */ jsxs(View, { style: styles.actionsColumn, children: [
|
|
1467
|
+
/* @__PURE__ */ jsx(
|
|
1468
|
+
NativeImagesMenuAction,
|
|
1469
|
+
{
|
|
1470
|
+
label: labels.duplicate,
|
|
1471
|
+
onPress: () => onItemsChange(copyManagedImage(items, item.id)),
|
|
1472
|
+
style: actionButtonStyle,
|
|
1473
|
+
children: /* @__PURE__ */ jsx(NativeImagesMenuIcon, { name: "copy" })
|
|
1474
|
+
}
|
|
1475
|
+
),
|
|
1476
|
+
/* @__PURE__ */ jsx(
|
|
1477
|
+
NativeImagesMenuAction,
|
|
1478
|
+
{
|
|
1479
|
+
label: labels.rotate,
|
|
1480
|
+
onPress: () => onItemsChange(rotateManagedImage(items, item.id)),
|
|
1481
|
+
style: actionButtonStyle,
|
|
1482
|
+
children: /* @__PURE__ */ jsx(NativeImagesMenuIcon, { name: "rotate" })
|
|
1483
|
+
}
|
|
1484
|
+
),
|
|
1485
|
+
/* @__PURE__ */ jsx(
|
|
1486
|
+
NativeImagesMenuAction,
|
|
1487
|
+
{
|
|
1488
|
+
label: labels.delete,
|
|
1489
|
+
danger: true,
|
|
1490
|
+
onPress: () => onItemsChange(deleteManagedImage(items, item.id)),
|
|
1491
|
+
style: actionButtonStyle,
|
|
1492
|
+
children: /* @__PURE__ */ jsx(NativeImagesMenuIcon, { name: "trash", color: "#b91c1c" })
|
|
1493
|
+
}
|
|
1494
|
+
)
|
|
1353
1495
|
] })
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
/* @__PURE__ */ jsx(
|
|
1358
|
-
NativeImagesMenuAction,
|
|
1359
|
-
{
|
|
1360
|
-
label: labels.duplicate,
|
|
1361
|
-
onPress: () => onItemsChange(copyManagedImage(items, item.id)),
|
|
1362
|
-
style: actionButtonStyle,
|
|
1363
|
-
children: /* @__PURE__ */ jsx(NativeImagesMenuIcon, { name: "copy" })
|
|
1364
|
-
}
|
|
1365
|
-
),
|
|
1366
|
-
/* @__PURE__ */ jsx(
|
|
1367
|
-
NativeImagesMenuAction,
|
|
1368
|
-
{
|
|
1369
|
-
label: labels.rotate,
|
|
1370
|
-
onPress: () => onItemsChange(rotateManagedImage(items, item.id)),
|
|
1371
|
-
style: actionButtonStyle,
|
|
1372
|
-
children: /* @__PURE__ */ jsx(NativeImagesMenuIcon, { name: "rotate" })
|
|
1373
|
-
}
|
|
1374
|
-
),
|
|
1375
|
-
/* @__PURE__ */ jsx(
|
|
1376
|
-
NativeImagesMenuAction,
|
|
1377
|
-
{
|
|
1378
|
-
label: labels.delete,
|
|
1379
|
-
danger: true,
|
|
1380
|
-
onPress: () => onItemsChange(deleteManagedImage(items, item.id)),
|
|
1381
|
-
style: actionButtonStyle,
|
|
1382
|
-
children: /* @__PURE__ */ jsx(NativeImagesMenuIcon, { name: "trash", color: "#b91c1c" })
|
|
1383
|
-
}
|
|
1384
|
-
)
|
|
1385
|
-
] })
|
|
1386
|
-
] });
|
|
1496
|
+
]
|
|
1497
|
+
}
|
|
1498
|
+
);
|
|
1387
1499
|
}
|
|
1388
1500
|
function NativeImagesMenu({
|
|
1389
1501
|
items,
|
|
@@ -1400,7 +1512,69 @@ function NativeImagesMenu({
|
|
|
1400
1512
|
renderThumbnail
|
|
1401
1513
|
}) {
|
|
1402
1514
|
const managed = useMemo(() => items.filter(isManagedImage), [items]);
|
|
1515
|
+
const managedIds = useMemo(() => managed.map((item) => item.id), [managed]);
|
|
1403
1516
|
const [collapsed, setCollapsed] = useState(!defaultOpen);
|
|
1517
|
+
const [dragState, setDragState] = useState(null);
|
|
1518
|
+
const rowLayoutsRef = useRef(/* @__PURE__ */ new Map());
|
|
1519
|
+
const getRowLayouts = useCallback(
|
|
1520
|
+
() => managedIds.map((id) => rowLayoutsRef.current.get(id)).filter((layout) => layout != null),
|
|
1521
|
+
[managedIds]
|
|
1522
|
+
);
|
|
1523
|
+
const handleRowLayout = useCallback((layout) => {
|
|
1524
|
+
rowLayoutsRef.current.set(layout.id, layout);
|
|
1525
|
+
}, []);
|
|
1526
|
+
const handleDragStart = useCallback(
|
|
1527
|
+
(id) => {
|
|
1528
|
+
const fromIndex = managedIds.indexOf(id);
|
|
1529
|
+
if (fromIndex < 0) return;
|
|
1530
|
+
setDragState({
|
|
1531
|
+
activeId: id,
|
|
1532
|
+
fromIndex,
|
|
1533
|
+
currentIndex: fromIndex,
|
|
1534
|
+
dragDeltaY: 0
|
|
1535
|
+
});
|
|
1536
|
+
},
|
|
1537
|
+
[managedIds]
|
|
1538
|
+
);
|
|
1539
|
+
const handleDragMove = useCallback(
|
|
1540
|
+
(id, dragDeltaY) => {
|
|
1541
|
+
setDragState((current) => {
|
|
1542
|
+
if (!current || current.activeId !== id) return current;
|
|
1543
|
+
const currentIndex = getNativeImagesMenuReorderIndex({
|
|
1544
|
+
activeId: id,
|
|
1545
|
+
managedIds,
|
|
1546
|
+
rowLayouts: getRowLayouts(),
|
|
1547
|
+
dragDeltaY
|
|
1548
|
+
});
|
|
1549
|
+
return {
|
|
1550
|
+
...current,
|
|
1551
|
+
currentIndex: currentIndex >= 0 ? currentIndex : current.fromIndex,
|
|
1552
|
+
dragDeltaY
|
|
1553
|
+
};
|
|
1554
|
+
});
|
|
1555
|
+
},
|
|
1556
|
+
[getRowLayouts, managedIds]
|
|
1557
|
+
);
|
|
1558
|
+
const handleDragEnd = useCallback(
|
|
1559
|
+
(id, dragDeltaY) => {
|
|
1560
|
+
const fromIndex = managedIds.indexOf(id);
|
|
1561
|
+
const currentIndex = getNativeImagesMenuReorderIndex({
|
|
1562
|
+
activeId: id,
|
|
1563
|
+
managedIds,
|
|
1564
|
+
rowLayouts: getRowLayouts(),
|
|
1565
|
+
dragDeltaY
|
|
1566
|
+
});
|
|
1567
|
+
setDragState(null);
|
|
1568
|
+
if (fromIndex < 0 || currentIndex < 0 || fromIndex === currentIndex) return;
|
|
1569
|
+
const orderedIds = moveNativeManagedImageId(
|
|
1570
|
+
managedIds,
|
|
1571
|
+
fromIndex,
|
|
1572
|
+
currentIndex
|
|
1573
|
+
);
|
|
1574
|
+
onItemsChange(reorderManagedImages(items, orderedIds));
|
|
1575
|
+
},
|
|
1576
|
+
[getRowLayouts, items, managedIds, onItemsChange]
|
|
1577
|
+
);
|
|
1404
1578
|
if (managed.length === 0) return null;
|
|
1405
1579
|
const resolvedLabels = resolveLabels(labels);
|
|
1406
1580
|
if (collapsed) {
|
|
@@ -1445,15 +1619,23 @@ function NativeImagesMenu({
|
|
|
1445
1619
|
{
|
|
1446
1620
|
style: styles.listScroll,
|
|
1447
1621
|
contentContainerStyle: styles.listContent,
|
|
1622
|
+
scrollEnabled: dragState == null,
|
|
1448
1623
|
showsVerticalScrollIndicator: false,
|
|
1449
|
-
children: managed.map((item) => /* @__PURE__ */ jsx(
|
|
1624
|
+
children: managed.map((item, index) => /* @__PURE__ */ jsx(
|
|
1450
1625
|
NativeImagesMenuRow,
|
|
1451
1626
|
{
|
|
1452
1627
|
item,
|
|
1453
1628
|
items,
|
|
1454
1629
|
labels: resolvedLabels,
|
|
1630
|
+
isDragging: dragState?.activeId === item.id,
|
|
1631
|
+
isDropTarget: dragState != null && dragState.activeId !== item.id && dragState.currentIndex === index,
|
|
1632
|
+
dragDeltaY: dragState?.activeId === item.id ? dragState.dragDeltaY : 0,
|
|
1455
1633
|
onItemsChange,
|
|
1456
1634
|
onFocusItem,
|
|
1635
|
+
onDragStart: handleDragStart,
|
|
1636
|
+
onDragMove: handleDragMove,
|
|
1637
|
+
onDragEnd: handleDragEnd,
|
|
1638
|
+
onRowLayout: handleRowLayout,
|
|
1457
1639
|
getImageUri,
|
|
1458
1640
|
renderThumbnail,
|
|
1459
1641
|
rowStyle,
|
|
@@ -1513,6 +1695,19 @@ var styles = StyleSheet.create({
|
|
|
1513
1695
|
dangerActionButton: {
|
|
1514
1696
|
backgroundColor: "#fef2f2"
|
|
1515
1697
|
},
|
|
1698
|
+
draggingRow: {
|
|
1699
|
+
backgroundColor: "#eef2f7",
|
|
1700
|
+
elevation: 4,
|
|
1701
|
+
opacity: 0.85,
|
|
1702
|
+
zIndex: 1
|
|
1703
|
+
},
|
|
1704
|
+
dropTargetRow: {
|
|
1705
|
+
backgroundColor: "#f8fafc"
|
|
1706
|
+
},
|
|
1707
|
+
handleDragging: {
|
|
1708
|
+
backgroundColor: "#e2e8f0",
|
|
1709
|
+
borderRadius: 6
|
|
1710
|
+
},
|
|
1516
1711
|
handle: {
|
|
1517
1712
|
alignItems: "center",
|
|
1518
1713
|
height: 128,
|
|
@@ -3139,6 +3334,26 @@ function pointInNativeSelectedItemBounds(item, worldPoint) {
|
|
|
3139
3334
|
);
|
|
3140
3335
|
return local.x >= 0 && local.x <= bounds.width && local.y >= 0 && local.y <= bounds.height;
|
|
3141
3336
|
}
|
|
3337
|
+
function resolveNativeSelectionContextMenuRequest({
|
|
3338
|
+
interactive,
|
|
3339
|
+
toolId,
|
|
3340
|
+
selectedItems,
|
|
3341
|
+
worldPoint,
|
|
3342
|
+
screenPoint
|
|
3343
|
+
}) {
|
|
3344
|
+
if (!interactive || toolId !== "select") return null;
|
|
3345
|
+
const editableSelectedItems = selectedItems.filter((item) => !item.locked);
|
|
3346
|
+
if (editableSelectedItems.length === 0) return null;
|
|
3347
|
+
const pressedSelectedItem = editableSelectedItems.some(
|
|
3348
|
+
(item) => pointInNativeSelectedItemBounds(item, worldPoint)
|
|
3349
|
+
);
|
|
3350
|
+
if (!pressedSelectedItem) return null;
|
|
3351
|
+
return {
|
|
3352
|
+
itemIds: editableSelectedItems.map((item) => item.id),
|
|
3353
|
+
x: screenPoint.x,
|
|
3354
|
+
y: screenPoint.y
|
|
3355
|
+
};
|
|
3356
|
+
}
|
|
3142
3357
|
function resolveNativeCustomPlacement(toolId, customPlacement, customPlacements) {
|
|
3143
3358
|
if (customPlacement?.toolId === toolId) return customPlacement;
|
|
3144
3359
|
return customPlacements?.find((placement) => placement.toolId === toolId) ?? null;
|
|
@@ -5058,6 +5273,18 @@ function applyRotationFromPointer(item, startRotation, startPointerAngleRad, poi
|
|
|
5058
5273
|
}
|
|
5059
5274
|
return { ...item, rotation: startRotation + delta };
|
|
5060
5275
|
}
|
|
5276
|
+
function moveItemByDelta(item, dx, dy) {
|
|
5277
|
+
return {
|
|
5278
|
+
...item,
|
|
5279
|
+
x: item.x + dx,
|
|
5280
|
+
y: item.y + dy,
|
|
5281
|
+
bounds: {
|
|
5282
|
+
...item.bounds,
|
|
5283
|
+
x: item.bounds.x + dx,
|
|
5284
|
+
y: item.bounds.y + dy
|
|
5285
|
+
}
|
|
5286
|
+
};
|
|
5287
|
+
}
|
|
5061
5288
|
function resizeItemByHandle(item, start, handle, currentWorld) {
|
|
5062
5289
|
const sb = normalizeRect(start.bounds);
|
|
5063
5290
|
if (!itemAllowsResizeHandle(item, handle)) {
|
|
@@ -5282,6 +5509,39 @@ function hitTestNativeRemotePresence(peers, camera, point) {
|
|
|
5282
5509
|
return null;
|
|
5283
5510
|
}
|
|
5284
5511
|
|
|
5512
|
+
// src/native/native-shape-clipboard.ts
|
|
5513
|
+
var NATIVE_SHAPE_CLIPBOARD_PASTE_OFFSET_WORLD = 24;
|
|
5514
|
+
function copyNativeSelectedShapeItems(items, selectedIds) {
|
|
5515
|
+
if (selectedIds.length === 0) return null;
|
|
5516
|
+
const copies = selectedIds.map((id) => items.find((item) => item.id === id)).filter((item) => item != null);
|
|
5517
|
+
if (copies.length === 0) return null;
|
|
5518
|
+
return copies.map((item) => JSON.parse(JSON.stringify(item)));
|
|
5519
|
+
}
|
|
5520
|
+
function pasteNativeShapeClipboard(input) {
|
|
5521
|
+
if (input.clipboard.length === 0) return null;
|
|
5522
|
+
const clones = cloneVectorSceneItemsWithNewIds(input.clipboard);
|
|
5523
|
+
const moved = clones.map(
|
|
5524
|
+
(item) => moveItemByDelta(
|
|
5525
|
+
item,
|
|
5526
|
+
NATIVE_SHAPE_CLIPBOARD_PASTE_OFFSET_WORLD,
|
|
5527
|
+
NATIVE_SHAPE_CLIPBOARD_PASTE_OFFSET_WORLD
|
|
5528
|
+
)
|
|
5529
|
+
);
|
|
5530
|
+
if (moved.length === 0) return null;
|
|
5531
|
+
return {
|
|
5532
|
+
items: [...input.items, ...moved],
|
|
5533
|
+
selectedIds: moved.map((item) => item.id)
|
|
5534
|
+
};
|
|
5535
|
+
}
|
|
5536
|
+
function duplicateNativeSelectedShapes(input) {
|
|
5537
|
+
const clipboard = copyNativeSelectedShapeItems(input.items, input.selectedIds);
|
|
5538
|
+
if (!clipboard) return null;
|
|
5539
|
+
return pasteNativeShapeClipboard({
|
|
5540
|
+
items: input.items,
|
|
5541
|
+
clipboard
|
|
5542
|
+
});
|
|
5543
|
+
}
|
|
5544
|
+
|
|
5285
5545
|
// src/native/native-transient-items.ts
|
|
5286
5546
|
function moveNativeTransientItems({
|
|
5287
5547
|
items,
|
|
@@ -5330,6 +5590,11 @@ var NATIVE_VIEWPORT_OVERLAY_Z_INDEX = 40;
|
|
|
5330
5590
|
var NATIVE_VIEWPORT_OVERLAY_ELEVATION = 40;
|
|
5331
5591
|
var NATIVE_VIEWPORT_EXTERNAL_OVERLAY_Z_INDEX = 20;
|
|
5332
5592
|
var NATIVE_VIEWPORT_EXTERNAL_OVERLAY_ELEVATION = 20;
|
|
5593
|
+
var LONG_PRESS_CONTEXT_MENU_MS = 520;
|
|
5594
|
+
var LONG_PRESS_CONTEXT_MENU_CANCEL_PX = 10;
|
|
5595
|
+
var NATIVE_CONTEXT_MENU_WIDTH = 168;
|
|
5596
|
+
var NATIVE_CONTEXT_MENU_HEIGHT = 184;
|
|
5597
|
+
var NATIVE_CONTEXT_MENU_MARGIN = 12;
|
|
5333
5598
|
function isPlacementTool(toolId) {
|
|
5334
5599
|
return toolId === "rect" || toolId === "ellipse" || toolId === "architectural-cloud" || toolId === "line" || toolId === "arrow";
|
|
5335
5600
|
}
|
|
@@ -5402,6 +5667,102 @@ function fitCameraToWorldRect(camera, viewportW, viewportH, worldRect, padding)
|
|
|
5402
5667
|
camera.x = viewportW / 2 - cx * z;
|
|
5403
5668
|
camera.y = viewportH / 2 - cy * z;
|
|
5404
5669
|
}
|
|
5670
|
+
function clampNativeContextMenuState(menu, size) {
|
|
5671
|
+
return {
|
|
5672
|
+
...menu,
|
|
5673
|
+
x: Math.max(
|
|
5674
|
+
NATIVE_CONTEXT_MENU_MARGIN,
|
|
5675
|
+
Math.min(
|
|
5676
|
+
menu.x,
|
|
5677
|
+
Math.max(NATIVE_CONTEXT_MENU_MARGIN, size.width - NATIVE_CONTEXT_MENU_WIDTH)
|
|
5678
|
+
)
|
|
5679
|
+
),
|
|
5680
|
+
y: Math.max(
|
|
5681
|
+
NATIVE_CONTEXT_MENU_MARGIN,
|
|
5682
|
+
Math.min(
|
|
5683
|
+
menu.y - NATIVE_CONTEXT_MENU_HEIGHT - NATIVE_CONTEXT_MENU_MARGIN,
|
|
5684
|
+
Math.max(
|
|
5685
|
+
NATIVE_CONTEXT_MENU_MARGIN,
|
|
5686
|
+
size.height - NATIVE_CONTEXT_MENU_HEIGHT - NATIVE_CONTEXT_MENU_MARGIN
|
|
5687
|
+
)
|
|
5688
|
+
)
|
|
5689
|
+
)
|
|
5690
|
+
};
|
|
5691
|
+
}
|
|
5692
|
+
function NativeSelectionContextMenu({
|
|
5693
|
+
x,
|
|
5694
|
+
y,
|
|
5695
|
+
canPaste,
|
|
5696
|
+
onCopy,
|
|
5697
|
+
onPaste,
|
|
5698
|
+
onDuplicate,
|
|
5699
|
+
onDelete
|
|
5700
|
+
}) {
|
|
5701
|
+
return /* @__PURE__ */ jsxs(
|
|
5702
|
+
View,
|
|
5703
|
+
{
|
|
5704
|
+
style: [
|
|
5705
|
+
styles4.nativeSelectionContextMenu,
|
|
5706
|
+
{
|
|
5707
|
+
left: x,
|
|
5708
|
+
top: y
|
|
5709
|
+
}
|
|
5710
|
+
],
|
|
5711
|
+
children: [
|
|
5712
|
+
/* @__PURE__ */ jsx(NativeSelectionContextMenuButton, { label: "Copy", onPress: onCopy }),
|
|
5713
|
+
/* @__PURE__ */ jsx(
|
|
5714
|
+
NativeSelectionContextMenuButton,
|
|
5715
|
+
{
|
|
5716
|
+
label: "Paste",
|
|
5717
|
+
onPress: onPaste,
|
|
5718
|
+
disabled: !canPaste
|
|
5719
|
+
}
|
|
5720
|
+
),
|
|
5721
|
+
/* @__PURE__ */ jsx(NativeSelectionContextMenuButton, { label: "Duplicate", onPress: onDuplicate }),
|
|
5722
|
+
/* @__PURE__ */ jsx(
|
|
5723
|
+
NativeSelectionContextMenuButton,
|
|
5724
|
+
{
|
|
5725
|
+
label: "Delete",
|
|
5726
|
+
onPress: onDelete,
|
|
5727
|
+
destructive: true
|
|
5728
|
+
}
|
|
5729
|
+
)
|
|
5730
|
+
]
|
|
5731
|
+
}
|
|
5732
|
+
);
|
|
5733
|
+
}
|
|
5734
|
+
function NativeSelectionContextMenuButton({
|
|
5735
|
+
label,
|
|
5736
|
+
onPress,
|
|
5737
|
+
disabled = false,
|
|
5738
|
+
destructive = false
|
|
5739
|
+
}) {
|
|
5740
|
+
return /* @__PURE__ */ jsx(
|
|
5741
|
+
Pressable,
|
|
5742
|
+
{
|
|
5743
|
+
accessibilityRole: "button",
|
|
5744
|
+
accessibilityState: { disabled },
|
|
5745
|
+
disabled,
|
|
5746
|
+
onPress,
|
|
5747
|
+
style: ({ pressed }) => [
|
|
5748
|
+
styles4.nativeSelectionContextMenuButton,
|
|
5749
|
+
pressed && !disabled ? styles4.nativeSelectionContextMenuButtonPressed : void 0,
|
|
5750
|
+
disabled ? styles4.nativeSelectionContextMenuButtonDisabled : void 0
|
|
5751
|
+
],
|
|
5752
|
+
children: /* @__PURE__ */ jsx(
|
|
5753
|
+
Text,
|
|
5754
|
+
{
|
|
5755
|
+
style: [
|
|
5756
|
+
styles4.nativeSelectionContextMenuButtonText,
|
|
5757
|
+
destructive ? styles4.nativeSelectionContextMenuDeleteText : void 0,
|
|
5758
|
+
disabled ? styles4.nativeSelectionContextMenuButtonTextDisabled : void 0
|
|
5759
|
+
],
|
|
5760
|
+
children: label
|
|
5761
|
+
}
|
|
5762
|
+
)
|
|
5763
|
+
}
|
|
5764
|
+
);
|
|
5765
|
+
}
|
|
5405
5766
|
var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
5406
5767
|
items,
|
|
5407
5768
|
selectedIds = [],
|
|
@@ -5468,6 +5829,16 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5468
5829
|
selectedIdsRef.current = selectedIds;
|
|
5469
5830
|
const remotePresenceRef = useRef(remotePresence);
|
|
5470
5831
|
remotePresenceRef.current = remotePresence;
|
|
5832
|
+
const shapeClipboardRef = useRef(null);
|
|
5833
|
+
const [selectionContextMenu, setSelectionContextMenu] = useState(null);
|
|
5834
|
+
const selectionContextMenuRef = useRef(
|
|
5835
|
+
null
|
|
5836
|
+
);
|
|
5837
|
+
selectionContextMenuRef.current = selectionContextMenu;
|
|
5838
|
+
const contextMenuLongPressTimerRef = useRef(
|
|
5839
|
+
null
|
|
5840
|
+
);
|
|
5841
|
+
const contextMenuLongPressStartRef = useRef(null);
|
|
5471
5842
|
const dragStateRef = useRef({ kind: "idle" });
|
|
5472
5843
|
useEffect(() => {
|
|
5473
5844
|
const committedItems = items;
|
|
@@ -5485,6 +5856,16 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5485
5856
|
transientItemsRef.current = null;
|
|
5486
5857
|
setTransientItems(null);
|
|
5487
5858
|
}, []);
|
|
5859
|
+
const clearNativeContextMenuLongPress = useCallback(() => {
|
|
5860
|
+
if (contextMenuLongPressTimerRef.current) {
|
|
5861
|
+
clearTimeout(contextMenuLongPressTimerRef.current);
|
|
5862
|
+
contextMenuLongPressTimerRef.current = null;
|
|
5863
|
+
}
|
|
5864
|
+
contextMenuLongPressStartRef.current = null;
|
|
5865
|
+
}, []);
|
|
5866
|
+
const closeNativeSelectionContextMenu = useCallback(() => {
|
|
5867
|
+
setSelectionContextMenu(null);
|
|
5868
|
+
}, []);
|
|
5488
5869
|
const commitTransientItemsPreview = useCallback(() => {
|
|
5489
5870
|
const nextItems = transientItemsRef.current;
|
|
5490
5871
|
const change = onItemsChangeRef.current;
|
|
@@ -5517,6 +5898,9 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5517
5898
|
if (laserClearTimerRef.current) {
|
|
5518
5899
|
clearTimeout(laserClearTimerRef.current);
|
|
5519
5900
|
}
|
|
5901
|
+
if (contextMenuLongPressTimerRef.current) {
|
|
5902
|
+
clearTimeout(contextMenuLongPressTimerRef.current);
|
|
5903
|
+
}
|
|
5520
5904
|
},
|
|
5521
5905
|
[]
|
|
5522
5906
|
);
|
|
@@ -5601,6 +5985,10 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5601
5985
|
}
|
|
5602
5986
|
const camera = cameraRef.current;
|
|
5603
5987
|
const [cameraTick, setCameraTick] = useState(0);
|
|
5988
|
+
const selectedItems = useMemo(
|
|
5989
|
+
() => activeItems.filter((item) => selectedIds.includes(item.id)),
|
|
5990
|
+
[activeItems, selectedIds]
|
|
5991
|
+
);
|
|
5604
5992
|
const screenToWorld = useCallback(
|
|
5605
5993
|
(sx, sy) => {
|
|
5606
5994
|
const cam = cameraRef.current;
|
|
@@ -5609,6 +5997,59 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5609
5997
|
},
|
|
5610
5998
|
[]
|
|
5611
5999
|
);
|
|
6000
|
+
const startNativeContextMenuLongPress = useCallback(
|
|
6001
|
+
(point) => {
|
|
6002
|
+
clearNativeContextMenuLongPress();
|
|
6003
|
+
if (toolIdRef.current !== "select") return;
|
|
6004
|
+
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
6005
|
+
const request = resolveNativeSelectionContextMenuRequest({
|
|
6006
|
+
interactive,
|
|
6007
|
+
toolId: toolIdRef.current,
|
|
6008
|
+
selectedItems,
|
|
6009
|
+
worldPoint: { x: worldX, y: worldY },
|
|
6010
|
+
screenPoint: point
|
|
6011
|
+
});
|
|
6012
|
+
if (!request) return;
|
|
6013
|
+
contextMenuLongPressStartRef.current = point;
|
|
6014
|
+
contextMenuLongPressTimerRef.current = setTimeout(() => {
|
|
6015
|
+
contextMenuLongPressTimerRef.current = null;
|
|
6016
|
+
contextMenuLongPressStartRef.current = null;
|
|
6017
|
+
dragStateRef.current = { kind: "idle" };
|
|
6018
|
+
lastPanPoint.current = null;
|
|
6019
|
+
lastPinchDist.current = null;
|
|
6020
|
+
clearTransientItemsPreview();
|
|
6021
|
+
setRealtimePlacementPreview(null);
|
|
6022
|
+
setSelectionContextMenu(
|
|
6023
|
+
clampNativeContextMenuState(
|
|
6024
|
+
{
|
|
6025
|
+
...request,
|
|
6026
|
+
canPaste: shapeClipboardRef.current !== null
|
|
6027
|
+
},
|
|
6028
|
+
size
|
|
6029
|
+
)
|
|
6030
|
+
);
|
|
6031
|
+
}, LONG_PRESS_CONTEXT_MENU_MS);
|
|
6032
|
+
},
|
|
6033
|
+
[
|
|
6034
|
+
clearNativeContextMenuLongPress,
|
|
6035
|
+
clearTransientItemsPreview,
|
|
6036
|
+
interactive,
|
|
6037
|
+
screenToWorld,
|
|
6038
|
+
selectedItems,
|
|
6039
|
+
setRealtimePlacementPreview,
|
|
6040
|
+
size
|
|
6041
|
+
]
|
|
6042
|
+
);
|
|
6043
|
+
const cancelNativeContextMenuLongPressAfterMove = useCallback(
|
|
6044
|
+
(point) => {
|
|
6045
|
+
const start = contextMenuLongPressStartRef.current;
|
|
6046
|
+
if (!start) return;
|
|
6047
|
+
if (Math.hypot(point.x - start.x, point.y - start.y) > LONG_PRESS_CONTEXT_MENU_CANCEL_PX) {
|
|
6048
|
+
clearNativeContextMenuLongPress();
|
|
6049
|
+
}
|
|
6050
|
+
},
|
|
6051
|
+
[clearNativeContextMenuLongPress]
|
|
6052
|
+
);
|
|
5612
6053
|
const notifyWorldPointerMove = useCallback(
|
|
5613
6054
|
(point) => {
|
|
5614
6055
|
const { worldX, worldY } = screenToWorld(point.x, point.y);
|
|
@@ -5631,10 +6072,6 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5631
6072
|
}, []);
|
|
5632
6073
|
const hideToolCursor = useCallback(() => {
|
|
5633
6074
|
}, []);
|
|
5634
|
-
const selectedItems = useMemo(
|
|
5635
|
-
() => activeItems.filter((item) => selectedIds.includes(item.id)),
|
|
5636
|
-
[activeItems, selectedIds]
|
|
5637
|
-
);
|
|
5638
6075
|
const selectedStyleInspectorState = useMemo(() => {
|
|
5639
6076
|
const styleableItems = selectedItems.filter(
|
|
5640
6077
|
(item) => !item.locked && getNativeStyleInspectorToolId(item) !== null
|
|
@@ -5679,10 +6116,77 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5679
6116
|
},
|
|
5680
6117
|
[patchCurrentStrokeStyle]
|
|
5681
6118
|
);
|
|
6119
|
+
const copySelectedShapes = useCallback(() => {
|
|
6120
|
+
if (!interactive) return false;
|
|
6121
|
+
const clipboard = copyNativeSelectedShapeItems(
|
|
6122
|
+
itemsRef.current,
|
|
6123
|
+
selectedIdsRef.current
|
|
6124
|
+
);
|
|
6125
|
+
if (!clipboard) return false;
|
|
6126
|
+
shapeClipboardRef.current = clipboard;
|
|
6127
|
+
return true;
|
|
6128
|
+
}, [interactive]);
|
|
6129
|
+
const pasteCopiedShapes = useCallback(() => {
|
|
6130
|
+
if (!interactive) return false;
|
|
6131
|
+
const change = onItemsChangeRef.current;
|
|
6132
|
+
const clipboard = shapeClipboardRef.current;
|
|
6133
|
+
if (!change || !clipboard) return false;
|
|
6134
|
+
const pasted = pasteNativeShapeClipboard({
|
|
6135
|
+
items: itemsRef.current,
|
|
6136
|
+
clipboard
|
|
6137
|
+
});
|
|
6138
|
+
if (!pasted) return false;
|
|
6139
|
+
change(pasted.items);
|
|
6140
|
+
onSelectionChangeRef.current?.(pasted.selectedIds);
|
|
6141
|
+
return true;
|
|
6142
|
+
}, [interactive]);
|
|
6143
|
+
const duplicateSelectedShapes = useCallback(() => {
|
|
6144
|
+
if (!interactive) return false;
|
|
6145
|
+
const change = onItemsChangeRef.current;
|
|
6146
|
+
if (!change) return false;
|
|
6147
|
+
const duplicated = duplicateNativeSelectedShapes({
|
|
6148
|
+
items: itemsRef.current,
|
|
6149
|
+
selectedIds: selectedIdsRef.current
|
|
6150
|
+
});
|
|
6151
|
+
if (!duplicated) return false;
|
|
6152
|
+
change(duplicated.items);
|
|
6153
|
+
onSelectionChangeRef.current?.(duplicated.selectedIds);
|
|
6154
|
+
return true;
|
|
6155
|
+
}, [interactive]);
|
|
6156
|
+
const handleCopySelectedShapesFromMenu = useCallback(() => {
|
|
6157
|
+
copySelectedShapes();
|
|
6158
|
+
closeNativeSelectionContextMenu();
|
|
6159
|
+
}, [closeNativeSelectionContextMenu, copySelectedShapes]);
|
|
6160
|
+
const handlePasteCopiedShapesFromMenu = useCallback(() => {
|
|
6161
|
+
pasteCopiedShapes();
|
|
6162
|
+
closeNativeSelectionContextMenu();
|
|
6163
|
+
}, [closeNativeSelectionContextMenu, pasteCopiedShapes]);
|
|
6164
|
+
const handleDuplicateSelectedShapesFromMenu = useCallback(() => {
|
|
6165
|
+
duplicateSelectedShapes();
|
|
6166
|
+
closeNativeSelectionContextMenu();
|
|
6167
|
+
}, [closeNativeSelectionContextMenu, duplicateSelectedShapes]);
|
|
6168
|
+
const handleDeleteSelectedShapes = useCallback(() => {
|
|
6169
|
+
const menu = selectionContextMenuRef.current;
|
|
6170
|
+
const ids = menu?.itemIds ?? selectedIdsRef.current;
|
|
6171
|
+
if (ids.length === 0) return false;
|
|
6172
|
+
const change = onItemsChangeRef.current;
|
|
6173
|
+
if (!change) return false;
|
|
6174
|
+
const idSet = new Set(ids);
|
|
6175
|
+
const nextItems = itemsRef.current.filter((item) => !idSet.has(item.id));
|
|
6176
|
+
if (nextItems.length === itemsRef.current.length) return false;
|
|
6177
|
+
change(nextItems);
|
|
6178
|
+
onSelectionChangeRef.current?.(
|
|
6179
|
+
selectedIdsRef.current.filter((id) => !idSet.has(id))
|
|
6180
|
+
);
|
|
6181
|
+
closeNativeSelectionContextMenu();
|
|
6182
|
+
return true;
|
|
6183
|
+
}, [closeNativeSelectionContextMenu]);
|
|
5682
6184
|
const lastPinchDist = useRef(null);
|
|
5683
6185
|
const lastPanPoint = useRef(null);
|
|
5684
6186
|
const beginDragAtScreenPoint = useCallback(
|
|
5685
6187
|
(point) => {
|
|
6188
|
+
closeNativeSelectionContextMenu();
|
|
6189
|
+
startNativeContextMenuLongPress(point);
|
|
5686
6190
|
lastPinchDist.current = null;
|
|
5687
6191
|
lastPanPoint.current = null;
|
|
5688
6192
|
const sx = point.x;
|
|
@@ -5896,15 +6400,18 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
5896
6400
|
dragStateRef.current = { kind: "pan" };
|
|
5897
6401
|
},
|
|
5898
6402
|
[
|
|
6403
|
+
closeNativeSelectionContextMenu,
|
|
5899
6404
|
interactive,
|
|
5900
6405
|
requestSelectToolAfterUse,
|
|
5901
6406
|
screenToWorld,
|
|
5902
6407
|
setRealtimePlacementPreview,
|
|
6408
|
+
startNativeContextMenuLongPress,
|
|
5903
6409
|
updateToolCursorPoint
|
|
5904
6410
|
]
|
|
5905
6411
|
);
|
|
5906
6412
|
const applyDragMoveAtScreenPoint = useCallback(
|
|
5907
6413
|
(point, pagePoint) => {
|
|
6414
|
+
cancelNativeContextMenuLongPressAfterMove(point);
|
|
5908
6415
|
const cam = cameraRef.current;
|
|
5909
6416
|
if (!cam) return;
|
|
5910
6417
|
updateToolCursorPoint(point);
|
|
@@ -6043,6 +6550,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6043
6550
|
}
|
|
6044
6551
|
},
|
|
6045
6552
|
[
|
|
6553
|
+
cancelNativeContextMenuLongPressAfterMove,
|
|
6046
6554
|
requestRender,
|
|
6047
6555
|
screenToWorld,
|
|
6048
6556
|
setRealtimePlacementPreview,
|
|
@@ -6052,6 +6560,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6052
6560
|
);
|
|
6053
6561
|
const finishDragAtScreenPoint = useCallback(
|
|
6054
6562
|
(point) => {
|
|
6563
|
+
clearNativeContextMenuLongPress();
|
|
6055
6564
|
lastPinchDist.current = null;
|
|
6056
6565
|
lastPanPoint.current = null;
|
|
6057
6566
|
updateToolCursorPoint(point);
|
|
@@ -6299,6 +6808,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6299
6808
|
dragStateRef.current = { kind: "idle" };
|
|
6300
6809
|
},
|
|
6301
6810
|
[
|
|
6811
|
+
clearNativeContextMenuLongPress,
|
|
6302
6812
|
requestSelectToolAfterNativeLinkUse,
|
|
6303
6813
|
requestSelectToolAfterUse,
|
|
6304
6814
|
screenToWorld,
|
|
@@ -6342,6 +6852,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6342
6852
|
const sx = evt.nativeEvent.locationX;
|
|
6343
6853
|
const sy = evt.nativeEvent.locationY;
|
|
6344
6854
|
if (touches && touches.length >= 2) {
|
|
6855
|
+
clearNativeContextMenuLongPress();
|
|
6345
6856
|
hideToolCursor();
|
|
6346
6857
|
notifyWorldPointerLeave();
|
|
6347
6858
|
dragStateRef.current = { kind: "pan" };
|
|
@@ -6358,6 +6869,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6358
6869
|
const pageX = evt.nativeEvent.pageX;
|
|
6359
6870
|
const pageY = evt.nativeEvent.pageY;
|
|
6360
6871
|
if (touches && touches.length >= 2) {
|
|
6872
|
+
clearNativeContextMenuLongPress();
|
|
6361
6873
|
hideToolCursor();
|
|
6362
6874
|
notifyWorldPointerLeave();
|
|
6363
6875
|
const t0 = touches[0];
|
|
@@ -6388,6 +6900,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6388
6900
|
});
|
|
6389
6901
|
},
|
|
6390
6902
|
onPanResponderTerminate: () => {
|
|
6903
|
+
clearNativeContextMenuLongPress();
|
|
6391
6904
|
lastPinchDist.current = null;
|
|
6392
6905
|
lastPanPoint.current = null;
|
|
6393
6906
|
hideToolCursor();
|
|
@@ -6404,6 +6917,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6404
6917
|
[
|
|
6405
6918
|
applyDragMoveAtScreenPoint,
|
|
6406
6919
|
beginDragAtScreenPoint,
|
|
6920
|
+
clearNativeContextMenuLongPress,
|
|
6407
6921
|
finishDragAtScreenPoint,
|
|
6408
6922
|
requestRender,
|
|
6409
6923
|
hideToolCursor,
|
|
@@ -6429,9 +6943,18 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6429
6943
|
options?.padding ?? 0.08
|
|
6430
6944
|
);
|
|
6431
6945
|
requestRender();
|
|
6432
|
-
}
|
|
6946
|
+
},
|
|
6947
|
+
copySelectedShapes,
|
|
6948
|
+
pasteCopiedShapes,
|
|
6949
|
+
duplicateSelectedShapes
|
|
6433
6950
|
}),
|
|
6434
|
-
[
|
|
6951
|
+
[
|
|
6952
|
+
copySelectedShapes,
|
|
6953
|
+
duplicateSelectedShapes,
|
|
6954
|
+
pasteCopiedShapes,
|
|
6955
|
+
requestRender,
|
|
6956
|
+
size
|
|
6957
|
+
]
|
|
6435
6958
|
);
|
|
6436
6959
|
const activeStyleToolId = toolId === "draw" || toolId === "marker" ? toolId : null;
|
|
6437
6960
|
const styleInspectorToolId = selectedStyleInspectorState?.toolId ?? activeStyleToolId;
|
|
@@ -6549,7 +7072,17 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6549
7072
|
pointerEvents: "box-none",
|
|
6550
7073
|
children: toolbar
|
|
6551
7074
|
}
|
|
6552
|
-
)
|
|
7075
|
+
),
|
|
7076
|
+
interactive && selectionContextMenu ? /* @__PURE__ */ jsx(
|
|
7077
|
+
NativeSelectionContextMenu,
|
|
7078
|
+
{
|
|
7079
|
+
...selectionContextMenu,
|
|
7080
|
+
onCopy: handleCopySelectedShapesFromMenu,
|
|
7081
|
+
onPaste: handlePasteCopiedShapesFromMenu,
|
|
7082
|
+
onDuplicate: handleDuplicateSelectedShapesFromMenu,
|
|
7083
|
+
onDelete: handleDeleteSelectedShapes
|
|
7084
|
+
}
|
|
7085
|
+
) : null
|
|
6553
7086
|
] }),
|
|
6554
7087
|
/* @__PURE__ */ jsx(
|
|
6555
7088
|
Modal,
|
|
@@ -6612,6 +7145,50 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
6612
7145
|
] });
|
|
6613
7146
|
});
|
|
6614
7147
|
var styles4 = StyleSheet.create({
|
|
7148
|
+
nativeSelectionContextMenu: {
|
|
7149
|
+
position: "absolute",
|
|
7150
|
+
width: NATIVE_CONTEXT_MENU_WIDTH,
|
|
7151
|
+
minHeight: NATIVE_CONTEXT_MENU_HEIGHT,
|
|
7152
|
+
flexDirection: "column",
|
|
7153
|
+
alignItems: "stretch",
|
|
7154
|
+
justifyContent: "flex-start",
|
|
7155
|
+
padding: 4,
|
|
7156
|
+
borderRadius: 14,
|
|
7157
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
7158
|
+
borderColor: "#d4d4d8",
|
|
7159
|
+
backgroundColor: "#ffffff",
|
|
7160
|
+
shadowColor: "#000000",
|
|
7161
|
+
shadowOpacity: 0.16,
|
|
7162
|
+
shadowRadius: 18,
|
|
7163
|
+
shadowOffset: { width: 0, height: 8 },
|
|
7164
|
+
elevation: NATIVE_VIEWPORT_OVERLAY_ELEVATION + 4,
|
|
7165
|
+
zIndex: NATIVE_VIEWPORT_OVERLAY_Z_INDEX + 4
|
|
7166
|
+
},
|
|
7167
|
+
nativeSelectionContextMenuButton: {
|
|
7168
|
+
width: "100%",
|
|
7169
|
+
minHeight: 42,
|
|
7170
|
+
alignItems: "flex-start",
|
|
7171
|
+
justifyContent: "center",
|
|
7172
|
+
borderRadius: 10,
|
|
7173
|
+
paddingHorizontal: 14
|
|
7174
|
+
},
|
|
7175
|
+
nativeSelectionContextMenuButtonPressed: {
|
|
7176
|
+
backgroundColor: "#f4f4f5"
|
|
7177
|
+
},
|
|
7178
|
+
nativeSelectionContextMenuButtonDisabled: {
|
|
7179
|
+
opacity: 0.45
|
|
7180
|
+
},
|
|
7181
|
+
nativeSelectionContextMenuButtonText: {
|
|
7182
|
+
color: "#18181b",
|
|
7183
|
+
fontSize: 14,
|
|
7184
|
+
fontWeight: "400"
|
|
7185
|
+
},
|
|
7186
|
+
nativeSelectionContextMenuButtonTextDisabled: {
|
|
7187
|
+
color: "#71717a"
|
|
7188
|
+
},
|
|
7189
|
+
nativeSelectionContextMenuDeleteText: {
|
|
7190
|
+
color: "#dc2626"
|
|
7191
|
+
},
|
|
6615
7192
|
nativeLinkDialogBackdrop: {
|
|
6616
7193
|
flex: 1,
|
|
6617
7194
|
alignItems: "center",
|