creating a custom configuration table?

creating a custom configuration table?

agcglass
Contributor Contributor
705 Views
3 Replies
Message 1 of 4

creating a custom configuration table?

agcglass
Contributor
Contributor

Hello all,

 

I have been playing around with the configuration table recently. It is defiantly a great thing! But for my project it is not the most user friendly. I have been trying to watch and read as much as possible on using the API and create a custom Configure table better suited to my needs. But I have no idea what i am doing and am finding my way through as usual. 

How do you create a text box that can operate your user Parameters? I would also like to know how you can add your components/extrude functions to a check box? Is there any way to add a text box next to the check box to determine the parameters I have set for the pull handle lengths?

 

Below is what I have so far on the code that gets my basic layout and the start of all my hardware lists. 

 

import adsk.core, adsk.fusion
import os
from ...lib import fusion360utils as futil
from ... import config
app = adsk.core.Application.get()
ui = app.userInterface

#Need to bring in the design and user parameters

design = adsk.fusion.Design.cast(app.activeProduct)
userParam = design.userParameters


# TODO *** Specify the command identity information. ***
CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_cmdDialog'
CMD_NAME = 'Hradware Selection'
CMD_Description = 'A Fusion 360 Add-in Command with a dialog'

# Specify that the command will be promoted to the panel.
IS_PROMOTED = True

# TODO *** Define the location where the command button will be created. ***
# This is done by specifying the workspace, the tab, and the panel, and the
# command it will be inserted beside. Not providing the command to position it
# will insert it at the end.
WORKSPACE_ID = 'FusionSolidEnvironment'
PANEL_ID = 'ConfigurePanel'
COMMAND_BESIDE_ID = 'Displayconfigurationpanel'

# Resource location for command icons, here we assume a sub folder in this directory named "resources".
ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '')

# Local list of event handlers used to maintain a reference so
# they are not released and garbage collected.
local_handlers = []

#get the user parameters

door_opening_width = design.userParameters.itemByName('door_opening_width')
door_opening_height = design.userParameters.itemByName('door_opening_height')

# Executed when add-in is run.
def start():
    # Create a command Definition.
    cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER)

    # Define an event handler for the command created event. It will be called when the button is clicked.
    futil.add_handler(cmd_def.commandCreated, command_created)

    # ******** Add a button into the UI so the user can run the command. ********
    # Get the target workspace the button will be created in.
    workspace = ui.workspaces.itemById(WORKSPACE_ID)

    # Get the panel the button will be created in.
    panel = workspace.toolbarPanels.itemById(PANEL_ID)

    # Create the button command control in the UI after the specified existing command.
    control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False)

    # Specify if the command is promoted to the main toolbar.
    control.isPromoted = IS_PROMOTED


# Executed when add-in is stopped.
def stop():
    # Get the various UI elements for this command
    workspace = ui.workspaces.itemById(WORKSPACE_ID)
    panel = workspace.toolbarPanels.itemById(PANEL_ID)
    command_control = panel.controls.itemById(CMD_ID)
    command_definition = ui.commandDefinitions.itemById(CMD_ID)

    # Delete the button command control
    if command_control:
        command_control.deleteMe()

    # Delete the command definition
    if command_definition:
        command_definition.deleteMe()


# Function that is called when a user clicks the corresponding button in the UI.
# This defines the contents of the command dialog and connects to the command related events.
def command_created(args: adsk.core.CommandCreatedEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Created Event')

    inputs = args.command.commandInputs

# TODO Define the dialog for your command by adding different inputs to the command.

#create input for door size

    #inputs.addTextBoxCommandInput('text_box', 'Some Text', 'Enter Some Text', 1, False)

    # Create a value input field and set the default using 1 unit of the default length unit.
    defaultLengthUnits = app.activeProduct.unitsManager.defaultLengthUnits
    default_value = adsk.core.ValueInput.createByString('1')
    #inputs.addValueInput('value_input', 'Some Value', defaultLengthUnits, default_value)

    # create input for door size
    inputs.addTextBoxCommandInput('text_box', 'Door Opening Width', door_opening_width.expression, 1, False)

    inputs.addTextBoxCommandInput('text_box2', 'Door Opening Height', door_opening_height.expression, 1, False)

# list of exit devices to choose from

    group_input = inputs.addGroupCommandInput('group_input', 'Exit Device')
    group_input.isExpanded = False
    children = group_input.children

    bool_value_input = children.addBoolValueInput('bool_value_input', 'Von Duprin 98/99 CVR', True, '', False)
    bool_value_input.tooltip = "Could be either a button or a check box"

    bool_value_input = children.addBoolValueInput('bool_value_input', 'Von Duprin 98/99 Rim', True, '', False)
    bool_value_input.tooltip = "Could be either a button or a check box"

# list of trim options to choose from

    group_input = inputs.addGroupCommandInput('group_input', 'Trim Options')
    group_input.isExpanded = False
    children = group_input.children

    bool_value_input = children.addBoolValueInput('bool_value_input', 'Pull Hnadle', True, '', False)
    bool_value_input.tooltip = "Could be either a button or a check box"

    bool_value_input = children.addBoolValueInput('bool_value_input', '996L', True, '', False)
    bool_value_input.tooltip = "Could be either a button or a check box"

    bool_value_input = children.addBoolValueInput('bool_value_input', 'Rim Cylinder', True, '', False)
    bool_value_input.tooltip = "Could be either a button or a check box"

    bool_value_input = children.addBoolValueInput('bool_value_input', 'Less Trim', True, '', False)
    bool_value_input.tooltip = "Could be either a button or a check box"

# list of hinge options to choose from

    group_input = inputs.addGroupCommandInput('group_input', 'Hinge Options')
    group_input.isExpanded = False
    children = group_input.children

    bool_value_input = children.addBoolValueInput('bool_value_input', 'Butt Hinge', True, '', False)
    bool_value_input.tooltip = "Could be either a button or a check box"

    bool_value_input = children.addBoolValueInput('bool_value_input', 'Standard Pivots', True, '', False)
    bool_value_input.tooltip = "Could be either a button or a check box"

    # TODO Connect to the events that are needed by this command.
    futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers)
    futil.add_handler(args.command.inputChanged, command_input_changed, local_handlers=local_handlers)
    futil.add_handler(args.command.executePreview, command_preview, local_handlers=local_handlers)
    futil.add_handler(args.command.validateInputs, command_validate_input, local_handlers=local_handlers)
    futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers)


