private async void ResizeWebView(object sender, EventArgs eventArgs)
        {
            var isActuallyReallyFinishedLoadingForRealz = false;

            while (!isActuallyReallyFinishedLoadingForRealz)
            {
                var result = _webView.EvaluateJavascript("(function (){return true})();");
                bool.TryParse(result, out isActuallyReallyFinishedLoadingForRealz);
            }

            var frame = _webView.Frame;

            frame.Height = 10;

            _webView.Frame = frame;

            var fittingSize = _webView.SizeThatFits(SizeF.Empty);

            frame.Size = fittingSize;

            _webView.Frame            = frame;
            _webView.ScrollView.Frame = frame;

            var bounds = new Rectangle(Element.Bounds.X, Element.Bounds.Y, Element.Bounds.Width, frame.Height);
            await Element.LayoutTo(bounds, Element.TransitionSpeedMsec, Element.Easing);

            Element.HeightRequest = bounds.Height;
        }
        private void DrawCustomShapeDrawing()
        {
            if (customShapeDrawing != null)
            {
                var poly = new Polygon();

                poly.DataContext = Element;

                poly.Fill   = (SolidColorBrush) new ColorConverter().Convert(customShapeDrawing.ShapeColor, null, null, null);
                poly.Stroke = (SolidColorBrush) new ColorConverter().Convert(customShapeDrawing.BorderColor, null, null, null);

                poly.Points = new PointCollection();

                Xamarin.Forms.Rectangle rect = new Xamarin.Forms.Rectangle(0, 0, customShapeDrawing.Width, customShapeDrawing.Height);

                rect.Size = new Size(customShapeDrawing.Width, customShapeDrawing.Height);
                foreach (XYCoordinate xy in customShapeDrawing.PointsShapeCoordinateList)
                {
                    poly.Points.Add(new Windows.Foundation.Point(rect.Width * xy.X, rect.Height * xy.Y));
                }
                poly.FillRule = FillRule.EvenOdd;

                SetNativeControl(poly);
            }
        }
Пример #3
0
 private void RenderScene(Xamarin.Forms.Rectangle rect)
 {
     camera.SetViewPort((float)rect.Width, (float)rect.Height);
     firstObject.Rotate(new Vector3(0, 1, 0), ang);
     ang = ang + 1;
     firstObject.Render(camera);
     GL.Finish();
 }
Пример #4
0
 /// <summary>
 /// Sets the position of the button afterwards for all android versions below Lollipop, where the calculated fabSize is not correct.
 /// This repositioning cannot be done in the OnSizeAllocated method because the button have to be
 /// added first to get the right button width and height.
 /// </summary>
 private void SetButtonPosition(double width)
 {
     Button.SizeChanged += (sender, e) =>
     {
         var buttonRect = new Rectangle
         {
             Top  = Height - bottomSheetSize - Button.Height / 2,
             Size = new Size(Button.Width, Button.Height),
             X    = width - buttonRightPadding - Button.Width
         };
         Button.LayoutTo(buttonRect, 0);
     };
 }
		public async override void LayoutSubviews ()
		{
			base.LayoutSubviews ();

			var contenSizeHeight = _tableView.ContentSize.Height;
			var frame = _tableView.Frame;
			frame.Height = contenSizeHeight;

			_tableView.Frame = frame;

			var bounds = new Xamarin.Forms.Rectangle(Element.Bounds.X, Element.Bounds.Y, Element.Bounds.Width, frame.Height);
			await Element.LayoutTo(bounds, _formsListView.TransitionSpeedMsec, _formsListView.Easing);
			_formsListView.HeightRequest = bounds.Height;
		}
Пример #6
0
        void OnKeyboardNotification(NSNotification notification)
        {
            if (!IsViewLoaded)
            {
                return;
            }
            var frameBegin = UIKeyboard.FrameBeginFromNotification(notification);
            var frameEnd   = UIKeyboard.FrameEndFromNotification(notification);
            var bounds     = Element.Bounds;
            var newBounds  = new Xamarin.Forms.Rectangle(bounds.Left, bounds.Top, bounds.Width, bounds.Height - frameBegin.Top + frameEnd.Top);

            Element.Layout(newBounds);

            this.replaceKeyboardInputAccessoryView();
        }
