Get component position relative to application window

gui

#1

I have a component with a tiling background pattern.
To properly align the pattern over multiple components, I need to know each component’s position relative to a reference position.
The component’s screen position is not suitable as a reference position, as the pattern would appear to move relative to the top-level component when the application window is moved.

Therefore, the most suitable reference position is the top-left corner of the application window. Is there a simple way to get a component’s position relative to the application window?
My current approach is to call getParentComponent() and sum getBoundsInParent() until reaching a juce::TopLevelWindow component.

int x = 0;
int y = 0;
juce::Component *component = this;
while (component && !dynamic_cast<juce::TopLevelWindow *>(component)) {
	auto bounds = component->getBoundsInParent();
	x += bounds.getX();
	y += bounds.getY();

	component = component->getParentComponent();
}
juce::Point<int> referencePos(x, y);

Is there perhaps a better way to do this?


#2

For the snippet, there is a function called Component::getTopLevelComponent() for that.

And to get a local point relative to the topLevelComponent:

auto pointOnTopLevel = getLocalPoint (getTopLevelComponent(), {x, y});

Hope that helps


#3

Unfortunately, getTopLevelComponent returns the application window itself, I purposely wanted its direct child (the PluginEditor), so that coordinates are relative to 0, 0 of the actual content.

Thanks for your help though, although not directly applicable to my case, such functions were what I was looking for!


#4

I see… well, getTopLevelComponent() finds the top most component, that is directly on the desktop. So that should apply for the AudioProcessorEditor, because it’s parent is not necessarily a JUCE component, so it should be wrapped as OS component.

Anyway, there is also a solution to that: Component::findParentComponentOfClass(), used like that:

auto* editor = findParentComponentOfClass<AudioProcessorEditor>();

#5

Thanks, this worked!

Here’s the code I ended up with (ComponentClass is a template name):

// get the component's position relative to the plugin editor
juce::Point<int> referencePos;
if (auto *editor = ComponentClass::template findParentComponentOfClass<juce::AudioProcessorEditor>()) {
	auto localPoint = ComponentClass::getLocalPoint(editor, juce::Point<int>(0, 0));
	referencePos = {-localPoint.getX(), -localPoint.getY()};
}