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

Commit

Permalink
[Enhancement] Shapes (#9218)
Browse files Browse the repository at this point in the history
* Added Shapes to Core and Core Gallery samples
Implemented basic Shapes on iOS

* Added basic shapes Android implementation

* Fixed UWP namespace conflicts

* Fixed WPF namespace conflicts

* Implemented basic shapes on UWP

* Fixed UWP Ellipse and Rectangle size issue

* Fixed Tizen Build

* Changes to fix the build errors

* Exclude shapes renderers from Tizen compilation

* Implemented LineCap and LineJoin in Android and iOS

* Implemented LineCap and LineJoin on UWP

* Fixed build error

* Updated Polygon sample

* Fixed UWP Build error (namespace conflicts)

* Fixed namespaces collision build error

* Added "Shapes_Experimental" flag

* Update UWP ShapeRenderer size logic

* Updated iOS and Android ShapeRenderer size logic

* Fixed UWP Build error

* Added WPF implementation

* Fixed Tizen Build error

* Added Shapes macOS implementation

* Fixed broken unit tests

* Use the same Shapes classes between UWP and WPF backends

* Fixed flipper macOS shape issue

* Changed Shape class to be abstract

* Added Polygon and Polyline unit tests

* Added more Shapes Unit Tests

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

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

fixes #2452 (partially)
fixes #9178
  • Loading branch information
jsuarezruiz committed Jun 8, 2020
1 parent 50a209f commit 9efe531
Show file tree
Hide file tree
Showing 132 changed files with 3,557 additions and 219 deletions.
17 changes: 17 additions & 0 deletions Stubs/Xamarin.Forms.Platform.cs
Expand Up @@ -174,6 +174,23 @@ internal class _RefreshViewRenderer { }

[RenderWith(typeof(SwipeViewRenderer))]
internal class _SwipeViewRenderer { }

#if !TIZEN4_0
[RenderWith(typeof(EllipseRenderer))]
internal class _EllipseRenderer { }

[RenderWith(typeof(LineRenderer))]
internal class _LineRenderer { }

[RenderWith(typeof(PolylineRenderer))]
internal class _PolylineRenderer { }

[RenderWith(typeof(PolygonRenderer))]
internal class _PolygonRenderer { }

[RenderWith(typeof(RectangleRenderer))]
internal class _RectangleRenderer { }
#endif
}


Expand Down
@@ -1,6 +1,5 @@
using System;
using Android.Content;
using Android.Graphics;
#if __ANDROID_29__
using AndroidX.AppCompat.Widget;
using AndroidX.RecyclerView.Widget;
Expand All @@ -11,6 +10,7 @@
using Xamarin.Forms.ControlGallery.Android;
using Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.AlternateLayoutGalleries;
using Xamarin.Forms.Platform.Android;
using ARect = Android.Graphics.Rect;
using AView = Android.Views.View;

[assembly: ExportRenderer(typeof(StaggeredCollectionView), typeof(StaggeredCollectionViewRenderer))]
Expand Down Expand Up @@ -70,7 +70,7 @@ public SpacingItemDecoration(StaggeredGridItemsLayout itemsLayout)
}
}