Пример #7
0
 /// <summary>
 /// Layout the botton sheet to it's pending state, with animation.
 /// </summary>
 /// <returns>The task.</returns>
 private async Task SetBottomSheetPending()
 {
     Rectangle bottomSheetRect = new Rectangle
     {
         Left = 0,
         Top  = Height * (1 - bottomSheetExtensionFraction / 2),
         Size = new Size(Width, Height * bottomSheetExtensionFraction / 2)
     };
     Rectangle buttonRect = new Rectangle
     {
         Top  = bottomSheetRect.Top - Button.Height / 2,
         Size = new Size(Button.Width, Button.Height),
         X    = Button.X
     };
     await Task.WhenAll(BottomSheetContentView.LayoutTo(bottomSheetRect), Button.LayoutTo(buttonRect));
 }
Пример #8
0
        public static UIView ConvertFormsToNative(View view, Rectangle rect)
        {
            var renderer = Platform.CreateRenderer(view);

            renderer.NativeView.Frame = new CGRect(0, 0, rect.Width, rect.Height);

            renderer.NativeView.AutoresizingMask = UIViewAutoresizing.All;
            renderer.NativeView.ContentMode      = UIViewContentMode.ScaleToFill;

            renderer.Element.Layout(rect);

            var nativeView = renderer.NativeView;

            nativeView.SetNeedsLayout();

            return(nativeView);
        }
Пример #9
0
        async void OnScrollRequestedAsync(object sender, ScrollToRequestedEventArgs e)
        {
            var x = e.ScrollX;
            var y = e.ScrollY;

            if (e.Mode == ScrollToMode.Element)
            {
                var itemPosition = (Element as IScrollViewController).GetScrollPositionForElement(e.Element as VisualElement, e.Position);
                x = itemPosition.X;
                y = itemPosition.Y;
            }
            var region = new Xamarin.Forms.Rectangle(x, y, Element.Width, Element.Height).ToPixel();

            await ScrollToAsync(region, e.ShouldAnimate).ConfigureAwait(false);

            Element.SendScrollFinished();
        }
Пример #10
0
        /// <summary>
        /// Touch handling
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
        {
            var parent = VisualTreeHelper.GetParent(this);

            while (parent != null)
            {
                if (parent is PhoneApplicationPage)
                {
                    var page = parent as PhoneApplicationPage;

                    // Get this' position on screen
                    var transform        = this.TransformToVisual(page);
                    var absolutePosition = transform.Transform(new System.Windows.Point(0, 0));
                    var ourRect          = new Xamarin.Forms.Rectangle(absolutePosition.X, absolutePosition.Y, this.Width, this.Height);

                    // Get main touch point
                    var mainTouchPoint = e.GetPrimaryTouchPoint(page);

                    // Make sure our control is actually in the touch zone
                    if (!ourRect.Contains(mainTouchPoint.Position.X, mainTouchPoint.Position.Y))
                    {
                        return;
                    }

                    var touches = e.GetTouchPoints(this).Select(t => new NGraphics.Point(t.Position.X, t.Position.Y));

                    if (mainTouchPoint.Action == TouchAction.Move)
                    {
                        Element.TouchesMoved(touches);
                    }
                    else if (mainTouchPoint.Action == TouchAction.Down)
                    {
                        Element.TouchesBegan(touches);
                    }
                    else if (mainTouchPoint.Action == TouchAction.Up)
                    {
                        Element.TouchesEnded(touches);
                    }

                    break;
                }

                parent = VisualTreeHelper.GetParent(parent);
            }
        }
Пример #11
0
        private void ShowPopup(View view)
        {
            if (CrossMediaManager.Current.IsPlaying())
            {
                CrossMediaManager.Current.Stop();
            }
            var positionInParent       = _viewCoordinatesService.GetCoordinates(view);
            var absoluteLayoutInParent = _viewCoordinatesService.GetCoordinates(SizerView);

            _detailsPopupView = new MovieDetailsPopupView((Domain.Models.Movie)view.BindingContext);

            var absoluteX         = positionInParent.X - absoluteLayoutInParent.X;
            var absoluteY         = positionInParent.Y - absoluteLayoutInParent.Y;
            var popupInitialFrame = new Rectangle((int)absoluteX, (int)absoluteY, (int)view.Width, (int)view.Height);

            RootLayout.Children.Add(_detailsPopupView, popupInitialFrame);
            _detailsPopupView.Open(this, popupInitialFrame, RootLayout.Width, RootLayout.Height);
        }
