Page 1 of 1
How to create a custom panel?
Posted: 29 Mar 2018, 09:46
by UE4
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
Re: How to create a custom panel?
Posted: 29 Mar 2018, 15:32
by jsantos
Not sure to be following you here.
Panel inherits from
FrameworkElement, and that class contains the virtual functions
MeasureOverride and
ArrangeOverride.
Re: How to create a custom panel?
Posted: 02 Apr 2018, 08:41
by UE4
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;
}
Re: How to create a custom panel?
Posted: 02 Apr 2018, 11:52
by sfernandez
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).
Re: How to create a custom panel?
Posted: 02 Apr 2018, 15:05
by UE4
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>
Re: How to create a custom panel?
Posted: 02 Apr 2018, 18:44
by sfernandez
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()));
Re: How to create a custom panel?
Posted: 03 Apr 2018, 04:03
by UE4
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.
Re: How to create a custom panel?
Posted: 03 Apr 2018, 08:41
by jsantos
I am marking this as solved.