Skip to content
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue34402.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui;

namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.Github, 34402, "FlowDirection property not working on BoxView Control", PlatformAffected.All)]
public class Issue34402 : ContentPage
{
public Issue34402()
{
var boxViewLabel = new Label
{
Text = "BoxView with different corner radius values on each corner",
HorizontalOptions = LayoutOptions.Center,
AutomationId = "Issue34402Label"
};

var boxView = new BoxView
{
CornerRadius = new CornerRadius(30, 60, 10, 20),
Color = Colors.CornflowerBlue,
WidthRequest = 200,
HeightRequest = 200,
FlowDirection = FlowDirection.LeftToRight
};

var graphicsViewLabel = new Label
{
Text = "GraphicsView with a triangle drawable",
HorizontalOptions = LayoutOptions.Center,
AutomationId = "Issue34402GraphicsViewLabel"
};

var graphicsView = new GraphicsView
{
Drawable = new TriangleDrawable(),
WidthRequest = 200,
HeightRequest = 100,
FlowDirection = FlowDirection.LeftToRight
};
Comment thread
Dhivya-SF4094 marked this conversation as resolved.

var boxViewRtlButton = new Button
{
Text = "Toggle BoxView RTL",
AutomationId = "BoxViewRtlButton"
};

bool boxViewIsRtl = false;
boxViewRtlButton.Clicked += (s, e) =>
{
boxViewIsRtl = !boxViewIsRtl;
boxView.FlowDirection = boxViewIsRtl ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
};

var graphicsViewRtlButton = new Button
{
Text = "Toggle GraphicsView RTL",
AutomationId = "GraphicsViewRtlButton"
};

bool graphicsViewIsRtl = false;
graphicsViewRtlButton.Clicked += (s, e) =>
{
graphicsViewIsRtl = !graphicsViewIsRtl;
graphicsView.FlowDirection = graphicsViewIsRtl ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
};

Content = new VerticalStackLayout
{
Spacing = 20,
Children =
{
boxViewLabel,
boxView,
boxViewRtlButton,
graphicsViewLabel,
graphicsView,
graphicsViewRtlButton
}
};
}

class TriangleDrawable : IDrawable
{
public void Draw(ICanvas canvas, RectF dirtyRect)
{
canvas.StrokeColor = Colors.Black;
canvas.StrokeSize = 2;

// Right angle triangle fitted to the view bounds
float left = dirtyRect.Left + 10;
float right = dirtyRect.Right - 10;
float top = dirtyRect.Top + 10;
float bottom = dirtyRect.Bottom - 10;

PathF path = new PathF();
path.MoveTo(left, bottom); // bottom-left
path.LineTo(right, bottom); // bottom-right
path.LineTo(left, top); // top-left
path.Close();

canvas.DrawPath(path);
}
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues
{
public class Issue34402 : _IssuesUITest
{
public Issue34402(TestDevice device) : base(device) { }

public override string Issue => "FlowDirection property not working on BoxView Control";

[Test]
[Category(UITestCategories.BoxView)]
public void BoxViewFlowDirectionShouldMirrorOnRTL()
{
App.WaitForElement("Issue34402Label");
VerifyScreenshot("BoxView_LTR_Initial");

App.Tap("BoxViewRtlButton");
VerifyScreenshot("BoxView_RTL_AfterButton");
}

[Test]
[Category(UITestCategories.GraphicsView)]
public void GraphicsViewFlowDirectionShouldMirrorOnRTL()
{
App.WaitForElement("Issue34402GraphicsViewLabel");
VerifyScreenshot("GraphicsView_LTR_Initial");

App.Tap("GraphicsViewRtlButton");
VerifyScreenshot("GraphicsView_RTL_AfterButton");
}
Comment thread
Dhivya-SF4094 marked this conversation as resolved.
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/Core/src/Handlers/ShapeView/ShapeViewHandler.Standard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ public partial class ShapeViewHandler : ViewHandler<IShapeView, object>
protected override object CreatePlatformView() => throw new NotImplementedException();

public static void MapBackground(IShapeViewHandler handler, IShapeView shapeView) { }

// TODO: make it public in .net 11
internal static void MapFlowDirection(IShapeViewHandler handler, IShapeView shapeView) { }
public static void MapShape(IShapeViewHandler handler, IShapeView shapeView) { }
public static void MapAspect(IShapeViewHandler handler, IShapeView shapeView) { }
public static void MapFill(IShapeViewHandler handler, IShapeView shapeView) { }
Expand Down
8 changes: 8 additions & 0 deletions src/Core/src/Handlers/ShapeView/ShapeViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public partial class ShapeViewHandler : IShapeViewHandler
public static IPropertyMapper<IShapeView, IShapeViewHandler> Mapper = new PropertyMapper<IShapeView, IShapeViewHandler>(ViewHandler.ViewMapper)
{
[nameof(IShapeView.Background)] = MapBackground,
[nameof(IView.FlowDirection)] = MapFlowDirection,
[nameof(IShapeView.Shape)] = MapShape,
[nameof(IShapeView.Aspect)] = MapAspect,
[nameof(IShapeView.Fill)] = MapFill,
Expand Down Expand Up @@ -68,6 +69,13 @@ public static void MapBackground(IShapeViewHandler handler, IShapeView shapeView
handler.PlatformView?.InvalidateShape(shapeView);
}
}

// TODO: make it public in .net 11
internal static void MapFlowDirection(IShapeViewHandler handler, IShapeView shapeView)
{
handler.PlatformView?.UpdateFlowDirection(shapeView);
handler.PlatformView?.InvalidateShape(shapeView);
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Android.Text;
using Android.Util;
using Android.Views;
using ALayoutDirection = Android.Views.LayoutDirection;

namespace Microsoft.Maui.Graphics.Platform
{
Expand Down Expand Up @@ -59,6 +60,28 @@ public override void Draw(Canvas androidCanvas)
if (_drawable == null)
return;

if (LayoutDirection == ALayoutDirection.Rtl)
{
int save = androidCanvas.Save();
androidCanvas.Translate(Width, 0);
androidCanvas.Scale(-1, 1);
try
{
DrawContent(androidCanvas);
}
finally
{
androidCanvas.RestoreToCount(save);
}
}
else
{
DrawContent(androidCanvas);
}
}

void DrawContent(Canvas androidCanvas)
{
var dirtyRect = new RectF(0, 0, _width, _height);

_canvas.Canvas = androidCanvas;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Graphics.Canvas.UI.Xaml;
using System.Numerics;
using Microsoft.Graphics.Canvas.UI.Xaml;
#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
Expand Down Expand Up @@ -89,6 +90,14 @@ private void OnDraw(CanvasControl sender, CanvasDrawEventArgs args)
{
_canvas.Session = args.DrawingSession;
_canvas.CanvasSize = new global::Windows.Foundation.Size(_dirty.Width, _dirty.Height);

if (FlowDirection == FlowDirection.RightToLeft)
{
_canvas.ConcatenateTransform(
Matrix3x2.CreateScale(-1, 1) *
Matrix3x2.CreateTranslation(_dirty.Width, 0));
}

_drawable.Draw(_canvas, _dirty);
}
finally
Expand Down
22 changes: 22 additions & 0 deletions src/Graphics/src/Graphics/Platforms/iOS/PlatformGraphicsView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,28 @@ public override void Draw(CGRect dirtyRect)
coreGraphics.SetStrokeColorSpace(_colorSpace);
coreGraphics.SetPatternPhase(PatternPhase);

if (EffectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.RightToLeft)
{
coreGraphics.SaveState();
coreGraphics.TranslateCTM((nfloat)Bounds.Width, 0);
coreGraphics.ScaleCTM(-1, 1);
try
{
DrawContent(coreGraphics, dirtyRect);
}
finally
{
coreGraphics.RestoreState();
}
}
else
{
DrawContent(coreGraphics, dirtyRect);
}
}

void DrawContent(CoreGraphics.CGContext coreGraphics, CGRect dirtyRect)
{
if (Renderer is IGraphicsRenderer renderer)
{
renderer.Draw(coreGraphics, dirtyRect.AsRectangleF());
Expand Down
Loading