Esempio n. 1
0
        internal static CGPath CreateClippingPath(RectangleF rect, float radius)
        {
            var path = new CGPath();
            path.MoveToPoint(rect.GetMinX(), rect.GetMinY());
            path.AddLineToPoint(rect.GetMinX(), rect.GetMaxY() - radius);
            path.AddArcToPoint(rect.GetMinX(), rect.GetMaxY(), rect.GetMinX() + radius, rect.GetMaxY(), radius);
            path.AddLineToPoint(rect.GetMaxX() - radius, rect.GetMaxY());
            path.AddArcToPoint(rect.GetMaxX(), rect.GetMaxY(), rect.GetMaxX(), rect.GetMaxY() - radius, radius);
            path.AddLineToPoint(rect.GetMaxX(), rect.GetMinY());
            path.CloseSubpath();

            return path;
        }
Esempio n. 2
0
		public override void Draw (RectangleF rect)
		{
			using (var context = UIGraphics.GetCurrentContext ()) {

				// get the scale from the context by getting the current transform matrix, then asking for
				// its "a" component, which is one of the two scale components. We could also ask for "d".
				// This assumes (safely) that the view is being scaled equally in both dimensions.
				var scale = context.GetCTM ().xx;
				CATiledLayer tiledLayer = (CATiledLayer)this.Layer; 
				var tileSize = tiledLayer.TileSize;

				// Even at scales lower than 100%, we are drawing into a rect in the coordinate system of the full
				// image. One tile at 50% covers the width (in original image coordinates) of two tiles at 100%. 
				// So at 50% we need to stretch our tiles to double the width and height; at 25% we need to stretch 
				// them to quadruple the width and height; and so on.
				// (Note that this means that we are drawing very blurry images as the scale gets low. At 12.5%, 
				// our lowest scale, we are stretching about 6 small tiles to fill the entire original image area. 
				// But this is okay, because the big blurry image we're drawing here will be scaled way down before 
				// it is displayed.)
				tileSize.Width /= scale;
				tileSize.Height /= scale;

				// calculate the rows and columns of tiles that intersect the rect we have been asked to draw
				int firstCol = (int)Math.Floor (rect.GetMinX () / tileSize.Width);
				int lastCol = (int)Math.Floor ((rect.GetMaxX () - 1) / tileSize.Width);
				int firstRow = (int)Math.Floor (rect.GetMinY () / tileSize.Height);
				int lastRow = (int)Math.Floor ((rect.GetMaxY () - 1) / tileSize.Height);

				for (int row = firstRow; row <= lastRow; row++) {
					for (int col = firstCol; col <= lastCol; col++) {
					 
						UIImage tile = TileForScale (scale, row, col);
						var tileRect = new RectangleF (tileSize.Width * col, tileSize.Height * row, tileSize.Width, tileSize.Height);
						// if the tile would stick outside of our bounds, we need to truncate it so as to avoid
						// stretching out the partial tiles at the right and bottom edges
						tileRect.Intersect (this.Bounds);
						tile.Draw (tileRect);
					}
				}
			}
		}
		void FillRoundedRect (RectangleF rect, CGContext context)
		{
			float radius = 10.0f;
			context.BeginPath ();
			context.SetGrayFillColor (0.0f, this.Opacity);
			context.MoveTo (rect.GetMinX () + radius, rect.GetMinY ());
			context.AddArc (rect.GetMaxX () - radius, rect.GetMinY () + radius, radius, (float)(3 * Math.PI / 2), 0f, false);
			context.AddArc (rect.GetMaxX () - radius, rect.GetMaxY () - radius, radius, 0, (float)(Math.PI / 2), false);
			context.AddArc (rect.GetMinX () + radius, rect.GetMaxY () - radius, radius, (float)(Math.PI / 2), (float)Math.PI, false);
			context.AddArc (rect.GetMinX () + radius, rect.GetMinY () + radius, radius, (float)Math.PI, (float)(3 * Math.PI / 2), false);
			context.ClosePath ();
			context.FillPath ();
		}
		public CGPath GetCellBorderPath(RectangleF rect)
		{
			var cornerRadius = 10;
			
			float minx = rect.GetMinX(), midx = rect.GetMidX(), maxx = rect.GetMaxX();
			float miny = rect.GetMinY(), midy = rect.GetMidY(), maxy = rect.GetMaxY();
			
			CGPath path = new CGPath();
			
			var cellPosition = CellPosition;

			if (cellPosition == CellPosition.Top)
			{
				minx = minx + 1;
				miny = miny + 1;
				
				maxx = maxx - 1;
				
				path.MoveToPoint(minx, maxy);
				path.AddArcToPoint(minx, miny, midx, miny, cornerRadius);
				path.AddArcToPoint(maxx, miny, maxx, maxy, cornerRadius);
				path.AddLineToPoint(maxx, maxy);
			}
			else if (cellPosition == CellPosition.Bottom)
			{
				minx = minx + 1;
				
				maxx = maxx - 1;
				maxy = maxy - 1;
				
				path.MoveToPoint(minx, miny);
				path.AddArcToPoint(minx, maxy, midx, maxy, cornerRadius);
				path.AddArcToPoint(maxx, maxy, maxx, miny, cornerRadius);
				path.AddLineToPoint(maxx, miny);
			}
			else if (cellPosition == CellPosition.Middle)
			{
				minx = minx + 1;
				maxx = maxx - 1;
				
				path.MoveToPoint(minx, miny);
				path.AddLineToPoint(maxx, miny);
				path.AddLineToPoint(maxx, maxy);
				path.AddLineToPoint(minx, maxy);
			}
			else if (cellPosition == CellPosition.Single)
			{
				minx = minx + 1;
				miny = miny + 1;
				
				maxx = maxx - 1;
				maxy = maxy - 1;
				
				path.MoveToPoint(minx, midy);
				path.AddArcToPoint(minx, miny, midx, miny, cornerRadius);
				path.AddArcToPoint(maxx, miny, maxx, midy, cornerRadius);
				path.AddArcToPoint(maxx, maxy, midx, maxy, cornerRadius);
				path.AddArcToPoint(minx, maxy, minx, midy, cornerRadius);
				
			}

			path.CloseSubpath();
			return path;
		}
