久々にFusion360です。
こちらを答えてみました。
How to create a `BrowserCommandInput` and populate it with initial data from Fusion? - Autodesk Community
"ダイアログを表示する時にBrowserCommandInputに初期値を渡したい”
と言う質問だと受け止めて答えてみました。
BrowserCommandInputはダイアログ上にHTMLを表示させる
コマンドインプットです。
全く使った事が無いのですが、仕組み的には全くパレットと同じです。
コードを見るとCommandCreatedイベント時にやろうとしていますが、
タイミングが違うんですよ。
CommandCreatedイベント時はコマンド自体が出来ておらず、イベント
終了後にコマンドが出来上がります。
その為、初期値の受け渡しの python -> javascript の一連の動きは
pythonでコマンド作成 -> ダイアログ表示 -> javascriptのDOMContentLoadedイベント発火 -> javascript側で"HTML読み込んだよ"と送信 -> pythonのincomingFromHTMLイベント発火 -> pythonで必要な情報を戻り値として送信 -> javascriptで情報を受け取り -> html側に反映
と結構な処理をさせる必要があります。
それともう一つ。BrowserCommandInputで表示させているブラウザは、javascriptは
非同期処理で書かなければなりません。
フォーラムではファイルを添付して中身が見れないので、こちらで
公開しておきます。(こちらはスクリプトです)
まずはエントリーポイントとなる、"BrowserCommandInputInitialDataTest.py"
# Fusion360API Python script import traceback import adsk import adsk.core as core import json _app: core.Application = None _ui: core.UserInterface = None _handlers = [] CMD_INFO = { 'id': 'kantoku_BrowserCommandInputInitialDataTest', 'name': 'test', 'tooltip': 'test' } _browserIpt: core.BrowserCommandInput = None class MyCommandCreatedHandler(core.CommandCreatedEventHandler): def __init__(self): super().__init__() def notify(self, args: core.CommandCreatedEventArgs): try: global _handlers cmd: core.Command = core.Command.cast(args.command) inputs: core.CommandInputs = cmd.commandInputs onDestroy = MyCommandDestroyHandler() cmd.destroy.add(onDestroy) _handlers.append(onDestroy) onHTMLEvent = MyHTMLEventHandler() cmd.incomingFromHTML.add(onHTMLEvent) _handlers.append(onHTMLEvent) global _browserIpt _browserIpt = inputs.addBrowserCommandInput( "_browserIptId", "Active Document Name:", "index.html", 50, ) except: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class MyHTMLEventHandler(core.HTMLEventHandler): def __init__(self): super().__init__() def notify(self, args): try: htmlArgs = core.HTMLEventArgs.cast(args) app: core.Application = core.Application.get() if htmlArgs.action == 'htmlLoaded': args.returnData = json.dumps({ "name": app.activeDocument.name, }) except: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class MyCommandDestroyHandler(core.CommandEventHandler): def __init__(self): super().__init__() def notify(self, args: core.CommandEventArgs): adsk.terminate() def run(context): try: global _app, _ui _app = core.Application.get() _ui = _app.userInterface cmdDef: core.CommandDefinition = _ui.commandDefinitions.itemById( CMD_INFO['id'] ) if not cmdDef: cmdDef = _ui.commandDefinitions.addButtonDefinition( CMD_INFO['id'], CMD_INFO['name'], CMD_INFO['tooltip'] ) global _handlers onCommandCreated = MyCommandCreatedHandler() cmdDef.commandCreated.add(onCommandCreated) _handlers.append(onCommandCreated) cmdDef.execute() adsk.autoTerminate(False) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
続いて、表示されるHTMLファイル(index.html)。
(javascriptもこれに書き込んでます)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <div> <label id="activeDocName">Unknown</label> </div> </body> <script> document.addEventListener("DOMContentLoaded", () => { let adskWaiter = setInterval(() => { if (window.adsk) { clearInterval(adskWaiter); adsk.fusionSendData("htmlLoaded", "").then((ret) => { let data = JSON.parse(ret); let activeDocNameLabel = document.getElementById("activeDocName"); activeDocNameLabel.textContent = data["name"]; }, 100); } }); }); </script> </html>