Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update a preview version of ConstraintLayout.Maui #4

Merged
merged 3 commits into from
May 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![NuGet version(SharpConstraintLayout.Core)](https://img.shields.io/nuget/v/SharpConstraintLayout.Core?label=SharpConstraintLayout.Core)](https://www.nuget.org/packages/SharpConstraintLayout.Core/)
[![NuGet version(SharpConstraintLayout.Maui.Native)](https://img.shields.io/nuget/v/SharpConstraintLayout.Maui.Native?label=SharpConstraintLayout.Maui.Native)](https://www.nuget.org/packages/SharpConstraintLayout.Maui.Native/)

[![NuGet version(SharpConstraintLayout.Maui)](https://img.shields.io/nuget/v/SharpConstraintLayout.Maui?label=SharpConstraintLayout.Maui)](https://www.nuget.org/packages/SharpConstraintLayout.Maui/)
This is a C# port of [ConstraintLayout](https://github.com/androidx/constraintlayout), it convert [constraintlayout.core](https://github.com/androidx/constraintlayout/tree/main/constraintlayout/core) and create ConstraintLayout for WPF. Now, you can use ConstraintLayout in C# world 🎆

## Using ConstraintLayout
Expand Down
37 changes: 31 additions & 6 deletions SharpConstraintLayout.Maui.Example/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
namespace SharpConstraintLayout.Maui.Example;
using ReloadPreview;
using SharpConstraintLayout.Maui.DebugTool;

namespace SharpConstraintLayout.Maui.Example;

public partial class App : Application
{
public App()
{
InitializeComponent();
public App()
{
InitializeComponent();

MainPage = new AppShell();

#if DEBUG
HotReload.Instance.Reload += () =>
{
try
{
this.Dispatcher.Dispatch(() =>
{
var view = HotReload.Instance.ReloadClass<AppShell>() as Page;
MainPage = view;
SimpleDebug.WriteLine($"HotReload:{view} " + view.GetHashCode());
});

}
catch (Exception ex)
{
SimpleDebug.WriteLine(ex.ToString());
}

MainPage = new AppShell();
}
};
HotReload.Instance.Init("192.168.0.144", 100);
#endif
}
}
8 changes: 5 additions & 3 deletions SharpConstraintLayout.Maui.Example/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using SharpConstraintLayout.Maui.Widget;
using static SharpConstraintLayout.Maui.Widget.FluentConstraintSet;
using SharpConstraintLayout.Maui.Helper.Widget;
using SharpConstraintLayout.Maui.DebugTool;

namespace SharpConstraintLayout.Maui.Example
{
Expand Down Expand Up @@ -60,7 +61,7 @@ void CircleConstraintTest(ConstraintLayout page)
layoutSet.Clone(layout);
layoutSet.Select(FirstButton).CenterTo()
.Select(SecondButton, FouthTextBlock)
.CircleTo(FirstButton, new[] { 50, 100 }, new[] { 60f, 240 });
.CircleTo(FirstButton, new[] { 100, 100 }, new[] { 60f, 240 });
layoutSet.ApplyTo(layout);
}

Expand All @@ -73,9 +74,9 @@ void CircleConstraintTest(ConstraintLayout page)
UIThread.Invoke(() =>
{
//The distance between SecondButton center and FirstButton center should equal to 50
SimpleTest.AreEqual(Math.Abs(SecondButton.GetBounds().Center.Y - FirstButton.GetBounds().Center.Y) * 2, 50, nameof(CircleConstraintTest), "The distence between SecondButton center and FirstButton center should equal to 50");
SimpleTest.AreEqual(Math.Abs(SecondButton.GetBounds().Center.Y - FirstButton.GetBounds().Center.Y) * 2, 100, nameof(CircleConstraintTest), "The distence between SecondButton center and FirstButton center should equal to 100");
//The distance between FouthTextBlock center and FirstButton center should equal to 50
SimpleTest.AreEqual(Math.Abs(FouthTextBlock.GetBounds().Center.Y - FirstButton.GetBounds().Center.Y) * 2, 50, nameof(CircleConstraintTest), "The distence between FouthTextBlock center and FirstButton center should equal to 50");
SimpleTest.AreEqual(Math.Abs(FouthTextBlock.GetBounds().Center.Y - FirstButton.GetBounds().Center.Y) * 2, 100, nameof(CircleConstraintTest), "The distence between FouthTextBlock center and FirstButton center should equal to 100");
}, page);

index++;
Expand Down Expand Up @@ -347,6 +348,7 @@ private void GuidelineTest(ConstraintLayout page)
await Task.Delay(3000);//wait ui show
UIThread.Invoke(() =>
{
SimpleDebug.WriteLine($"{page} position={page.GetBounds()}");
SimpleTest.AreEqual(page.GetSize().Width / 2, layout.GetBounds().X, nameof(GuidelineTest), "Horiable guideline should at center");
}, page);
});
Expand Down
24 changes: 17 additions & 7 deletions SharpConstraintLayout.Maui.Example/MainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Microsoft.Maui.Controls.Shapes;
using SharpConstraintLayout.Maui.DebugTool;
using SharpConstraintLayout.Maui.Widget;
using static SharpConstraintLayout.Maui.Widget.FluentConstraintSet;

namespace SharpConstraintLayout.Maui.Example;

Expand All @@ -18,15 +20,20 @@ public MainPage()
{
InitializeComponent();

ConstraintLayout.DEBUG = true;
//ConstraintLayout.DEBUG = true;
ConstraintLayout.MEASURE_MEASURELAYOUT = true;
var content = new ConstraintLayout();
var content = new ConstraintLayout()
{
ConstrainPaddingTop = 10,
ConstrainPaddingBottom = 10,
ConstrainPaddingLeft = 10,
ConstrainPaddingRight = 10,
Background = new SolidColorBrush(Colors.HotPink),
};
Page.Content = content;
createControls();
this.Background = new SolidColorBrush(Colors.HotPink);

//BaseAlignTest(content);
//BaselineTest(content);
//BaselineTest(content);
//GuidelineTest(content);
BarrierTest(content);
//VisibilityTest(content);
Expand All @@ -35,7 +42,6 @@ public MainPage()
//CircleConstraintTest(content);
//PlatformLayoutInConstraintLayoutTest(content);
//FlowPerformanceTest(content);

}

private void createControls()
Expand Down Expand Up @@ -68,7 +74,11 @@ private void createControls()
{
Text = "FifthTextBox",
};

FifthTextBox.SizeChanged += (sender, e) =>
{
//layout.InvalidateMeasure();
SimpleDebug.WriteLine("FifthTextBox.SizeChanged");
};
//https://stackoverflow.com/questions/35710355/uwpc-adding-text-to-richtextblock
SixthRichTextBlock = new Editor()
{
Expand Down
4 changes: 4 additions & 0 deletions SharpConstraintLayout.Maui.Example/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public static MauiApp CreateMauiApp()
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.ConfigureMauiHandlers(handler =>
{
//handler.AddHandler(typeof(ConstraintLayout), typeof(Microsoft.Maui.Handlers.LayoutHandler));
});

return builder.Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="ReloadPreview" Version="3.0.6" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SharpConstraintLayout.Maui\SharpConstraintLayout.Maui.csproj" />
</ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions SharpConstraintLayout.Maui.Native.Example/MainPage.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public partial class MainPage : ConstraintLayout

public MainPage()
{
ConstraintLayout.DEBUG = false;
//ConstraintLayout.DEBUG = false;
ConstraintLayout.MEASURE_MEASURELAYOUT = true;
//ConstraintLayout.MEASUREEVERYWIDGET = true;
//ConstraintLayout.MEASUREEVERYCHILD = true;
Expand All @@ -39,7 +39,7 @@ public MainPage()

//BaseAlignTest(this);
//BaselineTest(this); //bug:first time not align baseline
//GuidelineTest(this);
GuidelineTest(this);
//BarrierTest(this);//bug:text box have false length
//VisibilityTest(this);//bug:invisiable not correct
//FlowTest(this);
Expand All @@ -51,7 +51,7 @@ public MainPage()
//GroupTest(this);
//PlaceholderTest(this);
//SizeTest(this);
ConstraintLayoutInScrollViewTest(this);
//ConstraintLayoutInScrollViewTest(this);
}

void ConstraintLayoutInScrollViewTest(ConstraintLayout page)
Expand Down
34 changes: 17 additions & 17 deletions SharpConstraintLayout.Maui.Native.Example/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,23 +387,23 @@ void PlatformLayoutInConstraintLayoutTest(ConstraintLayout page)
}, page);
});
#endif
using (var layoutSet = new FluentConstraintSet())
{
layoutSet.Clone(page);
layoutSet.Select(stackPanel)
.CenterYTo().LeftToLeft()
.Width(SizeBehavier.WrapContent)
.Height(SizeBehavier.WrapContent)
.Select(grid)
.TopToBottom(stackPanel, 10).LeftToLeft()
.Width(SizeBehavier.WrapContent)
.Height(SizeBehavier.WrapContent)
.Select(scrollView)
.TopToBottom(grid, 10).BottomToBottom().LeftToLeft()
.Width(SizeBehavier.WrapContent)//ios don't know size
.Height(SizeBehavier.MatchConstraint);
layoutSet.ApplyTo(page);
}
/* using (var layoutSet = new FluentConstraintSet())
{
layoutSet.Clone(page);
layoutSet.Select(stackPanel)
.CenterYTo().LeftToLeft()
.Width(SizeBehavier.WrapContent)
.Height(SizeBehavier.WrapContent)
.Select(grid)
.TopToBottom(stackPanel, 10).LeftToLeft()
.Width(SizeBehavier.WrapContent)
.Height(SizeBehavier.WrapContent)
.Select(scrollView)
.TopToBottom(grid, 10).BottomToBottom().LeftToLeft()
.Width(SizeBehavier.WrapContent)//ios don't know size
.Height(SizeBehavier.MatchConstraint);
layoutSet.ApplyTo(page);
}*/
}

