Hi there.
SelectionCommandInput is used to create an add-in that appears pre-selected when the dialog is displayed.
I'm having trouble getting it to work the way I want it to, so if you know of a way to get around this, please let me know.
I have created a script to reproduce the behavior.
# Fusion360API Python script
import traceback
import adsk.fusion
import adsk.core
_app: adsk.core.Application = None
_ui: adsk.core.UserInterface = None
_handlers = []
_selIpt: adsk.core.SelectionCommandInput = None
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandCreatedEventArgs):
# adsk.core.Application.get().log(args.firingEvent.name)
try:
global _handlers
cmd: adsk.core.Command = adsk.core.Command.cast(args.command)
inputs: adsk.core.CommandInputs = cmd.commandInputs
onDestroy = MyCommandDestroyHandler()
cmd.destroy.add(onDestroy)
_handlers.append(onDestroy)
onExecute = MyExecuteHandler()
cmd.execute.add(onExecute)
_handlers.append(onExecute)
onActivate = MyActivateHandler()
cmd.activate.add(onActivate)
_handlers.append(onActivate)
global _selIpt
_selIpt = inputs.addSelectionInput(
'selIptId',
'sketch curves',
'select sketch curves'
)
_selIpt.setSelectionLimits(0)
_selIpt.addSelectionFilter(
adsk.core.SelectionCommandInput.SketchCurves
)
# Preselect sketch lines
global _app
des: adsk.fusion.Design = _app.activeProduct
root: adsk.fusion.Component = des.rootComponent
sktLines: adsk.fusion.SketchLines = root.sketches[0].sketchCurves.sketchLines
_selIpt.clearSelection()
_selIpt.addSelection(sktLines[0])
_selIpt.addSelection(sktLines[1])
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
class MyActivateHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandEventArgs):
# adsk.core.Application.get().log(args.firingEvent.name)
# Preselect sketch lines
global _app, _selIpt
des: adsk.fusion.Design = _app.activeProduct
root: adsk.fusion.Component = des.rootComponent
sktLines: adsk.fusion.SketchLines = root.sketches[0].sketchCurves.sketchLines
_selIpt.clearSelection()
_selIpt.addSelection(sktLines[0])
_selIpt.addSelection(sktLines[1])
pass
class MyExecuteHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandEventArgs):
# adsk.core.Application.get().log(args.firingEvent.name)
global _app, _selIpt
selCount = _selIpt.selectionCount
_app.log(f'selectionCount:{selCount}')
for idx in range(selCount):
_app.log(f' {_selIpt.selection(idx).entity.entityToken}')
class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandEventArgs):
# adsk.core.Application.get().log(args.firingEvent.name)
adsk.terminate()
def run(context):
try:
global _app, _ui
_app = adsk.core.Application.get()
_ui = _app.userInterface
initSketchLines()
cmdDef: adsk.core.CommandDefinition = _ui.commandDefinitions.itemById(
'test_cmd'
)
if not cmdDef:
cmdDef = _ui.commandDefinitions.addButtonDefinition(
'test_cmd',
'Test',
'Test'
)
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()))
def initSketchLines():
app: adsk.core.Application = adsk.core.Application.get()
app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
des: adsk.fusion.Design = app.activeProduct
root: adsk.fusion.Component = des.rootComponent
skt: adsk.fusion.Sketch = root.sketches.add(
root.xYConstructionPlane
)
sktLines: adsk.fusion.SketchLines = skt.sketchCurves.sketchLines
P3D = adsk.core.Point3D
points =[
(P3D.create(1,0,0), P3D.create(1,2,0)),
(P3D.create(2,0,0), P3D.create(2,2,0)),
(P3D.create(3,0,0), P3D.create(3,2,0)),
(P3D.create(4,0,0), P3D.create(4,2,0)),
]
for p1, p2 in points:
sktLines.addByTwoPoints(p1, p2)
app.activeViewport.fit()
When I run it, it creates a sketch in a new document and draws 4 straight lines.
When the dialog appears, two of the lines are selected.
I was hoping that if I click on them, which are already selected, they will be deselected. However, the number of selections increases.
Furthermore, when the OK button is pressed in this state, the number of selections and the entityToken of the selected elements are output to the text command window, but duplicate entityTokens are output.
This is an example of the output.
selectionCount:3
/v4BAAAARlJLZXkAH4sIAAAAAAAA/zNQsFAwAEJDBSMgBrOMLIAsQwUTkIiZgsKhrUV5HR7hbUZM/Esmpt0CqjBSMDZTSDVJMjJNNDPUNU00MdY1sUgz000yN7bQTU00tkhKSbU0M7UwBKsFmsGABsD2GSiArTM1NIJYaw5UamCsYAAAqQ064ZIAAAA=
/v4BAAAARlJLZXkAH4sIAAAAAAAA/zNQsFAwAEJDBSMgBrOMLIAsQwUTkIiZgsKhrUV5HR7hbUZM/Esmpt0CqjBSMDZTSDVJMjJNNDPUNU00MdY1sUgz000yN7bQTU00tkhKSbU0M7UwBKsFmsGABsD2GSiArTM1NIJYaw5UamCmYAAAQs/x55IAAAA=
/v4BAAAARlJLZXkAH4sIAAAAAAAA/zNQsFAwAEJDBSMgBrOMLIAsQwUTkIiZgsKhrUV5HR7hbUZM/Esmpt0CqjBSMDZTSDVJMjJNNDPUNU00MdY1sUgz000yN7bQTU00tkhKSbU0M7UwBKsFmsGABsD2GSiArTM1NIJYaw5UamCmYAAAQs/x55IAAAA=
I tried addSelection with the commandCreated and activate events, but they did not work as expected.
Does anyone know a good way to make addSelection deselect a selected element when it is clicked from the selected state and the dialog is displayed?
Please advise.
Solved! Go to Solution.
Solved by kandennti. Go to Solution.
I got the behavior I wanted by using the inputChanged event, so I will share it with you.
The InputChangedHandler checks for elements selected by SelectionCommandInput, deems duplicates as "unselect," and makes them unselectable.
# Fusion360API Python script
import traceback
import adsk.fusion
import adsk.core
_app: adsk.core.Application = None
_ui: adsk.core.UserInterface = None
_handlers = []
_selIpt: adsk.core.SelectionCommandInput = None
class MyInputChangedHandler(adsk.core.InputChangedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.InputChangedEventArgs):
adsk.core.Application.get().log(args.firingEvent.name)
global _selIpt
if args.input != _selIpt:
return
ents = [_selIpt.selection(i).entity for i in range(_selIpt.selectionCount)]
unique = []
[unique.append(x) for x in ents if x not in unique]
if len(ents) == len(unique):
return
singles = [x for x in unique if ents.count(x) == 1]
_selIpt.clearSelection()
[_selIpt.addSelection(x) for x in singles]
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandCreatedEventArgs):
# adsk.core.Application.get().log(args.firingEvent.name)
try:
global _handlers
cmd: adsk.core.Command = adsk.core.Command.cast(args.command)
inputs: adsk.core.CommandInputs = cmd.commandInputs
onDestroy = MyCommandDestroyHandler()
cmd.destroy.add(onDestroy)
_handlers.append(onDestroy)
onExecute = MyExecuteHandler()
cmd.execute.add(onExecute)
_handlers.append(onExecute)
onActivate = MyActivateHandler()
cmd.activate.add(onActivate)
_handlers.append(onActivate)
onInputChanged = MyInputChangedHandler()
cmd.inputChanged.add(onInputChanged)
_handlers.append(onInputChanged)
global _selIpt
_selIpt = inputs.addSelectionInput(
'selIptId',
'sketch curves',
'select sketch curves'
)
_selIpt.setSelectionLimits(0)
_selIpt.addSelectionFilter(
adsk.core.SelectionCommandInput.SketchCurves
)
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
class MyActivateHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandEventArgs):
adsk.core.Application.get().log(args.firingEvent.name)
# Preselect sketch lines
global _app, _selIpt
des: adsk.fusion.Design = _app.activeProduct
root: adsk.fusion.Component = des.rootComponent
sktLines: adsk.fusion.SketchLines = root.sketches[0].sketchCurves.sketchLines
_selIpt.clearSelection()
_selIpt.addSelection(sktLines[0])
_selIpt.addSelection(sktLines[1])
class MyExecuteHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandEventArgs):
# adsk.core.Application.get().log(args.firingEvent.name)
global _app, _selIpt
selCount = _selIpt.selectionCount
_app.log(f'selectionCount:{selCount}')
for idx in range(selCount):
_app.log(f' {_selIpt.selection(idx).entity.entityToken}')
class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandEventArgs):
# adsk.core.Application.get().log(args.firingEvent.name)
adsk.terminate()
def run(context):
try:
global _app, _ui
_app = adsk.core.Application.get()
_ui = _app.userInterface
initSketchLines()
cmdDef: adsk.core.CommandDefinition = _ui.commandDefinitions.itemById(
'test_cmd'
)
if not cmdDef:
cmdDef = _ui.commandDefinitions.addButtonDefinition(
'test_cmd',
'Test',
'Test'
)
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()))
def initSketchLines():
app: adsk.core.Application = adsk.core.Application.get()
app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
des: adsk.fusion.Design = app.activeProduct
root: adsk.fusion.Component = des.rootComponent
skt: adsk.fusion.Sketch = root.sketches.add(
root.xYConstructionPlane
)
sktLines: adsk.fusion.SketchLines = skt.sketchCurves.sketchLines
P3D = adsk.core.Point3D
points =[
(P3D.create(1,0,0), P3D.create(1,2,0)),
(P3D.create(2,0,0), P3D.create(2,2,0)),
(P3D.create(3,0,0), P3D.create(3,2,0)),
(P3D.create(4,0,0), P3D.create(4,2,0)),
]
for p1, p2 in points:
sktLines.addByTwoPoints(p1, p2)
app.activeViewport.fit()
What was a little odd was that using the addSelection method in ActivateHandler would trigger the inputChanged event, but using the addSelection method in inputChanged would not trigger the inputChanged event.
Can't find what you're looking for? Ask the community or share your knowledge.