UE4
Topic Author
Posts: 62
Joined: 29 Dec 2017, 06:32

How to create a custom panel?

29 Mar 2018, 09:46

Hi,
I want to create a custom panel, like this:
//WPF
class RadialPanel : Panel
	{
		protected override Size MeasureOverride(Size availableSize)
		{
            foreach(UIElement elem in Children)
			{
				elem.Measure(new Size(float.PositiveInfinity, float.PositiveInfinity));
			}


			return base.MeasureOverride(availableSize);
		}

		protected override Size ArrangeOverride(Size finalSize)
		{
            if(Children.Count == 0)
			{
				return finalSize;
			}

			double Angle = 0;

			double AngularSpace = (360.0 / Children.Count) * (Math.PI / 180);
			double radiusX = finalSize.Width / 2.4;
			double radiusY = finalSize.Height / 2.4;


            foreach(UIElement elem in Children)
			{
				Point childPosition = new Point(Math.Cos(Angle) * radiusX, -Math.Sin(Angle) * radiusY);

				Point ActualPoint = new Point(finalSize.Width * 0.5 + childPosition.X - elem.DesiredSize.Width * 0.5, finalSize.Height * 0.5 + childPosition.Y - elem.DesiredSize.Height * 0.5);

				elem.Arrange(new Rect(ActualPoint.X, ActualPoint.Y, elem.DesiredSize.Width, elem.DesiredSize.Height));

				Angle += AngularSpace;
			}

			return finalSize;
			//return base.ArrangeOverride(finalSize);
		}

        
	}

then I find nothing to override in Noesis::Panel
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: How to create a custom panel?

29 Mar 2018, 15:32

Not sure to be following you here. Panel inherits from FrameworkElement, and that class contains the virtual functions MeasureOverride and ArrangeOverride.
 
UE4
Topic Author
Posts: 62
Joined: 29 Dec 2017, 06:32

Re: How to create a custom panel?

02 Apr 2018, 08:41

Not sure to be following you here. Panel inherits from FrameworkElement, and that class contains the virtual functions MeasureOverride and ArrangeOverride.
Hi,
I override the 2 functions in c++, it works for normal way, but does not show Items if I set it as the PanelTemplate of the ListBox

Size RadialPanel::MeasureOverride(const Size& availableSize)
{
	for (int i = 0; i < GetChildren()->Count(); ++i)
	{
		UIElement* elem = (UIElement*)(GetChildren()->Get(i));
		if (elem != nullptr)
		{
			elem->Measure(Size::Infinite());
		}
	}

	return Panel::MeasureOverride(availableSize);
}

Size RadialPanel::ArrangeOverride(const Size& finalSize)
{
	if (GetChildren()->Count() == 0)
	{
		return finalSize;
	}

	float Angle = 0;

	float AngularSpace = (360.f / GetChildren()->Count()) * DegToRad;
	float radiusX = finalSize.width / 2.4f;
	float radiusY = finalSize.height / 2.4;

	for (int i = 0; i < GetChildren()->Count(); ++i)
	{
		UIElement* elem = (UIElement*)(GetChildren()->Get(i));
		if (elem != nullptr)
		{
			Point ChildPosition(Cos(Angle) * radiusX, -Sin(Angle) * radiusY);
			Point ActualPoint(finalSize.width * 0.5f + ChildPosition.x - elem->GetDesiredSize().width * 0.5f,
				finalSize.height * 0.5f + ChildPosition.y - elem->GetDesiredSize().height * 0.5f);
			elem->Arrange(Rect(ActualPoint.x, ActualPoint.y, elem->GetDesiredSize().width, elem->GetDesiredSize().height));

			Angle += AngularSpace;
		}
	}

	return finalSize;
}

 
User avatar
sfernandez
Site Admin
Posts: 1912
Joined: 22 Dec 2011, 19:20

Re: How to create a custom panel?

02 Apr 2018, 11:52

In MeasureOverride your panel should return the minimal size it requires to show all its children inside the available space.
If you return base class MeasureOverride it will return a size of 0x0, which can lead to receiving a 0x0 size in ArrangeOverride, for example if panel is centered, in a Viewbox, or inside a ScrollViewer (as it occurs when it is used as ItemsPanel of a ListBox).
 
UE4
Topic Author
Posts: 62
Joined: 29 Dec 2017, 06:32

Re: How to create a custom panel?

02 Apr 2018, 15:05

In MeasureOverride your panel should return the minimal size it requires to show all its children inside the available space.
If you return base class MeasureOverride it will return a size of 0x0, which can lead to receiving a 0x0 size in ArrangeOverride, for example if panel is centered, in a Viewbox, or inside a ScrollViewer (as it occurs when it is used as ItemsPanel of a ListBox).
Hi,
I set the custom panel size to 200*200, and I can seee the background is right size. In debug, the ArrangeOverride param is 200 * 200 too.
 <ItemsControl ItemsSource="{Binding SpellTargetList}"      
                    Visibility="{Binding bShowSpellTargetPanel, Converter={StaticResource BoolToVisible}, FallbackValue=Visible}" Canvas.Left="300" Canvas.Top="310" Foreground="#FF917A7A" Background="#FFF7E6AB">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <local:RadialPanel Width="200" Height="200" Background="#FFFDCECE"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>

                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Button Content="{Binding DisplayName}"
                                    Command="{Binding DataContext.SelectSpellTarget, ElementName=SpellPanelControl}"
                                    CommandParameter="{Binding UniqueID}"
                                    Background="#FF7C7C7C" Margin="3" FontFamily="{StaticResource Font_KaiTi}" Foreground="#FF27B7FB" FontSize="18" Width="50" Height="50"></Button>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

 
User avatar
sfernandez
Site Admin
Posts: 1912
Joined: 22 Dec 2011, 19:20

Re: How to create a custom panel?

02 Apr 2018, 18:44

I found in your ArrangeOverride code this:
elem->Arrange(Rect(ActualPoint.x, ActualPoint.y, elem->GetDesiredSize().width, elem->GetDesiredSize().height));
Our C++ Rect constructor taking 4 floats expects (left, top, right, bottom), different from WPF C# Rect constructor, sorry for that.

You can write the following instead:
elem->Arrange(Rect(ActualPoint, elem->GetDesiredSize()));
 
UE4
Topic Author
Posts: 62
Joined: 29 Dec 2017, 06:32

Re: How to create a custom panel?

03 Apr 2018, 04:03

I found in your ArrangeOverride code this:
elem->Arrange(Rect(ActualPoint.x, ActualPoint.y, elem->GetDesiredSize().width, elem->GetDesiredSize().height));
Our C++ Rect constructor taking 4 floats expects (left, top, right, bottom), different from WPF C# Rect constructor, sorry for that.

You can write the following instead:
elem->Arrange(Rect(ActualPoint, elem->GetDesiredSize()));
Thank you.
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: How to create a custom panel?

03 Apr 2018, 08:41

I am marking this as solved.

Who is online

Users browsing this forum: Google [Bot] and 1 guest