Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with formattedText in Table

9 REPLIES 9
Reply
Message 1 of 10
ebunn3
216 Views, 9 Replies

Problem with formattedText in Table

Hi,

 

I'm having some difficulty with formattedText in tables.  I am trying to change the alignment from the default 'left' to 'center' when run within the CommandCreatedEventHandler.   The formatting works for everything except the alignment. 

If I put the same formattedText code into the InputChangedEventHandler it works fine.  Problem is the InputChangedEventHandler doesn't fire until the user does something on the form.  Is there a way to get the InputChangedEventHandler to fire at the end of the CommandCreatedEventHandler automatically so I can format my tables when the form opens?

 

PLEASE LOOK AT MESSAGE 4 OF 4 FOR A WORKING EXAMPLE OF THIS PROBLEM.

 

Thanks,

 

Eric

 

 

textAdd = [[['Tk. ('+units+')','h'],
            ['Min Range ('+ss_force+')','h'],
            ['Opt.('+ss_force+')','h'],
            ['Max Range ('+ss_force+')','h']]]
            
            # createTable_withTextAndCtrls(self,id,name,inputs,minRows,maxRows,rowSpace,colSpace,numRows,spacing,textAdd,transparency = False)
            #def createGroup(self,input,id,name,expanded = True,chkbox = False,chkbox_checked= False):
            groupChildInputs1 = self.createGroup(tabChildInputs1,'PerformanceInfoGrp','Performance Information Table (all faces by thickness)',True,False)
            tableH = self.createTable_withTextAndCtrls('table1_H','loadRange_H',groupChildInputs1,1,len(textAdd),1,1,len(textAdd),'1:3:1:3',textAdd,False)

            # #reformat header colors
            inputs.itemById('table1_H_textBox_H00').formattedText = '<div align="center", style="font-size:11px", style="color:black" ><b>' + textAdd[0][0][0] + '</b></div>'
            inputs.itemById('table1_H_textBox_H01').formattedText = '<div align="center", style="font-size:11px" , style="color:#999900" ><b>' + textAdd[0][1][0] + '</b></div>'
            inputs.itemById('table1_H_textBox_H02').formattedText = '<div align="center", style="font-size:11px" , style="color:green" ><b>' + textAdd[0][2][0] + '</b></div>'
            inputs.itemById('table1_H_textBox_H03').formattedText = '<div align="center", style="font-size:11px" , style="color:#FF4A4A" ><b>' + textAdd[0][3][0] + '</b></div>'

 

 

9 REPLIES 9
Message 2 of 10
Jorge_Jaramillo
in reply to: ebunn3

 Hi @ebunn3 ,

 

Please try with a single style attribute like so:

<div style="text-align:center; font-size:11px; color:black"><b>Text</b></div>

Inside the div there shouldn't be commas as attribute separators; and the align attribute is deprecated and text-align should be used instead.

 

Hope this help.

 

Best regards,

Jorge

Message 3 of 10
ebunn3
in reply to: Jorge_Jaramillo

I tried reformatting the formatted text html as suggested and it made no difference.   This appears to be some type of bug with formatted text in tables.   
I’ll put together a simple example and post.   

Message 4 of 10
ebunn3
in reply to: ebunn3

I've put together a test script to illustrate the problem below.  If you run the script you will see the table header has all of it's text left justified.  It is supposed to be centered.  I duplicated the lines of code that are controlling the formatted text for the last column in the header and put it into the InputChangedEventHandler.  If you adjust one of the slidders you will see the text change to centered in the last column.  It appears that the formatting will not work until after the form is opened.  

 

I need to fire the InputChangedEventHandler when the form opens to correct the problem.  

 

Here is the form when it is opened:

ebunn3_0-1658836137371.png

 

Here is the form after one of the sliders is moved:

ebunn3_1-1658836198610.png

 

 

Eric

 