void AnimationTest(ConstraintLayout page)
Expand Down
4 changes: 3 additions & 1 deletion SharpConstraintLayout.Maui.Native/Widget/ConstraintLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,7 @@ public void AndroidSourceCodeMeasureUseSpecForWindows(ConstraintWidget widget, B
* AndroidX.ConstraintLayout use mDirtyHierarchy to mark need measure, but it like also measure all.
* At Windows, WrapPanel also remeasure all, i feel it not good, so Windows i use these code still.
*/
#if !__MAUI__
#if __ANDROID__ && !__MAUI__
//before measure,we don't know new size, we just know it is dirty,
//so all dirty need remeasure,other view that wrap content maybe not remeasure.
Expand Down Expand Up @@ -1049,6 +1050,7 @@ public void AndroidSourceCodeMeasureUseSpecForWindows(ConstraintWidget widget, B
}
}
}
#endif
bool horizontalMatchConstraints = (horizontalBehavior == ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);
bool verticalMatchConstraints = (verticalBehavior == ConstraintWidget.DimensionBehaviour.MATCH_CONSTRAINT);

Expand Down Expand Up @@ -1101,7 +1103,7 @@ public void AndroidSourceCodeMeasureUseSpecForWindows(ConstraintWidget widget, B
#else
(w, h) = child.MeasureSelf(horizontalSpec, verticalSpec);
#endif
if (DEBUG) SimpleDebug.WriteLine($"{child.GetType().FullName} after onMeasure: widget={widget},control={child.GetWrapContentSize()}");
if (DEBUG) SimpleDebug.WriteLine($"{child.GetType().FullName} after onMeasure: widget={widget},control={child.GetWrapContentSize()},measured=({w} x {h})");
}
widget.setLastMeasureSpec(horizontalSpec, verticalSpec);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ public static (int measuredWidth, int measureWidth) MeasureSelf(this UIElement e
#if __MAUI__
w = MeasureSpec.GetSize(horizontalSpec);
h = MeasureSpec.GetSize(verticalSpec);
var sizeRequest = element.Measure(w, h);
w = GetDefaultSize((int)sizeRequest.Request.Width, horizontalSpec);
h = GetDefaultSize((int)sizeRequest.Request.Height, verticalSpec);
var sizeRequest = (element as IView).Measure(w, h);
w = GetDefaultSize((int)sizeRequest.Width, horizontalSpec);
h = GetDefaultSize((int)sizeRequest.Height, verticalSpec);
#elif WINDOWS
w = MeasureSpec.GetSize(horizontalSpec);
h = MeasureSpec.GetSize(verticalSpec);
Expand Down
7 changes: 7 additions & 0 deletions SharpConstraintLayout.Maui/SharpConstraintLayout.Maui.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
<Version>2.1.1.1</Version>
<Description>constraintlayout for maui</Description>
<Copyright></Copyright>
<PackageProjectUrl>https://github.com/xtuzy/SharpConstraintLayout</PackageProjectUrl>
<RepositoryUrl>https://github.com/xtuzy/SharpConstraintLayout</RepositoryUrl>
<PackageReleaseNotes>first preview version for maui</PackageReleaseNotes>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>

</PropertyGroup>

Expand Down
22 changes: 8 additions & 14 deletions SharpConstraintLayout.Maui/Widget/ConstraintLayout.Maui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,39 +71,34 @@ protected override ILayoutManager CreateLayoutManager()

void LayoutChild(UIElement element, int x, int y, int w, int h)
{
element.Arrange(new Rect(x, y, w, h));
//AbsoluteLayout.SetLayoutBounds(element, new Rect(x, y, w, h));
(element as IView).Arrange(new Rect(x, y, w, h));
}
#endregion

public Size GetLastMeasureSize() { return new Size(mLastMeasureWidth, mLastMeasureHeight); }
}

