SelectionCommandInput looses selection when interacting with User Parameters

SelectionCommandInput looses selection when interacting with User Parameters

hawx75
Participant Participant
601 Views
2 Replies
Message 1 of 3

SelectionCommandInput looses selection when interacting with User Parameters

hawx75
Participant
Participant

I am trying to create a command that requires a selection and edits a user param before the command is terminated. When you edit the text box either a user parameter is updated or created, both causing the selection command to loose any selections. Also doExecutePreview doesn't seem to show changes made to user parameters. Below is an example script of what I'm trying to do. 

 

import adsk.core, adsk.fusion, traceback

_app = None
_ui  = None

_handlers = []

class MyCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            inputs = eventArgs.inputs
            cmdInput = eventArgs.input

            if cmdInput.id == "writable_textBox":
                userParams = _app.activeProduct.userParameters
                param = userParams.itemByName('test')

                if param:
                    param.expression = "100 mm" # Doing this causes a selection loss
                else:
                    valueInput = adsk.core.ValueInput.createByString('10')
                    param = userParams.add('test', valueInput, 'mm', '') # Doing this causes a selection loss
                    param.expression = "100 mm" # Doing this causes a selection loss

            cmdInput.parentCommand.doExecutePreview() # This doesn't show changes made to user params
          
        except:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
          
class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            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:
            # Get the command that was created.
            cmd = adsk.core.Command.cast(args.command)

            # Connect to the command destroyed event.
            onDestroy = MyCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

            # Connect to the input changed event.           
            onInputChanged = MyCommandInputChangedHandler()
            cmd.inputChanged.add(onInputChanged)
            _handlers.append(onInputChanged)    

            # Get the CommandInputs collection associated with the command.
            inputs = cmd.commandInputs

            # Create a selection input.
            selectionInput = inputs.addSelectionInput('selection', 'Select', 'Basic select command input')
            selectionInput.setSelectionLimits(0)

            # Create an editable textbox input.
            inputs.addTextBoxCommandInput('writable_textBox', 'Text Box 2', 'Edit this textbox to change user param named test', 2, 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

        # Get the existing command definition or create it if it doesn't already exist.
        cmdDef = _ui.commandDefinitions.itemById('cmdInputs')
        if not cmdDef:
            cmdDef = _ui.commandDefinitions.addButtonDefinition('cmdInputs', 'Command Inputs', '')

        # Connect to the command created event.
        onCommandCreated = MyCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        # Execute the command definition.
        cmdDef.execute()

        # Prevent this module from being terminated when the script returns, because we are waiting for event handlers to fire.
        adsk.autoTerminate(False)
    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
0 Likes
602 Views
2 Replies
Replies (2)
Message 2 of 3

kandennti
Mentor
Mentor

Hi @hawx75 .

 

When I tried, I certainly lost my choice.

 

As a workaround, we have created a global list.
Back up selected items every time a selection occurs and reselect each time a text change is made.

import adsk.core, adsk.fusion, traceback

_app = None
_ui  = None

_handlers = []
_selectionItems = []

class MyCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            inputs = eventArgs.inputs
            cmdInput = eventArgs.input

            global _selectionItems
            si :adsk.core.SelectionCommandInput = inputs.itemById('selection')

            if cmdInput.id == 'selection':
                _selectionItems = [si.selection(idx).entity for idx in range(si.selectionCount)]

            if cmdInput.id == "writable_textBox":
                userParams = _app.activeProduct.userParameters
                param = userParams.itemByName('test')

                if param:s
                    param.expression = "100 mm" # Doing this causes a selection loss
                else:
                    valueInput = adsk.core.ValueInput.createByString('10')
                    param = userParams.add('test', valueInput, 'mm', '') # Doing this causes a selection loss
                    param.expression = "100 mm" # Doing this causes a selection loss

                for ent in _selectionItems:
                    si.addSelection(ent)
cmdInput.parentCommand.doExecutePreview() # This doesn't show changes made to user params except: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

・・・

However, another problem occurred.
Parameter values were added and changed on debugging, but nothing changed when returning to the GUI.

I didn't know the cause.

 

 

0 Likes
Message 3 of 3

hawx75
Participant
Participant

hi @kandennti 

 

Thx for your reply. I moved the code for modifying the user param to executepreviewhandler and now the selection persists and the model shows the change to the user param. 

 

import adsk.core, adsk.fusion, traceback

_app = None
_ui  = None

_handlers = []

class MyCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            inputs = eventArgs.inputs
            cmdInput = eventArgs.input

            if cmdInput.id == "writable_textBox":
                cmdInput.parentCommand.doExecutePreview()
          
        except:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class MyCommandExecutePreviewHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        app = adsk.core.Application.get()
        ui = app.userInterface
        try:
            eventArgs = adsk.core.CommandEventArgs.cast(args)
            inputs = eventArgs.command.commandInputs

            userParams = _app.activeProduct.userParameters
            param = userParams.itemByName('test')

            valueInput = inputs.itemById('writable_textBox')

            if param:
                try:
                    param.expression = valueInput.text
                    valueInput.isValueError = False
                except:
                    valueInput.isValueError = True
            else:
                ui.messageBox("please create an extrusion driven by a user paramter named test")
        except:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
          
class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            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:
            # Get the command that was created.
            cmd = adsk.core.Command.cast(args.command)

            # Connect to the command destroyed event.
            onDestroy = MyCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

            # Connect to the input changed event.           
            onInputChanged = MyCommandInputChangedHandler()
            cmd.inputChanged.add(onInputChanged)
            _handlers.append(onInputChanged)   

            # Connect doExecutePreview Event
            onExecutePreview = MyCommandExecutePreviewHandler()
            cmd.executePreview.add(onExecutePreview)
            _handlers.append(onExecutePreview) 

            # Get the CommandInputs collection associated with the command.
            inputs = cmd.commandInputs

            # Create a selection input.
            selectionInput = inputs.addSelectionInput('selection', 'Select', 'Basic select command input')
            selectionInput.setSelectionLimits(0)

            # Create an editable textbox input.
            inputs.addTextBoxCommandInput('writable_textBox', 'Text Box 2', '100mm', 2, 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

        # Get the existing command definition or create it if it doesn't already exist.
        cmdDef = _ui.commandDefinitions.itemById('cmdInputs')
        if not cmdDef:
            cmdDef = _ui.commandDefinitions.addButtonDefinition('cmdInputs', 'Command Inputs', '')

        # Connect to the command created event.
        onCommandCreated = MyCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        # Execute the command definition.
        cmdDef.execute()

        # Prevent this module from being terminated when the script returns, because we are waiting for event handlers to fire.
        adsk.autoTerminate(False)
    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))