From af631b91f0c2a741969aff06d8b371edaf84c097 Mon Sep 17 00:00:00 2001 From: jedrek0429 <64475360+jedrek0429@users.noreply.github.com> Date: Fri, 29 Mar 2024 19:53:30 +0100 Subject: [PATCH 01/21] Add a context menu in webmap --- .../net/pl3x/map/core/configuration/Lang.java | 6 ++ .../renderer/task/UpdateSettingsData.java | 5 ++ core/src/main/resources/locale/lang_pl.yml | 4 ++ webmap/src/Pl3xMap.ts | 2 + webmap/src/control/ContextMenuControl.ts | 59 +++++++++++++++++++ webmap/src/control/ControlManager.ts | 12 ++++ webmap/src/scss/styles.scss | 23 ++++++++ webmap/src/settings/Lang.ts | 32 +++++++++- 8 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 webmap/src/control/ContextMenuControl.ts diff --git a/core/src/main/java/net/pl3x/map/core/configuration/Lang.java b/core/src/main/java/net/pl3x/map/core/configuration/Lang.java index e076f3e1a..fd9c34583 100644 --- a/core/src/main/java/net/pl3x/map/core/configuration/Lang.java +++ b/core/src/main/java/net/pl3x/map/core/configuration/Lang.java @@ -204,6 +204,12 @@ public final class Lang extends AbstractConfig { public static String UI_BLOCKINFO_LABEL = "BlockInfo"; @Key("ui.blockinfo.value") public static String UI_BLOCKINFO_VALUE = "
"; + @Key("ui.contextmenu.label") + public static String UI_CONTEXTMENU_LABEL = "ContextMenu"; + @Key("ui.contextmenu.copy-coords") + public static String UI_CONTEXTMENU_COPY_COORDS = "Copy coordinates"; + @Key("ui.contextmenu.center-map") + public static String UI_CONTEXTMENU_CENTER_MAP = "Center map here"; @Key("ui.coords.label") public static String UI_COORDS_LABEL = "Coordinates"; @Key("ui.coords.value") diff --git a/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java b/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java index b3369b64a..8ede74e85 100644 --- a/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java +++ b/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java @@ -161,6 +161,11 @@ private void parseSettings() { lang.put("title", Lang.UI_TITLE); lang.put("langFile", Lang.UI_BLOCK_AND_BIOME_LANG_FILE); lang.put("blockInfo", Map.of("label", Lang.UI_BLOCKINFO_LABEL, "value", Lang.UI_BLOCKINFO_VALUE)); + lang.put("contextMenu", Map.of( + "label", Lang.UI_CONTEXTMENU_LABEL, + "copyCoords", Lang.UI_CONTEXTMENU_COPY_COORDS, + "centerMap", Lang.UI_CONTEXTMENU_CENTER_MAP + )); lang.put("coords", Map.of("label", Lang.UI_COORDS_LABEL, "value", Lang.UI_COORDS_VALUE)); lang.put("layers", Map.of("label", Lang.UI_LAYERS_LABEL, "value", Lang.UI_LAYERS_VALUE)); lang.put("link", Map.of("label", Lang.UI_LINK_LABEL, "value", Lang.UI_LINK_VALUE)); diff --git a/core/src/main/resources/locale/lang_pl.yml b/core/src/main/resources/locale/lang_pl.yml index f0566dcbd..e61441f43 100644 --- a/core/src/main/resources/locale/lang_pl.yml +++ b/core/src/main/resources/locale/lang_pl.yml @@ -109,6 +109,10 @@ ui: blockinfo: label: Informacje o bloku # Or keep it BlockInfo? value:
+ contextmenu: + label: ContextMenu + copy-coords: Skopiuj współrzędne + center-map: Wyśrodkuj mapę w tym miejscu coords: label: Współrzędne value: , , diff --git a/webmap/src/Pl3xMap.ts b/webmap/src/Pl3xMap.ts index 0a69dd996..761e16a0e 100644 --- a/webmap/src/Pl3xMap.ts +++ b/webmap/src/Pl3xMap.ts @@ -3,6 +3,7 @@ import {ControlManager} from "./control/ControlManager"; import {PlayerManager} from "./player/PlayerManager"; import {WorldManager} from "./world/WorldManager"; import {getJSON} from "./util/Util"; +import ContextMenuControl from "./control/ContextMenuControl"; import SidebarControl from "./control/SidebarControl"; import Pl3xMapLeafletMap from "./map/Pl3xMapLeafletMap"; import "./scss/styles.scss"; @@ -48,6 +49,7 @@ export class Pl3xMap { this._langPalette.set(data[0], data[1]); }); }); + this.controlManager.contextMenuControl = new ContextMenuControl(this); this.controlManager.sidebarControl = new SidebarControl(this); const promise: Promise = this.worldManager.init(this._settings); this.update(); diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts new file mode 100644 index 000000000..94b9f9076 --- /dev/null +++ b/webmap/src/control/ContextMenuControl.ts @@ -0,0 +1,59 @@ +import * as L from "leaflet"; +import {Pl3xMap} from "../Pl3xMap"; + +export default class ContextMenuControl extends L.Control { + private readonly _pl3xmap: Pl3xMap; + private _dom: HTMLDivElement = L.DomUtil.create('div'); + + + constructor(pl3xmap: Pl3xMap) { + super(); + this._pl3xmap = pl3xmap; + this._pl3xmap.map.on('contextmenu', this._show, this); + this._pl3xmap.map.on('click', this._hide, this); + } + + onAdd(): HTMLDivElement { + this._dom = L.DomUtil.create('div', 'leaflet-control leaflet-control-contextmenu', this._pl3xmap.map.getContainer()); + this._dom.dataset.label = this._pl3xmap.settings!.lang.contextMenu.label; + return this._dom; + } + + private _show(event: L.LeafletMouseEvent): void { + L.DomEvent.stopPropagation(event); + this._dom.innerHTML = ''; + this._getItems(event).forEach((item) => { + const menuItem = L.DomUtil.create('div', 'leaflet-control-contextmenu-item', this._dom); + menuItem.innerHTML = item.label; + L.DomEvent.on(menuItem, 'click', (e) => { + L.DomEvent.stopPropagation(e); + item.callback(); + this._hide(); + }); + }); + this._dom.style.display = 'block'; + this._dom.style.left = event.containerPoint.x + 'px'; + this._dom.style.top = event.containerPoint.y + 'px'; + } + + private _hide(): void { + this._dom.style.display = 'none'; + } + + private _getItems(e: L.LeafletMouseEvent): Map void }> { + const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; + const coords = `(${x}, ${y ?? '???'}, ${z})`; + + const items = new Map(); + items.set('copyCoords', { + label: `${this._pl3xmap.settings!.lang.contextMenu.copyCoords} ${coords}`, + callback: () => navigator.clipboard.writeText(coords), + }); + items.set('centerMap', { + label: this._pl3xmap.settings!.lang.contextMenu.centerMap, + callback: () => this._pl3xmap.map.panTo(e.latlng), + }); + + return items; + } +} \ No newline at end of file diff --git a/webmap/src/control/ControlManager.ts b/webmap/src/control/ControlManager.ts index 0ff0eb9b4..87678eb1f 100644 --- a/webmap/src/control/ControlManager.ts +++ b/webmap/src/control/ControlManager.ts @@ -2,11 +2,13 @@ import {Pl3xMap} from "../Pl3xMap"; import {BlockInfoControl} from "./BlockInfoControl"; import {CoordsControl} from "./CoordsControl"; import {LinkControl} from "./LinkControl"; +import ContextMenuControl from "./ContextMenuControl"; import SidebarControl from "./SidebarControl"; export class ControlManager { private readonly _pl3xmap: Pl3xMap; + private _contextMenuControl?: ContextMenuControl; private _sidebarControl?: SidebarControl private _blockInfoControl?: BlockInfoControl; private _coordsControl?: CoordsControl; @@ -16,6 +18,16 @@ export class ControlManager { this._pl3xmap = pl3xmap; } + get contextMenuControl(): ContextMenuControl | undefined { + return this._contextMenuControl; + } + + set contextMenuControl(menu: ContextMenuControl | undefined) { + this._contextMenuControl?.remove(); + this._contextMenuControl = menu; + this._contextMenuControl?.addTo(this._pl3xmap.map); + } + get sidebarControl(): SidebarControl | undefined { return this._sidebarControl; } diff --git a/webmap/src/scss/styles.scss b/webmap/src/scss/styles.scss index ae47f571f..46cf6cdda 100644 --- a/webmap/src/scss/styles.scss +++ b/webmap/src/scss/styles.scss @@ -229,3 +229,26 @@ img.leaflet-tile { } } } + +.leaflet-control-contextmenu { + display: none; + position: absolute; + background-color: var(--ui-background); + border: var(--ui-border); + border-radius: var(--ui-border-radius); + overflow: hidden; + z-index: 10000; /* Ensure the menu appears over other map controls */ +} + +.leaflet-control-contextmenu-item { + padding: 5px; + font-size: 12px; + color: var(--ui-text); + cursor: pointer; + transition: background-color 0.3s ease-in-out; + + &:hover { + background-color: var(--ui-background-hover); + color: var(--ui-text-hover); + } +} diff --git a/webmap/src/settings/Lang.ts b/webmap/src/settings/Lang.ts index bf401a473..76659c6df 100644 --- a/webmap/src/settings/Lang.ts +++ b/webmap/src/settings/Lang.ts @@ -4,6 +4,7 @@ export class Lang { private readonly _title: string; private readonly _langFile: string; + private readonly _contextMenu: ContextMenu; private readonly _coords: Label; private readonly _blockInfo: Label; private readonly _layers: Label; @@ -12,9 +13,10 @@ export class Lang { private readonly _players: Label; private readonly _worlds: Label; - constructor(title: string, langFile: string, coords: Label, blockInfo: Label, layers: Label, link: Label, markers: Label, players: Label, worlds: Label) { + constructor(title: string, langFile: string, contextMenu: ContextMenu, coords: Label, blockInfo: Label, layers: Label, link: Label, markers: Label, players: Label, worlds: Label) { this._title = title; this._langFile = langFile; + this._contextMenu = contextMenu; this._coords = coords; this._blockInfo = blockInfo; this._layers = layers; @@ -32,6 +34,10 @@ export class Lang { return this._langFile; } + get contextMenu(): ContextMenu { + return this._contextMenu; + } + get coords(): Label { return this._coords; } @@ -81,3 +87,27 @@ export class Label { return this._value; } } + +export class ContextMenu { + private readonly _label: string; + private readonly _copyCoords: string; + private readonly _centerMap: string; + + constructor(label: string, copyCoords: string, centerMap: string) { + this._label = label; + this._copyCoords = copyCoords; + this._centerMap = centerMap; + } + + get label(): string { + return this._label; + } + + get copyCoords(): string { + return this._copyCoords; + } + + get centerMap(): string { + return this._centerMap; + } +} From 0077e66507fbff9d4b66b3f41bbbbfef835c8b40 Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 29 Mar 2024 18:23:16 -0700 Subject: [PATCH 02/21] whitespace --- webmap/src/settings/Lang.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmap/src/settings/Lang.ts b/webmap/src/settings/Lang.ts index 52b15ec1d..85fa01972 100644 --- a/webmap/src/settings/Lang.ts +++ b/webmap/src/settings/Lang.ts @@ -13,7 +13,7 @@ export class Lang { private readonly _players: Label; private readonly _worlds: Label; - constructor(title: string, langFile: string,contextMenu: ContextMenu, coords: Label, blockInfo: BlockInfo, layers: Label, link: Label, markers: Label, players: Label, worlds: Label) { + constructor(title: string, langFile: string, contextMenu: ContextMenu, coords: Label, blockInfo: BlockInfo, layers: Label, link: Label, markers: Label, players: Label, worlds: Label) { this._title = title; this._langFile = langFile; this._contextMenu = contextMenu; From 94fa8ce2846e84b85a49f6429fdc9a8b67f9ea82 Mon Sep 17 00:00:00 2001 From: jedrek0429 <64475360+jedrek0429@users.noreply.github.com> Date: Mon, 1 Apr 2024 00:52:03 +0200 Subject: [PATCH 03/21] Add more configurability and custom html for the context menus --- .../net/pl3x/map/core/configuration/Lang.java | 2 + .../map/core/configuration/WorldConfig.java | 31 +++++++ .../renderer/task/UpdateSettingsData.java | 10 +++ core/src/main/resources/locale/lang-pl.yml | 1 + webmap/src/Pl3xMap.ts | 1 - webmap/src/control/ContextMenuControl.ts | 78 ++++++++++++---- webmap/src/control/LinkControl.ts | 4 + webmap/src/settings/Lang.ts | 8 +- webmap/src/settings/WorldSettings.ts | 90 +++++++++++++++++++ webmap/src/world/WorldManager.ts | 2 + 10 files changed, 207 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/net/pl3x/map/core/configuration/Lang.java b/core/src/main/java/net/pl3x/map/core/configuration/Lang.java index 8d4b8bfea..871ac7e16 100644 --- a/core/src/main/java/net/pl3x/map/core/configuration/Lang.java +++ b/core/src/main/java/net/pl3x/map/core/configuration/Lang.java @@ -219,6 +219,8 @@ public final class Lang extends AbstractConfig { public static String UI_CONTEXTMENU_LABEL = "ContextMenu"; @Key("ui.contextmenu.copy-coords") public static String UI_CONTEXTMENU_COPY_COORDS = "Copy coordinates"; + @Key("ui.contextmenu.copy-link") + public static String UI_CONTEXTMENU_COPY_LINK = "Copy link to here"; @Key("ui.contextmenu.center-map") public static String UI_CONTEXTMENU_CENTER_MAP = "Center map here"; @Key("ui.coords.label") diff --git a/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java b/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java index 350f57cba..c84ea04fc 100644 --- a/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java +++ b/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java @@ -126,6 +126,37 @@ public final class WorldConfig extends AbstractConfig { @Comment(""" The display position for the link box""") public String UI_LINK = "bottomright"; + + @Key("ui.context-menu.enabled") + @Comment(""" + Enable the context menu.""") + public boolean UI_CONTEXT_MENU_ENABLED = true; + + @Key("ui.context-menu.items") + @Comment(""" + Items to show in the context menu. Leave empty for custom html. + Available items are: + copy-coords, copy-link, center-map""") + public List<@NotNull String> UI_CONTEXT_MENU_ITEMS = new ArrayList<>() {{ + add("copy-coords"); + add("copy-link"); + add("center-map"); + }}; + + @Key("ui.context-menu.custom-html.enabled") + @Comment(""" + Use custom html for the context menu.""") + public boolean UI_CONTEXT_MENU_CUSTOM_HTML_ENABLED = false; + + @Key("ui.context-menu.custom-html.html") + @Comment(""" + Custom html for the context menu.""") + public String UI_CONTEXT_MENU_CUSTOM_HTML_HTML = ""; + + @Key("ui.context-menu.custom-html.css") + @Comment(""" + Custom css for the context menu.""") + public String UI_CONTEXT_MENU_CUSTOM_HTML_CSS = ""; @Key("center.x") @Comment(""" diff --git a/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java b/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java index 4eaee3f34..a81916960 100644 --- a/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java +++ b/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java @@ -123,6 +123,15 @@ public void run() { ui.put("coords", config.UI_COORDS); ui.put("blockinfo", config.UI_BLOCKINFO); ui.put("attribution", config.UI_ATTRIBUTION); + ui.put("contextMenu", Map.of( + "enabled", config.UI_CONTEXT_MENU_ENABLED, + "items", config.UI_CONTEXT_MENU_ITEMS, + "customHtml", Map.of( + "enabled", config.UI_CONTEXT_MENU_CUSTOM_HTML_ENABLED, + "html", config.UI_CONTEXT_MENU_CUSTOM_HTML_HTML, + "css", config.UI_CONTEXT_MENU_CUSTOM_HTML_CSS + ) + )); Map settings = new LinkedHashMap<>(); settings.put("name", world.getName().replace(":", "-")); @@ -168,6 +177,7 @@ private void parseSettings() { lang.put("contextMenu", Map.of( "label", Lang.UI_CONTEXTMENU_LABEL, "copyCoords", Lang.UI_CONTEXTMENU_COPY_COORDS, + "copyLink", Lang.UI_CONTEXTMENU_COPY_LINK, "centerMap", Lang.UI_CONTEXTMENU_CENTER_MAP )); lang.put("coords", Map.of("label", Lang.UI_COORDS_LABEL, "value", Lang.UI_COORDS_VALUE)); diff --git a/core/src/main/resources/locale/lang-pl.yml b/core/src/main/resources/locale/lang-pl.yml index 3b7057e43..992c8e0e2 100644 --- a/core/src/main/resources/locale/lang-pl.yml +++ b/core/src/main/resources/locale/lang-pl.yml @@ -119,6 +119,7 @@ ui: contextmenu: label: ContextMenu copy-coords: Skopiuj współrzędne + copy-link: Skopiuj link do tego miejsca center-map: Wyśrodkuj mapę w tym miejscu coords: label: Współrzędne diff --git a/webmap/src/Pl3xMap.ts b/webmap/src/Pl3xMap.ts index 761e16a0e..280607cd0 100644 --- a/webmap/src/Pl3xMap.ts +++ b/webmap/src/Pl3xMap.ts @@ -49,7 +49,6 @@ export class Pl3xMap { this._langPalette.set(data[0], data[1]); }); }); - this.controlManager.contextMenuControl = new ContextMenuControl(this); this.controlManager.sidebarControl = new SidebarControl(this); const promise: Promise = this.worldManager.init(this._settings); this.update(); diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 94b9f9076..4de8687b1 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -1,36 +1,54 @@ import * as L from "leaflet"; import {Pl3xMap} from "../Pl3xMap"; +import {ContextMenuCustomHtml, ContextMenuItemType} from "../settings/WorldSettings"; export default class ContextMenuControl extends L.Control { private readonly _pl3xmap: Pl3xMap; private _dom: HTMLDivElement = L.DomUtil.create('div'); + private _customHtml: ContextMenuCustomHtml; constructor(pl3xmap: Pl3xMap) { super(); this._pl3xmap = pl3xmap; + this._customHtml = pl3xmap.worldManager.currentWorld?.settings.ui.contextMenu.customHtml ?? new ContextMenuCustomHtml(); + if (this._pl3xmap.worldManager.currentWorld?.settings.ui.contextMenu.enabled) { + this._init(); + } + } + + private _init(): void { this._pl3xmap.map.on('contextmenu', this._show, this); this._pl3xmap.map.on('click', this._hide, this); + if (this._customHtml.enabled) { + const style = L.DomUtil.create('style', 'leaflet-control-contextmenu-custom-style', document.head); + style.innerHTML = this._customHtml.css; + } } onAdd(): HTMLDivElement { - this._dom = L.DomUtil.create('div', 'leaflet-control leaflet-control-contextmenu', this._pl3xmap.map.getContainer()); + this._dom = L.DomUtil.create('div', 'leaflet-control leaflet-control-contextmenu'); this._dom.dataset.label = this._pl3xmap.settings!.lang.contextMenu.label; + if (this._customHtml.enabled) { + this._dom.innerHTML = this._customHtml.html; + } return this._dom; } private _show(event: L.LeafletMouseEvent): void { L.DomEvent.stopPropagation(event); - this._dom.innerHTML = ''; - this._getItems(event).forEach((item) => { - const menuItem = L.DomUtil.create('div', 'leaflet-control-contextmenu-item', this._dom); - menuItem.innerHTML = item.label; - L.DomEvent.on(menuItem, 'click', (e) => { - L.DomEvent.stopPropagation(e); - item.callback(); - this._hide(); + if (!this._customHtml.enabled) { + this._dom.innerHTML = ''; + this._getItems(event).forEach((item) => { + const menuItem = L.DomUtil.create('div', 'leaflet-control-contextmenu-item', this._dom); + menuItem.innerHTML = item.label; + L.DomEvent.on(menuItem, 'click', (e) => { + L.DomEvent.stopPropagation(e); + item.callback(); + this._hide(); + }); }); - }); + } this._dom.style.display = 'block'; this._dom.style.left = event.containerPoint.x + 'px'; this._dom.style.top = event.containerPoint.y + 'px'; @@ -43,15 +61,39 @@ export default class ContextMenuControl extends L.Control { private _getItems(e: L.LeafletMouseEvent): Map void }> { const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; const coords = `(${x}, ${y ?? '???'}, ${z})`; + const world = this._pl3xmap.worldManager.currentWorld; + const settings = world?.settings.ui.contextMenu; + const items: Map void }> = new Map(); - const items = new Map(); - items.set('copyCoords', { - label: `${this._pl3xmap.settings!.lang.contextMenu.copyCoords} ${coords}`, - callback: () => navigator.clipboard.writeText(coords), - }); - items.set('centerMap', { - label: this._pl3xmap.settings!.lang.contextMenu.centerMap, - callback: () => this._pl3xmap.map.panTo(e.latlng), + settings?.items.forEach((item) => { + switch (item) { + case ContextMenuItemType.copyCoords: + items.set('copyCoords', { + label: `${this._pl3xmap.settings!.lang.contextMenu.copyCoords} ${coords}`, + callback: () => navigator.clipboard.writeText(coords), + }); + break; + case ContextMenuItemType.copyLink: + items.set('copyLink', { + label: this._pl3xmap.settings!.lang.contextMenu.copyLink, + callback: () => navigator.clipboard.writeText( + window.location.href + + this._pl3xmap.controlManager.linkControl?.getUrlFromCoords( + x, + z, + this._pl3xmap.map.getCurrentZoom(), + world + ) + ), + }); + break; + case ContextMenuItemType.centerMap: + items.set('centerMap', { + label: this._pl3xmap.settings!.lang.contextMenu.centerMap, + callback: () => this._pl3xmap.map.panTo(e.latlng), + }); + break; + } }); return items; diff --git a/webmap/src/control/LinkControl.ts b/webmap/src/control/LinkControl.ts index dbed4f04e..421bee0b3 100644 --- a/webmap/src/control/LinkControl.ts +++ b/webmap/src/control/LinkControl.ts @@ -43,6 +43,10 @@ export class LinkControl extends ControlBox { const zoom: number = this._pl3xmap.map.getCurrentZoom(); const x: number = Math.floor(center[0]); const z: number = Math.floor(center[1]); + return this.getUrlFromCoords(x, z, zoom, world); + } + + public getUrlFromCoords(x: number, z: number, zoom: number, world?: World): string { let url: string = `?`; if (world !== undefined) { url += `world=${world.name}&renderer=${world.currentRenderer?.label ?? 'basic'}`; diff --git a/webmap/src/settings/Lang.ts b/webmap/src/settings/Lang.ts index 85fa01972..ef23ee997 100644 --- a/webmap/src/settings/Lang.ts +++ b/webmap/src/settings/Lang.ts @@ -131,11 +131,13 @@ export class BlockInfo extends Label { export class ContextMenu { private readonly _label: string; private readonly _copyCoords: string; + private readonly _copyLink: string; private readonly _centerMap: string; - constructor(label: string, copyCoords: string, centerMap: string) { + constructor(label: string, copyCoords: string, copyLink: string, centerMap: string) { this._label = label; this._copyCoords = copyCoords; + this._copyLink = copyLink; this._centerMap = centerMap; } @@ -146,6 +148,10 @@ export class ContextMenu { get copyCoords(): string { return this._copyCoords; } + + get copyLink(): string { + return this._copyLink; + } get centerMap(): string { return this._centerMap; diff --git a/webmap/src/settings/WorldSettings.ts b/webmap/src/settings/WorldSettings.ts index a4f413737..60cb391ad 100644 --- a/webmap/src/settings/WorldSettings.ts +++ b/webmap/src/settings/WorldSettings.ts @@ -135,6 +135,7 @@ export class UI { private _coords: string = 'bottomcenter'; private _blockinfo: string = 'bottomleft'; private _attribution: boolean = true; + private _contextMenu: ContextMenuSettings = new ContextMenuSettings(); get link(): string { return this._link; @@ -167,7 +168,96 @@ export class UI { set attribution(value: boolean) { this._attribution = value; } + + get contextMenu(): ContextMenuSettings { + return this._contextMenu; + } + + set contextMenu(value: ContextMenuSettings) { + this._contextMenu = value; + } +} + +/** + * Represents a world's context menu settings. + */ +export class ContextMenuSettings { + private _enabled: boolean = true; + private _items: ContextMenuItemType[] = [ + ContextMenuItemType.copyCoords, + ContextMenuItemType.copyLink, + ContextMenuItemType.centerMap, + ]; + private _customHtml: ContextMenuCustomHtml = new ContextMenuCustomHtml(); + + get enabled(): boolean { + return this._enabled; + } + + set enabled(value: boolean) { + this._enabled = value; + } + + get items(): ContextMenuItemType[] { + return this._items; + } + + set items(value: ContextMenuItemType[]) { + this._items = value; + } + + get customHtml(): ContextMenuCustomHtml { + return this._customHtml; + } + + set customHtml(value: ContextMenuCustomHtml) { + this._customHtml = value; + } +} + +/** + * Represents a world's context menu item. + */ +export enum ContextMenuItemType { + copyCoords = 'copy-coords', + copyLink = 'copy-link', + centerMap = 'center-map', +} + +/** + * Represents a world's context menu custom HTML. + */ +export class ContextMenuCustomHtml { + private _enabled: boolean = false; + private _html: string = ''; + private _css: string = ''; + + get enabled(): boolean { + return this._enabled; + } + + set enabled(value: boolean) { + this._enabled = value; + } + + get html(): string { + return this._html; + } + + set html(value: string) { + this._html = value; + } + + get css(): string { + return this._css; + } + + set css(value: string) { + this._css = value; + } } + + /** * Represents a world's zoom settings. diff --git a/webmap/src/world/WorldManager.ts b/webmap/src/world/WorldManager.ts index 3cad9a98e..c23f2ef4f 100644 --- a/webmap/src/world/WorldManager.ts +++ b/webmap/src/world/WorldManager.ts @@ -6,6 +6,7 @@ import {Settings} from "../settings/Settings"; import {Renderer, World} from "./World"; import {fireCustomEvent, getUrlParam} from "../util/Util"; import {UI, WorldSettings} from "../settings/WorldSettings"; +import ContextMenuControl from "../control/ContextMenuControl"; /** * The world manager. Manages all loaded worlds. @@ -78,6 +79,7 @@ export class WorldManager { ); const ui: UI = world.settings.ui; + this._pl3xmap.controlManager.contextMenuControl = new ContextMenuControl(this._pl3xmap); this._pl3xmap.controlManager.linkControl = ui.link ? new LinkControl(this._pl3xmap, ui.link) : undefined; this._pl3xmap.controlManager.coordsControl = ui.coords ? new CoordsControl(this._pl3xmap, ui.coords) : undefined; this._pl3xmap.controlManager.blockInfoControl = ui.blockinfo ? new BlockInfoControl(this._pl3xmap, ui.blockinfo) : undefined; From a85b820dc47a51eec8e698b450da90cf27b46f06 Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben <64475360+jedrek0429@users.noreply.github.com> Date: Tue, 2 Apr 2024 13:36:09 +0200 Subject: [PATCH 04/21] Apply suggestions from code review Co-authored-by: Kuba_Z2 <77853483+KubaZ2@users.noreply.github.com> --- webmap/src/control/ContextMenuControl.ts | 4 ++-- webmap/src/settings/Lang.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 4de8687b1..097e910f9 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -48,7 +48,7 @@ export default class ContextMenuControl extends L.Control { this._hide(); }); }); - } + } this._dom.style.display = 'block'; this._dom.style.left = event.containerPoint.x + 'px'; this._dom.style.top = event.containerPoint.y + 'px'; @@ -98,4 +98,4 @@ export default class ContextMenuControl extends L.Control { return items; } -} \ No newline at end of file +} diff --git a/webmap/src/settings/Lang.ts b/webmap/src/settings/Lang.ts index ef23ee997..91fda0ea5 100644 --- a/webmap/src/settings/Lang.ts +++ b/webmap/src/settings/Lang.ts @@ -117,7 +117,6 @@ export class BlockInfoUnknown { export class BlockInfo extends Label { private readonly _unknown: BlockInfoUnknown; - constructor(label: string, value: string, unknown: BlockInfoUnknown) { super(label, value); this._unknown = unknown; From 9af1026e1038ae51ebf0915e77eec3dc0737d042 Mon Sep 17 00:00:00 2001 From: granny Date: Wed, 3 Apr 2024 21:17:48 -0700 Subject: [PATCH 05/21] make the context menu items a button --- webmap/src/control/ContextMenuControl.ts | 2 +- webmap/src/scss/styles.scss | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 097e910f9..cc3acd39b 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -40,7 +40,7 @@ export default class ContextMenuControl extends L.Control { if (!this._customHtml.enabled) { this._dom.innerHTML = ''; this._getItems(event).forEach((item) => { - const menuItem = L.DomUtil.create('div', 'leaflet-control-contextmenu-item', this._dom); + const menuItem = L.DomUtil.create('button', 'leaflet-control-contextmenu-item', this._dom); menuItem.innerHTML = item.label; L.DomEvent.on(menuItem, 'click', (e) => { L.DomEvent.stopPropagation(e); diff --git a/webmap/src/scss/styles.scss b/webmap/src/scss/styles.scss index 46cf6cdda..1372475e8 100644 --- a/webmap/src/scss/styles.scss +++ b/webmap/src/scss/styles.scss @@ -244,7 +244,6 @@ img.leaflet-tile { padding: 5px; font-size: 12px; color: var(--ui-text); - cursor: pointer; transition: background-color 0.3s ease-in-out; &:hover { From a8dc6a617c29528355a190237f81222671abcd74 Mon Sep 17 00:00:00 2001 From: granny Date: Wed, 3 Apr 2024 21:18:31 -0700 Subject: [PATCH 06/21] make contextmenu a flexbox --- webmap/src/control/ContextMenuControl.ts | 2 +- webmap/src/scss/styles.scss | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index cc3acd39b..3f7204ad8 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -49,7 +49,7 @@ export default class ContextMenuControl extends L.Control { }); }); } - this._dom.style.display = 'block'; + this._dom.style.display = 'flex'; this._dom.style.left = event.containerPoint.x + 'px'; this._dom.style.top = event.containerPoint.y + 'px'; } diff --git a/webmap/src/scss/styles.scss b/webmap/src/scss/styles.scss index 1372475e8..77c7fb308 100644 --- a/webmap/src/scss/styles.scss +++ b/webmap/src/scss/styles.scss @@ -233,6 +233,10 @@ img.leaflet-tile { .leaflet-control-contextmenu { display: none; position: absolute; + flex-direction: column; + font-family: monospace; + text-align: left; + white-space: pre; background-color: var(--ui-background); border: var(--ui-border); border-radius: var(--ui-border-radius); @@ -242,7 +246,6 @@ img.leaflet-tile { .leaflet-control-contextmenu-item { padding: 5px; - font-size: 12px; color: var(--ui-text); transition: background-color 0.3s ease-in-out; From 693aa6fd5f1c5cf1c678a87033d16624bee82acc Mon Sep 17 00:00:00 2001 From: granny Date: Wed, 3 Apr 2024 21:18:49 -0700 Subject: [PATCH 07/21] make each coordinate a variable --- core/src/main/java/net/pl3x/map/core/configuration/Lang.java | 2 +- webmap/src/control/ContextMenuControl.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/net/pl3x/map/core/configuration/Lang.java b/core/src/main/java/net/pl3x/map/core/configuration/Lang.java index 871ac7e16..f1b1fde3f 100644 --- a/core/src/main/java/net/pl3x/map/core/configuration/Lang.java +++ b/core/src/main/java/net/pl3x/map/core/configuration/Lang.java @@ -218,7 +218,7 @@ public final class Lang extends AbstractConfig { @Key("ui.contextmenu.label") public static String UI_CONTEXTMENU_LABEL = "ContextMenu"; @Key("ui.contextmenu.copy-coords") - public static String UI_CONTEXTMENU_COPY_COORDS = "Copy coordinates"; + public static String UI_CONTEXTMENU_COPY_COORDS = "X: Y: Z: "; @Key("ui.contextmenu.copy-link") public static String UI_CONTEXTMENU_COPY_LINK = "Copy link to here"; @Key("ui.contextmenu.center-map") diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 3f7204ad8..287ff509b 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -69,7 +69,10 @@ export default class ContextMenuControl extends L.Control { switch (item) { case ContextMenuItemType.copyCoords: items.set('copyCoords', { - label: `${this._pl3xmap.settings!.lang.contextMenu.copyCoords} ${coords}`, + label: this._pl3xmap.settings!.lang.contextMenu.copyCoords + .replace(//g, "" + x) + .replace(//g, "" + y) + .replace(//g, "" + z), callback: () => navigator.clipboard.writeText(coords), }); break; From ce169e1494e3aad79757d340a36732c354c9fbb5 Mon Sep 17 00:00:00 2001 From: granny Date: Wed, 3 Apr 2024 21:45:54 -0700 Subject: [PATCH 08/21] take inspiration from LiveAtlas' contextmenu --- webmap/src/control/ContextMenuControl.ts | 31 +++++++++++++++++++----- webmap/src/scss/styles.scss | 2 ++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 287ff509b..70a8d5a5d 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -36,7 +36,16 @@ export default class ContextMenuControl extends L.Control { } private _show(event: L.LeafletMouseEvent): void { - L.DomEvent.stopPropagation(event); + // Ignore right-clicks on controls (https://github.com/JLyne/LiveAtlas/blob/0819cdf2728b49d361f9adfda09ff08311a59337/src/components/map/MapContextMenu.vue#L188-L194) + if(event.originalEvent.target && (event.originalEvent.target as HTMLElement).closest('.leaflet-control')) { + return; + } + + event.originalEvent.stopImmediatePropagation(); + event.originalEvent.preventDefault(); + + this._dom.style.visibility = 'visible'; + if (!this._customHtml.enabled) { this._dom.innerHTML = ''; this._getItems(event).forEach((item) => { @@ -49,13 +58,24 @@ export default class ContextMenuControl extends L.Control { }); }); } + + // Don't position offscreen (https://github.com/JLyne/LiveAtlas/blob/0819cdf2728b49d361f9adfda09ff08311a59337/src/components/map/MapContextMenu.vue#L123-L135) + const x = Math.min( + window.innerWidth - this._dom.offsetWidth - 10, + event.originalEvent.clientX + ), + y = Math.min( + window.innerHeight - this._dom.offsetHeight - 10, + event.originalEvent.clientY + ); + this._dom.style.display = 'flex'; - this._dom.style.left = event.containerPoint.x + 'px'; - this._dom.style.top = event.containerPoint.y + 'px'; + this._dom.style.transform = `translate(${x}px, ${y}px)`; } private _hide(): void { - this._dom.style.display = 'none'; + this._dom.style.visibility = 'hidden'; + this._dom.style.left = '-1000'; } private _getItems(e: L.LeafletMouseEvent): Map void }> { @@ -82,8 +102,7 @@ export default class ContextMenuControl extends L.Control { callback: () => navigator.clipboard.writeText( window.location.href + this._pl3xmap.controlManager.linkControl?.getUrlFromCoords( - x, - z, + x, z, this._pl3xmap.map.getCurrentZoom(), world ) diff --git a/webmap/src/scss/styles.scss b/webmap/src/scss/styles.scss index 77c7fb308..6a7295c45 100644 --- a/webmap/src/scss/styles.scss +++ b/webmap/src/scss/styles.scss @@ -235,6 +235,8 @@ img.leaflet-tile { position: absolute; flex-direction: column; font-family: monospace; + top: 0; + left: 0; text-align: left; white-space: pre; background-color: var(--ui-background); From 3b859f53e2bf9568a7323093390776cc59dec1ce Mon Sep 17 00:00:00 2001 From: granny Date: Wed, 3 Apr 2024 23:50:01 -0700 Subject: [PATCH 09/21] remove custom html --- .../map/core/configuration/WorldConfig.java | 44 +++++++++++----- .../renderer/task/UpdateSettingsData.java | 6 +-- webmap/src/control/ContextMenuControl.ts | 42 +++++++-------- webmap/src/scss/styles.scss | 27 ---------- webmap/src/settings/WorldSettings.ts | 51 +++---------------- 5 files changed, 61 insertions(+), 109 deletions(-) diff --git a/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java b/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java index c84ea04fc..30499c202 100644 --- a/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java +++ b/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java @@ -134,7 +134,7 @@ public final class WorldConfig extends AbstractConfig { @Key("ui.context-menu.items") @Comment(""" - Items to show in the context menu. Leave empty for custom html. + Items to show in the context menu. Available items are: copy-coords, copy-link, center-map""") public List<@NotNull String> UI_CONTEXT_MENU_ITEMS = new ArrayList<>() {{ @@ -142,21 +142,37 @@ public final class WorldConfig extends AbstractConfig { add("copy-link"); add("center-map"); }}; - - @Key("ui.context-menu.custom-html.enabled") - @Comment(""" - Use custom html for the context menu.""") - public boolean UI_CONTEXT_MENU_CUSTOM_HTML_ENABLED = false; - - @Key("ui.context-menu.custom-html.html") - @Comment(""" - Custom html for the context menu.""") - public String UI_CONTEXT_MENU_CUSTOM_HTML_HTML = ""; - - @Key("ui.context-menu.custom-html.css") + + @Key("ui.context-menu.css") @Comment(""" Custom css for the context menu.""") - public String UI_CONTEXT_MENU_CUSTOM_HTML_CSS = ""; + public static String UI_CONTEXT_MENU_CSS = """ + .leaflet-control-contextmenu { + display: none; + position: absolute; + flex-direction: column; + font-family: monospace; + top: 0; + left: 0; + text-align: left; + white-space: pre; + background-color: var(--ui-background); + border: var(--ui-border); + border-radius: var(--ui-border-radius); + overflow: hidden; + z-index: 10000; /* Ensure the menu appears over other map controls */ + } + + .leaflet-control-contextmenu-item { + padding: 5px; + color: var(--ui-text); + transition: background-color 0.3s ease-in-out; + + &:hover { + background-color: var(--ui-background-hover); + color: var(--ui-text-hover); + } + }"""; @Key("center.x") @Comment(""" diff --git a/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java b/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java index 5d3a97765..e69ba9d75 100644 --- a/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java +++ b/core/src/main/java/net/pl3x/map/core/renderer/task/UpdateSettingsData.java @@ -127,11 +127,7 @@ public void run() { ui.put("contextMenu", Map.of( "enabled", config.UI_CONTEXT_MENU_ENABLED, "items", config.UI_CONTEXT_MENU_ITEMS, - "customHtml", Map.of( - "enabled", config.UI_CONTEXT_MENU_CUSTOM_HTML_ENABLED, - "html", config.UI_CONTEXT_MENU_CUSTOM_HTML_HTML, - "css", config.UI_CONTEXT_MENU_CUSTOM_HTML_CSS - ) + "css", config.UI_CONTEXT_MENU_CSS )); Map settings = new LinkedHashMap<>(); diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 70a8d5a5d..63073d058 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -1,17 +1,18 @@ import * as L from "leaflet"; import {Pl3xMap} from "../Pl3xMap"; -import {ContextMenuCustomHtml, ContextMenuItemType} from "../settings/WorldSettings"; +import {ContextMenuItemType} from "../settings/WorldSettings"; +import {insertCss, removeCss} from "../util/Util"; +import Pl3xMapLeafletMap from "../map/Pl3xMapLeafletMap"; export default class ContextMenuControl extends L.Control { private readonly _pl3xmap: Pl3xMap; private _dom: HTMLDivElement = L.DomUtil.create('div'); - private _customHtml: ContextMenuCustomHtml; + private _id: string = 'pl3xmap-content-menu'; constructor(pl3xmap: Pl3xMap) { super(); this._pl3xmap = pl3xmap; - this._customHtml = pl3xmap.worldManager.currentWorld?.settings.ui.contextMenu.customHtml ?? new ContextMenuCustomHtml(); if (this._pl3xmap.worldManager.currentWorld?.settings.ui.contextMenu.enabled) { this._init(); } @@ -20,21 +21,24 @@ export default class ContextMenuControl extends L.Control { private _init(): void { this._pl3xmap.map.on('contextmenu', this._show, this); this._pl3xmap.map.on('click', this._hide, this); - if (this._customHtml.enabled) { - const style = L.DomUtil.create('style', 'leaflet-control-contextmenu-custom-style', document.head); - style.innerHTML = this._customHtml.css; + + const css = this._pl3xmap.worldManager.currentWorld?.settings.ui.contextMenu.css; + if (css !== undefined) { + insertCss(css, this._id); } } onAdd(): HTMLDivElement { this._dom = L.DomUtil.create('div', 'leaflet-control leaflet-control-contextmenu'); this._dom.dataset.label = this._pl3xmap.settings!.lang.contextMenu.label; - if (this._customHtml.enabled) { - this._dom.innerHTML = this._customHtml.html; - } return this._dom; } + + onRemove(_map: Pl3xMapLeafletMap): void { + removeCss(this._id); + } + private _show(event: L.LeafletMouseEvent): void { // Ignore right-clicks on controls (https://github.com/JLyne/LiveAtlas/blob/0819cdf2728b49d361f9adfda09ff08311a59337/src/components/map/MapContextMenu.vue#L188-L194) if(event.originalEvent.target && (event.originalEvent.target as HTMLElement).closest('.leaflet-control')) { @@ -46,18 +50,16 @@ export default class ContextMenuControl extends L.Control { this._dom.style.visibility = 'visible'; - if (!this._customHtml.enabled) { - this._dom.innerHTML = ''; - this._getItems(event).forEach((item) => { - const menuItem = L.DomUtil.create('button', 'leaflet-control-contextmenu-item', this._dom); - menuItem.innerHTML = item.label; - L.DomEvent.on(menuItem, 'click', (e) => { - L.DomEvent.stopPropagation(e); - item.callback(); - this._hide(); - }); + this._dom.innerHTML = ''; + this._getItems(event).forEach((item) => { + const menuItem = L.DomUtil.create('button', 'leaflet-control-contextmenu-item', this._dom); + menuItem.innerHTML = item.label; + L.DomEvent.on(menuItem, 'click', (e) => { + L.DomEvent.stopPropagation(e); + item.callback(); + this._hide(); }); - } + }); // Don't position offscreen (https://github.com/JLyne/LiveAtlas/blob/0819cdf2728b49d361f9adfda09ff08311a59337/src/components/map/MapContextMenu.vue#L123-L135) const x = Math.min( diff --git a/webmap/src/scss/styles.scss b/webmap/src/scss/styles.scss index 6a7295c45..ae47f571f 100644 --- a/webmap/src/scss/styles.scss +++ b/webmap/src/scss/styles.scss @@ -229,30 +229,3 @@ img.leaflet-tile { } } } - -.leaflet-control-contextmenu { - display: none; - position: absolute; - flex-direction: column; - font-family: monospace; - top: 0; - left: 0; - text-align: left; - white-space: pre; - background-color: var(--ui-background); - border: var(--ui-border); - border-radius: var(--ui-border-radius); - overflow: hidden; - z-index: 10000; /* Ensure the menu appears over other map controls */ -} - -.leaflet-control-contextmenu-item { - padding: 5px; - color: var(--ui-text); - transition: background-color 0.3s ease-in-out; - - &:hover { - background-color: var(--ui-background-hover); - color: var(--ui-text-hover); - } -} diff --git a/webmap/src/settings/WorldSettings.ts b/webmap/src/settings/WorldSettings.ts index 60cb391ad..2f449ab05 100644 --- a/webmap/src/settings/WorldSettings.ts +++ b/webmap/src/settings/WorldSettings.ts @@ -188,8 +188,8 @@ export class ContextMenuSettings { ContextMenuItemType.copyLink, ContextMenuItemType.centerMap, ]; - private _customHtml: ContextMenuCustomHtml = new ContextMenuCustomHtml(); - + private _css: string = ''; + get enabled(): boolean { return this._enabled; } @@ -205,13 +205,13 @@ export class ContextMenuSettings { set items(value: ContextMenuItemType[]) { this._items = value; } - - get customHtml(): ContextMenuCustomHtml { - return this._customHtml; + + get css(): string { + return this._css; } - - set customHtml(value: ContextMenuCustomHtml) { - this._customHtml = value; + + set css(value: string) { + this._css = value; } } @@ -224,41 +224,6 @@ export enum ContextMenuItemType { centerMap = 'center-map', } -/** - * Represents a world's context menu custom HTML. - */ -export class ContextMenuCustomHtml { - private _enabled: boolean = false; - private _html: string = ''; - private _css: string = ''; - - get enabled(): boolean { - return this._enabled; - } - - set enabled(value: boolean) { - this._enabled = value; - } - - get html(): string { - return this._html; - } - - set html(value: string) { - this._html = value; - } - - get css(): string { - return this._css; - } - - set css(value: string) { - this._css = value; - } -} - - - /** * Represents a world's zoom settings. */ From 1378fef1395772406906a6553076c5f6253bd8ea Mon Sep 17 00:00:00 2001 From: granny Date: Wed, 3 Apr 2024 23:51:17 -0700 Subject: [PATCH 10/21] remove unused onRemove parameter --- webmap/src/control/ContextMenuControl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 63073d058..bc0258cb7 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -35,7 +35,7 @@ export default class ContextMenuControl extends L.Control { } - onRemove(_map: Pl3xMapLeafletMap): void { + onRemove(): void { removeCss(this._id); } From 6d2c66c36cbfd2ab97fe9d14e658ee3506b10423 Mon Sep 17 00:00:00 2001 From: granny Date: Wed, 3 Apr 2024 23:53:11 -0700 Subject: [PATCH 11/21] remove unused import --- webmap/src/Pl3xMap.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/webmap/src/Pl3xMap.ts b/webmap/src/Pl3xMap.ts index 280607cd0..0a69dd996 100644 --- a/webmap/src/Pl3xMap.ts +++ b/webmap/src/Pl3xMap.ts @@ -3,7 +3,6 @@ import {ControlManager} from "./control/ControlManager"; import {PlayerManager} from "./player/PlayerManager"; import {WorldManager} from "./world/WorldManager"; import {getJSON} from "./util/Util"; -import ContextMenuControl from "./control/ContextMenuControl"; import SidebarControl from "./control/SidebarControl"; import Pl3xMapLeafletMap from "./map/Pl3xMapLeafletMap"; import "./scss/styles.scss"; From adb03e141f434785c99b0307d175ba9893856454 Mon Sep 17 00:00:00 2001 From: granny Date: Wed, 3 Apr 2024 23:58:05 -0700 Subject: [PATCH 12/21] update copy-coords value in lang file --- core/src/main/resources/locale/lang-pl.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/locale/lang-pl.yml b/core/src/main/resources/locale/lang-pl.yml index 992c8e0e2..359671365 100644 --- a/core/src/main/resources/locale/lang-pl.yml +++ b/core/src/main/resources/locale/lang-pl.yml @@ -118,7 +118,7 @@ ui: biome: Nieznany biom contextmenu: label: ContextMenu - copy-coords: Skopiuj współrzędne + copy-coords: , , copy-link: Skopiuj link do tego miejsca center-map: Wyśrodkuj mapę w tym miejscu coords: From c6b7bba2b7730eed8cb6d04bfaffe57b4c13ef6d Mon Sep 17 00:00:00 2001 From: granny Date: Thu, 4 Apr 2024 00:01:03 -0700 Subject: [PATCH 13/21] update copy-coords value in lang file x2 --- core/src/main/resources/locale/lang-pl.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/locale/lang-pl.yml b/core/src/main/resources/locale/lang-pl.yml index 359671365..60717d2b5 100644 --- a/core/src/main/resources/locale/lang-pl.yml +++ b/core/src/main/resources/locale/lang-pl.yml @@ -118,7 +118,7 @@ ui: biome: Nieznany biom contextmenu: label: ContextMenu - copy-coords: , , + copy-coords: 'X: Y: Z: ' copy-link: Skopiuj link do tego miejsca center-map: Wyśrodkuj mapę w tym miejscu coords: From b2e3077914ba1788dfa0b7c306522307c6f3507a Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 5 Apr 2024 11:01:31 -0700 Subject: [PATCH 14/21] move display flex into leaflet-control-contextmenu class --- .../main/java/net/pl3x/map/core/configuration/WorldConfig.java | 1 + webmap/src/control/ContextMenuControl.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java b/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java index 30499c202..f37622a15 100644 --- a/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java +++ b/core/src/main/java/net/pl3x/map/core/configuration/WorldConfig.java @@ -150,6 +150,7 @@ public final class WorldConfig extends AbstractConfig { .leaflet-control-contextmenu { display: none; position: absolute; + display: flex; flex-direction: column; font-family: monospace; top: 0; diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index bc0258cb7..67d6ffe13 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -71,7 +71,6 @@ export default class ContextMenuControl extends L.Control { event.originalEvent.clientY ); - this._dom.style.display = 'flex'; this._dom.style.transform = `translate(${x}px, ${y}px)`; } From d8aa273540a5fdd5945cd8e5b9eac4f081c082ff Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 5 Apr 2024 11:13:10 -0700 Subject: [PATCH 15/21] use String constructor --- webmap/src/control/ContextMenuControl.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 67d6ffe13..1e2c1325a 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -91,9 +91,9 @@ export default class ContextMenuControl extends L.Control { case ContextMenuItemType.copyCoords: items.set('copyCoords', { label: this._pl3xmap.settings!.lang.contextMenu.copyCoords - .replace(//g, "" + x) - .replace(//g, "" + y) - .replace(//g, "" + z), + .replace(//g, String(x)) + .replace(//g, String(y)) + .replace(//g, String(z)), callback: () => navigator.clipboard.writeText(coords), }); break; From 26450a21e8788c56eb6956519d0d28dcbc63256d Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 5 Apr 2024 11:13:18 -0700 Subject: [PATCH 16/21] remove unused import --- webmap/src/control/ContextMenuControl.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 1e2c1325a..9d8eb06cf 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -2,7 +2,6 @@ import * as L from "leaflet"; import {Pl3xMap} from "../Pl3xMap"; import {ContextMenuItemType} from "../settings/WorldSettings"; import {insertCss, removeCss} from "../util/Util"; -import Pl3xMapLeafletMap from "../map/Pl3xMapLeafletMap"; export default class ContextMenuControl extends L.Control { private readonly _pl3xmap: Pl3xMap; From c6bdd76c2ebb2cb92b2d4ca679aa08fb46cc6372 Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 5 Apr 2024 11:13:55 -0700 Subject: [PATCH 17/21] remove dash from id --- webmap/src/control/ContextMenuControl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 9d8eb06cf..f1f5d35ec 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -6,7 +6,7 @@ import {insertCss, removeCss} from "../util/Util"; export default class ContextMenuControl extends L.Control { private readonly _pl3xmap: Pl3xMap; private _dom: HTMLDivElement = L.DomUtil.create('div'); - private _id: string = 'pl3xmap-content-menu'; + private _id: string = 'pl3xmap-contentmenu'; constructor(pl3xmap: Pl3xMap) { From eff01b792d4af66da336a6d389ae766e6c06b84e Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 5 Apr 2024 11:56:05 -0700 Subject: [PATCH 18/21] content -> context --- webmap/src/control/ContextMenuControl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index f1f5d35ec..c5ab4417a 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -6,7 +6,7 @@ import {insertCss, removeCss} from "../util/Util"; export default class ContextMenuControl extends L.Control { private readonly _pl3xmap: Pl3xMap; private _dom: HTMLDivElement = L.DomUtil.create('div'); - private _id: string = 'pl3xmap-contentmenu'; + private _id: string = 'pl3xmap-contextmenu'; constructor(pl3xmap: Pl3xMap) { From ac770d09b88f1d2d9138890fe31ac70e38825eb3 Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 5 Apr 2024 11:58:05 -0700 Subject: [PATCH 19/21] bleugh --- webmap/src/control/ContextMenuControl.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index c5ab4417a..b480d07d1 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -90,9 +90,9 @@ export default class ContextMenuControl extends L.Control { case ContextMenuItemType.copyCoords: items.set('copyCoords', { label: this._pl3xmap.settings!.lang.contextMenu.copyCoords - .replace(//g, String(x)) - .replace(//g, String(y)) - .replace(//g, String(z)), + .replace(//g, x.toString()) + .replace(//g, y?.toString() ?? '???') + .replace(//g, z.toString()), callback: () => navigator.clipboard.writeText(coords), }); break; From cdd801c9c9d654b86e512c2c2095a135c54d3d49 Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 12 Apr 2024 07:15:37 -0700 Subject: [PATCH 20/21] replace the switch case with a map that "gets" the item if set in config --- webmap/src/control/ContextMenuControl.ts | 105 ++++++++++++----------- 1 file changed, 55 insertions(+), 50 deletions(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index b480d07d1..1ed5c41f0 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -3,11 +3,54 @@ import {Pl3xMap} from "../Pl3xMap"; import {ContextMenuItemType} from "../settings/WorldSettings"; import {insertCss, removeCss} from "../util/Util"; +type ContextMenuCallback = { + label: () => string; + callback: (e: L.LeafletMouseEvent) => void; +}; + export default class ContextMenuControl extends L.Control { private readonly _pl3xmap: Pl3xMap; private _dom: HTMLDivElement = L.DomUtil.create('div'); private _id: string = 'pl3xmap-contextmenu'; - + private _items: Map = new Map( + [ + [ContextMenuItemType.copyCoords, { + label: () => { + const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; + return this._pl3xmap.settings!.lang.contextMenu.copyCoords + .replace(//g, x.toString()) + .replace(//g, y?.toString() ?? '???') + .replace(//g, z.toString()) + }, + callback: () => { + const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; + const coords = `(${x}, ${y ?? '???'}, ${z})`; + navigator.clipboard.writeText(coords) + }, + }], + [ContextMenuItemType.copyLink, { + label: () => this._pl3xmap.settings!.lang.contextMenu.copyLink, + callback : () => { + const {x, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; + const world = this._pl3xmap.worldManager.currentWorld; + navigator.clipboard.writeText( + window.location.href + + this._pl3xmap.controlManager.linkControl?.getUrlFromCoords( + x, z, + this._pl3xmap.map.getCurrentZoom(), + world + ) + ) + }, + }], + [ContextMenuItemType.centerMap, { + label: () => this._pl3xmap.settings!.lang.contextMenu.centerMap, + callback: (event: L.LeafletMouseEvent) => { + this._pl3xmap.map.panTo(event.latlng); + }, + }] + ] + ); constructor(pl3xmap: Pl3xMap) { super(); @@ -16,7 +59,7 @@ export default class ContextMenuControl extends L.Control { this._init(); } } - + private _init(): void { this._pl3xmap.map.on('contextmenu', this._show, this); this._pl3xmap.map.on('click', this._hide, this); @@ -50,12 +93,17 @@ export default class ContextMenuControl extends L.Control { this._dom.style.visibility = 'visible'; this._dom.innerHTML = ''; - this._getItems(event).forEach((item) => { + + const world = this._pl3xmap.worldManager.currentWorld; + world?.settings.ui.contextMenu?.items?.forEach(itemType => { + const item: ContextMenuCallback | undefined = this._items.get(itemType); + if (item === undefined) return; + const menuItem = L.DomUtil.create('button', 'leaflet-control-contextmenu-item', this._dom); - menuItem.innerHTML = item.label; - L.DomEvent.on(menuItem, 'click', (e) => { - L.DomEvent.stopPropagation(e); - item.callback(); + menuItem.innerHTML = item.label(); + L.DomEvent.on(menuItem, 'click', (ev) => { + L.DomEvent.stopPropagation(ev); + item.callback(event); this._hide(); }); }); @@ -77,47 +125,4 @@ export default class ContextMenuControl extends L.Control { this._dom.style.visibility = 'hidden'; this._dom.style.left = '-1000'; } - - private _getItems(e: L.LeafletMouseEvent): Map void }> { - const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; - const coords = `(${x}, ${y ?? '???'}, ${z})`; - const world = this._pl3xmap.worldManager.currentWorld; - const settings = world?.settings.ui.contextMenu; - const items: Map void }> = new Map(); - - settings?.items.forEach((item) => { - switch (item) { - case ContextMenuItemType.copyCoords: - items.set('copyCoords', { - label: this._pl3xmap.settings!.lang.contextMenu.copyCoords - .replace(//g, x.toString()) - .replace(//g, y?.toString() ?? '???') - .replace(//g, z.toString()), - callback: () => navigator.clipboard.writeText(coords), - }); - break; - case ContextMenuItemType.copyLink: - items.set('copyLink', { - label: this._pl3xmap.settings!.lang.contextMenu.copyLink, - callback: () => navigator.clipboard.writeText( - window.location.href + - this._pl3xmap.controlManager.linkControl?.getUrlFromCoords( - x, z, - this._pl3xmap.map.getCurrentZoom(), - world - ) - ), - }); - break; - case ContextMenuItemType.centerMap: - items.set('centerMap', { - label: this._pl3xmap.settings!.lang.contextMenu.centerMap, - callback: () => this._pl3xmap.map.panTo(e.latlng), - }); - break; - } - }); - - return items; - } } From c1ba1fb5a0706f7251e389d74c068bf7de732a18 Mon Sep 17 00:00:00 2001 From: granny Date: Fri, 12 Apr 2024 07:17:27 -0700 Subject: [PATCH 21/21] whitespace --- webmap/src/control/ContextMenuControl.ts | 75 ++++++++++++------------ 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/webmap/src/control/ContextMenuControl.ts b/webmap/src/control/ContextMenuControl.ts index 1ed5c41f0..07b154226 100644 --- a/webmap/src/control/ContextMenuControl.ts +++ b/webmap/src/control/ContextMenuControl.ts @@ -12,45 +12,44 @@ export default class ContextMenuControl extends L.Control { private readonly _pl3xmap: Pl3xMap; private _dom: HTMLDivElement = L.DomUtil.create('div'); private _id: string = 'pl3xmap-contextmenu'; - private _items: Map = new Map( - [ - [ContextMenuItemType.copyCoords, { - label: () => { - const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; - return this._pl3xmap.settings!.lang.contextMenu.copyCoords - .replace(//g, x.toString()) - .replace(//g, y?.toString() ?? '???') - .replace(//g, z.toString()) - }, - callback: () => { - const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; - const coords = `(${x}, ${y ?? '???'}, ${z})`; - navigator.clipboard.writeText(coords) - }, - }], - [ContextMenuItemType.copyLink, { - label: () => this._pl3xmap.settings!.lang.contextMenu.copyLink, - callback : () => { - const {x, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; - const world = this._pl3xmap.worldManager.currentWorld; - navigator.clipboard.writeText( - window.location.href + - this._pl3xmap.controlManager.linkControl?.getUrlFromCoords( - x, z, - this._pl3xmap.map.getCurrentZoom(), - world - ) + private _items: Map = new Map([ + [ContextMenuItemType.copyCoords, { + label: () => { + const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; + return this._pl3xmap.settings!.lang.contextMenu.copyCoords + .replace(//g, x.toString()) + .replace(//g, y?.toString() ?? '???') + .replace(//g, z.toString()) + }, + callback: () => { + const {x, y, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; + const coords = `(${x}, ${y ?? '???'}, ${z})`; + navigator.clipboard.writeText(coords) + }, + }], + [ContextMenuItemType.copyLink, { + label: () => this._pl3xmap.settings!.lang.contextMenu.copyLink, + callback : () => { + const {x, z} = this._pl3xmap.controlManager.coordsControl ?? {x: 0, y: 0, z: 0}; + const world = this._pl3xmap.worldManager.currentWorld; + navigator.clipboard.writeText( + window.location.href + + this._pl3xmap.controlManager.linkControl?.getUrlFromCoords( + x, z, + this._pl3xmap.map.getCurrentZoom(), + world ) - }, - }], - [ContextMenuItemType.centerMap, { - label: () => this._pl3xmap.settings!.lang.contextMenu.centerMap, - callback: (event: L.LeafletMouseEvent) => { - this._pl3xmap.map.panTo(event.latlng); - }, - }] - ] - ); + ) + }, + }], + [ContextMenuItemType.centerMap, { + label: () => this._pl3xmap.settings!.lang.contextMenu.centerMap, + callback: (event: L.LeafletMouseEvent) => { + this._pl3xmap.map.panTo(event.latlng); + }, + }] + + ]); constructor(pl3xmap: Pl3xMap) { super();