Пример #12
0
        /// <summary>
        /// Layout the bottom sheet to its extended state, with animation.
        /// </summary>
        /// <returns>The task.</returns>
        private async Task ExtendBottomSheet()
        {
            var bottomSheetRect = new Rectangle
            {
                Left = 0,
                Top  = Height * (1 - bottomSheetExtensionFraction),
                Size = new Size(Width, Height * bottomSheetExtensionFraction)
            };
            var buttonRect = new Rectangle
            {
                Top  = bottomSheetRect.Top - Button.Height / 2,
                Size = new Size(Button.Width, Button.Height),
                X    = Button.X
            };
            await Task.WhenAll(BottomSheetContentView.LayoutTo(bottomSheetRect), Button.LayoutTo(buttonRect), Button.RotateXTo(180));

            bottomSheetState = BottomSheetState.Extended;
        }
Пример #13
0
        /// <summary>
        /// Layout the bottom sheet to its collapsed state, with animation.
        /// </summary>
        /// <returns>The task.</returns>
        private async Task CollapseBottomSheet()
        {
            var bottomSheetRect = new Rectangle
            {
                Left = 0,
                Top  = Height - bottomSheetSize,
                Size = new Size(Width, bottomSheetSize)
            };
            var buttonRect = new Rectangle
            {
                Top  = bottomSheetRect.Top - Button.Height / 2,
                Size = new Size(Button.Width, Button.Height),
                X    = Button.X
            };
            await Task.WhenAll(BottomSheetContentView.LayoutTo(bottomSheetRect), Button.LayoutTo(buttonRect), Button.RotateXTo(0));

            bottomSheetState = BottomSheetState.Collapsed;
        }
Пример #14
0
 /// <summary>
 /// Essa aqui é a função que trata da renderização da view de opengl;
 /// </summary>
 /// <param name="rect"></param>
 private void OpenGLViewOnDisplay(Xamarin.Forms.Rectangle rect)
 {
     GL.Viewport((int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height);
     if (!Initialized)
     {
         InitializeScene(rect);
     }
     GL.ClearColor(currentR, 0, 0, 1.0f);
     GL.Clear((ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit));
     currentR += 0.01f;
     if (currentR >= 1.0f)
     {
         currentR = 0;
     }
     if (Initialized)
     {
         RenderScene(rect);
     }
 }
Пример #15
0
        private void InitializeScene(Xamarin.Forms.Rectangle rect)
        {
            GL.Enable(All.DepthTest);
            GL.Disable(All.CullFace);
            GL.Enable(All.Texture2D);
            GL.Enable(All.Blend);
            GL.BlendFunc(All.One, All.Zero);

            camera = new Camera((float)rect.Width, (float)rect.Height);
            float[] focus = new float[] { 0, 0, 0 };
            float[] eye   = new float[] { 5, 0, 100 };
            float[] vup   = new float[] { 0, 1, 0 };
            camera.LookAt(focus, eye, vup);

            Object3dSource firstObjectSource = new FileReaderObject3dSource();

            firstObject = firstObjectSource.Fabricate();
            Initialized = true;
        }
Пример #16
0
        private Android.Views.View ConvertFormsToNative(Xamarin.Forms.View view, Xamarin.Forms.Rectangle size)
        {
            viewRenderer = Platform.CreateRendererWithContext(view, Context);
            var viewGroup = viewRenderer.View;

            viewRenderer.Tracker.UpdateLayout();

            if (view.HeightRequest > 0)
            {
                size.Height = view.HeightRequest;
            }

            var layoutParams = new ViewGroup.LayoutParams((int)(size.Width * Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density), (int)(size.Height * Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density));

            viewGroup.LayoutParameters = layoutParams;
            view.Layout(size);
            viewGroup.Layout(0, 0, (int)view.Width, (int)view.Height);
            return(viewGroup);
        }
Пример #17
0
 public static T Rect <T>(this T rectanglegeometry, Xamarin.Forms.Rectangle rect) where T : IRxRectangleGeometry
 {
     rectanglegeometry.Rect = rect;
     return(rectanglegeometry);
 }
Пример #18
0
 public static RectangleF ToRectangleF(this Rectangle rect)
 {
     return new RectangleF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height);
 }
