From 79a44306a6946757ff1c752dbe1660f72cfacde2 Mon Sep 17 00:00:00 2001 From: Marek Wilniewiec Date: Thu, 27 Mar 2025 22:01:56 +0100 Subject: [PATCH] [editable-layers] Real double-click used to finish drawing --- .../src/edit-modes/draw-line-string-mode.ts | 47 ++++++++--------- .../src/edit-modes/draw-polygon-mode.ts | 52 +++++++++---------- .../src/edit-modes/edit-mode.ts | 5 +- .../src/edit-modes/geojson-edit-mode.ts | 2 + .../editable-layers/src/edit-modes/types.ts | 3 ++ .../editable-layers/editable-geojson-layer.ts | 9 +++- .../src/editable-layers/editable-layer.ts | 12 ++++- 7 files changed, 75 insertions(+), 55 deletions(-) diff --git a/modules/editable-layers/src/edit-modes/draw-line-string-mode.ts b/modules/editable-layers/src/edit-modes/draw-line-string-mode.ts index 9ad8b739..bce02120 100644 --- a/modules/editable-layers/src/edit-modes/draw-line-string-mode.ts +++ b/modules/editable-layers/src/edit-modes/draw-line-string-mode.ts @@ -11,7 +11,8 @@ import { ModeProps, GuideFeatureCollection, GuideFeature, - Tooltip + Tooltip, + DoubleClickEvent } from './types'; import {getPickedEditHandle} from './utils'; import {GeoJsonEditMode} from './geojson-edit-mode'; @@ -47,17 +48,7 @@ export class DrawLineStringMode extends GeoJsonEditMode { // They clicked the last point (or double-clicked), so add the LineString // reset distance to new calculate this.dist = 0; - const lineStringToAdd: LineString = { - type: 'LineString', - coordinates: [...clickSequence] - }; - - this.resetClickSequence(); - - const editAction = this.getAddFeatureAction(lineStringToAdd, props.data); - if (editAction) { - props.onEdit(editAction); - } + this.finishDrawing(props); } else if (positionAdded) { // new tentative point props.onEdit({ @@ -71,21 +62,29 @@ export class DrawLineStringMode extends GeoJsonEditMode { } } + handleDoubleClick(event: DoubleClickEvent, props: ModeProps) { + this.finishDrawing(props); + } + + finishDrawing(props: ModeProps) { + const clickSequence = this.getClickSequence(); + if (clickSequence.length > 1) { + const lineStringToAdd: LineString = { + type: 'LineString', + coordinates: [...clickSequence] + }; + this.resetClickSequence(); + const editAction = this.getAddFeatureAction(lineStringToAdd, props.data); + if (editAction) { + props.onEdit(editAction); + } + } + } + handleKeyUp(event: KeyboardEvent, props: ModeProps) { const {key} = event; if (key === 'Enter') { - const clickSequence = this.getClickSequence(); - if (clickSequence.length > 1) { - const lineStringToAdd: LineString = { - type: 'LineString', - coordinates: [...clickSequence] - }; - this.resetClickSequence(); - const editAction = this.getAddFeatureAction(lineStringToAdd, props.data); - if (editAction) { - props.onEdit(editAction); - } - } + this.finishDrawing(props); } else if (key === 'Escape') { this.resetClickSequence(); props.onEdit({ diff --git a/modules/editable-layers/src/edit-modes/draw-polygon-mode.ts b/modules/editable-layers/src/edit-modes/draw-polygon-mode.ts index c5f83bb1..2664e38e 100644 --- a/modules/editable-layers/src/edit-modes/draw-polygon-mode.ts +++ b/modules/editable-layers/src/edit-modes/draw-polygon-mode.ts @@ -10,7 +10,8 @@ import { ModeProps, GuideFeatureCollection, TentativeFeature, - GuideFeature + GuideFeature, + DoubleClickEvent } from './types'; import {Polygon, FeatureCollection} from '../utils/geojson-types'; import {getPickedEditHandle} from './utils'; @@ -83,6 +84,23 @@ export class DrawPolygonMode extends GeoJsonEditMode { return guides; } + finishDrawing(props: ModeProps) { + const clickSequence = this.getClickSequence(); + if (clickSequence.length > 2) { + const polygonToAdd: Polygon = { + type: 'Polygon', + coordinates: [[...clickSequence, clickSequence[0]]] + }; + + this.resetClickSequence(); + + const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props); + if (editAction) { + props.onEdit(editAction); + } + } + } + // eslint-disable-next-line complexity handleClick(event: ClickEvent, props: ModeProps) { const {picks} = event; @@ -117,19 +135,7 @@ export class DrawPolygonMode extends GeoJsonEditMode { clickedEditHandle.properties.positionIndexes[0] === clickSequence.length - 1) ) { // They clicked the first or last point (or double-clicked), so complete the polygon - - // Remove the hovered position - const polygonToAdd: Polygon = { - type: 'Polygon', - coordinates: [[...clickSequence, clickSequence[0]]] - }; - - this.resetClickSequence(); - - const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props); - if (editAction) { - props.onEdit(editAction); - } + this.finishDrawing(props); } else if (positionAdded) { // new tentative point props.onEdit({ @@ -143,21 +149,13 @@ export class DrawPolygonMode extends GeoJsonEditMode { } } + handleDoubleClick(event: DoubleClickEvent, props: ModeProps) { + this.finishDrawing(props); + } + handleKeyUp(event: KeyboardEvent, props: ModeProps) { if (event.key === 'Enter') { - const clickSequence = this.getClickSequence(); - if (clickSequence.length > 2) { - const polygonToAdd: Polygon = { - type: 'Polygon', - coordinates: [[...clickSequence, clickSequence[0]]] - }; - this.resetClickSequence(); - - const editAction = this.getAddFeatureOrBooleanPolygonAction(polygonToAdd, props); - if (editAction) { - props.onEdit(editAction); - } - } + this.finishDrawing(props); } else if (event.key === 'Escape') { this.resetClickSequence(); props.onEdit({ diff --git a/modules/editable-layers/src/edit-modes/edit-mode.ts b/modules/editable-layers/src/edit-modes/edit-mode.ts index ff37b47f..757a8cd0 100644 --- a/modules/editable-layers/src/edit-modes/edit-mode.ts +++ b/modules/editable-layers/src/edit-modes/edit-mode.ts @@ -11,12 +11,15 @@ import { StopDraggingEvent, DraggingEvent, Tooltip, - ModeProps + ModeProps, + DoubleClickEvent } from './types'; export interface EditMode { // Called when the pointer went down and up without dragging regardless of whether something was picked handleClick(event: ClickEvent, props: ModeProps): void; + // Called when the pointer double-clicked + handleDoubleClick(event: DoubleClickEvent, props: ModeProps): void; // Called when the pointer moved, regardless of whether the pointer is down, up, and whether something was picked handlePointerMove(event: PointerMoveEvent, props: ModeProps): void; // Called when the pointer went down on something rendered by this layer and the pointer started to move diff --git a/modules/editable-layers/src/edit-modes/geojson-edit-mode.ts b/modules/editable-layers/src/edit-modes/geojson-edit-mode.ts index 17a1d02e..2793d8df 100644 --- a/modules/editable-layers/src/edit-modes/geojson-edit-mode.ts +++ b/modules/editable-layers/src/edit-modes/geojson-edit-mode.ts @@ -253,6 +253,8 @@ export class GeoJsonEditMode implements EditMode): void {} + handleDoubleClick(event: ClickEvent, props: ModeProps): void {} + handlePointerMove(event: PointerMoveEvent, props: ModeProps): void { const tentativeFeature = this.createTentativeFeature(props); if (tentativeFeature) { diff --git a/modules/editable-layers/src/edit-modes/types.ts b/modules/editable-layers/src/edit-modes/types.ts index ed49aa5d..e6d4b150 100644 --- a/modules/editable-layers/src/edit-modes/types.ts +++ b/modules/editable-layers/src/edit-modes/types.ts @@ -44,6 +44,9 @@ export type BasePointerEvent = { // Represents a click event export type ClickEvent = BasePointerEvent; +// Represents a double click event +export type DoubleClickEvent = BasePointerEvent; + // Represents an event that occurs when the pointer goes down and the cursor starts moving export type StartDraggingEvent = BasePointerEvent & { pointerDownPicks?: Pick[] | null; diff --git a/modules/editable-layers/src/editable-layers/editable-geojson-layer.ts b/modules/editable-layers/src/editable-layers/editable-geojson-layer.ts index fa6784b3..9c46b67c 100644 --- a/modules/editable-layers/src/editable-layers/editable-geojson-layer.ts +++ b/modules/editable-layers/src/editable-layers/editable-geojson-layer.ts @@ -12,7 +12,8 @@ import { StartDraggingEvent, StopDraggingEvent, DraggingEvent, - PointerMoveEvent + PointerMoveEvent, + DoubleClickEvent } from '../edit-modes/types'; import {ViewMode} from '../edit-modes/view-mode'; @@ -567,6 +568,12 @@ export class EditableGeoJsonLayer extends EditableLayer< this.getActiveMode().handleClick(event, this.getModeProps(this.props) as any); } + onLayerDoubleClick(event: DoubleClickEvent): void { + if (this.getActiveMode().handleDoubleClick) { + this.getActiveMode().handleDoubleClick(event, this.getModeProps(this.props) as any); + } + } + onLayerKeyUp(event: KeyboardEvent): void { this.getActiveMode().handleKeyUp(event, this.getModeProps(this.props) as any); } diff --git a/modules/editable-layers/src/editable-layers/editable-layer.ts b/modules/editable-layers/src/editable-layers/editable-layer.ts index ca724afd..3c87eb03 100644 --- a/modules/editable-layers/src/editable-layers/editable-layer.ts +++ b/modules/editable-layers/src/editable-layers/editable-layer.ts @@ -11,11 +11,12 @@ import { ClickEvent, StartDraggingEvent, StopDraggingEvent, - PointerMoveEvent + PointerMoveEvent, + DoubleClickEvent } from '../edit-modes/types'; import {Position} from '../utils/geojson-types'; -const EVENT_TYPES = ['click', 'pointermove', 'panstart', 'panmove', 'panend', 'keyup']; +const EVENT_TYPES = ['click', 'pointermove', 'panstart', 'panmove', 'panend', 'keyup', 'dblclick']; // TODO(v9): remove generic layer export type EditableLayerProps = CompositeLayerProps & { @@ -36,6 +37,9 @@ export abstract class EditableLayer< onLayerClick(event: ClickEvent): void { // default implementation - do nothing } + onLayerDoubleClick(event: DoubleClickEvent): void { + // default implementation - do nothing + } onStartDragging(event: StartDraggingEvent): void { // default implementation - do nothing @@ -132,6 +136,10 @@ export abstract class EditableLayer< }); } + _ondblclick({srcEvent}: any) { + this.onLayerDoubleClick(srcEvent); + } + _onkeyup({srcEvent}: {srcEvent: KeyboardEvent}) { this.onLayerKeyUp(srcEvent); }