internal class ConstraintLayoutManager : LayoutManager
public class ConstraintLayoutManager : LayoutManager
{
WeakReference<IMauiConstraintLayout> Layout;

public ConstraintLayoutManager(IMauiConstraintLayout constraintLayout) : base(constraintLayout)
{
Layout = new WeakReference<IMauiConstraintLayout>(constraintLayout);
}

public override Size Measure(double widthConstraint, double heightConstraint)
{
//base.Measure(widthConstraint, heightConstraint);
Layout.TryGetTarget(out var layout);

var availableSize = new Size(widthConstraint, heightConstraint);
var layout = Layout as ConstraintLayout;
(int horizontalSpec, int verticalSpec) = layout.MakeSpec(layout, availableSize);

(int horizontalSpec, int verticalSpec) = layout.MakeSpec(layout as ConstraintLayout, availableSize);
var finalSize = layout.MeasureLayout(availableSize, horizontalSpec, verticalSpec);

return layout.MeasureLayout(availableSize, horizontalSpec, verticalSpec);
return finalSize;
}

public override Size ArrangeChildren(Rect bounds)
{
Size finalSize = bounds.Size;
Layout.TryGetTarget(out var layout);
var layout = Layout as ConstraintLayout;
var lastMeasureSize = layout.GetLastMeasureSize();
if (finalSize.Width != lastMeasureSize.Width || finalSize.Height != lastMeasureSize.Height)
{
Expand All @@ -113,12 +108,11 @@ public override Size ArrangeChildren(Rect bounds)
}

layout.ArrangeLayout();
//base.ArrangeChildren(bounds);
return finalSize;
}
}

interface IMauiConstraintLayout : Microsoft.Maui.ILayout
public interface IMauiConstraintLayout : Microsoft.Maui.ILayout
{
Size MeasureLayout(Size availableSize, int horizontalSpec = 0, int verticalSpec = 0);
void ArrangeLayout();
Expand Down