From 3a478f341d3a02014e6ea862f8fa65ebffa84a70 Mon Sep 17 00:00:00 2001 From: Hendrik Brummermann Date: Sat, 28 Feb 2026 02:30:16 +0100 Subject: [PATCH] use HeldObjectManager.get() --- src/js/stendhal/SingletonRepo.ts | 13 +++----- src/js/stendhal/ui/HeldObject.ts | 14 ++++---- src/js/stendhal/ui/ViewPort.ts | 33 +++++++++---------- .../component/ItemContainerImplementation.ts | 27 +++++++-------- .../ui/dialog/DropQuantitySelectorDialog.ts | 8 ++--- 5 files changed, 45 insertions(+), 50 deletions(-) diff --git a/src/js/stendhal/SingletonRepo.ts b/src/js/stendhal/SingletonRepo.ts index 740c5b46c6..229007b928 100644 --- a/src/js/stendhal/SingletonRepo.ts +++ b/src/js/stendhal/SingletonRepo.ts @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright © 2003-2024 - Faiumoni e. V. * + * Copyright © 2003-2026 - Faiumoni e. V. * *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * @@ -19,8 +19,8 @@ import { FacingHandler } from "./util/FacingHandler"; import { KeyHandler } from "./util/KeyHandler"; import { SessionManager } from "./util/SessionManager"; -import { CStatus } from "./data/CStatus"; import { CacheManager } from "./data/CacheManager"; +import { CStatus } from "./data/CStatus"; import { EmojiStore } from "./data/EmojiStore"; import { GroupManager } from "./data/GroupManager"; import { Paths } from "./data/Paths"; @@ -28,11 +28,10 @@ import { Paths } from "./data/Paths"; import { LoopedSoundSourceManager } from "./data/sound/LoopedSoundSourceManager"; import { SoundManager } from "./data/sound/SoundManager"; -import { ui } from "./ui/UI"; -import { UIComponentEnum } from "./ui/UIComponentEnum"; -import { HeldObjectManager } from "./ui/HeldObject"; import { Inventory } from "./ui/Inventory"; import { SoftwareJoystickController } from "./ui/SoftwareJoystickController"; +import { ui } from "./ui/UI"; +import { UIComponentEnum } from "./ui/UIComponentEnum"; import { UIUpdateObserver } from "./ui/UIUpdateObserver"; import { ChatInputComponent } from "./ui/component/ChatInputComponent"; @@ -82,10 +81,6 @@ export class SingletonRepo { return GroupManager.get(); } - static getHeldObjectManager(): HeldObjectManager { - return HeldObjectManager.get(); - } - static getInventory(): Inventory { return Inventory.get(); } diff --git a/src/js/stendhal/ui/HeldObject.ts b/src/js/stendhal/ui/HeldObject.ts index e52617750b..158741b7f5 100644 --- a/src/js/stendhal/ui/HeldObject.ts +++ b/src/js/stendhal/ui/HeldObject.ts @@ -37,11 +37,13 @@ export interface HeldObject { */ export class HeldObjectManager { + /** Singleton instance. */ + private static instance: HeldObjectManager; + /** Image displayed when an object is "held". */ private image: HTMLCanvasElement|HTMLImageElement; - /** Singleton instance. */ - private static instance: HeldObjectManager; + public heldObject?: HeldObject; /** @@ -75,9 +77,7 @@ export class HeldObjectManager { canvas.height = sprite.height!; let ctx = canvas.getContext("2d")!; ctx.clearRect(0, 0, sprite.width!, sprite.height!); - sprite.drawOntoWithZoom(ctx, 0, 0, 24, 24); - - + sprite.drawOntoWithZoom(ctx, 0, 0, 32, 32); if (e instanceof DragEvent) { e.dataTransfer?.setDragImage(canvas, 0, 0); @@ -108,7 +108,7 @@ export class HeldObjectManager { * Initial position of displayed image. */ public set(obj: HeldObject, pos?: Point) { - stendhal.ui.heldObject = obj; + this.heldObject = obj; this.onSet(pos); } @@ -135,7 +135,7 @@ export class HeldObjectManager { * Hides object image. */ public onRelease() { - // NOTE: should we unset `stendhal.ui.heldObject` here? + // NOTE: should we unset `heldObject` here? this.setVisible(false); } diff --git a/src/js/stendhal/ui/ViewPort.ts b/src/js/stendhal/ui/ViewPort.ts index eef55dad2b..fba92cd20d 100644 --- a/src/js/stendhal/ui/ViewPort.ts +++ b/src/js/stendhal/ui/ViewPort.ts @@ -12,7 +12,7 @@ import { marauroa } from "marauroa"; import { stendhal } from "../stendhal"; -import { HeldObject } from "./HeldObject"; +import { HeldObject, HeldObjectManager } from "./HeldObject"; import { ui } from "./UI"; import { UIComponentEnum } from "./UIComponentEnum"; @@ -22,7 +22,6 @@ import { ActionContextMenu } from "./dialog/ActionContextMenu"; import { DropQuantitySelectorDialog } from "./dialog/DropQuantitySelectorDialog"; import { Client } from "../Client"; -import { singletons } from "../SingletonRepo"; import { AchievementBanner } from "../sprite/AchievementBanner"; import { EmojiSprite } from "../sprite/EmojiSprite"; @@ -30,10 +29,8 @@ import { NotificationBubble } from "../sprite/NotificationBubble"; import { SpeechBubble } from "../sprite/SpeechBubble"; import { TextBubble } from "../sprite/TextBubble"; -import { htmlImageStore } from "data/HTMLImageStore"; import { TileMap } from "data/TileMap"; import { Zone } from "entity/Zone"; -import { HTMLImageElementUtil } from "sprite/image/HTMLImageElementUtil"; import { Canvas, RenderingContext2D } from "util/Types"; import { WeatherRenderer } from "util/WeatherRenderer"; import { Debug } from "../util/Debug"; @@ -664,7 +661,8 @@ export class ViewPort { } } - if (!draggedEntity || !singletons.getHeldObjectManager().prepare(draggedEntity, e)) { + if (!draggedEntity || !HeldObjectManager.get().prepare(draggedEntity, e)) { + e.preventDefault(); return; } @@ -677,10 +675,10 @@ export class ViewPort { let touchHandler = TouchHandler.get(); if (touchHandler.isTouchEvent(e)) { - singletons.getHeldObjectManager().set(heldObject, new Point(pos.pageX, pos.pageY)); + HeldObjectManager.get().set(heldObject, new Point(pos.pageX, pos.pageY)); touchHandler.setHolding(true); } else { - stendhal.ui.heldObject = heldObject; + HeldObjectManager.get().heldObject = heldObject; } } @@ -699,22 +697,23 @@ export class ViewPort { * Handles releasing an item or corpse from drag event. */ onDrop(e: DragEvent|TouchEvent) { - if (stendhal.ui.heldObject) { + let heldObject = HeldObjectManager.get().heldObject; + if (heldObject) { var pos = HTMLUtil.extractPosition(e); const targetSlot = HTMLUtil.parseSlotName((pos.target as HTMLElement).id); const action: any = { - "zone": stendhal.ui.heldObject.zone + "zone": heldObject.zone }; if (targetSlot === "viewport") { let viewPort = ViewPort.get(); action.x = Math.floor((pos.canvasRelativeX + viewPort.offsetX) / 32).toString(); action.y = Math.floor((pos.canvasRelativeY + viewPort.offsetY) / 32).toString(); - var id = stendhal.ui.heldObject.path.substr(1, stendhal.ui.heldObject.path.length - 2); + var id = heldObject.path.substring(1, heldObject.path.length - 1); var drop = /\t/.test(id); if (drop) { action["type"] = "drop"; - action["source_path"] = stendhal.ui.heldObject.path; + action["source_path"] = heldObject.path; } else { action["type"] = "displace"; action["baseitem"] = id; @@ -729,22 +728,22 @@ export class ViewPort { } } action["type"] = "equip"; - action["source_path"] = stendhal.ui.heldObject.path; + action["source_path"] = heldObject.path; action["target_path"] = "[" + objectId + "\t" + targetSlot + "]"; } - const quantity = stendhal.ui.heldObject.quantity; - const sourceSlot = stendhal.ui.heldObject.slot || "viewport"; + const quantity = heldObject.quantity; + const sourceSlot = heldObject.slot || "viewport"; // item was dropped - stendhal.ui.heldObject = undefined; + heldObject = undefined; - const touch_held = TouchHandler.get().holding() && quantity > 1; + const touch_held = TouchHandler.get().holding() && (quantity||1) > 1; // if ctrl is pressed or holding stackable item from touch event, we ask for the quantity // NOTE: don't create selector if touch source is ground if (e.ctrlKey || (touch_held && sourceSlot !== targetSlot)) { ui.createSingletonFloatingWindow("Quantity", new DropQuantitySelectorDialog(action, touch_held), pos.pageX - 50, pos.pageY - 25); } else { - singletons.getHeldObjectManager().onRelease(); + HeldObjectManager.get().onRelease(); marauroa.clientFramework.sendAction(action); } } diff --git a/src/js/stendhal/ui/component/ItemContainerImplementation.ts b/src/js/stendhal/ui/component/ItemContainerImplementation.ts index a1480633f2..86c02e666c 100644 --- a/src/js/stendhal/ui/component/ItemContainerImplementation.ts +++ b/src/js/stendhal/ui/component/ItemContainerImplementation.ts @@ -21,7 +21,7 @@ import { DropQuantitySelectorDialog } from "../dialog/DropQuantitySelectorDialog import { singletons } from "../../SingletonRepo"; import { htmlImageStore } from "data/HTMLImageStore"; -import { HTMLImageElementUtil } from "sprite/image/HTMLImageElementUtil"; +import { HeldObjectManager } from "ui/HeldObject"; import { HTMLUtil } from "ui/HTMLUtil"; import { TouchHandler } from "ui/TouchHandler"; import { ViewPort } from "ui/ViewPort"; @@ -190,7 +190,7 @@ export class ItemContainerImplementation { const slotNumber = target.id.slice(this.slot.length + this.suffix.length); let item = myobject[this.slot].getByIndex(slotNumber); if (item) { - if (!singletons.getHeldObjectManager().prepare(item, event)) { + if (!HeldObjectManager.get().prepare(item, event)) { return; } @@ -202,12 +202,12 @@ export class ItemContainerImplementation { }; if (event instanceof DragEvent && event.dataTransfer) { - stendhal.ui.heldObject = heldObject; + HeldObjectManager.get().heldObject = heldObject; } else if (this.touchHandler.isTouchEvent(event)) { this.touchHandler.setHolding(true); // TODO: move when supported by mouse events const pos = HTMLUtil.extractPosition(event); - singletons.getHeldObjectManager().set(heldObject, new Point(pos.pageX, pos.pageY)); + HeldObjectManager.get().set(heldObject, new Point(pos.pageX, pos.pageY)); } } else { event.preventDefault(); @@ -218,7 +218,7 @@ export class ItemContainerImplementation { * Handles displaying an icon for objects dragged with touch. */ private onTouchMove(event: TouchEvent) { - if (stendhal.ui.heldObject) { + if (HeldObjectManager.get().heldObject) { return; } this.onDragStart(event); @@ -251,8 +251,9 @@ export class ItemContainerImplementation { } private onDrop(event: DragEvent|TouchEvent) { + let heldObject = HeldObjectManager.get().heldObject; const myobject = this.object || marauroa.me; - if (stendhal.ui.heldObject) { + if (heldObject) { const pos = HTMLUtil.extractPosition(event); const id = (pos.target as HTMLElement).id; const targetSlot = HTMLUtil.parseSlotName(id); @@ -278,20 +279,20 @@ export class ItemContainerImplementation { } const action = { - "source_path": stendhal.ui.heldObject.path + "source_path": heldObject.path } as any; - const sameSlot = stendhal.ui.heldObject.slot === targetSlot; + const sameSlot = heldObject.slot === targetSlot; if (sameSlot) { action["type"] = "reorder"; action["new_position"] = this.parseIndex(id) || "" + (this.size - 1); } else { action["type"] = "equip"; action["target_path"] = "[" + objectId + "\t" + targetSlot + "]"; - action["zone"] = stendhal.ui.heldObject.zone; + action["zone"] = heldObject.zone; } - const quantity = stendhal.ui.heldObject.quantity; - stendhal.ui.heldObject = undefined; + const quantity = heldObject.quantity || 1; + HeldObjectManager.get().heldObject = undefined; // if ctrl is pressed or holding stackable item from touch event, we ask for the quantity const touch_held = this.touchHandler.holding() && quantity > 1; @@ -302,7 +303,7 @@ export class ItemContainerImplementation { new DropQuantitySelectorDialog(action, touch_held), pos.pageX - 50, pos.pageY - 25); } else { - singletons.getHeldObjectManager().onRelease(); + HeldObjectManager.get().onRelease(); marauroa.clientFramework.sendAction(action); } } @@ -381,7 +382,7 @@ export class ItemContainerImplementation { stendhal.ui.actionContextMenu.set(ui.createSingletonFloatingWindow("Action", new ActionContextMenu((event.target as any).dataItem, append), event.pageX - 50, event.pageY - 5)); - } else if (!stendhal.ui.heldObject) { + } else if (!HeldObjectManager.get().heldObject) { if (!stendhal.config.getBoolean("inventory.double-click") || this.isDoubleClick(event)) { marauroa.clientFramework.sendAction({ type: "use", diff --git a/src/js/stendhal/ui/dialog/DropQuantitySelectorDialog.ts b/src/js/stendhal/ui/dialog/DropQuantitySelectorDialog.ts index d0c7bb02f7..b4291550a0 100644 --- a/src/js/stendhal/ui/dialog/DropQuantitySelectorDialog.ts +++ b/src/js/stendhal/ui/dialog/DropQuantitySelectorDialog.ts @@ -9,10 +9,10 @@ * * ***************************************************************************/ -import { marauroa } from "marauroa" +import { marauroa } from "marauroa"; +import { HeldObjectManager } from "ui/HeldObject"; import { Component } from "../toolkit/Component"; -import { singletons } from "../../SingletonRepo"; export class DropQuantitySelectorDialog extends Component { @@ -49,7 +49,7 @@ export class DropQuantitySelectorDialog extends Component { * Drops selected quantity from stack. */ private onDrop(event: Event) { - singletons.getHeldObjectManager().onRelease(); + HeldObjectManager.get().onRelease(); let quantityStr = (this.child(".quantityselectorvalue") as HTMLInputElement).value; let quantity = parseInt(quantityStr); if (quantity > 0) { @@ -64,7 +64,7 @@ export class DropQuantitySelectorDialog extends Component { * Drops entire stack. */ private onDropAll(event: Event) { - singletons.getHeldObjectManager().onRelease(); + HeldObjectManager.get().onRelease(); marauroa.clientFramework.sendAction(this.action); this.componentElement.dispatchEvent(new Event("close")); event.preventDefault();