public override Carto.Graphics.Bitmap OnDrawPopup(PopupDrawInfo popupDrawInfo) { PopupStyle style = popupDrawInfo.Popup.Style; // Calculate scaled dimensions float DPToPX = popupDrawInfo.DPToPX; float PXTODP = 1 / DPToPX; if (style.ScaleWithDPI) { DPToPX = 1; } else { PXTODP = 1; } float screenWidth = popupDrawInfo.ScreenBounds.GetWidth() * PXTODP; float screenHeight = popupDrawInfo.ScreenBounds.GetHeight() * PXTODP; // Update sizes based on scale (uses extension method, cf. Shared/Extensions int fontSize = FontSize.Update(DPToPX); int triangleWidth = TriangleSize.Update(DPToPX); int triangleHeight = TriangleSize.Update(DPToPX); int strokeWidth = StrokeWidth.Update(DPToPX); int screenPadding = ScreenPadding.Update(DPToPX); // Set font var font = Android.Graphics.Typeface.Create("HelveticaNeue-Light", Android.Graphics.TypefaceStyle.Normal); // Calculate the maximum popup size, adjust with dpi int maxPopupWidth = (int)(Math.Min(screenWidth, screenHeight)); float halfStrokeWidth = strokeWidth * 0.5f; int maxTextWidth = maxPopupWidth - (2 * screenPadding + strokeWidth); // Measure text TextPaint textPaint = new TextPaint { Color = TextColor, TextSize = fontSize }; textPaint.SetTypeface(font); var textLayout = new StaticLayout(text, textPaint, maxTextWidth, Layout.Alignment.AlignNormal, 1, 0, false); int textX = (int)Math.Min(textPaint.MeasureText(text), textLayout.Width); int textY = textLayout.Height; int popupWidth = textX + (2 * PopupPadding + strokeWidth + triangleWidth); int popupHeight = textY + (2 * PopupPadding + strokeWidth); var bitmap = Android.Graphics.Bitmap.CreateBitmap(popupWidth, popupHeight, Android.Graphics.Bitmap.Config.Argb8888); var canvas = new Android.Graphics.Canvas(bitmap); var trianglePath = new Android.Graphics.Path(); trianglePath.MoveTo(triangleWidth, 0); trianglePath.LineTo(halfStrokeWidth, triangleHeight * 0.5f); trianglePath.LineTo(triangleWidth, triangleHeight); trianglePath.Close(); int triangleOffsetX = 0; int triangleOffsetY = (popupHeight - triangleHeight) / 2; // Create paint object var paint = new Android.Graphics.Paint(); paint.AntiAlias = true; paint.SetStyle(Android.Graphics.Paint.Style.Stroke); paint.StrokeWidth = strokeWidth; paint.Color = StrokeColor; // Stroke background var background = new Android.Graphics.RectF(); background.Left = triangleWidth; background.Top = halfStrokeWidth; background.Right = popupWidth - strokeWidth; background.Bottom = popupHeight - strokeWidth; canvas.DrawRect(background, paint); // Stroke triangle canvas.Save(); canvas.Translate(triangleOffsetX, triangleOffsetY); canvas.DrawPath(trianglePath, paint); canvas.Restore(); // Fill background paint.SetStyle(Android.Graphics.Paint.Style.Fill); paint.Color = BackgroundColor; canvas.DrawRect(background, paint); // Fill triangle canvas.Save(); canvas.Translate(triangleOffsetX, triangleOffsetY); canvas.DrawPath(trianglePath, paint); canvas.Restore(); if (textLayout != null) { // Draw text canvas.Save(); canvas.Translate(halfStrokeWidth + triangleWidth + PopupPadding, halfStrokeWidth + PopupPadding); textLayout.Draw(canvas); canvas.Restore(); } return BitmapUtils.CreateBitmapFromAndroidBitmap(bitmap); }
public override Carto.Graphics.Bitmap OnDrawPopup(PopupDrawInfo popupDrawInfo) { PopupStyle style = popupDrawInfo.Popup.Style; // Calculate scaled dimensions float DPToPX = popupDrawInfo.DPToPX; float PXTODP = 1 / DPToPX; if (style.ScaleWithDPI) { DPToPX = 1; } else { PXTODP = 1; } float screenWidth = popupDrawInfo.ScreenBounds.GetWidth() * PXTODP; float screenHeight = popupDrawInfo.ScreenBounds.GetHeight() * PXTODP; // Update sizes based on scale (uses extension method, cf. Shared/Extensions int fontSize = FontSize.Update(DPToPX); int triangleWidth = TriangleSize.Update(DPToPX); int triangleHeight = TriangleSize.Update(DPToPX); int strokeWidth = StrokeWidth.Update(DPToPX); int screenPadding = ScreenPadding.Update(DPToPX); // Set font var font = Android.Graphics.Typeface.Create("HelveticaNeue-Light", Android.Graphics.TypefaceStyle.Normal); // Calculate the maximum popup size, adjust with dpi int maxPopupWidth = (int)(Math.Min(screenWidth, screenHeight)); float halfStrokeWidth = strokeWidth * 0.5f; int maxTextWidth = maxPopupWidth - (2 * screenPadding + strokeWidth); // Measure text TextPaint textPaint = new TextPaint { Color = TextColor, TextSize = fontSize }; textPaint.SetTypeface(font); var textLayout = new StaticLayout(text, textPaint, maxTextWidth, Layout.Alignment.AlignNormal, 1, 0, false); int textX = (int)Math.Min(textPaint.MeasureText(text), textLayout.Width); int textY = textLayout.Height; int popupWidth = textX + (2 * PopupPadding + strokeWidth + triangleWidth); int popupHeight = textY + (2 * PopupPadding + strokeWidth); var bitmap = Android.Graphics.Bitmap.CreateBitmap(popupWidth, popupHeight, Android.Graphics.Bitmap.Config.Argb8888); var canvas = new Android.Graphics.Canvas(bitmap); var trianglePath = new Android.Graphics.Path(); trianglePath.MoveTo(triangleWidth, 0); trianglePath.LineTo(halfStrokeWidth, triangleHeight * 0.5f); trianglePath.LineTo(triangleWidth, triangleHeight); trianglePath.Close(); int triangleOffsetX = 0; int triangleOffsetY = (popupHeight - triangleHeight) / 2; // Create paint object var paint = new Android.Graphics.Paint(); paint.AntiAlias = true; paint.SetStyle(Android.Graphics.Paint.Style.Stroke); paint.StrokeWidth = strokeWidth; paint.Color = StrokeColor; // Stroke background var background = new Android.Graphics.RectF(); background.Left = triangleWidth; background.Top = halfStrokeWidth; background.Right = popupWidth - strokeWidth; background.Bottom = popupHeight - strokeWidth; canvas.DrawRect(background, paint); // Stroke triangle canvas.Save(); canvas.Translate(triangleOffsetX, triangleOffsetY); canvas.DrawPath(trianglePath, paint); canvas.Restore(); // Fill background paint.SetStyle(Android.Graphics.Paint.Style.Fill); paint.Color = BackgroundColor; canvas.DrawRect(background, paint); // Fill triangle canvas.Save(); canvas.Translate(triangleOffsetX, triangleOffsetY); canvas.DrawPath(trianglePath, paint); canvas.Restore(); if (textLayout != null) { // Draw text canvas.Save(); canvas.Translate(halfStrokeWidth + triangleWidth + PopupPadding, halfStrokeWidth + PopupPadding); textLayout.Draw(canvas); canvas.Restore(); } return(BitmapUtils.CreateBitmapFromAndroidBitmap(bitmap)); }
public override Bitmap OnDrawPopup(PopupDrawInfo popupDrawInfo) { string text = "Custom Popup"; PopupStyle style = popupDrawInfo.Popup.Style; // Calculate scaled dimensions float DPToPX = popupDrawInfo.DPToPX; float PXTODP = 1 / DPToPX; if (style.ScaleWithDPI) { DPToPX = 1; } else { PXTODP = 1; } float screenWidth = popupDrawInfo.ScreenBounds.GetWidth() * PXTODP; float screenHeight = popupDrawInfo.ScreenBounds.GetHeight() * PXTODP; // Update sizes based on scale (uses extension method, cf. Shared/Extensions int fontSize = FontSize.Update(DPToPX); int triangleWidth = TriangleSize.Update(DPToPX); int triangleHeight = TriangleSize.Update(DPToPX); int strokeWidth = StrokeWidth.Update(DPToPX); int screenPadding = ScreenPadding.Update(DPToPX); UIFont font = UIFont.FromName("HelveticaNeue-Light", fontSize); // Calculate the maximum popup size, adjust with dpi float maxPopupWidth = Math.Min(screenWidth, screenHeight); // Calculate maximum text and description width float halfStrokeWidth = strokeWidth * 0.5f; float maxTextWidth = maxPopupWidth - (2 * screenPadding + strokeWidth); CGSize textSize = text.StringSize(font, new CGSize(maxTextWidth, nfloat.MaxValue)); // Calculate bitmap size nfloat popupWidth = textSize.Width + 2 * PopupPadding + strokeWidth + triangleWidth; nfloat popupHeight = textSize.Height + 2 * PopupPadding + strokeWidth; CGSize popupSize = new CGSize(popupWidth, popupHeight); // Create graphics context; UIGraphics.BeginImageContext(popupSize); CGContext context = UIGraphics.GetCurrentContext(); CGRect backgroundStrokeRect = new CGRect( triangleWidth, halfStrokeWidth, popupWidth - (strokeWidth + triangleWidth), popupHeight - strokeWidth ); UIBezierPath backgroundPath = UIBezierPath.FromRoundedRect(backgroundStrokeRect, 1); backgroundPath.LineWidth = strokeWidth; // Prepare triangle path CGPath trianglePath = new CGPath(); trianglePath.MoveToPoint(triangleWidth, 0); trianglePath.AddLineToPoint(halfStrokeWidth, triangleHeight * 0.5f); trianglePath.AddLineToPoint(triangleWidth, triangleHeight); trianglePath.CloseSubpath(); // Calculate anchor point and triangle position nfloat triangleOffsetX = 0; nfloat triangleOffsetY = (popupHeight - triangleHeight) / 2; // Stroke background StrokeColor.SetStroke(); backgroundPath.Stroke(); // Stroke triangle context.SaveState(); context.TranslateCTM(triangleOffsetX, triangleOffsetY); context.SetLineWidth(strokeWidth); context.AddPath(trianglePath); context.SetStrokeColor(StrokeColor.CGColor); context.StrokePath(); context.RestoreState(); // Fill background BackgroundColor.SetFill(); backgroundPath.Fill(); // Fill triangle context.SaveState(); context.TranslateCTM(triangleOffsetX, triangleOffsetY); context.AddPath(trianglePath); context.SetFillColor(BackgroundColor.CGColor); context.FillPath(); context.RestoreState(); // Draw text context.SetFillColor(TextColor.CGColor); CGRect textRect = new CGRect( halfStrokeWidth + PopupPadding + triangleWidth, PopupPadding, textSize.Width, textSize.Height ); text.DrawString(textRect, font, UILineBreakMode.WordWrap); // Extract image UIImage image = UIGraphics.GetImageFromCurrentImageContext(); // Clean up UIGraphics.EndImageContext(); return(BitmapUtils.CreateBitmapFromUIImage(image)); }