Component::repaint()


#1

I have trouble with a component not being repainted. Let me explain the situation:

I have a main application that loads plugins as dynamic libraries. These plugins create a guy (a “Component”) and pass a pointer to it to the main application. The main application calls addAndMakeVisible at some point, to add these plugin-guis to its own gui.

Now, when I call repaint() inside the plugin-gui (code inside the dynamic library), it is not repainted until I call repaint() in the main application. My idea is, that repaint() relies on some static classes which are not shared between the library and the main application, but I can’t figure out how to solve this.

What can I do here?
StrangeMan


#2

I scrolled through the code involved with the repaint() call and did not find anything that could fail at the border of an application and a shared library - except a call done in NSViewComponentPeer::repaint() at the following line:

void AsyncRepaintMessage::messageCallback() { if (ComponentPeer::isValidPeer (peer)) peer->repaint (rect); }

The static ComponentPeer::isValidPeer(…) might not be shared between the library and the main application. Therefore, if code from the library calls repaint() at some point and gets its ComponentPeer via getPeer(), it will get a peer that was registered by the main application. A call to ComponentPeer::isValidPeer(…) will return false, because this peer is registered in the context of the main application but not in the context of the library. This is the point, where it fails.
(I hope my explanation was clear and correct, otherwise please tell me!).

So the only option for me is to synchronize static Array <ComponentPeer*> heavyweightPeers;(defined in juce_ComponentPeer.cpp) between the library and the main application, isn’t it?

How can I do that without changing JUCE-Code?

Thanks for replies!
StrangeMan


#3

I’m afraid that’s only the first of many, many horrible problems that you’ll hit when you try passing C++ objects between DLLs.


#4

I tried to avoid passing objects as much as possible, but I see no other way to display a plugins gui than passing “Component”-objects between dlls. I’m not the only one, who tries to write plugins… Can you give me a keyword to search for? Google was not very helpful for me so far…


#5

Nobody builds APIs using C++, it’ll never work. The way all plugins are done is by passing some kind of OS window handle that the plugin adds its window to.


#6

Well, that sounds promising.

I took a look at different JUCE classes, and it seems like I could generally stick any Component to a native OS handle using Component::addToDesktop (or TopLevelWindow::addToDesktop, …). Is there a juce class inherited from Component that will “create” such a handle and display it’s content inside itself? NSView looks promising for the mac, but i have not found anything for windows yet.

Well, I’ll try to find out more myself, but please correct me if anything of the above is wrong!


#7

Have a look at the way the audio plugin host works for some tips and tricks.


#8

Hi Jules (and community),

First of all: Thanks for your hints! I completely rewrote the plugin-part of my application and now it feels much better!

Now back to the GUI stuff: I spent several hours scrolling through the code of the plugin host demo and always ended up in the JuceVSTPluginFormat.cpp/.h files. All the window magic is done there, but unfortunately that does not help me much, because I don’t want to open the plugins GUI inside a new window - I’d like to attach it to a component inside my applications window. Now that I start to understand the tricks and concepts a bit better I wonder if it is even possible to do that?!


#9

Hallo again,

I spent a lot go time reading and searching but it seems like the only way to add a GUI to a shared library is to create a new window. That would completely destroy my applications concept. Is there no way to attach a plugins GUI to an area (or Component class) of an existing window?

Thank you,
StrangeMan