为什么我的工具的 ToolController 的 getPriority return 0?

Why does the ToolController's getPriority return 0 for my tool?

根据先前的 , you can implement getPriority for a forge viewer Tool. And according to another 扩展 ToolInterface 不起作用。因此,我不会像这样扩展实现我的工具的 ToolInterface:

class MyCustomExtension extends Autodesk.Viewing.Extension {
    constructor(viewer, options) {
        super(viewer, options);   
        this.theiaUtil = new TheiaUtil(this);     
    }

    getPriority() {
        console.log("Theia#getPriority called! ", (this.getPriority && this.getPriority() || 0)); 
        return 100000;
    }

    ...
}

我的工具的优先级在 ToolController 中返回为 0,尽管它不应该:

function getPriority(tool) 
{
    return tool.getPriority instanceof Function && tool.getPriority() || 0;
}

我不知道为什么这个函数 returns 0 as tool.getPriority instanceof Function returns true if I call MyCustomExtension.getPriority myself.

注意 ToolInterface 是这样实现的:

function ToolInterface()
{
    this.names = [ "unnamed" ];
    this.getNames = function() { return this.names; };
    this.getName = function() { return this.names[0]; };
    this.getPriority = function() { return 0; };
    this.register = function() {};
    this.deregister = function() {};
    this.activate = function(name, viewerApi) {};
    this.deactivate = function(name) {};
    this.update = function(highResTimestamp) { return false; };
    this.handleSingleClick = function( event, button ) { return false; };
    this.handleDoubleClick = function( event, button ) { return false; };
    this.handleSingleTap = function( event ) { return false; };
    this.handleDoubleTap = function( event ) { return false; };
    // ...
}

因此,简单地扩展 ToolInterface class 将不起作用,因为在构造函数中添加到实例的所有这些属性和函数将优先于您的实际 class方法。这也可能是您看到优先级值返回为零的原因 - 当您调用 myTool.getPriority() 时,您实际上并不是在调用 getPriority 方法,而是调用分配给 this.getPriorityToolInterface 的构造函数中。

要解决此问题,我建议明确删除 class' 构造函数中的相应字段(我在 implementing custom Forge Viewer tools 上的博客 post 中对此进行了解释):

class DrawTool extends Autodesk.Viewing.ToolInterface {
    constructor() {
        super();
        this.names = ['box-drawing-tool', 'sphere-drawing-tool'];
 
        // Hack: delete functions defined *on the instance* of the tool.
        // We want the tool controller to call our class methods instead.
        delete this.register;
        delete this.deregister;
        delete this.activate;
        delete this.deactivate;
        delete this.getPriority;
        delete this.handleMouseMove;
        delete this.handleButtonDown;
        delete this.handleButtonUp;
        delete this.handleSingleClick;
    }
 
    register() {
        console.log('DrawTool registered.');
    }
 
    deregister() {
        console.log('DrawTool unregistered.');
    }
 
    activate(name, viewer) {
        console.log('DrawTool activated.');
    }
 
    deactivate(name) {
        console.log('DrawTool deactivated.');
    }
 
    getPriority() {
        return 42; // Or feel free to use any number higher than 0 (which is the priority of all the default viewer tools)
    }

    // ...
}

TL;DR: 在工具栏按钮的按钮单击事件中激活工具而不是扩展的加载方法

class MyExtension extends Autodesk.Viewing.Extension {
    ...
    onToolbarCreated(toolbar) {
        const MyToolName = 'My.Tool.Name'
        let button = new Autodesk.Viewing.UI.Button('my-tool-button');
            button.onClick = (e) => {
            const controller = this.viewer.toolController;
            if (controller.isToolActivated(MyToolName)) {
                controller.deactivateTool(MyToolName);
                button.setState(Autodesk.Viewing.UI.Button.State.INACTIVE);
            } else {
                controller.activateTool(MyToolName);
                button.setState(Autodesk.Viewing.UI.Button.State.ACTIVE);
            }
        };
    }
    ...
}

我在扩展的加载方法中注册后立即激活了该工具。 Petr Broz 在他的博客 post 中的 github 存储库从工具栏中的按钮加载该工具。所以我将该工具的激活移动到对我有用的工具栏中的按钮单击。