Пример #19
0
        public App()
        {
            // Sample text from Treasure Island (Stevenson, 1894).
            var sampleText = "SQUIRE TRELAWNEY, Dr. Livesey, and the rest of these gentlemen having asked me to write down the whole particulars about Treasure Island, from the beginning to the end, keeping nothing back but the bearings of the island, and that only because there is still treasure not yet lifted, I take up my pen in the year of grace 17__ and go back to the time when my father kept the Admiral Benbow inn and the brown old seaman with the sabre cut first took up his lodging under our roof.";
            Func <MoveDetails, MoveDetails> doSomeFunMoving = (moveDetails) => {
                double    moveDelta = (moveDetails.DeltaMovement.Height < 0 ? moveDetails.DeltaMovement.Height : 0.0);              // currently only move for up panning
                Point     location;
                float     width = (float)moveDetails.CurrentBounds.Width;
                SizeF     remainingDelta;
                Rectangle bounds;
                while (moveDetails.DeltaMovement != SizeF.Empty)
                {
                    bounds         = moveDetails.CurrentBounds;
                    location       = bounds.Location;
                    remainingDelta = moveDetails.DeltaMovement;
                    switch (moveDetails.MoveIndex)
                    {
                    case 0:
                        location.Y += moveDelta;
                        if (location.Y < 0)
                        {
                            // Overshot destination; put the rest back; move on.
                            remainingDelta.Height  = (float)location.Y;
                            location.Y             = 0;
                            moveDetails.MoveIndex += 1;
                        }
                        else
                        {
                            remainingDelta = SizeF.Empty;
                        }
                        break;

                    case 1:
                        var  right        = bounds.Right;
                        var  left         = bounds.Left;
                        var  parentCenter = moveDetails.ParentBounds.Center.X;
                        bool moveLeft     = right < parentCenter || (parentCenter - left > right - parentCenter);
                        if (moveLeft)
                        {
                            location.X += moveDelta;
                        }
                        else
                        {
                            location.X -= moveDelta;
                        }
                        if (location.X < 0 || location.X + width > moveDetails.ParentBounds.Right)
                        {
                            // Overshot destination; put the rest back; move on.
                            if (location.X < 0)
                            {
                                remainingDelta.Height = (float)location.X;
                                location.X            = 0;
                            }
                            else
                            {
                                remainingDelta.Height = (float)moveDetails.ParentBounds.Right - width - (float)location.X;
                                location.X            = moveDetails.ParentBounds.Right - width;
                            }
                            moveDetails.DeltaMovement = remainingDelta;
                            moveDetails.MoveIndex    += 1;
                        }
                        else
                        {
                            remainingDelta = SizeF.Empty;
                        }
                        break;

                    case 2:
                        location.Y -= moveDelta;
                        if (location.Y > moveDetails.ParentBounds.Height)
                        {
                            // We're done now; zero out to stop loop.
                            remainingDelta         = SizeF.Empty;
                            moveDetails.MoveIndex += 1;
                        }
                        else
                        {
                            remainingDelta = SizeF.Empty;
                        }
                        break;

                    default:
                        remainingDelta = SizeF.Empty;
                        break;
                    }
                    bounds.Location           = location;
                    moveDetails.DeltaMovement = remainingDelta;
                    moveDetails.CurrentBounds = bounds;
                }
                return(moveDetails);
            };

            var wordLabels = sampleText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(word => new MovableLabel(doSomeFunMoving)
            {
                Text = word,
            }).ToList();

            funkyAbsoluteLayout = new AbsoluteLayout();
            foreach (var wordLabel in wordLabels)
            {
                funkyAbsoluteLayout.Children.Add(wordLabel);
            }
            ;
            const double lineLeading = 3;
            const double wordSpacing = 3;

            funkyAbsoluteLayout.SizeChanged += (sender, e) => {
                // Lay out a bunch of text manually, because YOLO and such.
                double x = 0;
                double y = 0;
                foreach (var wordLabel in wordLabels)
                {
                    if (x + wordLabel.Bounds.Width > funkyAbsoluteLayout.Width)
                    {
                        // NOTE: totally fails to wrap words longer than `funkyAbsoluteLayout.Width`.
                        y += wordLabel.Bounds.Height + lineLeading;
                        x  = 0;
                    }
                    var newBounds = new Rectangle(new Point(x, y), wordLabel.Bounds.Size);
                    AbsoluteLayout.SetLayoutBounds(wordLabel, newBounds);
                    x = newBounds.Right + wordSpacing;
                }
            };

            var touchesContentPage = new TouchesContentPage {
                Content         = funkyAbsoluteLayout,
                Padding         = new Thickness(5, Device.OnPlatform(iOS: 25, Android: 5, WinPhone: 5), 5, 5),
                BackgroundColor = Color.Aqua,
            };

            touchesContentPage.OnPanned += (object sender, SizeF e) => {
                // TODO: Parallel.ForEach?
                var parentBoundsWithoutPadding = touchesContentPage.Bounds;
                parentBoundsWithoutPadding.Height -= touchesContentPage.Padding.Bottom + touchesContentPage.Padding.Top;
                parentBoundsWithoutPadding.Width  -= touchesContentPage.Padding.Right + touchesContentPage.Padding.Left;
                foreach (var wordLabel in wordLabels)
                {
                    var moveDetails = new MoveDetails {
                        ParentBounds  = parentBoundsWithoutPadding,
                        CurrentBounds = wordLabel.Bounds,
                        DeltaMovement = e,
                    };
                    var resultMoveDetails = wordLabel.CalculateNewPosition(moveDetails);
                    AbsoluteLayout.SetLayoutBounds(wordLabel, resultMoveDetails.CurrentBounds);
                }
            };
            MainPage = touchesContentPage;
        }
