// If the cropping rectangle's size changed significantly, change the
        // view's center and scale according to the cropping rectangle.
        private void centerBasedOnHighlightView(HighlightView hv)
        {
            Rect drawRect = hv.DrawRect;

            float width  = drawRect.Width();
            float height = drawRect.Height();

            float thisWidth  = Width;
            float thisHeight = Height;

            float z1 = thisWidth / width * .6F;
            float z2 = thisHeight / height * .6F;

            float zoom = Math.Min(z1, z2);

            zoom = zoom * this.GetScale();
            zoom = Math.Max(1F, zoom);
            if ((Math.Abs(zoom - GetScale()) / zoom) > .1)
            {
                float[] coordinates = new float[]
                {
                    hv.CropRect.CenterX(),
                        hv.CropRect.CenterY()
                };

                ImageMatrix.MapPoints(coordinates);
                ZoomTo(zoom, coordinates[0], coordinates[1], 300F);
            }

            ensureVisible(hv);
        }
 protected override void PostTranslate(float deltaX, float deltaY)
 {
     base.PostTranslate(deltaX, deltaY);
     for (int i = 0; i < hightlightViews.Count; i++)
     {
         HighlightView hv = hightlightViews[i];
         hv.matrix.PostTranslate(deltaX, deltaY);
         hv.Invalidate();
     }
 }
        // Pan the displayed image to make sure the cropping rectangle is visible.
        private void ensureVisible(HighlightView hv)
        {
            Rect r = hv.DrawRect;

            int panDeltaX1 = Math.Max(0, IvLeft - r.Left);
            int panDeltaX2 = Math.Min(0, IvRight - r.Right);

            int panDeltaY1 = Math.Max(0, IvTop - r.Top);
            int panDeltaY2 = Math.Min(0, IvBottom - r.Bottom);

            int panDeltaX = panDeltaX1 != 0 ? panDeltaX1 : panDeltaX2;
            int panDeltaY = panDeltaY1 != 0 ? panDeltaY1 : panDeltaY2;

            if (panDeltaX != 0 || panDeltaY != 0)
            {
                PanBy(panDeltaX, panDeltaY);
            }
        }
        //protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
        //{
        //    base.OnActivityResult(requestCode, resultCode, data);
        //    if (resultCode != Result.Ok)
        //    {
        //        CropImageServiceAndroid.SetResult(new CropResult(false) { Message = resultCode.ToString() });
        //        Finish();
        //        return;
        //    }

        //    switch (requestCode)
        //    {
        //        case RequestCodeCamera:
        //            if (_maxWidth > 0 && _maxHeight > 0)
        //                ImageResizer.ResizeImage(this, _filePath, _filePath, _maxWidth, _maxHeight);
        //            MediaServiceAndroid.SetResult(new MediaResult(true) { FilePath = _filePath });
        //            break;
        //        case RequestCodeGallery:
        //            MediaServiceAndroid.SetResult(new MediaResult(true) { FilePath = RealPathHelper.GetPath(this, data.Data) });
        //            break;
        //    }
        //    Finish();
        //}

        #endregion

        #region Private helpers

        private void addHighlightView()
        {
            Crop = new HighlightView(imageView);

            int width  = bitmap.Width;
            int height = bitmap.Height;

            Rect imageRect = new Rect(0, 0, width, height);

            // make the default size about 4/5 of the width or height
            int cropWidth  = Math.Min(width, height) * 4 / 5;
            int cropHeight = cropWidth;

            if (aspectX != 0 && aspectY != 0)
            {
                if (aspectX > aspectY)
                {
                    cropHeight = cropWidth * aspectY / aspectX;
                }
                else
                {
                    cropWidth = cropHeight * aspectX / aspectY;
                }
            }

            int x = (width - cropWidth) / 2;
            int y = (height - cropHeight) / 2;

            RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight);

            Crop.Setup(imageView.ImageMatrix, imageRect, cropRect, aspectX != 0 && aspectY != 0);

            imageView.ClearHighlightViews();
            Crop.Focused = true;
            imageView.AddHighlightView(Crop);
        }
 public void AddHighlightView(HighlightView hv)
 {
     hightlightViews.Add(hv);
     Invalidate();
 }
        public override bool OnTouchEvent(MotionEvent ev)
        {
            CropImageActivity cropImage = (CropImageActivity)context;

            if (cropImage.Saving)
            {
                return(false);
            }

            switch (ev.Action)
            {
            case MotionEventActions.Down:

                for (int i = 0; i < hightlightViews.Count; i++)
                {
                    HighlightView hv   = hightlightViews[i];
                    var           edge = hv.GetHit(ev.GetX(), ev.GetY());
                    if (edge != HighlightView.HitPosition.None)
                    {
                        motionEdge           = edge;
                        mMotionHighlightView = hv;
                        mLastX = ev.GetX();
                        mLastY = ev.GetY();
                        mMotionHighlightView.Mode =
                            (edge == HighlightView.HitPosition.Move)
                                ? HighlightView.ModifyMode.Move
                                : HighlightView.ModifyMode.Grow;
                        break;
                    }
                }
                break;

            case MotionEventActions.Up:
                if (mMotionHighlightView != null)
                {
                    centerBasedOnHighlightView(mMotionHighlightView);
                    mMotionHighlightView.Mode = HighlightView.ModifyMode.None;
                }

                mMotionHighlightView = null;
                break;

            case MotionEventActions.Move:
                if (mMotionHighlightView != null)
                {
                    mMotionHighlightView.HandleMotion(motionEdge,
                                                      ev.GetX() - mLastX,
                                                      ev.GetY() - mLastY);
                    mLastX = ev.GetX();
                    mLastY = ev.GetY();

                    if (true)
                    {
                        // This section of code is optional. It has some user
                        // benefit in that moving the crop rectangle against
                        // the edge of the screen causes scrolling but it means
                        // that the crop rectangle is no longer fixed under
                        // the user's finger.
                        ensureVisible(mMotionHighlightView);
                    }
                }
                break;
            }

            switch (ev.Action)
            {
            case MotionEventActions.Up:
                Center(true, true);
                break;

            case MotionEventActions.Move:
                // if we're not zoomed then there's no point in even allowing
                // the user to move the image around.  This call to center puts
                // it back to the normalized location (with false meaning don't
                // animate).
                if (GetScale() == 1F)
                {
                    Center(true, true);
                }
                break;
            }

            return(true);
        }