public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (container == null) { // Currently in a layout without a container, so no reason to create our view. return null; } Point displaySize = new Point( ); Activity.WindowManager.DefaultDisplay.GetSize( displaySize ); ScreenSize = new System.Drawing.SizeF( displaySize.X, displaySize.Y ); // scale the image to match the view's width ScreenToImageScalar = (float) SourceImage.Width / (float) ScreenSize.Width; // get the scaled dimensions, maintaining aspect ratio float scaledWidth = (float)SourceImage.Width * (1.0f / ScreenToImageScalar); float scaledHeight = (float)SourceImage.Height * (1.0f / ScreenToImageScalar); // now, if the scaled height is too large, re-calc with Height is the dominant, // so we guarantee a fit within the view. if( scaledHeight > ScreenSize.Height ) { ScreenToImageScalar = (float) SourceImage.Height / (float) ScreenSize.Height; scaledWidth = (float)SourceImage.Width * (1.0f / ScreenToImageScalar); scaledHeight = (float)SourceImage.Height * (1.0f / ScreenToImageScalar); } ScaledSourceImage = Bitmap.CreateScaledBitmap( SourceImage, (int)scaledWidth, (int)scaledHeight, false ); // setup our layout for touch input RelativeLayout view = inflater.Inflate( Resource.Layout.ImageCrop, container, false ) as RelativeLayout; view.SetOnTouchListener( this ); // create the view that will display the image to crop ImageView = new AspectScaledImageView( Rock.Mobile.PlatformSpecific.Android.Core.Context ); ImageView.LayoutParameters = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent ); ImageView.LayoutParameters.Width = ScaledSourceImage.Width; ImageView.LayoutParameters.Height = ScaledSourceImage.Height; // center the image ImageView.SetX( (ScreenSize.Width - ImageView.LayoutParameters.Width ) / 2 ); ImageView.SetY( (ScreenSize.Height - ImageView.LayoutParameters.Height ) / 2 ); view.AddView( ImageView ); // create the draggable crop view that will let the user pic which part of the image to use. CropView = new View( Rock.Mobile.PlatformSpecific.Android.Core.Context ); CropView.LayoutParameters = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent ); // the crop view's dimensions should be based on what the user wanted to crop to. We'll do width, and then height as a scale of width. CropView.LayoutParameters.Width = (int) (scaledWidth < scaledHeight ? scaledWidth : scaledHeight); CropView.LayoutParameters.Height = (int) ((float) CropView.LayoutParameters.Width * CropAspectRatio); // the crop view should be a nice outlined rounded rect float _Radius = 3.0f; RoundRectShape rectShape = new RoundRectShape( new float[] { _Radius, _Radius, _Radius, _Radius, _Radius, _Radius, _Radius, _Radius }, null, null ); // configure its paint ShapeDrawable border = new ShapeDrawable( rectShape ); border.Paint.SetStyle( Paint.Style.Stroke ); border.Paint.StrokeWidth = 8; border.Paint.Color = Color.WhiteSmoke; CropView.Background = border; // set our clamp values CropViewMinPos = new PointF( (ScreenSize.Width - scaledWidth) / 2, (ScreenSize.Height - scaledHeight) / 2 ); CropViewMaxPos = new PointF( CropViewMinPos.X + (scaledWidth - CropView.LayoutParameters.Width), CropViewMinPos.Y + (scaledHeight - CropView.LayoutParameters.Height) ); view.AddView( CropView ); // create a mask layer that will block out the parts of the image that will be cropped MaskLayer = new Rock.Mobile.PlatformSpecific.Android.Graphics.MaskLayer( (int)ScreenSize.Width, (int)ScreenSize.Height, CropView.LayoutParameters.Width, CropView.LayoutParameters.Height, Rock.Mobile.PlatformSpecific.Android.Core.Context ); MaskLayer.LayoutParameters = new RelativeLayout.LayoutParams( (int)ScreenSize.Width, (int)ScreenSize.Height ); MaskLayer.Opacity = 0.00f; view.AddView( MaskLayer ); // Now setup our bottom area with cancel, crop, and text to explain RelativeLayout bottomBarLayout = new RelativeLayout( Rock.Mobile.PlatformSpecific.Android.Core.Context ); bottomBarLayout.LayoutParameters = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent ); ((RelativeLayout.LayoutParams)bottomBarLayout.LayoutParameters).AddRule( LayoutRules.AlignParentBottom ); // set the nav subBar color (including opacity) Color navColor = Rock.Mobile.UI.Util.GetUIColor( PrivateSubNavToolbarConfig.BackgroundColor ); navColor.A = (Byte) ( (float) navColor.A * PrivateSubNavToolbarConfig.Opacity ); bottomBarLayout.SetBackgroundColor( navColor ); bottomBarLayout.LayoutParameters.Height = 150; view.AddView( bottomBarLayout ); // setup the cancel button (which will undo cropping or take you back to the picture taker) CancelButton = new Button( Rock.Mobile.PlatformSpecific.Android.Core.Context ); CancelButton.LayoutParameters = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent ); CancelButton.Gravity = GravityFlags.Left; ((RelativeLayout.LayoutParams)CancelButton.LayoutParameters).AddRule( LayoutRules.AlignParentLeft ); // set the crop button's font Android.Graphics.Typeface fontFace = Rock.Mobile.PlatformSpecific.Android.Graphics.FontManager.Instance.GetFont( PrivateControlStylingConfig.Icon_Font_Secondary ); CancelButton.SetTypeface( fontFace, Android.Graphics.TypefaceStyle.Normal ); CancelButton.SetTextSize( Android.Util.ComplexUnitType.Dip, PrivateImageCropConfig.CropCancelButton_Size ); CancelButton.Text = PrivateImageCropConfig.CropCancelButton_Text; CancelButton.Click += (object sender, EventArgs e) => { // don't allow button presses while animations are going on if( Animating == false ) { // if they hit cancel while previewing, go back to editing if( Mode == CropMode.Previewing ) { SetMode( CropMode.Editing ); } else { // they pressed it while they're in editing mode, so go back to camera mode Activity.OnBackPressed( ); } } }; bottomBarLayout.AddView( CancelButton ); // setup the Confirm button, which will use a font to display its graphic ConfirmButton = new Button( Rock.Mobile.PlatformSpecific.Android.Core.Context ); ConfirmButton.LayoutParameters = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent ); ConfirmButton.Gravity = GravityFlags.Right; ((RelativeLayout.LayoutParams)ConfirmButton.LayoutParameters).AddRule( LayoutRules.AlignParentRight ); // set the crop button's font fontFace = Rock.Mobile.PlatformSpecific.Android.Graphics.FontManager.Instance.GetFont( PrivateControlStylingConfig.Icon_Font_Secondary ); ConfirmButton.SetTypeface( fontFace, Android.Graphics.TypefaceStyle.Normal ); ConfirmButton.SetTextSize( Android.Util.ComplexUnitType.Dip, PrivateImageCropConfig.CropOkButton_Size ); ConfirmButton.Text = PrivateImageCropConfig.CropOkButton_Text; // when clicked, we should crop the image. ConfirmButton.Click += (object sender, EventArgs e) => { // don't allow button presses while animations are going on if( Animating == false ) { // if they pressed confirm while editing, go to preview if( Mode == CropMode.Editing ) { SetMode( CropMode.Previewing ); } else { // notify the caller SpringboardParent.ModalFragmentDone( CroppedImage ); } } }; bottomBarLayout.AddView( ConfirmButton ); // start in editing mode (obviously) SetMode( CropMode.Editing ); // start the cropper centered MoveCropView( new PointF( (ScreenSize.Width - CropView.LayoutParameters.Width) / 2, (ScreenSize.Height - CropView.LayoutParameters.Height) / 2 ) ); MaskLayer.Position = new PointF( CropView.GetX( ), CropView.GetY( ) ); return view; }
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (container == null) { // Currently in a layout without a container, so no reason to create our view. return(null); } Point displaySize = new Point( ); Activity.WindowManager.DefaultDisplay.GetSize(displaySize); ScreenSize = new System.Drawing.SizeF(displaySize.X, displaySize.Y); // scale the image to match the view's width ScreenToImageScalar = (float)SourceImage.Width / (float)ScreenSize.Width; // get the scaled dimensions, maintaining aspect ratio float scaledWidth = (float)SourceImage.Width * (1.0f / ScreenToImageScalar); float scaledHeight = (float)SourceImage.Height * (1.0f / ScreenToImageScalar); // now, if the scaled height is too large, re-calc with Height is the dominant, // so we guarantee a fit within the view. if (scaledHeight > ScreenSize.Height) { ScreenToImageScalar = (float)SourceImage.Height / (float)ScreenSize.Height; scaledWidth = (float)SourceImage.Width * (1.0f / ScreenToImageScalar); scaledHeight = (float)SourceImage.Height * (1.0f / ScreenToImageScalar); } ScaledSourceImage = Bitmap.CreateScaledBitmap(SourceImage, (int)scaledWidth, (int)scaledHeight, false); // setup our layout for touch input RelativeLayout view = inflater.Inflate(Resource.Layout.ImageCrop, container, false) as RelativeLayout; view.SetOnTouchListener(this); // create the view that will display the image to crop ImageView = new AspectScaledImageView(Rock.Mobile.PlatformSpecific.Android.Core.Context); ImageView.LayoutParameters = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent); ImageView.LayoutParameters.Width = ScaledSourceImage.Width; ImageView.LayoutParameters.Height = ScaledSourceImage.Height; // center the image ImageView.SetX((ScreenSize.Width - ImageView.LayoutParameters.Width) / 2); ImageView.SetY((ScreenSize.Height - ImageView.LayoutParameters.Height) / 2); view.AddView(ImageView); // create the draggable crop view that will let the user pic which part of the image to use. CropView = new View(Rock.Mobile.PlatformSpecific.Android.Core.Context); CropView.LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent); // the crop view's dimensions should be based on what the user wanted to crop to. We'll do width, and then height as a scale of width. CropView.LayoutParameters.Width = (int)(scaledWidth < scaledHeight ? scaledWidth : scaledHeight); CropView.LayoutParameters.Height = (int)((float)CropView.LayoutParameters.Width * CropAspectRatio); // the crop view should be a nice outlined rounded rect float _Radius = 3.0f; RoundRectShape rectShape = new RoundRectShape(new float[] { _Radius, _Radius, _Radius, _Radius, _Radius, _Radius, _Radius, _Radius }, null, null); // configure its paint ShapeDrawable border = new ShapeDrawable(rectShape); border.Paint.SetStyle(Paint.Style.Stroke); border.Paint.StrokeWidth = 8; border.Paint.Color = Color.WhiteSmoke; CropView.Background = border; // set our clamp values CropViewMinPos = new PointF((ScreenSize.Width - scaledWidth) / 2, (ScreenSize.Height - scaledHeight) / 2); CropViewMaxPos = new PointF(CropViewMinPos.X + (scaledWidth - CropView.LayoutParameters.Width), CropViewMinPos.Y + (scaledHeight - CropView.LayoutParameters.Height)); view.AddView(CropView); // create a mask layer that will block out the parts of the image that will be cropped MaskLayer = new Rock.Mobile.PlatformSpecific.Android.Graphics.MaskLayer((int)ScreenSize.Width, (int)ScreenSize.Height, CropView.LayoutParameters.Width, CropView.LayoutParameters.Height, Rock.Mobile.PlatformSpecific.Android.Core.Context); MaskLayer.LayoutParameters = new RelativeLayout.LayoutParams((int)ScreenSize.Width, (int)ScreenSize.Height); MaskLayer.Opacity = 0.00f; view.AddView(MaskLayer); // Now setup our bottom area with cancel, crop, and text to explain RelativeLayout bottomBarLayout = new RelativeLayout(Rock.Mobile.PlatformSpecific.Android.Core.Context); bottomBarLayout.LayoutParameters = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent); ((RelativeLayout.LayoutParams)bottomBarLayout.LayoutParameters).AddRule(LayoutRules.AlignParentBottom); // set the nav subBar color (including opacity) Color navColor = Rock.Mobile.UI.Util.GetUIColor(PrivateSubNavToolbarConfig.BackgroundColor); navColor.A = (Byte)((float)navColor.A * PrivateSubNavToolbarConfig.Opacity); bottomBarLayout.SetBackgroundColor(navColor); view.AddView(bottomBarLayout); // setup the cancel button (which will undo cropping or take you back to the picture taker) CancelButton = new Button(Rock.Mobile.PlatformSpecific.Android.Core.Context); CancelButton.LayoutParameters = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent); CancelButton.Gravity = GravityFlags.Left; ((RelativeLayout.LayoutParams)CancelButton.LayoutParameters).AddRule(LayoutRules.AlignParentLeft); // set the crop button's font Android.Graphics.Typeface fontFace = Rock.Mobile.PlatformSpecific.Android.Graphics.FontManager.Instance.GetFont(PrivateControlStylingConfig.Icon_Font_Secondary); CancelButton.SetTypeface(fontFace, Android.Graphics.TypefaceStyle.Normal); CancelButton.SetTextSize(Android.Util.ComplexUnitType.Dip, PrivateImageCropConfig.CropCancelButton_Size); CancelButton.Text = PrivateImageCropConfig.CropCancelButton_Text; CancelButton.Click += (object sender, EventArgs e) => { // don't allow button presses while animations are going on if (Animating == false) { // if they hit cancel while previewing, go back to editing if (Mode == CropMode.Previewing) { SetMode(CropMode.Editing); } else { // they pressed it while they're in editing mode, so go back to camera mode Activity.OnBackPressed( ); } } }; bottomBarLayout.AddView(CancelButton); // setup the Confirm button, which will use a font to display its graphic ConfirmButton = new Button(Rock.Mobile.PlatformSpecific.Android.Core.Context); ConfirmButton.LayoutParameters = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent); ConfirmButton.Gravity = GravityFlags.Right; ((RelativeLayout.LayoutParams)ConfirmButton.LayoutParameters).AddRule(LayoutRules.AlignParentRight); // set the crop button's font fontFace = Rock.Mobile.PlatformSpecific.Android.Graphics.FontManager.Instance.GetFont(PrivateControlStylingConfig.Icon_Font_Secondary); ConfirmButton.SetTypeface(fontFace, Android.Graphics.TypefaceStyle.Normal); ConfirmButton.SetTextSize(Android.Util.ComplexUnitType.Dip, PrivateImageCropConfig.CropOkButton_Size); ConfirmButton.Text = PrivateImageCropConfig.CropOkButton_Text; // when clicked, we should crop the image. ConfirmButton.Click += (object sender, EventArgs e) => { // don't allow button presses while animations are going on if (Animating == false) { // if they pressed confirm while editing, go to preview if (Mode == CropMode.Editing) { SetMode(CropMode.Previewing); } else { // notify the caller SpringboardParent.ModalFragmentDone(CroppedImage); } } }; bottomBarLayout.AddView(ConfirmButton); // start in editing mode (obviously) SetMode(CropMode.Editing); // start the cropper centered MoveCropView(new PointF((ScreenSize.Width - CropView.LayoutParameters.Width) / 2, (ScreenSize.Height - CropView.LayoutParameters.Height) / 2)); MaskLayer.Position = new PointF(CropView.GetX( ), CropView.GetY( )); return(view); }