static IControl ImageImpl( IScheduler dispatcher, IObservable <IImage> streams, Optional <IObservable <Color> > overlayColor, Optional <IObservable <IColorMap> > colorMap, Optional <IObservable <Ratio <Pixels, Points> > > dpiOverride) { BehaviorSubject <Size <Points> > desiredSize = new BehaviorSubject <Size <Points> >(Size.Zero <Points>()); return(Control.Create( ctrl => { var dummyControl = new DpiAwareView() { AutoresizesSubviews = true }; ctrl.BindNativeDefaults(dummyControl, dispatcher); var tintedImage = new TintedImage() { AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.HeightSizable }; dummyControl.AddSubview(tintedImage); ctrl.BindNativeProperty(dispatcher, "image", dpiOverride.Or(dummyControl.GetDpi()) .CombineLatest(streams, colorMap.Select(x => x.Select(Optional.Some)).Or(Observable.Return <Optional <IColorMap> >(Optional.None())), (dpi, imgStreams, cm) => new { dpi, imgStreams, colorMap = cm }), x => { var iv = x.imgStreams.Load <NSImage>(x.dpi, x.colorMap); tintedImage.CurrentImage = iv.Image; tintedImage.SetFrameSize(dummyControl.Frame.Size); var size = Size.Create <Pixels>((double)iv.Image.Size.Width, (double)iv.Image.Size.Height) / iv.ScaleFactor; desiredSize.OnNext(size); }); overlayColor.Do( colorObs => { ctrl.BindNativeProperty( dispatcher, "tintColor", colorObs, color => tintedImage.TintColor = color.ToNSColor()); }); return dummyControl; }).WithSize(desiredSize.Transpose())); }
static IControl AnimateImpl(IList <ImageStream> streams, TimeSpan duration, IObservable <Color> overlayColor, IScheduler dispatcher) { var imgSize = new Size <Points>(0, 0); return(Control.Create( ctrl => { var nsimages = new List <NSImage>(); foreach (var imageStream in streams) { var img = NSImage.FromStream(imageStream.Create()); imgSize = imgSize.Max((double)img.Size.Width, (double)img.Size.Height); nsimages.Add(img); } var timePerImage = duration.TotalMilliseconds / nsimages.Count; var images = Observable.Interval(TimeSpan.FromMilliseconds((int)timePerImage)) .Select(f => nsimages[(int)f % nsimages.Count]); var dummyControl = new DpiAwareView() { AutoresizesSubviews = true }; dummyControl .GetDpi() .ConnectWhile(ctrl.IsRooted) .Select( dpi => Observable.FromAsync( async() => { var tintedImage = await Fusion.Application.MainThread.InvokeAsync( () => new TintedImage(nsimages[0], false) { AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.HeightSizable }); ctrl.BindNativeProperty( dispatcher, "currImage", images, image => tintedImage.CurrentImage = image); ctrl.BindNativeProperty( dispatcher, "tintColor", overlayColor, color => tintedImage.TintColor = color.ToNSColor()); await Fusion.Application.MainThread.InvokeAsync( () => { if (dummyControl.Subviews.IsEmpty() == false) { dummyControl.Subviews.Last().RemoveFromSuperview(); } tintedImage.SetFrameSize(dummyControl.Frame.Size); dummyControl.AddSubview(tintedImage); return Unit.Default; }); return Unit.Default; })) .Concat() .Subscribe(); ctrl.BindNativeDefaults(dummyControl, dispatcher); return dummyControl; }).WithSize(imgSize)); }