import adsk.core, adsk.fusion, adsk.cam, traceback

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
_handlers = []
_rowNumber = 0


# Event handler for the execute event.
class MyExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            pass
            # _ui.messageBox('Command executed.')
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


# Event handler for the destroy event.
class MyDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        adsk.terminate()
        

# Event handler for the commandCreated event.
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:

            eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
            inputs = adsk.core.CommandInputs.cast(eventArgs.command.commandInputs)
            cmd = adsk.core.Command.cast(args.command)

            #Create table as header
            #create list (nested list for each line in table.  each list item should be another nested list with the last item being
            # a code (ex: 't') to indicate the type of control)
            textAdd = [    [   ['MATERIAL','h'],['DROP HT.','h'],['USER MIN','h'],['USER MAX','h'],['TEST NOT CENTERED','h']    ]    ]
            # createTable_withTextAndCtrls(self,id,name,inputs,minRows,maxRows,rowSpace,colSpace,numRows,spacing,textAdd,transparency = False)
            self.createTable_withTextAndCtrls('table1','name of table',inputs,1,len(textAdd),1,1,len(textAdd),'1:1:1:1:3',textAdd,True)
            # textBox_H00
            # textBox_H01
            # textBox_H02
            # textBox_H03
            # textBox_H04

#REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE 
            t1 = inputs.itemById('textBox_H04')
            t1.formattedText = '<div align="center", style="font-size:11px", style="color:blue" ><b>TEST NOT CENTERED</b></div>'
            print('')
#REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE 

            #SLIDER EXAMPLE
            #create list (nested list for each line in table.  each list item should be another nested list with the last item being
            #addFloatSliderCommandInput(id, name,unitType, min, max, hasTwoSliders) 
            textAdd = [   [['Mat1','t'] , ['12','t'] , ['1.00','t'] , ['3.00','t'] ,   ["",1.00,3.00,True,True,'sl']] ,
            [['Mat1','t'] , ['18','t'] , ['2.00','t'] , ['4.00','t'] ,   ["",2.00,4.00,True,True,'sl']]        ]#slider
            # createTable_withTextAndCtrls(self,id,name,inputs,minRows,maxRows,rowSpace,colSpace,numRows,spacing,textAdd,transparency = False)
            self.createTable_withTextAndCtrls('slidderTable','slidder table',inputs,1,len(textAdd),2,2,len(textAdd),'1:1:1:1:3',textAdd,False)

            # Connect to command execute.
            onExecute = MyExecuteHandler()
            eventArgs.command.execute.add(onExecute)
            _handlers.append(onExecute)
            
            # Connect to the command terminate.
            onDestroy = MyDestroyHandler()
            eventArgs.command.destroy.add(onDestroy)
            _handlers.append(onDestroy)       

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

        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

    def createTable_withTextAndCtrls(self,id,name,inputs,minRows,maxRows,rowSpace,colSpace,numRows,spacing,textAdd,transparency = False):
        """textAdd = [   [   ['Hemp','t'] , ['12','t'] , ['1.00','t'] , ['3.00','t'] ,   
        ['1.00','1.50','3.00','sl']  , (cont for additional rows)  ]    ]   (t = text, sl = slider)"""
        # Create the table.
        #returnValue = commandInputs_var.addTableCommandInput(id, name, numberOfColumns, columnRatio)               
        table = adsk.core.TableCommandInput.cast(inputs.addTableCommandInput(id, name, numRows, spacing))
        table.minimumVisibleRows = minRows
        table.maximumVisibleRows = maxRows
        table.columnSpacing = colSpace
        table.rowSpacing = rowSpace
        if transparency == False:
            table.tablePresentationStyle = adsk.core.TablePresentationStyles.itemBorderTablePresentationStyle
            table.hasGrid = False  
        else:
            table.tablePresentationStyle = adsk.core.TablePresentationStyles.transparentBackgroundTablePresentationStyle
            table.hasGrid = False  
        
        # Create a selection command input and add it to the table.
        ct = 0
        for j in range(0,len(textAdd)):
            for i in range(0,len(textAdd[j])):
                #returnValue = commandInputs_var.addTextBoxCommandInput(id, name, formattedText, numRows, isReadOnly)
                if textAdd[j][i][len( textAdd[j][i] )-1] == 'h':
                    #HEADER
                    text = inputs.addTextBoxCommandInput('textBox_H' + str(j) + str(i), 
                    'textBox H' + str(ct),
                    '<div align="center", style="font-size:10px" , style="color:blue" ><b>' + textAdd[j][i][0] + '</b></div>',
                     1, True)
                    table.addCommandInput(text, j, i, False, False)
                    print(text.id)
                elif textAdd[j][i][len( textAdd[j][i] )-1]  == 'sl':#;print(   textAdd[j][i][len( textAdd[j][i] )-1]    )
                    #SLIDER
                    #addFloatSliderCommandInput(id, name, unitType, min, max, hasTwoSliders)
                    sliderInput = inputs.addFloatSliderCommandInput('sliderFloat{}'.format(j),
                    'Float Slider',
                    str(textAdd[j][i][0]),#unitType
                    float(textAdd[j][i][1]),#Min
                    float(textAdd[j][i][2]),#Max
                    bool(textAdd[j][i][3]))#hasTwoSliders True or False)
                    table.addCommandInput(sliderInput, j, i, 0, 0)
                    if textAdd[j][i][4] == True:  sliderInput.setText(str(textAdd[j][i][1]),str(textAdd[j][i][2]))
                elif textAdd[j][i][len( textAdd[j][i] )-1] == 't':
                    #TEXT BOX
                    text = inputs.addTextBoxCommandInput('textBox' + str(j) + str(i),
                    'textBox ' + str(ct), 
                    '<div align="center", style="font-size:11px" ><b>' + textAdd[j][i][0] + '</b></div>',
                    1,
                    True)
                    table.addCommandInput(text, j, i, False, False)
                elif textAdd[j][i][len( textAdd[j][i] )-1] == 'sp':
                    #SPINNER
                    #addFloatSpinnerCommandInput(id, name, unitType, min, max, spinStep, initialValue)
                    #["",1.00,3.00,.1,1.00,'sp'] 
                    spinnerInput = inputs.addFloatSpinnerCommandInput('spinnerFloat{}'.format(j), 
                    'Float Spinner',
                    str(textAdd[j][i][0]),#unitType
                    float(textAdd[j][i][1]),#Min
                    float(textAdd[j][i][2]),#Max
                    float(textAdd[j][i][3]),#spinStep
                    float(textAdd[j][i][4]))#initialValue
                    table.addCommandInput(spinnerInput, j, i, 0, 0)
                ct+=1

        return table
        
class MyCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            changedInputs = eventArgs.input
            inputs = eventArgs.firingEvent.sender.commandInputs

#REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE 
            t1 = inputs.itemById('textBox_H04')
            t1.formattedText = '<div align="center", style="font-size:11px", style="color:blue" ><b>TEST CENTERED</b></div>'
            print('')
#REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE REFORMATTING TABLE TEXT IN HEADER HERE 
 
        except:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui  = _app.userInterface
        
        # Create a command.
        cmd = _ui.commandDefinitions.itemById('tableTest')
        if cmd:
            cmd.deleteMe()
            
        cmd = _ui.commandDefinitions.addButtonDefinition('tableTest', 'Static Stress Analysis', 'Static Stress Analysis', '')
        
        # Connect to the command create event.
        onCommandCreated = MyCommandCreatedHandler()
        cmd.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        # Execute the command.
        cmd.execute()
        
        # Set this so the script continues to run.
        adsk.autoTerminate(False)

    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

Message 5 of 10
Jorge_Jaramillo
in reply to: ebunn3