Esempio n. 5
0
		public void SSDrawRoundedRect(CGContext context, RectangleF rect, float cornerRadius)
		{
			var minx = rect.GetMinX();
			var midx = rect.GetMidX();
			var maxx = rect.GetMaxX();
			var miny = rect.GetMinY();
			var midy = rect.GetMidY();
			var maxy = rect.GetMaxY();
			context.MoveTo(minx, midy);
			context.AddArcToPoint(minx, miny, midx, miny, cornerRadius);
			context.AddArcToPoint(maxx, miny, maxx, midy, cornerRadius);
			context.AddArcToPoint(maxx, maxy, midx, maxy, cornerRadius);
			context.AddArcToPoint(minx, maxy, minx, midy, cornerRadius);
			context.ClosePath();
			context.FillPath();
		}
Esempio n. 6
0
        public override void Draw(RectangleF a_rect)
        {
            // Set the back color to black
            GL.ClearColor (0.0f, 0.0f, 0.0f, 1.0f);

            // Clear all old bits
            GL.Clear ((int)(All.ColorBufferBit));

            GL.PushMatrix();

            RectangleF bds;

            if (_vertical)
            {
                GL.Scale (1f, -1f, 1f);
                bds = new RectangleF (0f, -1f,
                          	this.Bounds.Width * _scaleFactor,
                            this.Bounds.Height * _scaleFactor);
            } else {
                GL.Translate(0f, this.Bounds.Height * _scaleFactor, 0f);
                GL.Rotate(-90f, 0f, 0f, 1f);
                bds = new RectangleF (0f, 1f,
                            this.Bounds.Height * _scaleFactor,
                          	this.Bounds.Width * _scaleFactor);
            }

            if (_numLights == 0)
            {
                int i;
                float currentTop = 0f;

                for (i=0; i<_colorThresholds.Length; i++)
                {
                    LevelMeterColorThreshold thisThresh = _colorThresholds[i];
                    float val = Math.Min (thisThresh.maxValue, _level);

                    RectangleF rect = new RectangleF(
                                             0,
                                             (bds.Height) * currentTop,
                                             bds.Width,
                                             (bds.Height) * (val - currentTop)
                                             );

                    float [] vertices = new float[] {
                        rect.GetMinX (), rect.GetMinY (),
                        rect.GetMaxX (), rect.GetMinY (),
                        rect.GetMinX (), rect.GetMaxY (),
                        rect.GetMaxX (), rect.GetMaxY ()
                    };

                    CGColor clr = thisThresh.color.CGColor;
                    if (clr.NumberOfComponents != 4)
                        goto bail;
                    float [] rgba;
                    rgba = clr.Components;
                    GL.Color4 (rgba[0], rgba[1], rgba[2], _maxIntensity);

                    GL.VertexPointer(2, All.Float, 0, vertices);
                    GL.EnableClientState (All.VertexArray);

                    GL.DrawArrays(All.TriangleStrip, 0, 4);

                    if (_level < thisThresh.maxValue)
                        break;

                    currentTop = val;
                }
            }
            else
            {
                int light_i;
                float lightMinVal = 0f;
                float insetAmount, lightVSpace;
                lightVSpace = bds.Height / (float)_numLights;

                if (lightVSpace < 4f)
                    insetAmount = 0f;
                else if (lightVSpace < 8f)
                    insetAmount = 0.5f;
                else
                    insetAmount = 1f;

                int peakLight = -1;
                if (_peakLevel > 0f)
                {
                    peakLight = (int)(_peakLevel * _numLights);
                    if (peakLight >= _numLights)
                        peakLight = (int)(_numLights - 1);
                }

                for (light_i=0; light_i<_numLights; light_i++)
                {
                    float lightMaxVal = (float)(light_i + 1) / (float)_numLights;
                    float lightIntensity;
                    RectangleF lightRect;
                    UIColor lightColor;

                    if (light_i == peakLight)
                    {
                        lightIntensity = _maxIntensity;
                    }
                    else
                    {
                        lightIntensity = (_level - lightMinVal) / (lightMaxVal - lightMinVal);
                        lightIntensity = LevelMeter.LEVELMETER_CLAMP(0f, lightIntensity, _maxIntensity);
                        if ((!_variableLightIntensity) && (lightIntensity > 0f)) lightIntensity = _maxIntensity;
                    }

                    lightColor = _colorThresholds[0].color;
                    int color_i;
                    for (color_i=0; color_i<(_colorThresholds.Length-1); color_i++)
                    {
                        LevelMeterColorThreshold thisThresh = _colorThresholds[color_i];
                        LevelMeterColorThreshold nextThresh = _colorThresholds[color_i + 1];
                        if (thisThresh.maxValue <= lightMaxVal)
                            lightColor = nextThresh.color;
                    }

                    lightRect = new RectangleF(
                                           0f,
                                           bds.Y * (bds.Height * ((float)(light_i) / (float)_numLights)),
                                           bds.Width,
                                           bds.Height * (1f / (float)_numLights)
                                           );
                    lightRect = lightRect.Inset (insetAmount, insetAmount);

                    float [] vertices = {
                        lightRect.GetMinX (), lightRect.GetMinY (),
                        lightRect.GetMaxX (), lightRect.GetMinY (),
                        lightRect.GetMinX (), lightRect.GetMaxY (),
                        lightRect.GetMaxX (), lightRect.GetMaxY ()
                    };

                    GL.VertexPointer(2, All.Float, 0, vertices);
                    GL.EnableClientState (All.VertexArray);

                    if (lightIntensity == 1f)
                    {
                        CGColor clr = lightColor.CGColor;
                        if (clr.NumberOfComponents != 4)
                            goto bail;

                        float []  rgba;
                        rgba = clr.Components;
                        GL.Color4 (rgba[0], rgba[1], rgba[2], 1f);
                        GL.DrawArrays(All.TriangleStrip, 0, 4);
                    } else if (lightIntensity > 0f) {
                        CGColor clr = lightColor.CGColor;
                        if (clr.NumberOfComponents != 4)
                            goto bail;

                        float []  rgba;
                        rgba = clr.Components;
                        GL.Color4(rgba[0], rgba[1], rgba[2], lightIntensity);
                        GL.DrawArrays(All.TriangleStrip, 0, 4);
                    }

                    lightMinVal = lightMaxVal;
                }
            }

            bail:
            GL.PopMatrix ();

            GL.Flush ();
        }