# This event handler is called when the user clicks the OK button in the command dialog or
# is immediately called after the created event not command inputs were created for the dialog.
def command_execute(args: adsk.core.CommandEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Execute Event')

    # TODO ******************************** Your code here ********************************

    # Get a reference to your command's inputs.
    inputs = args.command.commandInputs
    text_box: adsk.core.TextBoxCommandInput = inputs.itemById('text_box')
    value_input: adsk.core.ValueCommandInput = inputs.itemById('value_input')

    # Do something interesting
    #text = text_box.text
    #expression = value_input.expression
    #msg = f'Your text: {text}<br>Your value: {expression}'
    #ui.messageBox(msg)

#get and set the user parameters
    door_opening_widthParamNew: adsk.core.TextBoxCommandInput = inputs.itemById('text_box')
   
    door_opening_heightParamNew: adsk.core.TextBoxCommandInput = inputs.itemById('text_box2')

    userParam.itemByName('door_opening_width').expression = door_opening_widthParamNew
    userParam.itemByName('door_opening_height').expression = door_opening_heightParamNew

# This event handler is called when the command needs to compute a new preview in the graphics window.
def command_preview(args: adsk.core.CommandEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Preview Event')
    inputs = args.command.commandInputs


# This event handler is called when the user changes anything in the command dialog
# allowing you to modify values of other inputs based on that change.
def command_input_changed(args: adsk.core.InputChangedEventArgs):
    changed_input = args.input
    inputs = args.inputs

    # General logging for debug.
    futil.log(f'{CMD_NAME} Input Changed Event fired from a change to {changed_input.id}')


# This event handler is called when the user interacts with any of the inputs in the dialog
# which allows you to verify that all of the inputs are valid and enables the OK button.
def command_validate_input(args: adsk.core.ValidateInputsEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Validate Input Event')

    inputs = args.inputs
   
    # Verify the validity of the input values. This controls if the OK button is enabled or not.
    valueInput = inputs.itemById('value_input')
    if valueInput.value >= 0:
        args.areInputsValid = True
    else:
        args.areInputsValid = False
       

# This event handler is called when the command terminates.
def command_destroy(args: adsk.core.CommandEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Destroy Event')

    global local_handlers
    local_handlers = []
0 Likes
706 Views
3 Replies
Replies (3)
Message 2 of 4

BrianEkins
Mentor
Mentor

There currently isn't any API support for the new configuration capabilities. But it sounds like you might have requirements that it doesn't address. The API provides access to all the parameters in a design. You can create a dialog that would display a table where you can display the names of the parameters and allow the user to provide different values. You'll want to look at the TableCommandInput and probably the TextCommandInput and ValueCommandInput. The table command input allows you to organize other command inputs within a table so you have rows and columns of inputs.

 

The table doesn't know it's representing a configuration table, and the inputs don't know they're representing parameters. That's all logic on your side. For example, you would store information that tells you that column 1 is for a certain parameter and display values in the rows of that column using ValueCommandInput objects for the different values that parameter can have. You would save all this information in your own data. I would probably convert it to JSON or XML and save it as an attribute on either the Design or root component. 

 

Anyway, you would end up building your own version of the new configuration capability that won't be as fancy, but it might better provide specifically what you need. It should be possible, but will take some work.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 3 of 4

agcglass
Contributor
Contributor

@BrianEkins this is what I have so far. I have figured out a table that works for what I am after. The only thing I am wanting to add is a text box to the right of the pull handle check box to manipulate the length. As well as be able to turn on or off the extrude feature for each checkbox. 

 

agcglass_0-1696968934193.png

 

0 Likes
Message 4 of 4

BrianEkins
Mentor
Mentor

The only way to get multiple items on one line is to use the TableCommandInput. It would take some experimentation to see if you can get a result that will look good.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes