el_BA
Topic Author
Posts: 6
Joined: 28 May 2024, 07:15
Location: Melbourne, Australia

custom panel not rendering multiple elements

15 Jan 2026, 05:06

Hey all,
I'm currently implementing a panel that positions elements with equal spacing. I've managed to make a mock control in C# functioning perfectly but trying to bring this across to C++ has the team stumped. It seems to be only rendering the first element for some reason, and no amount of debugging has gotten us anywhere.

Here's the functioning c#:
        protected override Size MeasureOverride(Size availableSize)
        {
            double height = 0;
            double width = 0;

            foreach (UIElement child in InternalChildren)
            {
                if (child == null)
                    continue;

                //get desired width and height of child - infinity to ask it how big it would be if it had unlimited space
                child.Measure(new Size(double.PositiveInfinity, availableSize.Height));

                //gets width of each child and adds them together to get the total val
                width += child.DesiredSize.Width;
                
                //panel height is the tallest child's height
                height = Math.Max(height, child.DesiredSize.Height);
            }
            //returns either the previous calculation OR available size if it comes out as infinity
            return new Size(double.IsInfinity(availableSize.Width) ? width : availableSize.Width, height);
        }
        
        protected override Size ArrangeOverride(Size finalSize)
        {
            int count = InternalChildren.Count; 

            //total needed width of all items - this is already done further up but I didn't realise until now, is fixed in c++
            double totalWidth = InternalChildren.Cast<UIElement>().Sum(c => c.DesiredSize.Width);

            //get remaining space and divide it by item count
            double spacing = count > 1 ? (finalSize.Width - totalWidth) / (count - 1) : 0;

            //positioning var
            double x = 0;

            foreach (UIElement child in InternalChildren)
            {
                child.Arrange(new Rect(x, 0, child.DesiredSize.Width, finalSize.Height));

                //next position is next to previous child, + spacing
                x += child.DesiredSize.Width + spacing;
            } 
            return finalSize;
        }

Here's the c++:
Noesis::Size paJustifyPanel::MeasureOverride(const Noesis::Size& availableSize)
{
	_children = this->GetInternalChildren();
	_childrenCount = _children->Count(); 
	
	_totalWidth = 0.0f;
	_totalHeight = 0.0f;
	
	for (int i = 0; i < _childrenCount; i++)
	{
		//grab child
		Noesis::BaseComponent* base = _children->GetComponent(i);
		Noesis::UIElement* child = Noesis::DynamicCast<Noesis::UIElement*>(base);
		
		if (child == nullptr)
			continue;
			
		child->Measure(Noesis::Size(Noesis::Size::Infinite().width, availableSize.height));
		
		//add child with to total width
		_totalWidth += child->GetDesiredSize().width;
		
		//total height is tallest child
		_totalHeight = paMath::max(_totalHeight, child->GetDesiredSize().height);
	}
 
 	//if available is infinite, return total width, otherwise available
	return Noesis::Size(Noesis::IsInfinity(availableSize.width) ? _totalWidth : availableSize.width, _totalHeight);
}

Noesis::Size paJustifyPanel::ArrangeOverride(const Noesis::Size& finalSize)
{	
	float spacing = _childrenCount > 1 ? (finalSize.width - _totalWidth) / (_childrenCount - 1) : 0;
	float x = 0.f;
	for (int i = 0; i < _childrenCount; i++)
	{
		Noesis::BaseComponent* base = _children->GetComponent(i);
		Noesis::UIElement* child = Noesis::DynamicCast<Noesis::UIElement*>(base);

		child->Arrange(Noesis::Rect(x, 0, child->GetDesiredSize().width, finalSize.height));
		x += child->GetDesiredSize().width + spacing;
	} 

	return finalSize;
} 

And here's the xaml I'm using to test:
<Controls:paJustifyPanel Height="500" Background="Pink">
            <Border Width="700" Height="200" Background="Red" BorderBrush="Cyan" BorderThickness="3"/>
            <Border Width="400" Height="200" Background="Green" BorderBrush="Magenta" BorderThickness="3"/>
            <Border Width="400" Height="200" Background="Blue" BorderBrush="Yellow" BorderThickness="3"/>
        </Controls:paJustifyPanel>
Here's how it appears in blend:
image_2026-01-15_143454285.png
image_2026-01-15_143454285.png (6.35 KiB) Viewed 22913 times
And here is how it appears in game:
image_2026-01-15_143558613.png
image_2026-01-15_143558613.png (11.18 KiB) Viewed 22913 times
And here is the inspector, showing that the other rects are *there*, just not rendering...
noesis inspector.png

Any help would be appreciated, thanks guys!
Last edited by el_BA on 15 Jan 2026, 06:37, edited 1 time in total.
El Perrin, UI Technical Artist @ Big Ant Studios
 
el_BA
Topic Author
Posts: 6
Joined: 28 May 2024, 07:15
Location: Melbourne, Australia

Re: custom panel not rendering multiple elements

15 Jan 2026, 06:36

Figured out the issue - it was this line in our c++:
child->Arrange(Noesis::Rect(x, 0, child->GetDesiredSize().width, finalSize.height));
Which looks the same as our c#:
child.Arrange(new Rect(x, 0, child.DesiredSize.Width, finalSize.Height)); 
However, the rect that we were using in c# uses relative positioning, while the c++ version uses absolute positioning.


The fixes are either:

Adding x to the desired width...
child->Arrange(Noesis::Rect(x, 0, child->GetDesiredSize().width + x, finalSize.height));
Or, the relative position version of Rect, which takes a point and a size.
child->Arrange(Noesis::Rect(Noesis::Point(x, 0), Noesis::Size(child->GetDesiredSize().width, finalSize.height))); 

It's been a long day.


Thanks guys!
El Perrin, UI Technical Artist @ Big Ant Studios
 
User avatar
BA_DeclanRogers
Posts: 6
Joined: 23 Apr 2024, 01:16
Location: Melbourne, Australia
Contact:

Re: custom panel not rendering multiple elements

15 Jan 2026, 06:45

A Very Long Day
Declan Rogers
Lead UI Programmer @ Big Ant Studios
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: custom panel not rendering multiple elements

15 Jan 2026, 11:08

We thought many times to align C++ code with the C# (WPF) version that takes (x, y, Width, Height) but as there is no change in the function signature it will break old customer code for sure. That is why we had to keep it that way.

Who is online

Users browsing this forum: No registered users and 4 guests