Пример #20
0
        private void OnUpdateNativeControl(CALayer caLayer)
        {
            VisualElement view       = this.Renderer.Element;
            NSView        nativeView = this.Renderer.NativeView;

            if (view == null || view.Batched)
            {
                return;
            }
            if (this.inputTransparent != view.InputTransparent)
            {
                // TODO: WT.?
                //nativeView.UserInteractionEnabled = !view.InputTransparent;
                this.inputTransparent = view.InputTransparent;
            }
            bool   boundsChanged = this.lastBounds != view.Bounds;
            int    num           = boundsChanged ? 0 : (!caLayer.Frame.IsEmpty ? 1 : 0);
            float  anchorX       = (float)view.AnchorX;
            float  anchorY       = (float)view.AnchorY;
            float  translationX  = (float)view.TranslationX;
            float  translationY  = (float)view.TranslationY;
            float  rotationX     = (float)view.RotationX;
            float  rotationY     = (float)view.RotationY;
            float  rotation      = (float)view.Rotation;
            float  scale         = (float)view.Scale;
            float  width         = (float)view.Width;
            float  height        = (float)view.Height;
            float  x             = (float)view.X;
            float  y             = (float)view.Y;
            float  opacity       = (float)view.Opacity;
            bool   isVisible     = (view.IsVisible ? 1 : 0) != 0;
            int    updateTarget  = Interlocked.Increment(ref this.updateCount);
            Action action        = (Action)(() =>
            {
                if (updateTarget != this.updateCount)
                {
                    return;
                }
                VisualElement visualElement = view;
                Element parent = view.Parent;
                bool flag = false;
                if (isVisible && caLayer.Hidden)
                {
                    caLayer.Hidden = false;
                    if (!caLayer.Frame.IsEmpty)
                    {
                        flag = true;
                    }
                }
                if (!isVisible && !caLayer.Hidden)
                {
                    caLayer.Hidden = true;
                    flag = true;
                }
                CATransform3D caTransform3D = CATransform3D.Identity;
                if (((visualElement is Page && !(visualElement is ContentPage) || ((double)width <= 0.0 || (double)height <= 0.0) ? 0 : (parent != null ? 1 : 0)) & (boundsChanged ? 1 : 0)) != 0)
                {
                    RectangleF rectangleF = new RectangleF(x, y, width, height);
                    caLayer.Transform = caTransform3D;
                    caLayer.Frame = (CGRect)rectangleF;
                    if (flag)
                    {
                        caLayer.LayoutSublayers();
                    }
                }
                else if ((double)width <= 0.0 || (double)height <= 0.0)
                {
                    caLayer.Hidden = true;
                    return;
                }
                caLayer.AnchorPoint = (CGPoint) new PointF(anchorX, anchorY);
                caLayer.Opacity = opacity;
                if (Math.Abs((double)anchorX - 0.5) > 0.001)
                {
                    caTransform3D = caTransform3D.Translate((nfloat)((anchorX - 0.5f) * width), (nfloat)0, (nfloat)0);
                }
                if (Math.Abs((double)anchorY - 0.5) > 0.001)
                {
                    caTransform3D = caTransform3D.Translate((nfloat)0, (nfloat)((anchorY - 0.5f) * height), (nfloat)0);
                }
                if ((double)Math.Abs(translationX) > 0.001 || (double)Math.Abs(translationY) > 0.001)
                {
                    caTransform3D = caTransform3D.Translate((nfloat)translationX, (nfloat)translationY, (nfloat)0);
                }
                if ((double)Math.Abs(scale - 1f) > 0.001)
                {
                    caTransform3D = caTransform3D.Scale((nfloat)scale);
                }
                if ((double)Math.Abs(rotationY % 180f) > 0.001 || (double)Math.Abs(rotationX % 180f) > 0.001)
                {
                    caTransform3D.m34 = (nfloat)(-1.0 / 400.0);
                }
                if ((double)Math.Abs(rotationX % 360f) > 0.001)
                {
                    caTransform3D = caTransform3D.Rotate((nfloat)((float)((double)rotationX * 3.14159274101257 / 180.0)), (nfloat)1f, (nfloat)0.0f, (nfloat)0.0f);
                }
                if ((double)Math.Abs(rotationY % 360f) > 0.001)
                {
                    caTransform3D = caTransform3D.Rotate((nfloat)((float)((double)rotationY * 3.14159274101257 / 180.0)), (nfloat)0.0f, (nfloat)1f, (nfloat)0.0f);
                }
                caTransform3D = caTransform3D.Rotate((nfloat)((float)((double)rotation * 3.14159274101257 / 180.0)), (nfloat)0.0f, (nfloat)0.0f, (nfloat)1f);
                caLayer.Transform = caTransform3D;
            });

            // TODO: Figure this out

            /*
             * if (num != 0)
             *      CADisplayLinkTicker.Default.Invoke (action);
             * else
             */
            action();
            this.lastBounds = view.Bounds;
        }
