static void StartStopAnimation(IImageVisualElementRenderer renderer, IImageElement controller) { if (renderer.IsDisposed || controller == null) { return; } if (controller.IsLoading) { return; } if (renderer.GetImage()?.Source is BitmapImage bitmapImage) { if (_nativeAnimationSupport) { if (controller.IsAnimationPlaying && !bitmapImage.IsPlaying) { bitmapImage.Play(); } else if (!controller.IsAnimationPlaying && bitmapImage.IsPlaying) { bitmapImage.Stop(); } bitmapImage.RegisterPropertyChangedCallback(BitmapImage.IsPlayingProperty, OnIsPlaying); } } }
public static async Task UpdateSource(IImageVisualElementRenderer renderer) { var Element = renderer.Element; var Control = renderer.GetNativeElement(); var imageElement = Element as IImageElement; if (renderer.IsDisposed || Element == null || Control == null) { return; } ImageSource placeholderError = null; if (imageElement is Image img) { placeholderError = img.ErrorPlaceholder; var source = await img.LoadingPlaceholder.ToWindowsImageSourceAsync(); renderer.SetImage(source); } var imageController = Element as IImageController; imageController?.SetIsLoading(true); try { var imagesource = await imageElement.Source.ToWindowsImageSourceAsync(); if (renderer.IsDisposed) { return; } if (imagesource is BitmapImage bitmapImage && _nativeAnimationSupport) { bitmapImage.AutoPlay = false; } if (Control != null) { renderer.SetImage(imagesource); } RefreshImage(renderer); // The ImageFailed event don't trigger when the local ImageSource is invalid, so we need to check the size. var size = renderer.GetDesiredSize(double.PositiveInfinity, double.PositiveInfinity); if (size.Request.IsZero && imageElement is Image) { imagesource = await placeholderError.ToWindowsImageSourceAsync(); renderer.SetImage(imagesource); } } finally { imageController?.SetIsLoading(false); } }
async static Task StartStopAnimation(IImageVisualElementRenderer renderer) { #if __MOBILE__ if (renderer.IsDisposed || renderer.Element == null || renderer.Control == null) { return; } if (renderer.GetImage() is FormsUIImageView imageView && renderer.Element is IImageElement imageElement && renderer.Element is IImageController imageController) { if (imageElement.IsLoading) { return; } if (imageView.Animation == null && imageElement.IsAnimationPlaying) { await SetImage(renderer, imageElement).ConfigureAwait(false); } if (imageView.Animation != null && imageElement.IsAnimationPlaying && !imageView.IsAnimating) { imageView.StartAnimating(); } else if (imageView.Animation != null && !imageElement.IsAnimationPlaying && imageView.IsAnimating) { imageView.StopAnimating(); } } #else await Task.CompletedTask; #endif }
static void OnControlChanged(object sender, EventArgs e) { IImageVisualElementRenderer renderer = sender as IImageVisualElementRenderer; var controller = renderer.Element as IImageElement; UpdateAspect(renderer, controller); }
public static async Task UpdateSource(IImageVisualElementRenderer renderer) { var Element = renderer.Element; var Control = renderer.GetNativeElement(); var imageElement = Element as IImageElement; if (renderer.IsDisposed || Element == null || Control == null) { return; } if (imageElement is Image img) { var source = await img.LoadingPlaceholder.ToWindowsImageSourceAsync(); renderer.SetImage(source); } var imageController = Element as IImageController; imageController?.SetIsLoading(true); try { // If it's a url image source and ToWindowsImageSourceAsync returns null, that was an error var imagesource = await imageElement.Source.ToWindowsImageSourceAsync(); if (imageElement.Source is UriImageSource && imagesource == null) { await DisplayErrorImage(renderer); return; } if (renderer.IsDisposed) { return; } if (imagesource is BitmapImage bitmapImage && _nativeAnimationSupport) { bitmapImage.AutoPlay = false; } if (Control != null) { renderer.SetImage(imagesource); } RefreshImage(renderer); } finally { imageController?.SetIsLoading(false); } }
static void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { IImageVisualElementRenderer renderer = sender as IImageVisualElementRenderer; var controller = renderer.Element as IImageElement; if (e.PropertyName == Image.AspectProperty.PropertyName) { UpdateAspect(renderer, controller); } }
static void OnElementChanged(object sender, VisualElementChangedEventArgs e) { if (e.NewElement != null) { IImageVisualElementRenderer renderer = sender as IImageVisualElementRenderer; var controller = renderer.Element as IImageElement; UpdateAspect(renderer, controller); } }
public static void SetOpacity(IImageVisualElementRenderer renderer, IImageElement imageElement) { var Element = renderer.Element; var Control = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } Control.Opaque = imageElement.IsOpaque; }
static internal void RefreshImage(IImageVisualElementRenderer renderer) { if (renderer.Element is IViewController element) { element?.InvalidateMeasure(InvalidationTrigger.RendererReady); } if (renderer.Element is IImageElement controller) { StartStopAnimation(renderer, controller); } }
public static async Task SetImage(IImageVisualElementRenderer renderer, IImageElement imageElement, Image oldElement = null) { _ = renderer ?? throw new ArgumentNullException(nameof(renderer), $"{nameof(ImageElementManager)}.{nameof(SetImage)} {nameof(renderer)} cannot be null"); _ = imageElement ?? throw new ArgumentNullException(nameof(imageElement), $"{nameof(ImageElementManager)}.{nameof(SetImage)} {nameof(imageElement)} cannot be null"); var Element = renderer.Element; var Control = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } var imageController = imageElement as IImageController; var source = imageElement.Source; if (oldElement != null) { var oldSource = oldElement.Source; if (Equals(oldSource, source)) { return; } if (oldSource is FileImageSource && source is FileImageSource && ((FileImageSource)oldSource).File == ((FileImageSource)source).File) { return; } renderer.SetImage(null); } imageController?.SetIsLoading(true); try { var uiimage = await source.GetNativeImageAsync(); if (renderer.IsDisposed) { return; } renderer.SetImage(Control == null ? null : uiimage); } finally { imageController?.SetIsLoading(false); } (imageElement as IViewController)?.NativeSizeChanged(); }
public static void SetAspect(IImageVisualElementRenderer renderer, IImageElement imageElement) { var Element = renderer.Element; var Control = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } Control.ContentMode = imageElement.Aspect.ToUIViewContentMode(); }
public static void SetOpacity(IImageVisualElementRenderer renderer, IImageElement imageElement) { var Element = renderer.Element; var Control = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } #if __MOBILE__ Control.Opaque = imageElement.IsOpaque; #else (Control as FormsNSImageView)?.SetIsOpaque(imageElement.IsOpaque); #endif }
public static void SetAspect(IImageVisualElementRenderer renderer, IImageElement imageElement) { var Element = renderer.Element; var Control = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } #if __MOBILE__ Control.ContentMode = imageElement.Aspect.ToUIViewContentMode(); #else Control.Layer.ContentsGravity = imageElement.Aspect.ToNSViewContentMode(); #endif }
public static void Dispose(IImageVisualElementRenderer renderer) { renderer.ElementPropertyChanged -= OnElementPropertyChanged; renderer.ElementChanged -= OnElementChanged; renderer.ControlChanged -= OnControlChanged; #if __MOBILE__ if (renderer.GetImage() is FormsUIImageView imageView && imageView.Animation != null) { imageView.Animation.AnimationStopped -= OnAnimationStopped; imageView.Animation.Dispose(); imageView.Animation = null; } #endif }
public static async Task UpdateSource(IImageVisualElementRenderer renderer) { var Element = renderer.Element; var Control = renderer.GetNativeElement(); var imageElement = Element as IImageElement; if (renderer.IsDisposed || Element == null || Control == null) { return; } var imageController = Element as IImageController; imageController?.SetIsLoading(true); ImageSource source = imageElement.Source; IImageSourceHandler handler; if (source != null && (handler = Registrar.Registered.GetHandlerForObject <IImageSourceHandler>(source)) != null) { Windows.UI.Xaml.Media.ImageSource imagesource; try { imagesource = await handler.LoadImageAsync(source); } catch (OperationCanceledException) { imagesource = null; } // In the time it takes to await the imagesource, some zippy little app // might have disposed of this Image already. if (Control != null) { renderer.SetImage(imagesource); } RefreshImage(imageElement as IViewController); } else { renderer.SetImage(null); imageController?.SetIsLoading(false); } }
internal static async Task DisplayErrorImage(IImageVisualElementRenderer renderer) { if (!(renderer?.Element is Image image)) { return; } ImageSource placeholderError = image.ErrorPlaceholder; if (placeholderError == null) { return; } var imagesource = await placeholderError.ToWindowsImageSourceAsync(); renderer.SetImage(imagesource); }
public static async Task UpdateSource(IImageVisualElementRenderer renderer) { var Element = renderer.Element; var Control = renderer.GetNativeElement(); var imageElement = Element as IImageElement; if (renderer.IsDisposed || Element == null || Control == null) { return; } var imageController = Element as IImageController; imageController?.SetIsLoading(true); try { var imagesource = await imageElement.Source.ToWindowsImageSourceAsync(); if (renderer.IsDisposed) { return; } if (imagesource is BitmapImage bitmapImage && _nativeAnimationSupport) { bitmapImage.AutoPlay = false; } if (Control != null) { renderer.SetImage(imagesource); } RefreshImage(renderer); } finally { imageController?.SetIsLoading(false); } }
public static void UpdateAspect(IImageVisualElementRenderer renderer, IImageElement controller) { var Element = renderer.Element; var Control = renderer.GetNativeElement(); var image = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } image.Stretch = GetStretch(controller.Aspect); if (controller.Aspect == Aspect.AspectFill || controller.Aspect == Aspect.AspectFit) { image.HorizontalAlignment = HorizontalAlignment.Center; image.VerticalAlignment = VerticalAlignment.Center; } else { image.HorizontalAlignment = HorizontalAlignment.Left; image.VerticalAlignment = VerticalAlignment.Top; } }
public static void Dispose(IImageVisualElementRenderer renderer) { renderer.ElementPropertyChanged -= OnElementPropertyChanged; renderer.ElementChanged -= OnElementChanged; renderer.ControlChanged -= OnControlChanged; }
static void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { IImageVisualElementRenderer renderer = sender as IImageVisualElementRenderer;
public static async Task SetImage(IImageVisualElementRenderer renderer, IImageElement imageElement, Image oldElement = null) { _ = renderer ?? throw new ArgumentNullException(nameof(renderer), $"{nameof(ImageElementManager)}.{nameof(SetImage)} {nameof(renderer)} cannot be null"); _ = imageElement ?? throw new ArgumentNullException(nameof(imageElement), $"{nameof(ImageElementManager)}.{nameof(SetImage)} {nameof(imageElement)} cannot be null"); var Element = renderer.Element; var Control = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } var imageController = imageElement as IImageController; var source = imageElement.Source; if (Control.Image?.Images != null && Control.Image.Images.Length > 1) { renderer.SetImage(null); } else if (oldElement != null) { var oldSource = oldElement.Source; if (Equals(oldSource, source)) { return; } if (oldSource is FileImageSource oldFile && source is FileImageSource newFile && oldFile == newFile) { return; } renderer.SetImage(null); } imageController?.SetIsLoading(true); try { var uiimage = await source.GetNativeImageAsync(); if (renderer.IsDisposed) { return; } // only set if we are still on the same image if (Control != null && imageElement.Source == source) { renderer.SetImage(uiimage); } else { uiimage?.Dispose(); } } finally { // only mark as finished if we are still on the same image if (imageElement.Source == source) { imageController?.SetIsLoading(false); } } (imageElement as IViewController)?.NativeSizeChanged(); }
public static async Task SetImage(IImageVisualElementRenderer renderer, IImageElement imageElement, Image oldElement = null) { _ = renderer ?? throw new ArgumentNullException($"{nameof(ImageElementManager)}.{nameof(SetImage)} {nameof(renderer)} cannot be null"); _ = imageElement ?? throw new ArgumentNullException($"{nameof(ImageElementManager)}.{nameof(SetImage)} {nameof(imageElement)} cannot be null"); var Element = renderer.Element; var Control = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } var imageController = imageElement as IImageController; var source = imageElement.Source; if (oldElement != null) { var oldSource = oldElement.Source; if (Equals(oldSource, source)) { return; } if (oldSource is FileImageSource && source is FileImageSource && ((FileImageSource)oldSource).File == ((FileImageSource)source).File) { return; } renderer.SetImage(null); } IImageSourceHandler handler; imageController?.SetIsLoading(true); try { if (source != null && (handler = Internals.Registrar.Registered.GetHandlerForObject <IImageSourceHandler>(source)) != null) { UIImage uiimage; try { uiimage = await handler.LoadImageAsync(source, scale : (float)UIScreen.MainScreen.Scale); } catch (OperationCanceledException) { uiimage = null; } if (renderer.IsDisposed) { return; } var imageView = Control; if (imageView != null) { renderer.SetImage(uiimage); } } else { renderer.SetImage(null); } } finally { imageController?.SetIsLoading(false); } (imageElement as IViewController)?.NativeSizeChanged(); }
public static async Task SetImage(IImageVisualElementRenderer renderer, IImageElement imageElement, Image oldElement = null) { _ = renderer ?? throw new ArgumentNullException(nameof(renderer), $"{nameof(ImageElementManager)}.{nameof(SetImage)} {nameof(renderer)} cannot be null"); _ = imageElement ?? throw new ArgumentNullException(nameof(imageElement), $"{nameof(ImageElementManager)}.{nameof(SetImage)} {nameof(imageElement)} cannot be null"); var Element = renderer.Element; var Control = renderer.GetImage(); if (renderer.IsDisposed || Element == null || Control == null) { return; } var imageController = imageElement as IImageController; var source = imageElement.Source; #if __MOBILE__ if (Control.Image?.Images != null && Control.Image.Images.Length > 1) { renderer.SetImage(null); } #else if (Control.Image != null && Control.Image.Representations().Length > 1) { renderer.SetImage(null); } #endif else if (oldElement != null) { var oldSource = oldElement.Source; if (Equals(oldSource, source)) { return; } if (oldSource is FileImageSource oldFile && source is FileImageSource newFile && oldFile == newFile) { return; } #if __MOBILE__ if (Control is FormsUIImageView imageView) { if (imageView.Animation != null) { Control.StopAnimating(); imageView.AnimationStopped -= OnAnimationStopped; imageView.Animation.Dispose(); } renderer.SetImage(null); imageView.Animation = null; } #endif } imageController?.SetIsLoading(true); try { #if __MOBILE__ bool useAnimation = imageController.GetLoadAsAnimation(); IAnimationSourceHandler handler = null; if (useAnimation && source != null) { handler = Controls.Internals.Registrar.Registered.GetHandlerForObject <IAnimationSourceHandler>(source); } if (handler != null) { FormsCAKeyFrameAnimation animation = await handler.LoadImageAnimationAsync(source, scale : (float)UIScreen.MainScreen.Scale).ConfigureAwait(false); if (animation != null && Control is FormsUIImageView imageView && imageElement.Source == source) { if (imageView.Animation != null) { imageView.AnimationStopped -= OnAnimationStopped; } imageView.Animation = animation; imageView.AnimationStopped += OnAnimationStopped; if ((bool)Element.GetValue(Image.IsAnimationPlayingProperty)) { imageView.StartAnimating(); } } else { animation?.Dispose(); } } else #endif { var uiimage = await source.GetNativeImageAsync(); if (renderer.IsDisposed) { return; } // only set if we are still on the same image if (Control != null && imageElement.Source == source) { renderer.SetImage(uiimage); } else { uiimage?.Dispose(); } } }