Skip to main content
DBarranca
Legend
March 7, 2013
Answered

How to update a ScriptUIGraphics object?

  • March 7, 2013
  • 2 replies
  • 3826 views

Hello,

I've been able to use ScriptUIGraphics, but as far as I've seen there's no way to update / change any object, nor it seems possible to call the onDraw() handler but once if it contains either fillPath() or strokePath() - which usually does.

For instance, the following test script pops up a panel with a red square in it. Fine. When you click the "Try" button, the onDraw() is fired again and should draw a smaller square, but stops with a very informative "cannot execute" error at some point within the onDraw():

// ScriptUI graphics update issue

// resource string

var winRes = "dialog {  \

    text: 'ScriptUI Graphics test',  \

    margins: 15, \

    alignChildren: 'row', \

    \

    canvas: Panel {  \

        preferredSize: [200, 200], \

        properties: {borderStyle: 'black'} , \

    }, \

    buttonsGroup: Group{ \

        cancelButton: Button { text: 'Cancel', properties:{name:'cancel'} }, \

        tryButton: Button { text: 'Try', properties:{name:'try'},size: [40,24], alignment:['right', 'center'] }, \

          }, \

}"

// Window

var win = new Window(winRes);

// define the graphic property

canvasGraphics = win.canvas.graphics

// do the drawing

win.canvas.onDraw = function() {

          // creates a red filled square

          canvasGraphics.newPath()

          canvasGraphics.rectPath(10, 10, 200, 200)

          canvasGraphics.fillPath(canvasGraphics.newBrush(canvasGraphics.BrushType.SOLID_COLOR, [1,0,0,1], 1)) // HERE

}

win.buttonsGroup.tryButton.onClick = function() {

          win.canvas.onDraw.call()

}

win.show()

When you run it, it works as expected; if you click the Try button, an error is fired when the script gets to the line ("HERE" in the code), that is: when it comes to fill the path.

Strangely enough! Because it doesn't seem to be a problem with the onDraw second call (apparently the second square path is constructed, but can't be filled).

Am I doing something wrong here? Should I first delete the original square (how?!), or somehow initialize it again? Are ScriptUIGraphics immutable somehow?

--- Update ---

Further experiments led me to understand that onDraw() (so the whole drawing) seem to be called just once - when the Window is shown. I've tried to remove and rebuild the canvas Panel altogether, but its own new onDraw() is never called - nor an explicit call works. Apparently you can't invoke win.show() again, nor hide and show it. Ouch!

--- ---

Thanks in advance for any suggestion

Davide

This topic has been closed for replies.
Correct answer DBarranca

It seems the trick is to switch from a Panel to a Custom component, which allows you something like:

// do the drawing

win.canvas.onDraw = redraw

function redraw() {

          // creates a red filled square

          canvasGraphics.newPath()

          canvasGraphics.rectPath(10, 10, 200, 200)

          canvasGraphics.fillPath(canvasGraphics.newBrush(canvasGraphics.BrushType.SOLID_COLOR, color(), 1)) // HERE

}

win.buttonsGroup.tryButton.onClick = function() {

      win.canvas.notify("onDraw")

}

It now works, but the component respond to all kind of events (mouseover, mouseclick), and I haven't been able so far to use successfully .preventDefault()

2 replies

Inspiring
September 19, 2018

'myObject.notify("onDraw")' is the real take-home lesson here. It evens works on icon buttons.

The docs say that the notify() method of a button accepts only 'one of: onClick, onChange, onChanging'. It says nothing about onDraw, but it works, and is simpler than other solutions I've seen discussed. Absolute gold!

Kukurykus
Legend
September 19, 2018

Read about it in JAVASCRIPT TOOLS GUIDE you access from one before last item in 'Help' menu of ExtendScript ToolKit.

Inspiring
September 19, 2018

Ah yes, so there it is… an obscure (but very helpful) mention on page 164. :-)

DBarranca
DBarrancaAuthorCorrect answer
Legend
March 7, 2013

It seems the trick is to switch from a Panel to a Custom component, which allows you something like:

// do the drawing

win.canvas.onDraw = redraw

function redraw() {

          // creates a red filled square

          canvasGraphics.newPath()

          canvasGraphics.rectPath(10, 10, 200, 200)

          canvasGraphics.fillPath(canvasGraphics.newBrush(canvasGraphics.BrushType.SOLID_COLOR, color(), 1)) // HERE

}

win.buttonsGroup.tryButton.onClick = function() {

      win.canvas.notify("onDraw")

}

It now works, but the component respond to all kind of events (mouseover, mouseclick), and I haven't been able so far to use successfully .preventDefault()

pixxxelschubser
Community Expert
Community Expert
March 8, 2013

Sorry, I do not understand what do you really want (because of my bad english)

Try to change the bg color of the panel in the dialog box by clicking on button? Something like this?

// ScriptUI graphics update issue

// resource string

var winRes = "dialog {  \

    text: 'ScriptUI Graphics test',  \

    margins: 15, \

    alignChildren: 'row', \

    \

    canvas: Panel {  \

        preferredSize: [200, 200], \

        properties: {borderStyle: 'black'} , \

    }, \

    buttonsGroup: Group{ \

        cancelButton: Button { text: 'Cancel', properties:{name:'cancel'} }, \

        tryButton: Button { text: 'Try', properties:{name:'try'},size: [40,24], alignment:['right', 'center'] }, \

          }, \

}"

// Window

var win = new Window(winRes);

// define the graphic property

win.canvas.graphics.backgroundColor = win.canvas.graphics.newBrush (win.canvas.graphics.BrushType.SOLID_COLOR, [1,0,0],1);

win.buttonsGroup.tryButton.onClick = function() { // change the graphic background property by click on Button [try]

win.canvas.graphics.backgroundColor = win.canvas.graphics.newBrush (win.canvas.graphics.BrushType.SOLID_COLOR, [0,0,1],1);

}

win.show()

???

DBarranca
DBarrancaAuthor
Legend
March 8, 2013

Hi pixxxel schubser,

I'm afraid this is not what I meant, possibly I haven't chosen the best example: you can easily change properties, but the problem is that when you draw graphics (ScriptUIPath objects) inside a component (in my case a ScriptUI Panel), you're not allowed to stroke or fill them but once, when the Window is drawn - that is, the .onDraw() function is triggered by the win.show().

Unless - I've discovered - you use a Custom component:

canvas: Panel { ...

// become:

canvas: Custom { ...

this, plus the handler I've written in my second post, actually solves the problem.

Davide