Hi @thomasa88
I wish every software developer care about user experience as much as you do.
I guess there is no high-level solution, but you can use solutions like low-level firing of keyboard events.
I used a platform-dependent solution for Windows from here and it worked. At the end of CommandCreatedEventHandler I called PressKey(VK_TAB) to fire the TAB keydown event. You can use platform-independent solutions like pyautogui.
Here is the sample script:
import adsk.core, adsk.fusion, traceback
import ctypes
from ctypes import wintypes
import time
user32 = ctypes.WinDLL('user32', use_last_error=True)
INPUT_KEYBOARD = 1
KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP = 0x0002
KEYEVENTF_UNICODE = 0x0004
KEYEVENTF_SCANCODE = 0x0008
MAPVK_VK_TO_VSC = 0
# msdn.microsoft.com/en-us/library/dd375731
VK_TAB = 0x09
VK_MENU = 0x12
# C struct definitions
wintypes.ULONG_PTR = wintypes.WPARAM
class MOUSEINPUT(ctypes.Structure):
_fields_ = (("dx", wintypes.LONG),
("dy", wintypes.LONG),
("mouseData", wintypes.DWORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.ULONG_PTR))
class KEYBDINPUT(ctypes.Structure):
_fields_ = (("wVk", wintypes.WORD),
("wScan", wintypes.WORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.ULONG_PTR))
def __init__(self, *args, **kwds):
super(KEYBDINPUT, self).__init__(*args, **kwds)
# some programs use the scan code even if KEYEVENTF_SCANCODE
# isn't set in dwFflags, so attempt to map the correct code.
if not self.dwFlags & KEYEVENTF_UNICODE:
self.wScan = user32.MapVirtualKeyExW(self.wVk,
MAPVK_VK_TO_VSC, 0)
class HARDWAREINPUT(ctypes.Structure):
_fields_ = (("uMsg", wintypes.DWORD),
("wParamL", wintypes.WORD),
("wParamH", wintypes.WORD))
class INPUT(ctypes.Structure):
class _INPUT(ctypes.Union):
_fields_ = (("ki", KEYBDINPUT),
("mi", MOUSEINPUT),
("hi", HARDWAREINPUT))
_anonymous_ = ("_input",)
_fields_ = (("type", wintypes.DWORD),
("_input", _INPUT))
def PressKey(hexKeyCode):
x = INPUT(type=INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=hexKeyCode))
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
_app = None
_ui = None
_done = False
_Executed = True
_handlers = []
class MyCommandExecuteHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
global _done
global _Executed
try:
product = _app.activeProduct
design = adsk.fusion.Design.cast(_app.activeProduct)
occurrences = design.rootComponent.occurrences
_done = True
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
#testDocuments()
adsk.terminate()
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
cmd = adsk.core.Command.cast(args.command)
onExecute = MyCommandExecuteHandler()
cmd.execute.add(onExecute)
_handlers.append(onExecute)
onDestroy = MyCommandDestroyHandler()
cmd.destroy.add(onDestroy)
_handlers.append(onDestroy)
onCommandTerminated = MyCommandTerminatedHandler()
_ui.commandTerminated.add(onCommandTerminated)
_handlers.append(onCommandTerminated)
inputs = cmd.commandInputs
stringInput = inputs.addStringValueInput('stringInput', "String", "")
PressKey(VK_TAB)
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
class MyCommandTerminatedHandler(adsk.core.ApplicationCommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
global _done
global _Executed
try:
#_done = _done + 1
#if _done == 3:
if _done == True and args.terminationReason == adsk.core.CommandTerminationReason.CancelledTerminationReason:
_done = False
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def run(context):
try:
global _app, _ui
_app = adsk.core.Application.get()
_ui = _app.userInterface
cmdDef = _ui.commandDefinitions.itemById('setFocus')
if not cmdDef:
cmdDef = _ui.commandDefinitions.addButtonDefinition('setFocus', 'Set Focus', 'Set Focus')
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()))