Hi @ebunn3 ,

 

I was checking your code, and I couldn't find a way that title get centered the first time it's set-up on CommandCreatedHandler.

 

From the documentation I found this regarding TextBoxCommandInput.formattedText property:

"(...) Formatted text includes any basic html formatting that has been defined (...)" : I wonder what they mean by basic, and it only makes reference to bold, italic, line break and anchor HTML's elements.  It'll nice to know what HTML version the implementation follows.

 

My suggestion about style="text-alig:center;" definitely does NOT work, which mean the implementation is not following the last HTML version.

 

And one think I found is that what you set on the first time under CommandCreatedHandler behaves different of that you set under InputChangedHandler.  The following code:

t1 = inputs.itemById('textBox_H04')
_app.log(f'MyCommandInputChangedHandler() 1. {t1.text=} {t1.formattedText=}')
t1.formattedText = 'TEST'
_app.log(f'MyCommandInputChangedHandler() 2. {t1.text=} {t1.formattedText=}')
t1.formattedText = '<div align="center" style="font-size:10px; font-weight:600; color:#0000ff;">TEST</div>'
_app.log(f'MyCommandInputChangedHandler() 3. {t1.text=} {t1.formattedText=}')

produces the following output:

 MyCommandInputChangedHandler() 1. t1.text='TEST' t1.formattedText='<span style=" font-size:10px; font-weight:600; color:#0000ff;">TEST</span>'
 MyCommandInputChangedHandler() 2. t1.text='TEST' t1.formattedText='<span style=" color:#3c3c3c;">TEST</span>'
 MyCommandInputChangedHandler() 3. t1.text='TEST' t1.formattedText='<span style=" font-size:10px; font-weight:600; color:#0000ff;">TEST</span>'

Look at the formattedText value in the middle which is enclosed inside span elements, when the value set without didn't include them.  And even though first and third messages have the same information, the label is just centered after the latter assignment (same commands, different results). 

 

I hope someone from the Autodesk team could give us some explanation about it.

Sad I couldn't help with the solution at the moment.

 

Regards,

Jorge

Message 6 of 10
kandennti
in reply to: ebunn3

@ebunn3 .

 

If you want to create dialogs with a certain level of design, I have recently felt that the only way is to use BrowserCommandInput.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-6C0C8148-98D0-4DBC-A4EC-D8E03A8A3B5B 

It is definitely more expressive.

 

However, it requires learning html+css+javascript, and I am having a hard time with it.

Message 7 of 10
ebunn3
in reply to: Jorge_Jaramillo

Thanks for the help with this. I appreciate it.

Eric
Message 8 of 10
ebunn3
in reply to: kandennti

Thank you @kandennti..  If I could only figure out how to fire the InputChangedEventHandler when the form first opens I could do all my table formatting in there.  That's the only solution I can think of right now.  Until then I will have to live with everything left justified.

 

Eric

Message 9 of 10
kandennti
in reply to: ebunn3

I came up with a workaround.
Move the slider slightly in the command.activate event, and then undo it so that it appears at the center position.

 

・・・
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
・・・
            onActivate = MyActivateHandler()
            cmd.activate.add(onActivate)
            _handlers.append(onActivate)
・・・


class MyActivateHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args: adsk.core.CommandEventArgs):
        inputs: adsk.core.CommandInputs = args.command.commandInputs

        sliderIpt: adsk.core.FloatSliderCommandInput = inputs.itemById('sliderFloat0')
        if not sliderIpt:
            return

        if sliderIpt.valueOne < sliderIpt.maximumValue + 0.0001:
            backUpValue = sliderIpt.valueOne
            sliderIpt.valueOne += 0.0001
            sliderIpt.valueOne = backUpValue

 

 

I hope the activate event doesn't fire at any other time than the first.

Message 10 of 10
ebunn3
in reply to: kandennti

I’ll try this!  Thanks.  

Eric

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report