Пример #21
0
 public static void FillRoundedRect(this IGraphics g, Xamarin.Forms.Rectangle r, double radius)
 {
     g.FillRoundedRect(r.Left, r.Top, r.Width, r.Height, radius);
 }
Пример #22
0
 public static void DrawImage(this IGraphics g, IImage img, Xamarin.Forms.Rectangle r)
 {
     g.DrawImage(img, r.X, r.Y, r.Width, r.Height);
 }
Пример #23
0
        public static List <Xamarin.Forms.Rectangle> GetIntersections(this List <Xamarin.Forms.Rectangle> boxes, Xamarin.Forms.Rectangle box)
        {
            var r = new List <Xamarin.Forms.Rectangle> ();

            foreach (var b in boxes)
            {
                if (b.IntersectsWith(box))
                {
                    r.Add(b);
                }
            }
            return(r);
        }
Пример #24
0
 public static Xamarin.Forms.Point GetCenter(this Xamarin.Forms.Rectangle r)
 {
     return(new Xamarin.Forms.Point(r.Left + r.Width / 2,
                                    r.Top + r.Height / 2));
 }
 public OverlayPlaylistLikeTutorialView(Xamarin.Forms.Rectangle likeContainerPosition, int totalLikes)
 {
     InitializeComponent();
     _likeContainerPosition = likeContainerPosition;
     _totalLikes            = totalLikes;
 }
