Copy link to clipboard
Copied
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
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,
...Copy link to clipboard
Copied
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()
Copy link to clipboard
Copied
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()
???
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
Could you post final code, as when I replace wrong part in your original one to that you marked as correct it doesn't work.
Copy link to clipboard
Copied
Hi,
I am wondering if a workaround has been found to counter this "bug" ?
Copy link to clipboard
Copied
Finally, I was able to write code that works in this particular case.
Here it's :
#target photoshop
function color () { return [(Math.random()),Math.random(),Math.random()] }
// ScriptUI graphics update issue
// resource string
var winRes = "dialog { \
text: 'ScriptUI Graphics test', \
margins: 15, \
alignChildren: 'row', \
\
canvas: Custom { \
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'] }, \
aSlider: Slider { properties: {minvalue: -50, maxvalue: 50, value: 50}}, \
}, \
}"
// Window
var win = new Window(winRes);
var theColor;
var rColor;
var theNewColor;
// define the graphic property
canvasGraphics = win.canvas.graphics;
// do the drawing
/////////////////////////////////////////////////////////////////////////////////////////////
win.buttonsGroup.tryButton.addEventListener ('click', function (e){
rColor = color();
return rColor, win.canvas.notify("onDraw")
});
//////////////////////////////////////////////////////////////////////////////////////////////
win.buttonsGroup.aSlider.addEventListener ('change', function (m){
rColor = color();
return rColor, win.canvas.notify("onDraw")
});
//////////////////////////////////////////////////////////////////////////////////////////////
win.canvas.onDraw = redraw;
function redraw(event) {
with ( this ) {
canvasGraphics.drawOSControl();
canvasGraphics.newPath();
canvasGraphics.rectPath(10, 10, 200, 200);
//
if ( event.mouseOver ) {
if ( rColor == undefined ) canvasGraphics.fillPath(canvasGraphics.newBrush(canvasGraphics.BrushType.SOLID_COLOR, theColor, 1))
else canvasGraphics.fillPath(canvasGraphics.newBrush(canvasGraphics.BrushType.SOLID_COLOR,rColor , 1))
} else {
theColor=color();
if ( theNewColor == undefined ) theNewColor = theColor, canvasGraphics.fillPath(canvasGraphics.newBrush(canvasGraphics.BrushType.SOLID_COLOR, theColor, 1));
if ( rColor == undefined && theNewColor !== undefined) rColor= color(), canvasGraphics.fillPath(canvasGraphics.newBrush(canvasGraphics.BrushType.SOLID_COLOR, rColor , 1));
if ( rColor !== undefined && theNewColor !== undefined) canvasGraphics.fillPath(canvasGraphics.newBrush(canvasGraphics.BrushType.SOLID_COLOR, rColor, 1));
}
}
return theColor, rColor ,theNewColor;
}
//////////////////////////////////////////////////////////////////////////////////////////////
win.show();
I don't know if another coding approach in order to resolve the problem exists. Would be happy to know.
Copy link to clipboard
Copied
'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!
Copy link to clipboard
Copied
Read about it in JAVASCRIPT TOOLS GUIDE you access from one before last item in 'Help' menu of ExtendScript ToolKit.
Copy link to clipboard
Copied
Ah yes, so there it is… an obscure (but very helpful) mention on page 164. 🙂