こちらの続きなのですが、
俺コマンドを作る3 - C#ATIA
内容的には、あちらのAddinSkeletonを使わずに書いていたこちらの続きです。
俺コマンドを作る1 - C#ATIA
作りかかっているアドインの処理部分は、大体上手く行っているのですが
制御的な部分で詰まりました。
やりたいことはこんな感じです。
コマンドを起動するとチェックボックス(本当はGroupCommandInput)が表示されます。
これをチェックを外し、OK押すと・・・例の如く何もしません。
再度コマンドを起動した時には、前回操作したチェックが外れた状態で
ダイアログが出てきて欲しいんです。
この仕組みが分からなかったんです。
遠回しな表現だと、こちらのトピに近いです。
解決済み: 次の操作も同じ円を描くことができますか? - Autodesk Community
ちょっとこれはボリュームが大きすぎて対処出来そうにないのが本音です。
(コマンドをフックすれば出来そうだけど、出来るのかな?)
恐らく他人には伝わらないと思うのですが書いておきます。自分の為に。
アドインはメモリに駐在しているような感じだけど、コマンド自体は駐在していないっぽく、
CommandDefinitionを保持している状態のToolbarPanelが駐在している。と思う。
コマンドはボタンが押されたタイミングでコマンド自体は作られている気がします。
チェックがOnかOffを保持していたいのですが、どうやらGlobalな変数に入れておいても Globalな変数で大丈夫です・・・。
ダメっぽかったです。
実現出来るものかどうかも分からぬまま、何かサンプルが見当たらないか探したところ
有りました。
アドインの方のギア作るやつです。
これ、コードのボリュームが大きく、吐き気がしてくるのですが
仕方が無いため読みました。で、分かりました。
ひょっとしたら幾つか方法が有りそうなのですが、このギアのアドインの場合は
こんな感じでした。
CAD部分の王様、Designオブジェクトにattributes(属性)プロパティが有ります。
help.autodesk.com
ここは、アドイン開発者が自由に属性を設定出来るうえ、ファイルの保存時にも属性が
保存されます。
ここに上記のチェックの状態を保存しておけば、複数コマンドを実行しても
前回の状態を保つことが出来る事が分かりました。
御興味もなかろうと思いますが、こんな処理です。
#FusionAPI_python addin #Author-kantoku #Description-俺コマンド(アドイン) 状態を保存するサンプル import adsk.core, adsk.fusion, traceback _app = adsk.core.Application.cast(None) _ui = adsk.core.UserInterface.cast(None) _handlers = [] # 俺コマンド情報 _cmdInfo = { 'id' : 'cmdOre', 'name' : '俺コマンド', 'tooltip' : '偉そうにしているが何も出来ない' } # グループコマンドインプット情報 _grpInfo = { 'id' : 'dlgGrp', 'name' : '変更して、良し!', 'value' : True } _grp = adsk.core.GroupCommandInput.cast(None) # 俺コマンドを追加するパネルのID _panelId = 'SolidScriptsAddinsPanel' def run(context): ui = None try: # 色々と使う、ApplicationとuserInterfaceを取得 global _app, _ui _app = adsk.core.Application.get() _ui = _app.userInterface # -- 俺コマンドを作成するためにcommandDefinitionを作るよ -- # 今利用出来る全てのコマンドを取得 cmdDefs :adsk.core.CommandDefinitions = _ui.commandDefinitions # 既に同一のIDの俺コマンドが無いか? 確認してみる global _cmdInfo cmdDef :adsk.core.CommandDefinition = cmdDefs.itemById(_cmdInfo['id']) if cmdDef: # 見つけたら非情にも消し去る(行儀悪いから良い子はしない) cmdDef.deleteMe() # commandDefinitionを作る # http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-04eb6198-72cd-4430-a6a4-8d68a1105b8e cmdDef = cmdDefs.addButtonDefinition( _cmdInfo['id'], _cmdInfo['name'], _cmdInfo['tooltip']) # 俺コマンドはイベントを使って産み出す # もうおまじないレベル # http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-895ee146-8697-4ba0-98e7-4f72b74edb4f global _handlers onCommandCreated = CommandCreatedHandler() cmdDef.commandCreated.add(onCommandCreated) _handlers.append(onCommandCreated) # -- 俺コマンドを呼び出しやすくする為にパネルに登録するから -- # 目的のパネル取得 global _panelId targetpanel :adsk.core.ToolbarPanel = _ui.allToolbarPanels.itemById(_panelId) # パネル内のコントロール取得 # あれはコントロールって呼ぶんだな controls :adsk.core.ToolbarControls = targetpanel.controls # 俺コマンドをパネルに登録 # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1ed0cfb5-2ad4-4285-9eec-484ef19f2729 cmdControl :adsk.core.ToolbarPanel = controls.addCommand(cmdDef) # 俺コマンドを使える状態にするぞ # あくまで登録しているだけで、コントロールが押されるまで待機 cmdControl.isVisible = True cmdControl.isPromoted = True cmdControl.isPromotedByDefault = True except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) # 俺コマンド作成 class CommandCreatedHandler(adsk.core.CommandCreatedEventHandler): def __init__(self): super().__init__() def notify(self, args): try: global _app, _ui, _handlers cmd = adsk.core.Command.cast(args.command) des :adsk.fusion.Design = _app.activeDocument # イベント onExecute = ExecuteHandler() cmd.execute.add(onExecute) _handlers.append(onExecute) # GroupCommandInputを追加 global _grpInfo, _grp inputs = cmd.commandInputs _grp = inputs.addGroupCommandInput(_grpInfo['id'], _grpInfo['name']) _grp.isEnabledCheckBoxDisplayed = True # チェックの有無をコマンドを前回使用した状態にしたい。 # その為、Designのattributes(属性)に残しておいたり、読み込むのがお手本みたい。 # で、探し出す。個人的に、 # 属性グループ名:コマンドID ,属性パラメータ名:コマンドインプットID # と、しておくのが分かりやすいんじゃないかと思っている。 # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-5726553F-6473-4045-A5DC-DC6F712CC751 attr :adsk.core.Attribute = des.attributes.itemByName( cmd.parentCommandDefinition.id, _grp.id) if attr: # 属性発見 _grp.isEnabledCheckBoxChecked = bool(int(attr.value)) else: # 属性見つからん _grp.isEnabledCheckBoxChecked = _grpInfo['value'] except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) # 俺コマンド実行 と言っても何もしない・・・けど # Designのattributes(属性)にダイアログ情報は残したい。 class ExecuteHandler(adsk.core.CommandEventHandler): def __init__(self): super().__init__() def notify(self, args): global _ui try: global _app des :adsk.fusion.Design = _app.activeDocument cmd = adsk.core.Command.cast(args.command) # 属性のvalueは文字のみなのね # bool -> in -> str で保存 面倒 global _grp des.attributes.add( cmd.parentCommandDefinition.id, _grp.id, str(int(_grp.isEnabledCheckBoxChecked)) ) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) # 俺コマンド削除 def stop(context): try: # 全てのパネルを取得 panels :adsk.core.ToolbarPanels = _ui.allToolbarPanels # 俺コマンドの入ったパネル取得 global _panelId panel :adsk.core.ToolbarPanel = panels.itemById(_panelId) # 行儀良く、俺コマンドを削除 global _cmdInfo if panel: panel.controls.itemById(_cmdInfo['id']).deleteMe() # 行儀良く、俺コマンドcmdDefを削除 cmdDefs :adsk.core.CommandDefinitions = _ui.commandDefinitions cmdDef :adsk.core.CommandDefinition = cmdDefs.itemById(_cmdInfo['id']) if cmdDef: cmdDef.deleteMe() # 個人的にゴミを残したくないのでDesignのattributes(属性)も削除 global _app des :adsk.fusion.Design = _app.activeDocument attrs = des.attributes.itemsByGroup(_cmdInfo['id']) [attr.deleteMe() for attr in attrs] except: print('Failed:\n{}'.format(traceback.format_exc()))
アドインを起動するとここに入ります。
このコマンドをチェックを入れたり外したりすると、次回も状態を保って起動します。
参考にしたギアのアドインは、属性を保存しっぱなしですが、
俺コマンドは自然に易しいため、アドイン停止時に属性を削除します。
前回のものはパネルの登録等が異常なほど丁寧な処理をしていましたが、
簡素化しています。他にもイロイロと現実的な状態かな?
間違いなく説明不足なのですが、必要な人もいないだろうと思ってます。
(必要だったらコメントください。1カ月ぐらいは覚えているハズ)