Skip to content

Commit

Permalink
[All] ScaleX and ScaleY (xamarin#1280)
Browse files Browse the repository at this point in the history
* [*] ScaleX and ScaleY

* Use scaleX and scaleY in sendViewBatchUpdate

* use scaleX and scaleY parameters in SendViewBatchUpdate
  • Loading branch information
StephaneDelcroix authored May 7, 2018
1 parent 8c23ad6 commit b79462c
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ public void sendBatchUpdate (
float rotation,
float rotationX,
float rotationY,
float scale,
float scaleX,
float scaleY,
float translationX,
float translationY){
setPivotX (pivotX);
Expand All @@ -96,8 +97,8 @@ public void sendBatchUpdate (
setRotation (rotation);
setRotationX (rotationX);
setRotationY (rotationY);
setScaleX (scale);
setScaleY (scale);
setScaleX (scaleX);
setScaleY (scaleY);
setTranslationX (translationX);
setTranslationY (translationY);
}
Expand All @@ -112,7 +113,8 @@ public static void sendViewBatchUpdate (
float rotation,
float rotationX,
float rotationY,
float scale,
float scaleX,
float scaleY,
float translationX,
float translationY){
view.setPivotX (pivotX);
Expand All @@ -128,8 +130,8 @@ public static void sendViewBatchUpdate (
view.setRotation (rotation);
view.setRotationX (rotationX);
view.setRotationY (rotationY);
view.setScaleX (scale);
view.setScaleY (scale);
view.setScaleX (scaleX);
view.setScaleY (scaleY);
view.setTranslationX (translationX);
view.setTranslationY (translationY);
}
Expand Down
37 changes: 31 additions & 6 deletions Xamarin.Forms.Controls/GalleryPages/ScaleRotate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,41 @@ public ScaleRotate()
scaleSlider.SetBinding(Slider.ValueProperty,
new Binding("Scale", BindingMode.TwoWay));

// Label and Slider for ScaleX property.
Label scaleXSliderValue = new Label {
VerticalTextAlignment = TextAlignment.Center
};
Grid.SetRow(scaleXSliderValue, 1);
Grid.SetColumn(scaleXSliderValue, 0);

Slider scaleXSlider = new Slider {
Maximum = 10
};
Grid.SetRow(scaleXSlider, 1);
Grid.SetColumn(scaleXSlider, 1);

// Set Bindings.
scaleXSliderValue.BindingContext = scaleXSlider;
scaleXSliderValue.SetBinding(Label.TextProperty,
new Binding("Value", BindingMode.OneWay, null, null, "ScaleX = {0:F1}"));

scaleXSlider.BindingContext = label;
scaleXSlider.SetBinding(Slider.ValueProperty,
new Binding("ScaleX", BindingMode.TwoWay));

// Label and Slider for Rotation property.
Label rotationSliderValue = new Label
{
VerticalTextAlignment = TextAlignment.Center
};
Grid.SetRow(rotationSliderValue, 1);
Grid.SetRow(rotationSliderValue, 2);
Grid.SetColumn(rotationSliderValue, 0);

Slider rotationSlider = new Slider
{
Maximum = 360
};
Grid.SetRow(rotationSlider, 1);
Grid.SetRow(rotationSlider, 2);
Grid.SetColumn(rotationSlider, 1);

// Set Bindings.
Expand All @@ -68,7 +90,7 @@ public ScaleRotate()
{
VerticalTextAlignment = TextAlignment.Center
};
Grid.SetRow(anchorxStepperValue, 2);
Grid.SetRow(anchorxStepperValue, 3);
Grid.SetColumn(anchorxStepperValue, 0);

Stepper anchorxStepper = new Stepper
Expand All @@ -77,7 +99,7 @@ public ScaleRotate()
Minimum = -1,
Increment = 0.5
};
Grid.SetRow(anchorxStepper, 2);
Grid.SetRow(anchorxStepper, 3);
Grid.SetColumn(anchorxStepper, 1);

// Set bindings.
Expand All @@ -94,7 +116,7 @@ public ScaleRotate()
{
VerticalTextAlignment = TextAlignment.Center
};
Grid.SetRow(anchoryStepperValue, 3);
Grid.SetRow(anchoryStepperValue, 4);
Grid.SetColumn(anchoryStepperValue, 0);

Stepper anchoryStepper = new Stepper
Expand All @@ -103,7 +125,7 @@ public ScaleRotate()
Minimum = -1,
Increment = 0.5
};
Grid.SetRow(anchoryStepper, 3);
Grid.SetRow(anchoryStepper, 4);
Grid.SetColumn(anchoryStepper, 1);

// Set bindings.
Expand All @@ -130,6 +152,7 @@ public ScaleRotate()
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
},
ColumnDefinitions =
{
Expand All @@ -140,6 +163,8 @@ public ScaleRotate()
{
scaleSliderValue,
scaleSlider,
scaleXSliderValue,
scaleXSlider,
rotationSliderValue,
rotationSlider,
anchorxStepperValue,
Expand Down
23 changes: 18 additions & 5 deletions Xamarin.Forms.Core/VisualElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ public partial class VisualElement : Element, IAnimatable, IVisualElementControl

public static readonly BindableProperty RotationYProperty = BindableProperty.Create("RotationY", typeof(double), typeof(VisualElement), default(double));

public static readonly BindableProperty ScaleProperty = BindableProperty.Create("Scale", typeof(double), typeof(VisualElement), 1d);
public static readonly BindableProperty ScaleProperty = BindableProperty.Create(nameof(Scale), typeof(double), typeof(VisualElement), 1d);

public static readonly BindableProperty ScaleXProperty = BindableProperty.Create(nameof(ScaleX), typeof(double), typeof(VisualElement), 1d);

public static readonly BindableProperty ScaleYProperty = BindableProperty.Create(nameof(ScaleY), typeof(double), typeof(VisualElement), 1d);

public static readonly BindableProperty IsVisibleProperty = BindableProperty.Create("IsVisible", typeof(bool), typeof(VisualElement), true,
propertyChanged: (bindable, oldvalue, newvalue) => ((VisualElement)bindable).OnIsVisibleChanged((bool)oldvalue, (bool)newvalue));
Expand Down Expand Up @@ -266,10 +270,19 @@ public double RotationY
set { SetValue(RotationYProperty, value); }
}

public double Scale
{
get { return (double)GetValue(ScaleProperty); }
set { SetValue(ScaleProperty, value); }
public double Scale {
get => (double)GetValue(ScaleProperty);
set => SetValue(ScaleProperty, value);
}

public double ScaleX {
get => (double)GetValue(ScaleXProperty);
set => SetValue(ScaleXProperty, value);
}

public double ScaleY {
get => (double)GetValue(ScaleYProperty);
set => SetValue(ScaleYProperty, value);
}

public Style Style
Expand Down
Binary file not shown.
31 changes: 20 additions & 11 deletions Xamarin.Forms.Platform.Android/VisualElementTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
if (e.PropertyName == VisualElement.XProperty.PropertyName || e.PropertyName == VisualElement.YProperty.PropertyName || e.PropertyName == VisualElement.WidthProperty.PropertyName ||
e.PropertyName == VisualElement.HeightProperty.PropertyName)
_layoutNeeded = true;
else if (e.PropertyName == VisualElement.AnchorXProperty.PropertyName || e.PropertyName == VisualElement.AnchorYProperty.PropertyName || e.PropertyName == VisualElement.ScaleProperty.PropertyName ||
else if (e.PropertyName == VisualElement.AnchorXProperty.PropertyName || e.PropertyName == VisualElement.AnchorYProperty.PropertyName || e.PropertyName == VisualElement.ScaleProperty.PropertyName || e.PropertyName == VisualElement.ScaleXProperty.PropertyName || e.PropertyName == VisualElement.ScaleYProperty.PropertyName ||
e.PropertyName == VisualElement.RotationProperty.PropertyName || e.PropertyName == VisualElement.RotationXProperty.PropertyName || e.PropertyName == VisualElement.RotationYProperty.PropertyName ||
e.PropertyName == VisualElement.IsVisibleProperty.PropertyName || e.PropertyName == VisualElement.OpacityProperty.PropertyName ||
e.PropertyName == VisualElement.TranslationXProperty.PropertyName || e.PropertyName == VisualElement.TranslationYProperty.PropertyName)
Expand All @@ -146,7 +146,7 @@ void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
UpdateAnchorX();
else if (e.PropertyName == VisualElement.AnchorYProperty.PropertyName)
UpdateAnchorY();
else if (e.PropertyName == VisualElement.ScaleProperty.PropertyName)
else if (e.PropertyName == VisualElement.ScaleProperty.PropertyName || e.PropertyName == VisualElement.ScaleXProperty.PropertyName || e.PropertyName == VisualElement.ScaleYProperty.PropertyName)
UpdateScale();
else if (e.PropertyName == VisualElement.RotationProperty.PropertyName)
UpdateRotation();
Expand Down Expand Up @@ -240,7 +240,7 @@ void SetElement(VisualElement oldElement, VisualElement newElement)
UpdateRotationX();
if (oldElement.RotationY != newElement.RotationY)
UpdateRotationY();
if (oldElement.Scale != newElement.Scale)
if (oldElement.Scale != newElement.Scale || oldElement.ScaleX != newElement.ScaleX || oldElement.ScaleY != newElement.ScaleY)
UpdateScale();
// ReSharper restore CompareOfFloatsByEqualityOperator

Expand Down Expand Up @@ -310,17 +310,26 @@ void UpdateNativeView(object sender, EventArgs e)
if (aview is FormsViewGroup)
{
var formsViewGroup = (FormsViewGroup)aview;
formsViewGroup.SendBatchUpdate((float)(view.AnchorX * _context.ToPixels(view.Width)), (float)(view.AnchorY * _context.ToPixels(view.Height)),
(int)(view.IsVisible ? ViewStates.Visible : ViewStates.Invisible), view.IsEnabled, (float)view.Opacity, (float)view.Rotation, (float)view.RotationX, (float)view.RotationY, (float)view.Scale,
_context.ToPixels(view.TranslationX), _context.ToPixels(view.TranslationY));
formsViewGroup.SendBatchUpdate((float)(view.AnchorX * _context.ToPixels(view.Width)),
(float)(view.AnchorY * _context.ToPixels(view.Height)),
(int)(view.IsVisible ? ViewStates.Visible : ViewStates.Invisible),
view.IsEnabled,
(float)view.Opacity,
(float)view.Rotation,
(float)view.RotationX,
(float)view.RotationY,
(float)view.ScaleX,
(float)view.ScaleY,
_context.ToPixels(view.TranslationX),
_context.ToPixels(view.TranslationY));
}
else
{
FormsViewGroup.SendViewBatchUpdate(aview, (float)(view.AnchorX * _context.ToPixels(view.Width)),
(float)(view.AnchorY * _context.ToPixels(view.Height)),
(int)(view.IsVisible ? ViewStates.Visible : ViewStates.Invisible), view.IsEnabled, (float)view.Opacity,
(float)view.Rotation, (float)view.RotationX, (float)view.RotationY, (float)view.Scale,
_context.ToPixels(view.TranslationX), _context.ToPixels(view.TranslationY));
(float)view.Rotation, (float)view.RotationX, (float)view.RotationY, (float)view.ScaleX,
(float)view.ScaleY, _context.ToPixels(view.TranslationX), _context.ToPixels(view.TranslationY));
}

Performance.Stop(reference);
Expand Down Expand Up @@ -368,8 +377,8 @@ void UpdateScale()
VisualElement view = _renderer.Element;
AView aview = _renderer.View;

aview.ScaleX = (float)view.Scale;
aview.ScaleY = (float)view.Scale;
aview.ScaleX = (float)view.Scale * (float)view.ScaleX;
aview.ScaleY = (float)view.Scale * (float)view.ScaleY;
}

void UpdateTranslationX()
Expand Down Expand Up @@ -411,4 +420,4 @@ public void OnViewDetachedFromWindow(AView detachedView)
}
}
}
}
}
7 changes: 3 additions & 4 deletions Xamarin.Forms.Platform.UAP/VisualElementTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ protected virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs
{
UpdateScaleAndRotation(Element, Container);
}
else if (e.PropertyName == VisualElement.ScaleProperty.PropertyName)
else if (e.PropertyName == VisualElement.ScaleProperty.PropertyName || e.PropertyName == VisualElement.ScaleXProperty.PropertyName || e.PropertyName == VisualElement.ScaleYProperty.PropertyName)
{
UpdateScaleAndRotation(Element, Container);
}
Expand Down Expand Up @@ -508,9 +508,8 @@ static void UpdateScaleAndRotation(VisualElement view, FrameworkElement framewor
{
double anchorX = view.AnchorX;
double anchorY = view.AnchorY;
double scale = view.Scale;
frameworkElement.RenderTransformOrigin = new Windows.Foundation.Point(anchorX, anchorY);
frameworkElement.RenderTransform = new ScaleTransform { ScaleX = scale, ScaleY = scale };
frameworkElement.RenderTransform = new ScaleTransform { ScaleX = view.Scale * view.ScaleX, ScaleY = view.Scale * view.ScaleY };

UpdateRotation(view, frameworkElement);
}
Expand Down Expand Up @@ -589,4 +588,4 @@ void HandleDoubleTapped(object sender, DoubleTappedRoutedEventArgs doubleTappedR
doubleTappedRoutedEventArgs.Handled = true;
}
}
}
}
8 changes: 5 additions & 3 deletions Xamarin.Forms.Platform.iOS/VisualElementTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == VisualElement.XProperty.PropertyName || e.PropertyName == VisualElement.YProperty.PropertyName || e.PropertyName == VisualElement.WidthProperty.PropertyName ||
e.PropertyName == VisualElement.HeightProperty.PropertyName || e.PropertyName == VisualElement.AnchorXProperty.PropertyName || e.PropertyName == VisualElement.AnchorYProperty.PropertyName ||
e.PropertyName == VisualElement.TranslationXProperty.PropertyName || e.PropertyName == VisualElement.TranslationYProperty.PropertyName || e.PropertyName == VisualElement.ScaleProperty.PropertyName ||
e.PropertyName == VisualElement.TranslationXProperty.PropertyName || e.PropertyName == VisualElement.TranslationYProperty.PropertyName || e.PropertyName == VisualElement.ScaleProperty.PropertyName || e.PropertyName == VisualElement.ScaleXProperty.PropertyName || e.PropertyName == VisualElement.ScaleYProperty.PropertyName ||
e.PropertyName == VisualElement.RotationProperty.PropertyName || e.PropertyName == VisualElement.RotationXProperty.PropertyName || e.PropertyName == VisualElement.RotationYProperty.PropertyName ||
e.PropertyName == VisualElement.IsVisibleProperty.PropertyName || e.PropertyName == VisualElement.IsEnabledProperty.PropertyName ||
e.PropertyName == VisualElement.InputTransparentProperty.PropertyName || e.PropertyName == VisualElement.OpacityProperty.PropertyName ||
Expand Down Expand Up @@ -154,6 +154,8 @@ void OnUpdateNativeControl(CALayer caLayer)
var rotationY = (float)view.RotationY;
var rotation = (float)view.Rotation;
var scale = (float)view.Scale;
var scaleX = (float)view.ScaleX * scale;
var scaleY = (float)view.ScaleY * scale;
var width = (float)view.Width;
var height = (float)view.Height;
var x = (float)view.X + (float)CompressedLayout.GetHeadlessOffset(view).X;
Expand Down Expand Up @@ -246,8 +248,8 @@ void OnUpdateNativeControl(CALayer caLayer)
if (Math.Abs(translationX) > epsilon || Math.Abs(translationY) > epsilon)
transform = transform.Translate(translationX, translationY, 0);

if (Math.Abs(scale - 1) > epsilon)
transform = transform.Scale(scale);
if (Math.Abs(scaleX - 1) > epsilon || Math.Abs(scaleY - 1) > epsilon)
transform = transform.Scale(scaleX, scaleY, scale);

// not just an optimization, iOS will not "pixel align" a view which has m34 set
if (Math.Abs(rotationY % 180) > epsilon || Math.Abs(rotationX % 180) > epsilon)
Expand Down

0 comments on commit b79462c

Please sign in to comment.