summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Core/Image.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Core/Image.cs')
-rw-r--r--Xamarin.Forms.Core/Image.cs145
1 files changed, 145 insertions, 0 deletions
diff --git a/Xamarin.Forms.Core/Image.cs b/Xamarin.Forms.Core/Image.cs
new file mode 100644
index 00000000..9e329331
--- /dev/null
+++ b/Xamarin.Forms.Core/Image.cs
@@ -0,0 +1,145 @@
+using System;
+using Xamarin.Forms.Platform;
+
+namespace Xamarin.Forms
+{
+ [RenderWith(typeof(_ImageRenderer))]
+ public class Image : View
+ {
+ public static readonly BindableProperty SourceProperty = BindableProperty.Create("Source", typeof(ImageSource), typeof(Image), default(ImageSource), propertyChanging: OnSourcePropertyChanging,
+ propertyChanged: OnSourcePropertyChanged);
+
+ public static readonly BindableProperty AspectProperty = BindableProperty.Create("Aspect", typeof(Aspect), typeof(Image), Aspect.AspectFit);
+
+ public static readonly BindableProperty IsOpaqueProperty = BindableProperty.Create("IsOpaque", typeof(bool), typeof(Image), false);
+
+ internal static readonly BindablePropertyKey IsLoadingPropertyKey = BindableProperty.CreateReadOnly("IsLoading", typeof(bool), typeof(Image), default(bool));
+
+ public static readonly BindableProperty IsLoadingProperty = IsLoadingPropertyKey.BindableProperty;
+
+ public Aspect Aspect
+ {
+ get { return (Aspect)GetValue(AspectProperty); }
+ set { SetValue(AspectProperty, value); }
+ }
+
+ public bool IsLoading
+ {
+ get { return (bool)GetValue(IsLoadingProperty); }
+ }
+
+ public bool IsOpaque
+ {
+ get { return (bool)GetValue(IsOpaqueProperty); }
+ set { SetValue(IsOpaqueProperty, value); }
+ }
+
+ [TypeConverter(typeof(ImageSourceConverter))]
+ public ImageSource Source
+ {
+ get { return (ImageSource)GetValue(SourceProperty); }
+ set { SetValue(SourceProperty, value); }
+ }
+
+ protected override void OnBindingContextChanged()
+ {
+ if (Source != null)
+ SetInheritedBindingContext(Source, BindingContext);
+
+ base.OnBindingContextChanged();
+ }
+
+ [Obsolete("Use OnMeasure")]
+ protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint)
+ {
+ SizeRequest desiredSize = base.OnSizeRequest(double.PositiveInfinity, double.PositiveInfinity);
+
+ double desiredAspect = desiredSize.Request.Width / desiredSize.Request.Height;
+ double constraintAspect = widthConstraint / heightConstraint;
+
+ double desiredWidth = desiredSize.Request.Width;
+ double desiredHeight = desiredSize.Request.Height;
+
+ if (desiredWidth == 0 || desiredHeight == 0)
+ return new SizeRequest(new Size(0, 0));
+
+ double width = desiredWidth;
+ double height = desiredHeight;
+ if (constraintAspect > desiredAspect)
+ {
+ // constraint area is proportionally wider than image
+ switch (Aspect)
+ {
+ case Aspect.AspectFit:
+ case Aspect.AspectFill:
+ height = Math.Min(desiredHeight, heightConstraint);
+ width = desiredWidth * (height / desiredHeight);
+ break;
+ case Aspect.Fill:
+ width = Math.Min(desiredWidth, widthConstraint);
+ height = desiredHeight * (width / desiredWidth);
+ break;
+ }
+ }
+ else if (constraintAspect < desiredAspect)
+ {
+ // constraint area is proportionally taller than image
+ switch (Aspect)
+ {
+ case Aspect.AspectFit:
+ case Aspect.AspectFill:
+ width = Math.Min(desiredWidth, widthConstraint);
+ height = desiredHeight * (width / desiredWidth);
+ break;
+ case Aspect.Fill:
+ height = Math.Min(desiredHeight, heightConstraint);
+ width = desiredWidth * (height / desiredHeight);
+ break;
+ }
+ }
+ else
+ {
+ // constraint area is same aspect as image
+ width = Math.Min(desiredWidth, widthConstraint);
+ height = desiredHeight * (width / desiredWidth);
+ }
+
+ return new SizeRequest(new Size(width, height));
+ }
+
+ void OnSourceChanged(object sender, EventArgs eventArgs)
+ {
+ OnPropertyChanged(SourceProperty.PropertyName);
+ InvalidateMeasure(InvalidationTrigger.MeasureChanged);
+ }
+
+ static void OnSourcePropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
+ {
+ ((Image)bindable).OnSourcePropertyChanged((ImageSource)oldvalue, (ImageSource)newvalue);
+ }
+
+ void OnSourcePropertyChanged(ImageSource oldvalue, ImageSource newvalue)
+ {
+ if (newvalue != null)
+ {
+ newvalue.SourceChanged += OnSourceChanged;
+ SetInheritedBindingContext(newvalue, BindingContext);
+ }
+ InvalidateMeasure(InvalidationTrigger.MeasureChanged);
+ }
+
+ static void OnSourcePropertyChanging(BindableObject bindable, object oldvalue, object newvalue)
+ {
+ ((Image)bindable).OnSourcePropertyChanging((ImageSource)oldvalue, (ImageSource)newvalue);
+ }
+
+ async void OnSourcePropertyChanging(ImageSource oldvalue, ImageSource newvalue)
+ {
+ if (oldvalue == null)
+ return;
+
+ oldvalue.SourceChanged -= OnSourceChanged;
+ await oldvalue.Cancel();
+ }
+ }
+} \ No newline at end of file