Dynamically adding components

Post Reply
poetix
Posts: 54
Joined: Mon Nov 28, 2022 3:26 pm

Dynamically adding components

Post by poetix »

I have some code in the Initialize method that is meant to add a series of output jacks to the module (saves painstakingly dragging them into place in the designer). They only actually appear in the module if another output jack is added separately in the InitializeControls method, otherwise they're invisible (although you can still connect cables to them). This seems like a bug?
London, UK
Developer, Vulpus Labs
Musician, w/trem
User avatar
Aarnville
Posts: 53
Joined: Sat Jun 18, 2022 5:14 pm

Re: Dynamically adding components

Post by Aarnville »

Plenty of people do that. Compare your code to the stuff that is auto-generated in InitialiseControls when you add a jack in the designer.
Or post a code snippet here.
poetix
Posts: 54
Joined: Mon Nov 28, 2022 3:26 pm

Re: Dynamically adding components

Post by poetix »

So here's the function that makes a new jack:

Code: Select all

   private VoltageAudioJack[] jacks;
   
   private VoltageAudioJack makeJack(String displayName, String internalName, int x, int y) {
      var outputJack = new VoltageAudioJack( displayName, internalName, this, JackType.JackType_AudioOutput );
      AddComponent( outputJack );
      outputJack.SetWantsMouseNotifications( false );
      outputJack.SetPosition( x, y );
      outputJack.SetSize( 37, 37 );
      outputJack.SetSkin( "Jack Straight" );
      outputJack.SetVisible(true);
      outputJack.SetEnabled(true);
      outputJack.SetZOrder(2);
      return outputJack;
   }
 
and here it is being called in the Initialize method:

Code: Select all

      jacks = new VoltageAudioJack[16];
      
      for (int i=0; i<16; i++) {
         var radians = (double) i * Math.PI / 2.7;
         var radius = 120 - (i * 6);
         
         int x = 130 + (int) ((double) radius * Math.cos(radians));
         int y= 130 + (int) ((double) radius * Math.sin(radians));
         
         jacks[i] = makeJack("output" + i, "output" + i, x, y);
      }
      
As I said, all of these jacks are invisible unless I also manually added a single jack in the designer, which gets initialised in the InitializeControls() method, e.g.

Code: Select all

void InitializeControls()
{

      outputJack4 = new VoltageAudioJack( "outputJack4", "outputJack4", this, JackType.JackType_AudioOutput );
      AddComponent( outputJack4 );
      outputJack4.SetWantsMouseNotifications( false );
      outputJack4.SetPosition( 19, 173 );
      outputJack4.SetSize( 37, 37 );
      outputJack4.SetSkin( "Jack Straight" );
}
My guess is, most of the time, people dynamically adding components also have at least one that's being created in InitializeControls, so maybe they don't observe the problem?
London, UK
Developer, Vulpus Labs
Musician, w/trem
UrbanCyborg
Posts: 625
Joined: Mon Nov 15, 2021 9:23 pm

Re: Dynamically adding components

Post by UrbanCyborg »

Just a guess, but the designer might be adding an import at the top of the file that's not immediately obvious.

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
User avatar
Aarnville
Posts: 53
Joined: Sat Jun 18, 2022 5:14 pm

Re: Dynamically adding components

Post by Aarnville »

Z-Order is the thing that leaps out there. Double-check them, including those of any background graphics or rectangles you may have.

If that's all good then maybe send a simplified version of your project to CA to see if they can make sense of it. It wouldn't be the first bug in the designer!
ColinP
Posts: 1000
Joined: Mon Aug 03, 2020 7:46 pm

Re: Dynamically adding components

Post by ColinP »

I came across the same problem ages ago. It seems that the graphical resource load isn't triggered by the init code as one would expect.

Often there's at least one jack socket (or more generally any GUI component) that one manually places on the panel so the bug only arises when everything is done programmatically.

If I remember correctly I got around the problem simply by manually placing one instance of each component needed in a corner of the panel and then makng it/them invisible with a call to SetVisible(). This forces the resources to load.

There might be a more elegant solution (perhaps using the Extra Skins property to fool VMD into loading the resources) but life is too short so I moved on.
terrymcg
Posts: 85
Joined: Mon Apr 08, 2019 12:35 am

Re: Dynamically adding components

Post by terrymcg »

ColinP wrote: Sat Dec 24, 2022 12:17 pm There might be a more elegant solution (perhaps using the Extra Skins property to fool VMD into loading the resources) but life is too short so I moved on.
This should do the trick, assuming it works the same way as "Extra Resources".

Before the existence of those two new-ish properties, you needed to include a non-programmatic reference to any skin you wanted to use in the module, leading to various tiny and/or hidden solutions. The two module properties provide a much neater way of letting VM know what 'extra' things you're planning to use.

Cheers,
--
Terry McG
SHARPmodular
Posts: 17
Joined: Mon May 23, 2022 1:54 pm

Re: Dynamically adding components

Post by SHARPmodular »

The skin you use for the dynamically placed objects must be available in the module, either by placing one with that skin or adding it to the extra resources...
if you place one object using the skin you want, you can always set that specific one to invisible and then use your routine to dynamically place the number of objects you do want...
Post Reply

Return to “Module Designer”