Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

addEventListener in a dockable panel

Explorer ,
Dec 08, 2020 Dec 08, 2020

I wrote a question earlier about this and received no response, but without a script example. Now, I have one. Basically, I have a script that I want to display all the current comp's layers in a list item. When the user changes to a new comp, I want the list to repopulate with the active comp's layers. This would require rebuilding the list item when the window gets focus. I've written a script that does this, but here's the rub: if you make it a dockable panel, it doesn't work, until you click the control itself. Here's the code for the NON-dockable window:

 

{
// WIN
// ===
var win = new Window("window"); 
    win.text = "addEventListener Test"; 
    win.orientation = "column"; 
    win.alignChildren = ["center","top"]; 
    win.spacing = 10; 
    win.margins = 16; 

// COL1
// ====
var col1 = win.add("group", undefined, {name: "col1"}); 
    col1.orientation = "row"; 
    col1.alignChildren = ["left","center"]; 
    col1.spacing = 10; 
    col1.margins = 0; 

// LISTBOX_GROUP
// =============
var listbox_group = col1.add("group", undefined, {name: "listbox_group"}); 
    listbox_group.orientation = "row"; 
    listbox_group.alignChildren = ["left","center"]; 
    listbox_group.spacing = 10; 
    listbox_group.margins = 0; 

var listbox1_array = ["Item 1","Item 2"]; 
var listbox1 = listbox_group.add("listbox", undefined, undefined, {name: "listbox1", items: listbox1_array}); 
    listbox1.preferredSize.width = 120; 

// COL2
// ====
var col2 = col1.add("group", undefined, {name: "col2"}); 
    col2.orientation = "column"; 
    col2.alignChildren = ["left","top"]; 
    col2.spacing = 10; 
    col2.margins = 0; 

// GROUP1
// ======
var group1 = col2.add("group", undefined, {name: "group1"}); 
    group1.orientation = "row"; 
    group1.alignChildren = ["left","center"]; 
    group1.spacing = 10; 
    group1.margins = 0; 

var statictext1 = group1.add("statictext", undefined, undefined, {name: "statictext1"}); 
    statictext1.text = "Position"; 

var edittext1 = group1.add('edittext {properties: {name: "edittext1"}}'); 
    edittext1.preferredSize.width = 70; 

// GROUP2
// ======
var group2 = col2.add("group", undefined, {name: "group2"}); 
    group2.orientation = "row"; 
    group2.alignChildren = ["left","center"]; 
    group2.spacing = 10; 
    group2.margins = 0; 

var button2 = group2.add("button", undefined, undefined, {name: "button2"}); 
    button2.text = "OK"; 

    button2.onClick = function() {
        win.close();
    };

listbox1.onChange = function(){

}    

var set_focus = true;
var populate_listbox = function(){
    var myComp = app.project.activeItem;
    var myLayers = myComp.layers;
    var mySelectedLayers = myComp.selectedLayers;
    listbox_group.remove(listbox1);
    for (i=1; i<myComp.numLayers; i++) {
        var tab_name = myLayers[i].index + ". " + myLayers[i].name;
        listbox1_array.push(tab_name);
    }
    listbox1 = listbox_group.add("listbox", undefined, undefined, {name: "listbox1", items: listbox1_array});
    listbox1.preferredSize.width = 120; 
    listbox1_array = []; // clear the array
    //refresh(listbox1);
    set_focus = false;
    win.layout.layout(true); 
    win.layout.resize(); 
}
win.addEventListener ("focus", function(){ 
    if (set_focus == true) { populate_listbox(); }
});

win.addEventListener("blur", function(){
    set_focus = true;
});

win.show();

}

Is there any way to replicate this in a dockable window? 

TOPICS
How to , Scripting , User interface or workspaces
614
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 09, 2020 Dec 09, 2020

I don't think it is possible, since there is no event for this.

A dirty hack is do check say once a second if the comp changed using app.scheduleTask(), but this really affects Ae's performance and therefore you should definitely not do it that way. I think the usual workaround is to offer a refresh button (yes, not ideal UX)

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 13, 2020 Dec 13, 2020

I second what Mathias has said - there's no native way of doing what you want, apart from re-reading AE DOM every couple of seconds, and this approach really bogs down the system and isn't recommended.

The best way is to keep it simple and reload data by clicking on a button in your script.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 13, 2020 Dec 13, 2020

That’s what I figured. The odd thing is, if you make the panel a non-dockable window, it works. Plus, the manual says that focus is an event for the window object, so it must be something specifically to do with the interface that blocks events from dockable windows. At least, that’s my non-expert opinion. 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 14, 2020 Dec 14, 2020
LATEST

I guess technically a panel is not really its own Window and that's why you don't get the event.

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines