|
2 | 2 | // Leaflet + OpenStreetMap renderer |
3 | 3 | // - No nodes/links |
4 | 4 | // - Graph data stores: map viewport + draggable markers georeferenced by lat/lng |
| 5 | +const { DialogV2 } = foundry.applications.api; |
5 | 6 |
|
6 | 7 | import { BaseRenderer } from "./base-renderer.js"; |
7 | 8 | import { log, safeUUID } from "../constants.js"; |
@@ -489,12 +490,80 @@ export class MapRenderer extends BaseRenderer { |
489 | 490 | if (!layer || layer.__fgGeomanBound) return; |
490 | 491 | layer.__fgGeomanBound = true; |
491 | 492 |
|
492 | | - // Any of these imply the persisted geojson must be updated. |
| 493 | + // Existing persistence triggers |
493 | 494 | const bump = () => this._updateGeomanDataFromLayers(); |
494 | 495 | try { layer.on?.("pm:edit", bump); } catch (_e) { /* ignore */ } |
495 | 496 | try { layer.on?.("pm:update", bump); } catch (_e) { /* ignore */ } |
496 | 497 | try { layer.on?.("pm:remove", bump); } catch (_e) { /* ignore */ } |
497 | 498 | try { layer.on?.("dragend", bump); } catch (_e) { /* ignore */ } |
| 499 | + |
| 500 | + // NEW: Right-click menu for shapes |
| 501 | + layer.on("contextmenu", (ev) => { |
| 502 | + // Prevent the map's default context menu from firing |
| 503 | + if (ev.originalEvent) { |
| 504 | + ev.originalEvent.stopPropagation(); |
| 505 | + ev.originalEvent.preventDefault(); |
| 506 | + } |
| 507 | + |
| 508 | + this._showRadialMenu({ |
| 509 | + clientX: ev.originalEvent?.clientX ?? 0, |
| 510 | + clientY: ev.originalEvent?.clientY ?? 0, |
| 511 | + items: [ |
| 512 | + { |
| 513 | + id: "color", |
| 514 | + label: "Change Color", |
| 515 | + icon: "fa-solid fa-palette", |
| 516 | + onClick: () => this._promptForGeomanColor(layer) |
| 517 | + }, |
| 518 | + { |
| 519 | + id: "delete", |
| 520 | + label: "Delete Shape", |
| 521 | + icon: "fa-solid fa-trash", |
| 522 | + onClick: () => { |
| 523 | + if (this._geomanLayer) { |
| 524 | + this._geomanLayer.removeLayer(layer); |
| 525 | + this._updateGeomanDataFromLayers(); |
| 526 | + } |
| 527 | + } |
| 528 | + } |
| 529 | + ] |
| 530 | + }); |
| 531 | + }); |
| 532 | + } |
| 533 | + |
| 534 | + /** |
| 535 | + * Opens a Foundry dialog to pick a new color for a Geoman layer. |
| 536 | + */ |
| 537 | + async _promptForGeomanColor(layer) { |
| 538 | + const currentStyle = layer.options?.color || "#3388ff"; |
| 539 | + |
| 540 | + const content = ` |
| 541 | + <div class="form-group"> |
| 542 | + <label>Choose Color</label> |
| 543 | + <div class="form-fields"> |
| 544 | + <input type="color" name="color" value="${currentStyle}"> |
| 545 | + </div> |
| 546 | + </div> |
| 547 | + `; |
| 548 | + |
| 549 | + const color = await DialogV2.prompt({ |
| 550 | + window: { title: "Shape Style" }, |
| 551 | + content: content, |
| 552 | + ok: { |
| 553 | + label: "Apply", |
| 554 | + callback: (event, button) => button.form.elements.color.value |
| 555 | + } |
| 556 | + }); |
| 557 | + |
| 558 | + if (color) { |
| 559 | + // Apply to the live Leaflet layer |
| 560 | + layer.setStyle({ |
| 561 | + color: color, |
| 562 | + fillColor: color |
| 563 | + }); |
| 564 | + // Trigger a save to the graph data |
| 565 | + this._updateGeomanDataFromLayers(); |
| 566 | + } |
498 | 567 | } |
499 | 568 |
|
500 | 569 | _updateGeomanDataFromLayers() { |
|
0 commit comments