Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
[Enhancement] Shapes (Path) (#9264)
Browse files Browse the repository at this point in the history
* Added Path definition in Core (Shapes)
Implemented Path in Android and iOS

* Fixed Android build errors

* Fixed UWP Build

* Fixed WPF Build

* Implemented PathRenderer on UWP

* Added unit tests

* Fixed namespaces conflicts in Platform projects

* Changes to fix the build errors

* Implemented Path Transformations in Android and iOS

* Fixed Build error in WPF and UWP

* Implemented Path Transformations in UWP

* Fixed iOS Build error

* Changes to fix the Build (Path namespace conflict)

* More changes to fix the build error

* Fixed Windows Build errors

* Fixed Path size issue on UWP

* Added Shapes_Experimental flag

* Updated path sample

* Updated Android ShapeRenderer size logic

* Added Shape Aspect sample in Core Gallery

* Added more Shapes samples

* Updated UWP PathRenderer size logic

* Updated droid and iOS pathRenderer size logic (same behavior in all the platforms)

* Updated UWP ShapeRenderer

* Implemented Path in WPF Backend

* Fixed build error

* Initial Clip implementation in WPF and UWP (work in progress)

* Added Path implementation on macOS

* Added Clip implementation in Android, iOS and macOS

* Fixed broken unit tests

* Notify the change of Geometry if any of the child properties changed

* Added new sample clipping different views

* Fixed flipped shape issue on macOS

* Added support to Clip using EllipseGeometry, LineGeometry and RectangleGeometry in UWP

* Changed Shape class to be abstract

* Moved Shapes to Xamarin.Forms.Shapes in Android, iOS and macOS

* Moved Shapes to Xamarin.Forms.Shapes namespace in Windows (UWP and WPF)

* Fixed wrong property in LineGeometry

* Fixed build error

* Added Clip Performance sample in Core Gallery

* Update Matrix.cs

* Update RectangleGeometry.cs

* Update Xamarin.Forms.Platform.macOS.csproj

* Some duplicate classes

* Update PointCollectionTests.cs

* Update ImageButtonRenderer.cs

* Update Xamarin.Forms.Platform.iOS.csproj

* Update Xamarin.Forms.Platform.iOS.csproj

* Fixed tabs error

Co-authored-by: Samantha Houts <samhouts@users.noreply.github.com>

fixes #2452 (partially)
fixes #9178
  • Loading branch information
jsuarezruiz committed Jun 9, 2020
1 parent 2343ee9 commit 9a9f71d
Show file tree
Hide file tree
Showing 142 changed files with 5,712 additions and 244 deletions.
3 changes: 3 additions & 0 deletions Stubs/Xamarin.Forms.Platform.cs
Expand Up @@ -176,6 +176,9 @@ internal class _RefreshViewRenderer { }
internal class _SwipeViewRenderer { }

#if !TIZEN4_0
[RenderWith(typeof(PathRenderer))]
internal class _PathRenderer { }

[RenderWith(typeof(EllipseRenderer))]
internal class _EllipseRenderer { }

Expand Down
5 changes: 2 additions & 3 deletions Xamarin.Forms.Build.Tasks/CssGenerator.cs
@@ -1,12 +1,11 @@
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.CSharp;

using Xamarin.Forms.Xaml;
using IOPath = System.IO.Path;

namespace Xamarin.Forms.Build.Tasks
{
Expand Down Expand Up @@ -79,7 +78,7 @@ public bool Execute()
void GenerateCode()
{
//Create the target directory if required
Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));
Directory.CreateDirectory(IOPath.GetDirectoryName(OutputFile));

var ccu = new CodeCompileUnit();
ccu.AssemblyCustomAttributes.Add(
Expand Down
6 changes: 2 additions & 4 deletions Xamarin.Forms.Build.Tasks/DebugXamlCTask.cs
@@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;

using static Microsoft.Build.Framework.MessageImportance;
using IOPath = System.IO.Path;

namespace Xamarin.Forms.Build.Tasks
{
Expand All @@ -28,7 +26,7 @@ public override bool Execute(out IList<Exception> thrownExceptions)
if (!string.IsNullOrEmpty(ReferencePath)) {
var paths = ReferencePath.Replace("//", "/").Split(';');
foreach (var p in paths) {
var searchpath = Path.GetDirectoryName(p);
var searchpath = IOPath.GetDirectoryName(p);
LoggingHelper.LogMessage(Low, $"{new string(' ', 2)}Adding searchpath {searchpath}");
resolver.AddSearchDirectory(searchpath);
}
Expand Down
8 changes: 3 additions & 5 deletions Xamarin.Forms.Build.Tasks/XamlCTask.cs
Expand Up @@ -5,14 +5,12 @@
using System.Linq;
using System.Xml;
using Microsoft.Build.Framework;

using Mono.Cecil;
using Mono.Cecil.Cil;

using Xamarin.Forms.Xaml;

using static Microsoft.Build.Framework.MessageImportance;
using static Mono.Cecil.Cil.OpCodes;
using IOPath = System.IO.Path;

namespace Xamarin.Forms.Build.Tasks
{
Expand Down Expand Up @@ -65,7 +63,7 @@ public override bool Execute(out IList<Exception> thrownExceptions)
if (!string.IsNullOrEmpty(ReferencePath)) {
var paths = ReferencePath.Replace("//", "/").Split(';').Distinct();
foreach (var p in paths) {
var searchpath = Path.GetDirectoryName(p);
var searchpath = IOPath.GetDirectoryName(p);
LoggingHelper.LogMessage(Low, $"{new string(' ', 2)}Adding searchpath {searchpath}");
xamlCResolver.AddSearchDirectory(searchpath);
}
Expand All @@ -82,7 +80,7 @@ public override bool Execute(out IList<Exception> thrownExceptions)
ReadSymbols = debug && !ValidateOnly, // We don't need symbols for ValidateOnly, since we won't be writing
};

using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(Path.GetFullPath(Assembly),readerParameters)) {
using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(IOPath.GetFullPath(Assembly),readerParameters)) {
CustomAttribute xamlcAttr;
if (assemblyDefinition.HasCustomAttributes &&
(xamlcAttr =
Expand Down
6 changes: 3 additions & 3 deletions Xamarin.Forms.Build.Tasks/XamlGTask.cs
@@ -1,9 +1,9 @@
using System;
using System.IO;
using System.Xml;

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using IOPath = System.IO.Path;

namespace Xamarin.Forms.Build.Tasks
{
Expand Down Expand Up @@ -38,9 +38,9 @@ public override bool Execute()
for (int i = 0; i < XamlFiles.Length; i++) {
var xamlFile = XamlFiles[i];
var outputFile = OutputFiles[i].ItemSpec;
if (Path.DirectorySeparatorChar == '/' && outputFile.Contains(@"\"))
if (IOPath.DirectorySeparatorChar == '/' && outputFile.Contains(@"\"))
outputFile = outputFile.Replace('\\','/');
else if (Path.DirectorySeparatorChar == '\\' && outputFile.Contains(@"/"))
else if (IOPath.DirectorySeparatorChar == '\\' && outputFile.Contains(@"/"))
outputFile = outputFile.Replace('/', '\\');

var generator = new XamlGenerator(xamlFile, Language, AssemblyName, outputFile, References, Log);
Expand Down
5 changes: 3 additions & 2 deletions Xamarin.Forms.Build.Tasks/XamlGenerator.cs
Expand Up @@ -11,6 +11,7 @@
using Xamarin.Forms.Xaml;
using Xamarin.Forms.Internals;
using Mono.Cecil;
using IOPath = System.IO.Path;

namespace Xamarin.Forms.Build.Tasks
{
Expand Down Expand Up @@ -173,7 +174,7 @@ internal bool ParseXaml(TextReader xaml)
void GenerateCode()
{
//Create the target directory if required
Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));
Directory.CreateDirectory(IOPath.GetDirectoryName(OutputFile));

var ccu = new CodeCompileUnit();
ccu.AssemblyCustomAttributes.Add(
Expand Down Expand Up @@ -390,7 +391,7 @@ void GatherXmlnsDefinitionAttributes()
string[] paths = References.Split(';').Distinct().ToArray();

foreach (var path in paths) {
string asmName = Path.GetFileName(path);
string asmName = IOPath.GetFileName(path);
if (AssemblyIsSystem(asmName))
// Skip the myriad "System." assemblies and others
continue;
Expand Down
6 changes: 3 additions & 3 deletions Xamarin.Forms.ControlGallery.Android/CacheService.cs
@@ -1,6 +1,6 @@
using System.IO;
using System.IO.IsolatedStorage;
using Xamarin.Forms.Controls;
using IOPath = System.IO.Path;

namespace Xamarin.Forms.ControlGallery.Android
{
Expand All @@ -15,9 +15,9 @@ static void DeleteFilesInDirectory (string directory)
{
using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication ()) {
if (isolatedStorage.DirectoryExists (directory)) {
var files = isolatedStorage.GetFileNames (Path.Combine (directory, "*"));
var files = isolatedStorage.GetFileNames (IOPath.Combine (directory, "*"));
foreach (string file in files) {
isolatedStorage.DeleteFile (Path.Combine (directory, file));
isolatedStorage.DeleteFile (IOPath.Combine (directory, file));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Xamarin.Forms.ControlGallery.Android/CustomRenderers.cs
Expand Up @@ -30,9 +30,9 @@
using FragmentTransaction = Android.Support.V4.App.FragmentTransaction;
using NestedScrollView = global::Android.Support.V4.Widget.NestedScrollView;
#endif
using System.IO;
using AMenuItemCompat = global::Android.Support.V4.View.MenuItemCompat;
using Android.Support.V4.Content;
using IOPath = System.IO.Path;

[assembly: ExportRenderer(typeof(Issue5461.ScrollbarFadingEnabledFalseScrollView), typeof(ScrollbarFadingEnabledFalseScrollViewRenderer))]
[assembly: ExportRenderer(typeof(Issue1942.CustomGrid), typeof(Issue1942GridRenderer))]
Expand Down Expand Up @@ -104,7 +104,7 @@ protected override void UpdateMenuItemIcon(Context context, IMenuItem menuItem,

if (toolBarItem.IconImageSource is FileImageSource fileImageSource)
{
var name = Path.GetFileNameWithoutExtension(fileImageSource.File);
var name = IOPath.GetFileNameWithoutExtension(fileImageSource.File);
var id = Xamarin.Forms.Platform.Android.ResourceManager.GetDrawableByName(name);
if (id != 0)
{
Expand Down
3 changes: 2 additions & 1 deletion Xamarin.Forms.ControlGallery.MacOS/NativeServices.cs
Expand Up @@ -5,6 +5,7 @@
using Xamarin.Forms.ControlGallery.MacOS;
using Xamarin.Forms.Controls;
using Xamarin.Forms.Platform.MacOS;
using IOPath = System.IO.Path;

[assembly: Dependency(typeof(TestCloudService))]
[assembly: Dependency(typeof(CacheService))]
Expand All @@ -19,7 +20,7 @@ public class CacheService : ICacheService
public void ClearImageCache()
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var cache = Path.Combine(documents, ".config", ".isolated-storage", "ImageLoaderCache");
var cache = IOPath.Combine(documents, ".config", ".isolated-storage", "ImageLoaderCache");
foreach (var file in Directory.GetFiles(cache))
{
File.Delete(file);
Expand Down
Expand Up @@ -142,5 +142,8 @@
<ItemGroup>
<Resource Include="bank.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="crimson.jpg" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
Binary file added Xamarin.Forms.ControlGallery.WPF/crimson.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -9,12 +9,11 @@
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Xamarin.Forms;
using Xamarin.Forms.ControlGallery.WindowsUniversal;
using Xamarin.Forms.Controls;
using Xamarin.Forms.Platform.UWP;
using WRectangleGeometry = Windows.UI.Xaml.Media.RectangleGeometry;
using WRect = Windows.Foundation.Rect;

namespace Xamarin.Forms.ControlGallery.WindowsUniversal
Expand Down
3 changes: 2 additions & 1 deletion Xamarin.Forms.ControlGallery.iOS/AppDelegate.cs
Expand Up @@ -10,6 +10,7 @@
using Xamarin.Forms.Controls;
using Xamarin.Forms.Controls.Issues;
using Xamarin.Forms.Platform.iOS;
using IOPath = System.IO.Path;

[assembly: Dependency(typeof(TestCloudService))]
[assembly: Dependency(typeof(CacheService))]
Expand Down Expand Up @@ -40,7 +41,7 @@ public class CacheService : ICacheService
public void ClearImageCache()
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var cache = Path.Combine(documents, ".config", ".isolated-storage", "ImageLoaderCache");
var cache = IOPath.Combine(documents, ".config", ".isolated-storage", "ImageLoaderCache");
foreach (var file in Directory.GetFiles(cache))
{
File.Delete(file);
Expand Down
Expand Up @@ -5,6 +5,7 @@
using System.Threading.Tasks;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using IOPath = System.IO.Path;

#if UITEST
using Xamarin.Forms.Core.UITests;
Expand Down Expand Up @@ -79,7 +80,7 @@ async Task CreateImage(string imageUrl)
#else
path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
#endif
SecondImageSource = Path.Combine(path, "Issue8821.gif");
SecondImageSource = IOPath.Combine(path, "Issue8821.gif");
File.WriteAllBytes(SecondImageSource, bytes);

_image.Source = SecondImageSource;
Expand Down
@@ -1,8 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.IO;
using System.Reflection;
using Xamarin.Forms.Internals;
using IOPath = System.IO.Path;

namespace Xamarin.Forms.Controls.GalleryPages.PerformanceGallery.Scenarios
{
Expand Down Expand Up @@ -53,7 +52,7 @@ internal class ImageScenario4 : PerformanceScenario
static ImageScenario4()
{
//NOTE: copy image to disk in static ctor, so not to interfere with timing
tempFile = Path.Combine(Path.GetTempPath(), $"{nameof(ImageScenario4)}.png");
tempFile = IOPath.Combine(IOPath.GetTempPath(), $"{nameof(ImageScenario4)}.png");
using (var embeddedStream = typeof(ImageScenario4).GetTypeInfo().Assembly.GetManifestResourceStream("Xamarin.Forms.Controls.GalleryPages.crimson.jpg"))
using (var fileStream = File.Create(tempFile))
embeddedStream.CopyTo(fileStream);
Expand Down
@@ -1,7 +1,7 @@
using System;
using System.Reflection;
using Xamarin.Forms.CustomAttributes;
using System.IO;
using IOPath = System.IO.Path;

#if UITEST
using Xamarin.Forms.Core.UITests;
Expand Down Expand Up @@ -61,7 +61,7 @@ static IApp InitializeApp()
#if __ANDROID__
static IApp InitializeAndroidApp()
{
var fullApkPath = Path.Combine(TestContext.CurrentContext.TestDirectory, AppPaths.ApkPath);
var fullApkPath = IOPath.Combine(TestContext.CurrentContext.TestDirectory, AppPaths.ApkPath);
var app = ConfigureApp.Android.ApkFile(fullApkPath).Debug().StartApp(UITest.Configuration.AppDataMode.DoNotClear);

if (bool.Parse((string)app.Invoke("IsPreAppCompat")))
Expand Down
@@ -0,0 +1,100 @@
using System;
using Xamarin.Forms.Shapes;

namespace Xamarin.Forms.Controls.GalleryPages.ShapesGalleries
{
public class AddRemoveClipGallery : ContentPage
{
readonly Image _image;
readonly Grid _grid;

public AddRemoveClipGallery()
{
Title = "Add/Remove Clip Gallery";

var layout = new StackLayout
{
Padding = 12
};

var imageInfo = new Label
{
HorizontalOptions = LayoutOptions.Center,
Text = "Image"
};

_image = new Image
{
Aspect = Aspect.AspectFill,
Source = new FileImageSource { File = "crimson.jpg" },
HorizontalOptions = LayoutOptions.Center,
HeightRequest = 150,
WidthRequest = 150
};

var gridInfo = new Label
{
HorizontalOptions = LayoutOptions.Center,
Text = "Grid"
};

_grid = new Grid
{
BackgroundColor = Color.Red,
HorizontalOptions = LayoutOptions.Center,
HeightRequest = 150,
WidthRequest = 150
};

var buttonLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.Center
};

var addButton = new Button
{
Text = "Add EllipseGeometry",
WidthRequest = 150
};

addButton.Clicked += OnAddButtonClicked;

var removeButton = new Button
{
Text = "Remove EllipseGeometry",
WidthRequest = 150
};

removeButton.Clicked += OnRemoveButtonClicked;

buttonLayout.Children.Add(addButton);
buttonLayout.Children.Add(removeButton);

layout.Children.Add(imageInfo);
layout.Children.Add(_image);
layout.Children.Add(gridInfo);
layout.Children.Add(_grid);
layout.Children.Add(buttonLayout);

Content = layout;
}

void OnAddButtonClicked(object sender, EventArgs e)
{
var ellipseGeometry = new EllipseGeometry
{
Center = new Point(75, 75),
RadiusX = 60,
RadiusY = 60
};

_image.Clip = _grid.Clip = ellipseGeometry;
}

void OnRemoveButtonClicked(object sender, EventArgs e)
{
_image.Clip = _grid.Clip = null;
}
}
}

0 comments on commit 9a9f71d

Please sign in to comment.