Пример #26
0
        public void SetPage(int page, int direction)
        {
            if (!_initialised)
            {
                throw new Exception("ExtendedCarouselView has not been initialised");
            }
            else
            {
                if (!_animating)
                {
                    // Prevent users from mashing the buttons when the app isnt ready.
                    _animating = true;

                    // Increase the page
                    _currentPage = page;

                    // Wrap pages around: (might not be necessary)
                    if (_currentPage > Pages.Count - 1)
                    {
                        _currentPage = 0;
                    }
                    else if (_currentPage < 0)
                    {
                        _currentPage = Pages.Count - 1;
                    }

                    ScrollView mainpgsv;
                    ScrollView nextpgsv;
                    ContentView mainpg;
                    ContentView nextpg;

                    // Prepare references to the pages to prepare for animation.
                    if (!_usingAltPage)
                    {
                        mainpgsv = _mainPageSV;
                        mainpg = _mainPage;

                        nextpgsv = _altPageSV;
                        nextpg = _altPage;
                    }
                    else
                    {
                        mainpgsv = _altPageSV;
                        mainpg = _altPage;

                        nextpgsv = _mainPageSV;
                        nextpg = _mainPage;
                    }
                    _usingAltPage = !_usingAltPage;

                    // Prepare view dimentions each time the page changes so layout alterations are
                    // not then fixed.
                    _dimen = new Rectangle(mainpgsv.X, mainpgsv.Y, mainpgsv.Width, mainpgsv.Height);

                    // Prepare next page, move into position and scroll appropriately.
                    var cpageModel = Pages[_currentPage];
                    nextpg.Content = cpageModel;

                    // Aniamtion is about to occurr, perform the 'OnAppearing' code
                    var iNextPgContent = nextpg.Content as IExtendedCarouselPage;
                    var iMainPgContent = mainpg.Content as IExtendedCarouselPage;
                    Page_Appearing(iNextPgContent);
                    Page_Disappearing(iMainPgContent);

                    // Inform the animation framework that we have a batch of aniamtions to perform
                    mainpgsv.BatchBegin();
                    nextpgsv.BatchBegin();

                    nextpgsv.ScrollToAsync(0, 0, false);
                    if (direction >= 0)
                    {
                        nextpgsv.Layout(new Rectangle(_dimen.X + _dimen.Width, _dimen.Y, _dimen.Width, _dimen.Height));
                    }
                    else
                    {
                        nextpgsv.Layout(new Rectangle(_dimen.X - _dimen.Width, _dimen.Y, _dimen.Width, _dimen.Height));
                    }

                    /* This is very important. Without it, interacting with entry elements in the view would cause
					 * the current page to swap beneath the previous page. This presumably is to do with the fact
					 * that animations dont layout the views as android normally would, so they snap back into their
					 * calculated positions when something (such as the keybaord) would cause the views to recalcualte. */
                    _baseLayout.RaiseChild(nextpgsv);

                    if (direction >= 0)
                    {
                        mainpgsv.LayoutTo(new Rectangle(_dimen.X - _dimen.Width, _dimen.Y, _dimen.Width, _dimen.Height), pageAnimationTime, Easing.CubicInOut);
                        nextpgsv.LayoutTo(new Rectangle(_dimen.X, _dimen.Y, _dimen.Width, _dimen.Height), pageAnimationTime, Easing.CubicInOut).ContinueWith((Task arg1) =>
                        {
                            _animating = false;
                            // Aniamtion is ending, alert the events
                            Page_Disappeared(iMainPgContent);
                            Page_Appeared(iNextPgContent);
                        });
                    }
                    else
                    {
                        mainpgsv.LayoutTo(new Rectangle(_dimen.X + _dimen.Width, _dimen.Y, _dimen.Width, _dimen.Height), pageAnimationTime, Easing.CubicInOut);
                        nextpgsv.LayoutTo(new Rectangle(_dimen.X, _dimen.Y, _dimen.Width, _dimen.Height), pageAnimationTime, Easing.CubicInOut).ContinueWith((Task arg1) =>
                        {
                            _animating = false;
                            // Aniamtion is ending, alert the events
                            Page_Disappeared(iMainPgContent);
                            Page_Appeared(iNextPgContent);
                        });
                    }

                    // Commit the animations and begin!
                    mainpgsv.BatchCommit();
                    nextpgsv.BatchCommit();
                }
            }
        }