public override void GetItemOffsets(Rect outRect, AView view, RecyclerView parent, RecyclerView.State state)
public override void GetItemOffsets(ARect outRect, AView view, RecyclerView parent, RecyclerView.State state)
{
base.GetItemOffsets(outRect, view, parent, state);

Expand Down
@@ -1,17 +1,11 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows;
using System.Windows.Media;
using Xamarin.Forms.ControlGallery.WPF.Renderers;
using Xamarin.Forms.Controls.Issues;
using Xamarin.Forms.Platform.WPF;
using WColor = System.Windows.Media.Color;
using WRect = System.Windows.Rect;

[assembly:ExportRenderer(typeof(Issue6693Control), typeof(Issue6693ControlRenderer))]
[assembly: ExportRenderer(typeof(Issue6693Control), typeof(Issue6693ControlRenderer))]
namespace Xamarin.Forms.ControlGallery.WPF.Renderers
{
public class Issue6693ControlRenderer:ViewRenderer<Issue6693Control,WIssue6693Control>
Expand All @@ -35,7 +29,7 @@ public WIssue6693Control()

protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawRectangle(Brushes.LightGray, new Pen(Brushes.Black, 1), new Rect(0,0,ActualWidth, ActualHeight));
drawingContext.DrawRectangle(Brushes.LightGray, new Pen(Brushes.Black, 1), new WRect(0,0,ActualWidth, ActualHeight));
var isEnabledText = IsEnabled ? "I'm enabled :)" : "I'm disabled :(";
drawingContext.DrawText(new FormattedText(isEnabledText,
System.Globalization.CultureInfo.CurrentCulture,
Expand Down
@@ -1,10 +1,10 @@
using Windows.Foundation;
using Windows.Graphics.Display;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using WRect = Windows.Foundation.Rect;

namespace Xamarin.Forms.ControlGallery.WindowsUniversal
{
Expand Down Expand Up @@ -47,7 +47,7 @@ public string Text

protected override Windows.Foundation.Size ArrangeOverride(Windows.Foundation.Size finalSize)
{
_textBlock.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
_textBlock.Arrange(new WRect(0, 0, finalSize.Width, finalSize.Height));
return finalSize;
}

Expand All @@ -57,7 +57,7 @@ protected override Windows.Foundation.Size MeasureOverride (Windows.Foundation.
_textBlock.Measure (availableSize);

// This deliberately does something wrong so we can demo fixing it
Rect bounds = ApplicationView.GetForCurrentView ().VisibleBounds;
WRect bounds = ApplicationView.GetForCurrentView ().VisibleBounds;
double scaleFactor = DisplayInformation.GetForCurrentView ().RawPixelsPerViewPixel;
var size = new Size (bounds.Width * scaleFactor, bounds.Height * scaleFactor);

Expand Down
Expand Up @@ -5,10 +5,11 @@
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
using Xamarin.Forms.ControlGallery.WindowsUniversal;
using Xamarin.Forms.Controls.Issues;
using Xamarin.Forms.Platform.UWP;
using WEllipse = Windows.UI.Xaml.Shapes.Ellipse;
using WShape = Windows.UI.Xaml.Shapes.Shape;

[assembly: ExportRenderer(typeof(Xamarin.Forms.Controls.Issues.Bugzilla42602.TextBoxView), typeof(Xamarin.Forms.ControlGallery.WindowsUniversal.TextBoxViewRenderer))]
[assembly: ExportRenderer(typeof(Issue1683.EntryKeyboardFlags), typeof(EntryRendererKeyboardFlags))]
Expand Down Expand Up @@ -143,7 +144,7 @@ protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
Children.Add(m_Canvas);

//ellipse
Shape ellipse = new Ellipse()
WShape ellipse = new WEllipse()
{
Width = 100,
Height = 100,
Expand Down
Expand Up @@ -15,7 +15,7 @@
using Xamarin.Forms.ControlGallery.WindowsUniversal;
using Xamarin.Forms.Controls;
using Xamarin.Forms.Platform.UWP;

using WRect = Windows.Foundation.Rect;

namespace Xamarin.Forms.ControlGallery.WindowsUniversal
{
Expand Down Expand Up @@ -119,17 +119,17 @@ void AddNativeControls(NestedNativeControlGalleryPage page)
// The broken control always tries to size itself to the screen width
// So figure that out and we'll know how far off it's laying itself out
Rect bounds = ApplicationView.GetForCurrentView().VisibleBounds;
WRect bounds = ApplicationView.GetForCurrentView().VisibleBounds;
double scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
var screenWidth = new Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor);
// We can re-center it by offsetting it during the Arrange call
double diff = Math.Abs(screenWidth.Width - finalSize.Width) / -2;
frameworkElement.Arrange(new Rect(diff, 0, finalSize.Width - diff, finalSize.Height));
frameworkElement.Arrange(new WRect(diff, 0, finalSize.Width - diff, finalSize.Height));
// Arranging the control to the left will make it show up past the edge of the stack layout
// We can fix that by clipping it manually
var clip = new RectangleGeometry { Rect = new Rect(-diff, 0, finalSize.Width, finalSize.Height) };
var clip = new RectangleGeometry { Rect = new WRect(-diff, 0, finalSize.Width, finalSize.Height) };
frameworkElement.Clip = clip;
return finalSize;
Expand Down
2 changes: 2 additions & 0 deletions Xamarin.Forms.Controls/CoreGallery.cs
Expand Up @@ -18,6 +18,7 @@
using Xamarin.Forms.Controls.GalleryPages.AppThemeGalleries;
using Xamarin.Forms.Controls.GalleryPages.ExpanderGalleries;
using Xamarin.Forms.Controls.GalleryPages.RadioButtonGalleries;
using Xamarin.Forms.Controls.GalleryPages.ShapesGalleries;

namespace Xamarin.Forms.Controls
{
Expand Down Expand Up @@ -360,6 +361,7 @@ public override string ToString()
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Horizontal), "ScrollView Gallery Horizontal"),
new GalleryPageFactory(() => new ScrollGallery(ScrollOrientation.Both), "ScrollView Gallery 2D"),
new GalleryPageFactory(() => new SearchBarCoreGalleryPage(), "SearchBar Gallery"),
new GalleryPageFactory(() => new ShapesGallery(), "Shapes Gallery"),
new GalleryPageFactory(() => new SliderCoreGalleryPage(), "Slider Gallery"),
new GalleryPageFactory(() => new StepperCoreGalleryPage(), "Stepper Gallery"),
new GalleryPageFactory(() => new SwitchCoreGalleryPage(), "Switch Gallery"),
Expand Down
30 changes: 13 additions & 17 deletions Xamarin.Forms.Controls/GalleryPages/MapElementsGallery.xaml.cs
@@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Xaml;
using Xamarin.Forms.Maps;
using Map = Xamarin.Forms.Maps;

namespace Xamarin.Forms.Controls.GalleryPages
{
Expand All @@ -22,9 +18,9 @@ enum SelectedElementType

SelectedElementType _selectedType;

Polyline _polyline;
Polygon _polygon;
Circle _circle;
Map.Polyline _polyline;
Map.Polygon _polygon;
Map.Circle _circle;

Random _random = new Random();

Expand All @@ -37,7 +33,7 @@ public MapElementsGallery()
new Position(39.828152, -98.569817),
Distance.FromMiles(1681)));

_polyline = new Polyline
_polyline = new Maps.Polyline
{
Geopath =
{
Expand All @@ -47,7 +43,7 @@ public MapElementsGallery()
}
};

_polygon = new Polygon
_polygon = new Maps.Polygon
{
StrokeColor = Color.FromHex("#002868"),
FillColor = Color.FromHex("#88BF0A30"),
Expand Down Expand Up @@ -108,10 +104,10 @@ void AddClicked(object sender, EventArgs e)
switch (_selectedType)
{
case SelectedElementType.Polyline:
Map.MapElements.Add(_polyline = new Polyline());
Map.MapElements.Add(_polyline = new Maps.Polyline());
break;
case SelectedElementType.Polygon:
Map.MapElements.Add(_polygon = new Polygon());
Map.MapElements.Add(_polygon = new Maps.Polygon());
break;
case SelectedElementType.Circle:
Map.MapElements.Add(_circle = new Circle());
Expand All @@ -125,18 +121,18 @@ void RemoveClicked(object sender, EventArgs e)
{
case SelectedElementType.Polyline:
Map.MapElements.Remove(_polyline);
_polyline = Map.MapElements.OfType<Polyline>().LastOrDefault();
_polyline = Map.MapElements.OfType<Maps.Polyline>().LastOrDefault();

if (_polyline == null)
Map.MapElements.Add(_polyline = new Polyline());
Map.MapElements.Add(_polyline = new Maps.Polyline());

break;
case SelectedElementType.Polygon:
Map.MapElements.Remove(_polygon);
_polygon = Map.MapElements.OfType<Polygon>().LastOrDefault();
_polygon = Map.MapElements.OfType<Maps.Polygon>().LastOrDefault();

if (_polygon == null)
Map.MapElements.Add(_polygon = new Polygon());
Map.MapElements.Add(_polygon = new Maps.Polygon());

break;
case SelectedElementType.Circle:
Expand Down
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Xamarin.Forms.Controls.GalleryPages.ShapesGalleries.AutoSizeShapesGallery"
Title="AutoSize Shapes Gallery">
<ContentPage.Content>
<Grid
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label
Text="The Ellipse below must occupy half of the available space."
TextColor="White"
BackgroundColor="Black"/>
<Grid
Grid.Row="1"
BackgroundColor="Yellow">
<Ellipse
StrokeThickness="4"
Stroke="Blue"
Fill="Green" />
</Grid>
<Grid
Grid.Row="2"
BackgroundColor="Orange"/>
</Grid>
</ContentPage.Content>
</ContentPage>
@@ -0,0 +1,10 @@
namespace Xamarin.Forms.Controls.GalleryPages.ShapesGalleries
{
public partial class AutoSizeShapesGallery : ContentPage
{
public AutoSizeShapesGallery()
{
InitializeComponent();
}
}
}
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Xamarin.Forms.Controls.GalleryPages.ShapesGalleries.EllipseGallery"
Title="Ellipse Gallery">
<ContentPage.Resources>
<ResourceDictionary>

<Style TargetType="Ellipse">
<Setter Property="HorizontalOptions" Value="Start" />
</Style>

</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<ScrollView>
<StackLayout
Padding="12">
<Label
Text="A basic Rectangle"/>
<Ellipse
Fill ="Red"
WidthRequest ="150"
HeightRequest ="50"/>
<Label
Text="A Circle"/>
<Ellipse
Stroke ="Red"
StrokeThickness="4"
WidthRequest ="150"
HeightRequest ="150"/>
<Label
Text="An Ellipse with stroke"/>
<Ellipse
Stroke ="Red"
StrokeThickness="4"
WidthRequest ="150"
HeightRequest ="50"/>
<Ellipse
Fill="DarkBlue"
Stroke ="Red"
StrokeThickness="4"
WidthRequest ="150"
HeightRequest ="50"/>
<Label
Text="An Ellipse with stroke dash"/>
<Ellipse
Fill="DarkBlue"
Stroke ="Red"
StrokeThickness="4"
StrokeDashArray="1, 1"
StrokeDashOffset="6"
WidthRequest ="150"
HeightRequest ="50"/>
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
@@ -0,0 +1,13 @@
using Xamarin.Forms.Internals;

namespace Xamarin.Forms.Controls.GalleryPages.ShapesGalleries
{
[Preserve(AllMembers = true)]
public partial class EllipseGallery : ContentPage
{
public EllipseGallery()
{
InitializeComponent();
}
}
}

0 comments on commit 9efe531

Please sign in to comment.