Immediately override the Ruler after extension to increase interoperability with other modules

This commit is contained in:
Manuel Vögele
2021-12-31 18:01:19 +01:00
parent 76cff06b66
commit c8a7c73ace
2 changed files with 154 additions and 150 deletions
+2 -2
View File
@@ -4,8 +4,8 @@ import {currentSpeedProvider, getColorForDistanceAndToken, getMovedDistanceFromT
import {checkDependencies, getHexSizeSupportTokenGridCenter, highlightMeasurementTerrainRuler} from "./compatibility.js"; import {checkDependencies, getHexSizeSupportTokenGridCenter, highlightMeasurementTerrainRuler} from "./compatibility.js";
import {moveEntities, onMouseMove} from "./foundry_imports.js" import {moveEntities, onMouseMove} from "./foundry_imports.js"
import {performMigrations} from "./migration.js" import {performMigrations} from "./migration.js"
import {DragRulerRuler} from "./ruler.js";
import {getMovementHistory, removeLastHistoryEntryIfAt, resetMovementHistory} from "./movement_tracking.js"; import {getMovementHistory, removeLastHistoryEntryIfAt, resetMovementHistory} from "./movement_tracking.js";
import {extendRuler} from "./ruler.js";
import {registerSettings, settingsKey} from "./settings.js" import {registerSettings, settingsKey} from "./settings.js"
import {recalculate} from "./socket.js"; import {recalculate} from "./socket.js";
import {SpeedProvider} from "./speed_provider.js" import {SpeedProvider} from "./speed_provider.js"
@@ -19,7 +19,7 @@ Hooks.once("init", () => {
hookKeyboardManagerFunctions() hookKeyboardManagerFunctions()
hookLayerFunctions(); hookLayerFunctions();
Ruler = DragRulerRuler; extendRuler();
window.dragRuler = { window.dragRuler = {
getColorForDistanceAndToken, getColorForDistanceAndToken,
+152 -148
View File
@@ -4,171 +4,175 @@ import {getMovementHistory} from "./movement_tracking.js";
import {settingsKey} from "./settings.js"; import {settingsKey} from "./settings.js";
import {getSnapPointForEntity, setSnapParameterOnOptions} from "./util.js"; import {getSnapPointForEntity, setSnapParameterOnOptions} from "./util.js";
export class DragRulerRuler extends Ruler { export function extendRuler() {
// Functions below are overridden versions of functions in Ruler class DragRulerRuler extends Ruler {
constructor(user, {color=null}={}) { // Functions below are overridden versions of functions in Ruler
super(user, {color}); constructor(user, {color=null}={}) {
this.previousWaypoints = []; super(user, {color});
this.previousLabels = this.addChild(new PIXI.Container()); this.previousWaypoints = [];
} this.previousLabels = this.addChild(new PIXI.Container());
clear() {
super.clear();
this.previousWaypoints = [];
this.previousLabels.removeChildren().forEach(c => c.destroy());
this.dragRulerRanges = undefined;
cancelScheduledMeasurement.call(this);
}
async moveToken(event) {
// This function is invoked by left clicking
if (!this.isDragRuler)
return await super.moveToken(event);
let options = {};
setSnapParameterOnOptions(this, options);
if (!game.settings.get(settingsKey, "swapSpacebarRightClick")) {
this.dragRulerAddWaypoint(this.destination, options);
}
else {
this.dragRulerDeleteWaypoint(event, options);
}
}
toJSON() {
const json = super.toJSON();
if (this.draggedEntity) {
const isToken = this.draggedEntity instanceof Token;
json["draggedEntityIsToken"] = isToken;
json["draggedEntity"] = this.draggedEntity.id;
}
return json;
}
update(data) {
// Don't show a GMs drag ruler to non GM players
if (data.draggedEntity && this.user.isGM && !game.user.isGM && !game.settings.get(settingsKey, "showGMRulerToPlayers"))
return;
if (data.draggedEntity) {
if (data.draggedEntityIsToken)
this.draggedEntity = canvas.tokens.get(data.draggedEntity);
else
this.draggedEntity = canvas.templates.get(data.draggedEntity);
} }
super.update(data); clear() {
} super.clear();
this.previousWaypoints = [];
measure(destination, options={}) { this.previousLabels.removeChildren().forEach(c => c.destroy());
if (this.isDragRuler) { this.dragRulerRanges = undefined;
return measure.call(this, destination, options); cancelScheduledMeasurement.call(this);
} }
else {
return super.measure(destination, options); async moveToken(event) {
// This function is invoked by left clicking
if (!this.isDragRuler)
return await super.moveToken(event);
let options = {};
setSnapParameterOnOptions(this, options);
if (!game.settings.get(settingsKey, "swapSpacebarRightClick")) {
this.dragRulerAddWaypoint(this.destination, options);
}
else {
this.dragRulerDeleteWaypoint(event, options);
}
} }
}
_endMeasurement() { toJSON() {
super._endMeasurement(); const json = super.toJSON();
this.draggedEntity = null; if (this.draggedEntity) {
} const isToken = this.draggedEntity instanceof Token;
json["draggedEntityIsToken"] = isToken;
// The functions below aren't present in the orignal Ruler class and are added by Drag Ruler json["draggedEntity"] = this.draggedEntity.id;
dragRulerAddWaypoint(point, options={}) { }
options.snap = options.snap ?? true; return json;
if (options.snap) {
point = getSnapPointForEntity(point.x, point.y, this.draggedEntity);
} }
this.waypoints.push(new PIXI.Point(point.x, point.y));
this.labels.addChild(new PreciseText("", CONFIG.canvasTextStyle));
}
dragRulerAddWaypointHistory(waypoints) { update(data) {
waypoints.forEach(waypoint => waypoint.isPrevious = true); // Don't show a GMs drag ruler to non GM players
this.waypoints = this.waypoints.concat(waypoints); if (data.draggedEntity && this.user.isGM && !game.user.isGM && !game.settings.get(settingsKey, "showGMRulerToPlayers"))
for (const waypoint of waypoints) { return;
if (data.draggedEntity) {
if (data.draggedEntityIsToken)
this.draggedEntity = canvas.tokens.get(data.draggedEntity);
else
this.draggedEntity = canvas.templates.get(data.draggedEntity);
}
super.update(data);
}
measure(destination, options={}) {
if (this.isDragRuler) {
return measure.call(this, destination, options);
}
else {
return super.measure(destination, options);
}
}
_endMeasurement() {
super._endMeasurement();
this.draggedEntity = null;
}
// The functions below aren't present in the orignal Ruler class and are added by Drag Ruler
dragRulerAddWaypoint(point, options={}) {
options.snap = options.snap ?? true;
if (options.snap) {
point = getSnapPointForEntity(point.x, point.y, this.draggedEntity);
}
this.waypoints.push(new PIXI.Point(point.x, point.y));
this.labels.addChild(new PreciseText("", CONFIG.canvasTextStyle)); this.labels.addChild(new PreciseText("", CONFIG.canvasTextStyle));
} }
}
dragRulerClearWaypoints() { dragRulerAddWaypointHistory(waypoints) {
this.waypoints = []; waypoints.forEach(waypoint => waypoint.isPrevious = true);
this.labels.removeChildren().forEach(c => c.destroy()); this.waypoints = this.waypoints.concat(waypoints);
} for (const waypoint of waypoints) {
this.labels.addChild(new PreciseText("", CONFIG.canvasTextStyle));
}
}
dragRulerDeleteWaypoint(event={preventDefault: () => {return}}, options={}) { dragRulerClearWaypoints() {
options.snap = options.snap ?? true; this.waypoints = [];
if (this.waypoints.filter(w => !w.isPrevious).length > 1) { this.labels.removeChildren().forEach(c => c.destroy());
event.preventDefault(); }
const mousePosition = canvas.app.renderer.plugins.interaction.mouse.getLocalPosition(canvas.tokens);
const rulerOffset = this.rulerOffset;
// Options are not passed to _removeWaypoint in vanilla Foundry. dragRulerDeleteWaypoint(event={preventDefault: () => {return}}, options={}) {
// Send them in case other modules have overriden that behavior and accept an options parameter (Toggle Snap to Grid) options.snap = options.snap ?? true;
this._removeWaypoint({x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y}, options); if (this.waypoints.filter(w => !w.isPrevious).length > 1) {
event.preventDefault();
const mousePosition = canvas.app.renderer.plugins.interaction.mouse.getLocalPosition(canvas.tokens);
const rulerOffset = this.rulerOffset;
// Options are not passed to _removeWaypoint in vanilla Foundry.
// Send them in case other modules have overriden that behavior and accept an options parameter (Toggle Snap to Grid)
this._removeWaypoint({x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y}, options);
game.user.broadcastActivity({ruler: this});
}
else {
this.dragRulerAbortDrag(event);
}
}
dragRulerAbortDrag(event={preventDefault: () => {return}}) {
const token = this.draggedEntity;
this._endMeasurement();
// Deactivate the drag workflow in mouse
token.mouseInteractionManager._deactivateDragEvents();
token.mouseInteractionManager.state = token.mouseInteractionManager.states.HOVER;
// This will cancel the current drag operation
// Pass in a fake event that hopefully is enough to allow other modules to function
token._onDragLeftCancel(event);
}
async dragRulerRecalculate(tokenIds) {
if (this._state !== Ruler.STATES.MEASURING)
return;
if (tokenIds && !tokenIds.includes(this.draggedEntity.id))
return;
const waypoints = this.waypoints.filter(waypoint => !waypoint.isPrevious);
this.dragRulerClearWaypoints();
if (game.settings.get(settingsKey, "enableMovementHistory"))
this.dragRulerAddWaypointHistory(getMovementHistory(this.draggedEntity));
for (const waypoint of waypoints) {
this.dragRulerAddWaypoint(waypoint, {snap: false});
}
this.measure(this.destination);
game.user.broadcastActivity({ruler: this}); game.user.broadcastActivity({ruler: this});
} }
else {
this.dragRulerAbortDrag(event); static dragRulerGetRaysFromWaypoints(waypoints, destination) {
if ( destination )
waypoints = waypoints.concat([destination]);
return waypoints.slice(1).map((wp, i) => {
const ray = new Ray(waypoints[i], wp);
ray.isPrevious = Boolean(waypoints[i].isPrevious);
return ray;
});
} }
}
dragRulerAbortDrag(event={preventDefault: () => {return}}) { dragRulerGetColorForDistance(distance) {
const token = this.draggedEntity; if (!this.isDragRuler)
this._endMeasurement();
// Deactivate the drag workflow in mouse
token.mouseInteractionManager._deactivateDragEvents();
token.mouseInteractionManager.state = token.mouseInteractionManager.states.HOVER;
// This will cancel the current drag operation
// Pass in a fake event that hopefully is enough to allow other modules to function
token._onDragLeftCancel(event);
}
async dragRulerRecalculate(tokenIds) {
if (this._state !== Ruler.STATES.MEASURING)
return;
if (tokenIds && !tokenIds.includes(this.draggedEntity.id))
return;
const waypoints = this.waypoints.filter(waypoint => !waypoint.isPrevious);
this.dragRulerClearWaypoints();
if (game.settings.get(settingsKey, "enableMovementHistory"))
this.dragRulerAddWaypointHistory(getMovementHistory(this.draggedEntity));
for (const waypoint of waypoints) {
this.dragRulerAddWaypoint(waypoint, {snap: false});
}
this.measure(this.destination);
game.user.broadcastActivity({ruler: this});
}
static dragRulerGetRaysFromWaypoints(waypoints, destination) {
if ( destination )
waypoints = waypoints.concat([destination]);
return waypoints.slice(1).map((wp, i) => {
const ray = new Ray(waypoints[i], wp);
ray.isPrevious = Boolean(waypoints[i].isPrevious);
return ray;
});
}
dragRulerGetColorForDistance(distance) {
if (!this.isDragRuler)
return this.color;
if (!this.draggedEntity.actor) {
return this.color;
}
// Don't apply colors if the current user doesn't have at least observer permissions
if (this.draggedEntity.actor.permission < 2) {
// If this is a pc and alwaysShowSpeedForPCs is enabled we show the color anyway
if (!(this.draggedEntity.actor.data.type === "character" && game.settings.get(settingsKey, "alwaysShowSpeedForPCs")))
return this.color; return this.color;
if (!this.draggedEntity.actor) {
return this.color;
}
// Don't apply colors if the current user doesn't have at least observer permissions
if (this.draggedEntity.actor.permission < 2) {
// If this is a pc and alwaysShowSpeedForPCs is enabled we show the color anyway
if (!(this.draggedEntity.actor.data.type === "character" && game.settings.get(settingsKey, "alwaysShowSpeedForPCs")))
return this.color;
}
distance = Math.round(distance * 100) / 100;
if (!this.dragRulerRanges)
this.dragRulerRanges = getRangesFromSpeedProvider(this.draggedEntity);
return getColorForDistanceAndToken(distance, this.draggedEntity, this.dragRulerRanges) ?? this.color;
} }
distance = Math.round(distance * 100) / 100;
if (!this.dragRulerRanges)
this.dragRulerRanges = getRangesFromSpeedProvider(this.draggedEntity);
return getColorForDistanceAndToken(distance, this.draggedEntity, this.dragRulerRanges) ?? this.color;
} }
Ruler = DragRulerRuler;
} }