Esempio n. 7
0
        private RectangleF GetTitleFrame(out NSDictionary titleTextStyles, AppStoreWindow window)
        {
            var drawsAsMainWindow = window.DrawsAsMainWindow();
            var titleTextShadow = drawsAsMainWindow ? window.TitleTextShadow : window.InactiveTitleTextShadow;
            if (titleTextShadow == null)
            {
                titleTextShadow = new NSShadow
                {
                    ShadowBlurRadius = 0f,
                    ShadowOffset = new SizeF(0f, -1.0f),
                    ShadowColor = NSColor.FromDeviceWhite(1.0f, 0.5f),
                };
            }

            var titleTextColor = drawsAsMainWindow ? window.TitleTextColor : window.InactiveTitleTextColor;
            if (titleTextColor == default(NSColor))
            {
                titleTextColor = AppStoreWindow.DefaultTitleTextColor(drawsAsMainWindow);
            }
            var titleFont = window.TitleFont ??
                            NSFont.TitleBarFontOfSize(NSFont.SystemFontSizeForControlSize(NSControlSize.Regular));

            var titleParagraphStyle = (NSParagraphStyle)NSParagraphStyle.DefaultParagraphStyle.MutableCopy();//new NSParagraphStyle { LineBreakMode = NSLineBreakMode.TruncatingTail };
            titleParagraphStyle.LineBreakMode = NSLineBreakMode.TruncatingTail;

            titleTextStyles = NSDictionary.FromObjectsAndKeys(
                new object[]
                {
                    titleFont, titleTextColor,
                    titleTextShadow, titleParagraphStyle
                },
                new object[]
                {
                    NSAttributedString.FontAttributeName, NSAttributedString.ForegroundColorAttributeName,
                    NSAttributedString.ShadowAttributeName, NSAttributedString.ParagraphStyleAttributeName
                });

            var titleSize = new NSAttributedString(window.Title, titleTextStyles).Size;
            var titleTextRect = new RectangleF(0, 0, titleSize.Width, titleSize.Height);

            var docIconButton = window.StandardWindowButton(NSWindowButton.DocumentIconButton);
            var versionButton = window.StandardWindowButton(NSWindowButton.DocumentVersionsButton);
            var closeButton = window.ButtonToLayout(NSWindowButton.CloseButton);
            var minimizeButton = window.ButtonToLayout(NSWindowButton.MiniaturizeButton);
            var zoomButton = window.ButtonToLayout(NSWindowButton.ZoomButton);

            if (docIconButton != null)
            {
                var docIconButtonFrame = ConvertRectFromView(docIconButton.Frame, docIconButton.Superview);
                titleTextRect.X = docIconButtonFrame.GetMaxX() + TITLE_DOCUMENT_BUTTON_OFFSET.Width;
                titleTextRect.Y = docIconButtonFrame.GetMidY() - titleSize.Height / 2f +
                TITLE_DOCUMENT_BUTTON_OFFSET.Height;
            }
            else if (versionButton != null)
            {
                var versionsButtonFrame = ConvertRectFromView(versionButton.Frame, versionButton.Superview);
                titleTextRect.X = versionsButtonFrame.GetMinX() - titleSize.Width + TITLE_VERSIONS_BUTTON_OFFSET;

                var document = ((NSWindowController)window.WindowController).Document;
                if (document.HasUnautosavedChanges || document.IsDocumentEdited)
                {
                    titleTextRect.X += TITLE_DOCUMENT_STATUS_X_OFFSET;
                }
            }
            else if (closeButton != null || minimizeButton != null || zoomButton != null)
            {
                var closeMaxX = closeButton == null ? 0f : closeButton.Frame.GetMaxX();
                var minimizeMaxX = minimizeButton == null ? 0f : minimizeButton.Frame.GetMaxX();
                var zoomMaxX = zoomButton == null ? 0f : zoomButton.Frame.GetMaxX();

                var adjustedX = Math.Max(Math.Max(closeMaxX, minimizeMaxX), zoomMaxX) + TITLE_MARGINS.Width;
                var proposedX = Bounds.GetMidX() - titleSize.Width / 2f;
                titleTextRect.X = Math.Max(proposedX, adjustedX);
            }
            else
            {
                titleTextRect.X = Bounds.GetMidX() - titleSize.Width / 2f;
            }

            var fullScreenButton = window.ButtonToLayout(NSWindowButton.FullScreenButton);
            if (fullScreenButton != null)
            {
                var fullScreenX = fullScreenButton.Frame.X;
                var maxTitleX = titleTextRect.GetMaxX();
                if ((fullScreenX - TITLE_MARGINS.Width) < titleTextRect.GetMaxX())
                {
                    titleTextRect.Width = titleTextRect.Size.Width - (maxTitleX - fullScreenX) - TITLE_MARGINS.Width;
                }
            }

            titleTextRect.Y = Bounds.GetMaxY() - titleSize.Height - TITLE_MARGINS.Height;

            return titleTextRect;
        }
		public void DetermineGeometry(SizeF size, RectangleF anchorRect, RectangleF displayArea, UIPopoverArrowDirection supportedDirections)
		{
			_Offset = PointF.Empty;
			_BackgroundRect = RectangleF.Empty;
			_ArrowRect = RectangleF.Empty;
			PopoverArrowDirection = UIPopoverArrowDirection.Unknown;
			
			var biggestSurface = 0.0f;
			var currentMinMargin = 0.0f;
			
			var upArrowImage = UIImage.FromBundle(this.Properties.UpArrowImage);
			var downArrowImage = UIImage.FromBundle(this.Properties.DownArrowImage);
			var leftArrowImage = UIImage.FromBundle(this.Properties.LeftArrowImage);
			var rightArrowImage = UIImage.FromBundle(this.Properties.RightArrowImage);
			
			foreach(var direction in (UIPopoverArrowDirection[])Enum.GetValues(typeof(UIPopoverArrowDirection))) {
				
				if(supportedDirections.HasFlag(direction)) {
					
					var bgRect = RectangleF.Empty;
					var arrowRect = RectangleF.Empty;
					var offset = PointF.Empty;
					var xArrowOffset = 0.0f;
					var yArrowOffset = 0.0f;
					var anchorPoint = PointF.Empty;
					
					switch(direction) {
						case UIPopoverArrowDirection.Up: {
							
							anchorPoint = new PointF(anchorRect.GetMidX(), anchorRect.GetMaxY());
							
							xArrowOffset = size.Width / 2 - upArrowImage.Size.Width / 2;
							yArrowOffset = Properties.TopBgMargin - upArrowImage.Size.Height;
							
							offset = new PointF(anchorPoint.X - xArrowOffset - upArrowImage.Size.Width / 2, anchorPoint.Y - yArrowOffset);
							bgRect = new RectangleF(0, 0, size.Width, size.Height);
						
							if(offset.X < 0) {
								xArrowOffset += offset.X;
								offset.X = 0;
							}
							else if(offset.X + size.Width > displayArea.Size.Width) {
								xArrowOffset += (offset.X + size.Width - displayArea.Size.Width);
								offset.X = displayArea.Size.Width - size.Width;
							}
						
							xArrowOffset = Math.Max(xArrowOffset, Properties.LeftBgMargin + Properties.ArrowMargin);
							xArrowOffset = Math.Min(xArrowOffset, size.Width - Properties.RightBgMargin - Properties.ArrowMargin - upArrowImage.Size.Width);
							
							arrowRect = new RectangleF(xArrowOffset, yArrowOffset, upArrowImage.Size.Width, upArrowImage.Size.Height);
						
							break;
						}
						case UIPopoverArrowDirection.Down: {
							anchorPoint = new PointF(anchorRect.GetMidX(), anchorRect.GetMinY());
						
							xArrowOffset = size.Width / 2 - downArrowImage.Size.Width / 2;
							yArrowOffset = size.Height - Properties.BottomBgMargin;
						
							offset = new PointF(anchorPoint.X - xArrowOffset - downArrowImage.Size.Width / 2,
								anchorPoint.Y - yArrowOffset - downArrowImage.Size.Height);
						
							bgRect = new RectangleF(0, 0, size.Width, size.Height);
						
							if(offset.X < 0) {
								xArrowOffset += offset.X;
								offset.X = 0;
							}
							else if(offset.X + size.Width > displayArea.Size.Width) {
								xArrowOffset += (offset.X + size.Width - displayArea.Size.Width);
								offset.X = displayArea.Size.Width - size.Width;
							}
						
							//cap arrow offset;
							xArrowOffset = Math.Max(xArrowOffset, Properties.LeftBgMargin + Properties.ArrowMargin);
							xArrowOffset = Math.Min(xArrowOffset, size.Width - Properties.RightBgMargin - Properties.ArrowMargin - downArrowImage.Size.Width);
							
							arrowRect = new RectangleF(xArrowOffset, yArrowOffset, downArrowImage.Size.Width, downArrowImage.Size.Height);
							
							break;
						}
						case UIPopoverArrowDirection.Left: {
							anchorPoint = new PointF(anchorRect.GetMaxX(), anchorRect.GetMidY());
						
							xArrowOffset = Properties.LeftBgMargin - leftArrowImage.Size.Width;
							yArrowOffset = size.Height / 2 - leftArrowImage.Size.Height / 2;
						
							offset = new PointF(anchorPoint.X - xArrowOffset, anchorPoint.Y - yArrowOffset - leftArrowImage.Size.Height / 2);
							bgRect = new RectangleF(0, 0, size.Width, size.Height);
							
							if(offset.Y < 0) {
								yArrowOffset += offset.Y;
								offset.Y = 0;
							}
							else if(offset.Y + size.Height > displayArea.Size.Height) {
								yArrowOffset += (offset.Y + size.Height) - displayArea.Size.Height;
								offset.Y = displayArea.Size.Height - size.Height;
							}
						
							//cap arrow offset;
							yArrowOffset = Math.Max(yArrowOffset, Properties.TopBgMargin + Properties.ArrowMargin);
							yArrowOffset = Math.Min(yArrowOffset, size.Height - Properties.BottomBgMargin - Properties.ArrowMargin - leftArrowImage.Size.Height);
						
							arrowRect = new RectangleF(xArrowOffset, yArrowOffset, leftArrowImage.Size.Width, leftArrowImage.Size.Height);
						
							break;	
						}
						case UIPopoverArrowDirection.Right: {
							anchorPoint = new PointF(anchorRect.GetMinX(), anchorRect.GetMidY());
							
							xArrowOffset = size.Width - Properties.RightBgMargin;
							yArrowOffset = size.Height / 2 - rightArrowImage.Size.Width / 2;
							
							offset = new PointF(anchorPoint.X - xArrowOffset - rightArrowImage.Size.Width, anchorPoint.Y - yArrowOffset - rightArrowImage.Size.Height / 2);
							bgRect = new RectangleF(0, 0, size.Width, size.Height);
						
							if(offset.Y < 0) {
								yArrowOffset += offset.Y;
								offset.Y = 0;
							}
							else if(offset.Y + size.Height > displayArea.Size.Height) {
								yArrowOffset += (offset.Y + size.Height) - displayArea.Size.Height;
								offset.Y = displayArea.Size.Height - size.Height;
							}
						
							//cap arrow offset;
							yArrowOffset = Math.Max(yArrowOffset, Properties.TopBgMargin + Properties.ArrowMargin);
							yArrowOffset = Math.Min(yArrowOffset, size.Height - Properties.BottomBgMargin - Properties.ArrowMargin - rightArrowImage.Size.Height);
						
							arrowRect = new RectangleF(xArrowOffset, yArrowOffset, rightArrowImage.Size.Width, rightArrowImage.Size.Height);
							
							break;	
						}
					}
					
					//end switch statement
					
//					var bgFrame = bgRect.RectOffset(offset.X, offset.Y);
//					var bgFrame = RectangleFExtensions.Offset(bgRect, offset.X, offset.Y);
					var bgFrame = bgRect;
					bgFrame.X += offset.X;
					bgFrame.Y += offset.Y;
					
					var minMarginLeft = bgFrame.GetMinX() - displayArea.GetMinX();
					var minMarginRight = displayArea.GetMaxX() - bgFrame.GetMaxY();
					var minMarginTop = bgFrame.GetMinY() - displayArea.GetMinY();
					var minMarginBottom = displayArea.GetMaxY() - bgFrame.GetMaxY();
					
					if(minMarginLeft < 0) {
					    // Popover is too wide and clipped on the left; decrease width
			    		// and move it to the right
						
						offset.X -= minMarginLeft;
						bgRect.Size.Width += minMarginLeft;
						minMarginLeft = 0;
						
						if(direction == UIPopoverArrowDirection.Right) {
							arrowRect.X = bgRect.GetMaxX() - Properties.RightBgMargin;
						}
					}
					
					if(minMarginRight < 0) {
						// Popover is too wide and clipped on the right; decrease width.
						
						bgRect.Size.Width += minMarginRight;
						minMarginRight = 0;
						
						if(direction == UIPopoverArrowDirection.Left) {
							arrowRect.X = bgRect.GetMinX() - leftArrowImage.Size.Width + Properties.LeftBgMargin;	
						}
					}
					
					if(minMarginTop < 0) {
						// Popover is too high and clipped at the top; decrease height and move it down
						
						offset.Y -= minMarginTop;
						bgRect.Size.Height += minMarginTop;
						minMarginTop = 0;
						
						if(direction == UIPopoverArrowDirection.Down) {
							arrowRect.Y = bgRect.GetMaxY() - Properties.BottomBgMargin;	
						}
					}

					if(minMarginBottom < 0) {
						// Popover is too high and clipped at the bottom; decrease height.
						
						bgRect.Size.Height += minMarginBottom;
						minMarginBottom = 0;
						
						if(direction == UIPopoverArrowDirection.Up) {
							arrowRect.Y = bgRect.GetMinY() - upArrowImage.Size.Height + Properties.TopBgMargin;	
						}
					}
					
					bgFrame = bgRect.RectOffset(offset.X, offset.Y);
					
					var minMargin = Math.Min(minMarginLeft, minMarginRight);
					minMargin = Math.Min(minMargin, minMarginTop);
					minMargin = Math.Min(minMargin, minMarginBottom);
					
					// Calculate intersection and surface
					var intersection = RectangleF.Intersect(displayArea, bgFrame);
					var surface = intersection.Size.Width * intersection.Size.Height;
					
					if(surface >= biggestSurface && minMargin >= currentMinMargin) {
						
						biggestSurface = surface;
						_Offset = offset;
						_ArrowRect = arrowRect;
						_BackgroundRect = bgRect;
						PopoverArrowDirection = direction;
						currentMinMargin = minMargin;
					}
				} // end if
			} //end foreach
			
			switch(PopoverArrowDirection) {
				case UIPopoverArrowDirection.Up:
					_ArrowImage = upArrowImage;
					break;
				case UIPopoverArrowDirection.Down:
					_ArrowImage = downArrowImage;
					break;
				case UIPopoverArrowDirection.Left:
					_ArrowImage = leftArrowImage;
					break;
				case UIPopoverArrowDirection.Right:
					_ArrowImage = rightArrowImage;
					break;
			}
		}