Пример #1
0
		protected override void OnDraw (Context ctx, Rectangle dirtyRect)
		{
			Image image = new CustomImage ();
			int x = 0;
			for (int n=4; n < 50; n += 4) {
				ctx.DrawImage (image.WithSize (n, n), x, 0);
				x += n;
			}

			int maxSize = 48;
			var warn = StockIcons.Error;
			x = 0;
			for (int n=8; n <= maxSize; n += 2) {
				ctx.DrawImage (warn, x, 50, n, n);
				x += n;
			}
			
			warn = StockIcons.Error.WithSize (maxSize).ToBitmap ();
			x = 0;
			for (int n=8; n <= maxSize; n += 2) {
				ctx.DrawImage (warn, x, 100, n, n);
				x += n;
			}

			ctx.DrawImage (image.WithSize (1000), new Rectangle (400, 0, 200, 1000), new Rectangle (0, 200, 200, 200));
			ctx.DrawImage (image.WithSize (1000), new Rectangle (400, 0, 200, 50), new Rectangle (210, 200, 200, 200));
		}
Пример #2
0
		protected override void OnDraw (Context ctx, Rectangle dirtyRect)
		{
			var w = Math.Truncate (Bounds.Width / 2);
			var h = Math.Truncate (Bounds.Height / 2);
			ctx.DrawImage (img_ss, new Rectangle (0, 0, w, h).Inflate (-10, -10));
			ctx.DrawImage (img_tt, new Rectangle (w, 0, w, h).Inflate (-10, -10));
			ctx.DrawImage (img_st, new Rectangle (0, h, w, h).Inflate (-10, -10));
			ctx.DrawImage (img_ts, new Rectangle (w, h, w, h).Inflate (-10, -10));
		}
Пример #3
0
		public void PatternsAndImages (Context ctx, double x, double y)
		{
			ctx.Save ();
			ctx.Translate (x, y);
			
			ctx.SetColor (Colors.Black);
			// Dashed lines

			ctx.SetLineWidth (2);
			ctx.SetLineDash (15, 10, 10, 5, 5);
			ctx.Rectangle (10, 10, 100, 100);
			ctx.Stroke ();
			ctx.SetLineDash (0);
			
			// Image
			var arcColor = new Color (1, 0, 1);
			ImageBuilder ib = new ImageBuilder (30, 30);
			ib.Context.Arc (15, 15, 15, 0, 360);
			ib.Context.SetColor (arcColor);
			ib.Context.Fill ();
			ib.Context.SetColor (Colors.DarkKhaki);
			ib.Context.Rectangle (0, 0, 5, 5);
			ib.Context.Fill ();
			var img = ib.ToVectorImage ();
			ctx.DrawImage (img, 0, 0);
			ctx.DrawImage (img, 0, 50, 50, 10);
			
			ctx.Arc (100, 100, 15, 0, 360);
			arcColor.Alpha = 0.4;
			ctx.SetColor (arcColor);
			ctx.Fill ();
			
			// ImagePattern
			
			ctx.Save ();
			
			ctx.Translate (x + 130, y);
			ctx.Pattern = new ImagePattern (img);
			ctx.Rectangle (0, 0, 100, 100);
			ctx.Fill ();
			ctx.Restore ();
			
			ctx.Restore ();
			
			// Setting pixels
			
			ctx.SetLineWidth (1);
			for (int i=0; i<50;i++) {
				for (var j=0; j<50;j++) {
					Color c = Color.FromHsl (0.5, (double)i / 50d, (double)j / 50d);
					ctx.Rectangle (i, j, 1, 1);
					ctx.SetColor (c);
					ctx.Fill ();
				}
			}
		}	
Пример #4
0
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            // Line arround
            ctx.SetColor(Colors.DarkGray);

            // Drive line arround
            ctx.Rectangle(Bounds);
            ctx.Fill();

            ctx.SetColor(Colors.Gray);
            ctx.Rectangle(Bounds.Inflate(-margin, -margin));
            ctx.Fill();

            // Draw image
            ctx.DrawImage(Image.FromResource(Logo), 5.0, 5.0);

            // Draw text
            ctx.SetColor(Colors.White);
            TextLayout _layout = new TextLayout();
            _layout.Font = Font.WithSize(22);
            _layout.Text = Label;
            _layout.SetFontWeight(FontWeight.Bold, 0, Label.Length);

            // Cocoa layouts
            ctx.DrawTextLayout(_layout, 45, ((Config.Cocoa || Config.Gtk) ? 5 : 2));
        }
Пример #5
0
        protected override void OnDraw(Context ctx, Rectangle bounds)
        {
            var best = GetImage(ctx.Styles);

            if (best != null)
            {
                ctx.DrawImage(best, bounds);
            }
        }
Пример #6
0
		protected override void OnDraw (Context ctx, Rectangle dirtyRect)
		{
			base.OnDraw (ctx, dirtyRect);
			
			for (int y = 0; y < img.Size.Height / 50; ++y) {
				for (int x = 0; x < img.Size.Width / 50; ++x) {
					ctx.DrawImage (img, new Rectangle (x*50, y*50, 50, 50), new Rectangle (x*55, y*55, 50, 50));
				}
			}
		}
Пример #7
0
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            base.OnDraw(ctx, dirtyRect);

            if (Image != null) {
                double width = Bounds.Width == 1 ? Image.Width : Bounds.Width;
                if (Bounds.Width == 1)
                    WidthRequest = width;

                // Scale height respect width
                double height = (Bounds.Width / Image.Width) * Image.Height;
                if (HeightRequest != height)
                    HeightRequest = height;
                else
                    height = Bounds.Height;

                ctx.DrawImage(Image, 0, 0, width, height);
            }
        }
Пример #8
0
        protected override void OnDraw(Context ctx, Rectangle bounds)
        {
            var size = !Size.IsZero ? Size : images [0].Size;

            ctx.Save();
            ctx.Translate(bounds.Location);
            if (!size.IsZero)
            {
                ctx.Scale(bounds.Width / size.Width, bounds.Height / size.Height);
            }

            for (int n = 0; n < images.Length; n++)
            {
                var image = images [n];
                if (image.Size != size)
                {
                    image = image.WithSize(size);
                }
                ctx.DrawImage(image, 0, 0);
            }

            ctx.Restore();
        }
Пример #9
0
		protected override void OnDraw (Context ctx, Rectangle dirtyRect)
		{
			base.OnDraw (ctx, dirtyRect);
			ctx.Save ();

			if (parent.CurrentRow < 0)
				return;

			var row_bounds = parent.ListView.GetRowBounds (parent.CurrentRow, false);
			var row_bg_bounds = parent.ListView.GetRowBounds (parent.CurrentRow, true);

			if (TrackerBg != null) {
				ctx.DrawImage (TrackerBg, row_bg_bounds, new Rectangle (0, 0, row_bg_bounds.Width, row_bg_bounds.Height));
			}

			foreach (var col in parent.ListView.Columns) {
				foreach (var cell in col.Views) {
					var cell_bg_bounds = parent.ListView.GetCellBounds (parent.CurrentRow, cell, true);
					var cell_bounds = parent.ListView.GetCellBounds (parent.CurrentRow, cell, false);
					cell_bounds.Y -= row_bg_bounds.Y;
					cell_bounds.X += parent.ListView.HorizontalScrollControl.Value;
					cell_bg_bounds.Y -= row_bg_bounds.Y;
					cell_bg_bounds.X += parent.ListView.HorizontalScrollControl.Value;
					ctx.SetColor (Colors.Red);
					ctx.Rectangle (cell_bg_bounds);
					ctx.Stroke ();
					ctx.SetColor (Colors.Green);
					ctx.Rectangle (cell_bounds);
					ctx.Stroke ();
				}
			}

			row_bounds.Y -= row_bg_bounds.Y;
			row_bounds.X += parent.ListView.HorizontalScrollControl.Value;
			row_bg_bounds.Y = 0;
			row_bg_bounds.X += parent.ListView.HorizontalScrollControl.Value;

			ctx.SetColor (Colors.Red);
			ctx.Rectangle (row_bg_bounds);
			ctx.Stroke ();

			ctx.SetColor (Colors.Blue);
			ctx.Rectangle (row_bounds);
			ctx.Stroke ();
			ctx.Restore ();
		}
Пример #10
0
		protected override void OnDraw (Context ctx, Rectangle bounds)
		{
			var best = GetImage (ctx.Styles);
			if (best != null)
				ctx.DrawImage (best, bounds);
		}
Пример #11
0
 protected override void OnDraw(Context ctx, Rectangle dirtyRect)
 {
     if (colorBox == null) {
         using (var ib = new ImageBuilder (size, size)) {
             for (int i=0; i<size; i++) {
                 for (int j=0; j<size; j++) {
                     ib.Context.Rectangle (i, j, 1, 1);
                     ib.Context.SetColor (GetColor (i,j));
                     ib.Context.Fill ();
                 }
             }
             colorBox = ib.ToImage ();
         }
     }
     ctx.DrawImage (colorBox, padding, padding);
     ctx.SetLineWidth (1);
     ctx.SetColor (Colors.Black);
     ctx.Rectangle (selection.X + padding - 2 + 0.5, selection.Y + padding - 2 + 0.5, 4, 4);
     ctx.Stroke ();
 }
Пример #12
0
        protected override void OnDraw(Xwt.Drawing.Context ctx)
        {
            base.OnDraw(ctx);

            // Simple rectangles

            ctx.SetLineWidth(1);
            ctx.Rectangle(100, 5, 10, 10);
            ctx.SetColor(Color.Black);
            ctx.Fill();

            ctx.Rectangle(115, 5, 10, 10);
            ctx.SetColor(Color.Black);
            ctx.Stroke();

            //

            ctx.SetLineWidth(3);
            ctx.Rectangle(100, 20, 10, 10);
            ctx.SetColor(Color.Black);
            ctx.Fill();

            ctx.Rectangle(115, 20, 10, 10);
            ctx.SetColor(Color.Black);
            ctx.Stroke();

            // Rectangle with hole

            ctx.Rectangle(10, 100, 40, 40);
            ctx.MoveTo(45, 135);
            ctx.RelLineTo(0, -20);
            ctx.RelLineTo(-20, 0);
            ctx.RelLineTo(0, 20);
            ctx.ClosePath();
            ctx.SetColor(Color.Black);
            ctx.Fill();

            // Dashed lines

            ctx.SetLineDash(15, 10, 10, 5, 5);
            ctx.Rectangle(100, 100, 100, 100);
            ctx.Stroke();
            ctx.SetLineDash(0);

            ImageBuilder ib = new ImageBuilder(30, 30, ImageFormat.ARGB32);

            ib.Context.Arc(15, 15, 15, 0, 360);
            ib.Context.SetColor(new Color(1, 0, 1));
            ib.Context.Rectangle(0, 0, 5, 5);
            ib.Context.Fill();
            var img = ib.ToImage();

            ctx.DrawImage(img, 90, 90);
            ctx.DrawImage(img, 90, 140, 50, 10);

            ctx.Arc(190, 190, 15, 0, 360);
            ctx.SetColor(new Color(1, 0, 1, 0.4));
            ctx.Fill();

            ctx.Save();
            ctx.Translate(90, 220);
            ctx.Pattern = new ImagePattern(img);
            ctx.Rectangle(0, 0, 100, 70);
            ctx.Fill();
            ctx.Restore();

            ctx.Translate(30, 30);
            double end = 270;

            for (double n = 0; n <= end; n += 5)
            {
                ctx.Save();
                ctx.Rotate(n);
                ctx.MoveTo(0, 0);
                ctx.RelLineTo(30, 0);
                double c = n / end;
                ctx.SetColor(new Color(c, c, c));
                ctx.Stroke();
                ctx.Restore();
            }

            ctx.ResetTransform();
        }
Пример #13
0
        protected sealed override void OnDraw(Context ctx, Rectangle bounds)
        {
            if (bounds.Width <= 0 || bounds.Height <= 0)
            {
                return;
            }

            var    frame                   = GetFrame(ctx.ScaleFactor);
            var    fixedWidth              = frame.Bitmap.Width - 2 - frame.StretchableWidth;
            var    fixedHeight             = frame.Bitmap.Height - 2 - frame.StretchableHeight;
            double totalVariableWidth      = bounds.Width - fixedWidth / frame.ScaleFactor;
            double totalVariableHeight     = bounds.Height - fixedHeight / frame.ScaleFactor;
            double remainingVariableHeight = totalVariableHeight;

            double y = bounds.Y, yb = 1;
            int    tileIndex = 0;

            ctx.Save();
            if (totalVariableWidth < 0)
            {
                if (fixedWidth > 0)
                {
                    ctx.Scale(bounds.Width / fixedWidth, 1);
                }
                totalVariableWidth = 0;
            }
            if (totalVariableHeight < 0)
            {
                if (fixedHeight > 0)
                {
                    ctx.Scale(1, bounds.Height / fixedHeight);
                }
                totalVariableHeight = 0;
            }

            foreach (var vs in frame.VerticalSections)
            {
                double sh = CalcSectionSize(frame, vs, totalVariableHeight, frame.StretchableHeight, ref remainingVariableHeight);

                double x = bounds.X, xb = 1;
                double remainingVariableWidth = totalVariableWidth;

                foreach (var hs in frame.HorizontalSections)
                {
                    var    sourceRegion = new Rectangle(xb, yb, hs.Size, vs.Size);
                    double sw           = CalcSectionSize(frame, hs, totalVariableWidth, frame.StretchableWidth, ref remainingVariableWidth);
                    var    targetRegion = new Rectangle(x, y, sw, sh);

                    if (vs.Mode != RenderMode.Tile && hs.Mode != RenderMode.Tile)
                    {
                        var t = GetTile(frame, tileIndex, sourceRegion);
                        ctx.DrawImage(t, targetRegion);
                    }
                    else
                    {
                        double pw = hs.Size / frame.ScaleFactor;
                        double ph = vs.Size / frame.ScaleFactor;
                        if (hs.Mode == RenderMode.Stretch)
                        {
                            pw = targetRegion.Width;
                        }
                        if (vs.Mode == RenderMode.Stretch)
                        {
                            ph = targetRegion.Height;
                        }

                        if (pw <= 0 || ph <= 0)
                        {
                            continue;
                        }

                        ctx.Save();
                        ctx.Translate(targetRegion.Location);
                        targetRegion.Location = Point.Zero;
                        ctx.Pattern           = new ImagePattern(GetTile(frame, tileIndex, sourceRegion).WithSize(pw, ph));
                        ctx.NewPath();
                        ctx.Rectangle(targetRegion);
                        ctx.Fill();
                        ctx.Restore();
                    }
                    x  += sw;
                    xb += hs.Size;
                    tileIndex++;
                }
                yb += vs.Size;
                y  += sh;
            }
            ctx.Restore();
        }
Пример #14
0
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            base.OnDraw(ctx, dirtyRect);

            if (isPressed || Active) {
                ctx.DrawImage(toggleButton && isPressed ? bg[1].WithAlpha(0.8) : bg[1], Point.Zero);
            } else {
                ctx.DrawImage(bg[0], Point.Zero);
            }

            ctx.DrawImage(icon, new Point(((icon.Width + bg[0].Width) / 2) - icon.Width, 0));
        }
Пример #15
0
        double DrawHeader(Context ctx)
        {
            Point textOffset = new Point(8, 4);

            textLayoutBold.Text = algorithm.Headline();
            Size textSize = textLayoutBold.GetSize();

            if (textSize.Width >= AbsMaxNodeSize.Width - textSize.Height * 2) {
                textLayoutBold.Width = textSize.Width = AbsMaxNodeSize.Width;
            }
            Point textPosition = bound.Location.Offset(textOffset);

            // headline background
            contentOffset.X = 6;
            contentOffset.Y = textOffset.Y + textSize.Height + 4;

            ctx.RoundRectangle(bound.Left + 1, bound.Top + 1, bound.Width - 2, contentOffset.Y, NodeRadius);
            ctx.SetColor(NodeHeadlineBackground);
            ctx.Fill();

            // text
            ctx.SetColor(NodeHeadlineTextColor);
            ctx.DrawTextLayout(textLayoutBold, textPosition);

            // icons
            double iconWidth = 0.0;
            foreach (var icon in icons) {
                if (icon.Value.Visible) {
                    iconWidth = icon.Value.Bounds.Width;
                    icon.Value.Bounds =
                        new Rectangle(bound.Width - icon.Value.Bounds.Width - 10, 3, icon.Value.Bounds.Width, icon.Value.Bounds.Height);
                    ctx.DrawImage(
                        icon.Value.Image,
                        bound.Location.Offset(icon.Value.Bounds.Location)
                    );
                }
            }

            double width = textSize.Width + iconWidth + 10 + NodeTextMargin;

            return width;
        }
Пример #16
0
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            base.OnDraw(ctx, dirtyRect);

            if (image != null) {
                if (Heighlighted && IsThumbnail) {
                    ctx.RoundRectangle(new Rectangle(Point.Zero, image.Size), 3);
                    ctx.SetColor(Colors.LightSteelBlue);
                    ctx.Fill();
                }

                ctx.DrawImage(image, (new Rectangle(Point.Zero, image.Size)).Inflate(-3, -3));

                if (mask != null && ShowMask) {
                    ctx.DrawImage(MaskBitmap, (new Rectangle(Point.Zero, image.Size)).Inflate(-3, -3), 0.6);
                }
            }

            if (isEditMode) {
                Point scaleFactor = new Point(
                                        scan.Size.Width / image.Size.Width,
                                        scan.Size.Height / image.Size.Height);
                ctx.SetColor(Mask.maskColor);

                foreach (MaskEntry p in scan.Mask.MaskPositions) {
                    switch (p.type) {
                    case MaskEntryType.Point:
                        ctx.SetLineWidth(p.pointerSize / scaleFactor.Y * 2);
                        ctx.LineTo(p.position.X / scaleFactor.X, p.position.Y / scaleFactor.Y);
                        ctx.Stroke();

                        ctx.Arc(
                            p.position.X / scaleFactor.X, p.position.Y / scaleFactor.Y,
                            p.pointerSize / scaleFactor.Y, 0, 360);
                        ctx.Fill();

                        ctx.MoveTo(p.position.X / scaleFactor.X, p.position.Y / scaleFactor.Y);
                        break;
                    case MaskEntryType.Space:
                        ctx.Stroke();
                        ctx.ClosePath();
                        break;
                    case MaskEntryType.Delete:
                        ctx.Arc(
                            p.position.X / scaleFactor.X, p.position.Y / scaleFactor.Y,
                            p.pointerSize / scaleFactor.Y, 0, 360);
                        ctx.Save();
                        ctx.Clip();
                        int newX = (int) Math.Min(Math.Max(
                                       p.position.X / scaleFactor.X - pointerSize / scaleFactor.Y, 0), scan.Size.Width);
                        int newY = (int) Math.Min(Math.Max(
                                       p.position.Y / scaleFactor.Y - pointerSize / scaleFactor.Y, 0), scan.Size.Height);

                        using (ImageBuilder ib =
                                   new ImageBuilder((pointerSize / scaleFactor.Y * 2), (pointerSize / scaleFactor.Y * 2))) {
                            BitmapImage bi = ib.ToBitmap();
                            image.WithBoxSize(image.Size).ToBitmap().CopyArea(
                                newX, newY,
                                (int) (pointerSize / scaleFactor.Y * 2), (int) (pointerSize / scaleFactor.Y * 2),
                                bi, 0, 0);
                            ctx.DrawImage(bi, new Point(newX, newY));
                        }
                        ctx.Restore();
                        ctx.ClosePath();
                        break;
                    }
                }

                ctx.Stroke();

                if (mousePosition != Point.Zero) {
                    ctx.Arc(mousePosition.X, mousePosition.Y, pointerSize / Math.Max(scaleFactor.X, scaleFactor.Y), 0, 360);
                    ctx.Fill();

                    if (mousePositionStart != Point.Zero) {
                        ctx.SetLineWidth((pointerSize / Math.Max(scaleFactor.X, scaleFactor.Y)) * 2);
                        ctx.SetColor(Mask.maskColor);
                        ctx.Arc(mousePositionStart.X, mousePositionStart.Y, pointerSize / Math.Max(scaleFactor.X, scaleFactor.Y), 0, 360);
                        ctx.Fill();
                        ctx.MoveTo(mousePosition);
                        ctx.LineTo(mousePositionStart);
                        ctx.Stroke();
                    }
                }
            }
        }
Пример #17
0
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            Point p = new Point (centre, centre);
            DrawFocus (ctx, p);
            if (!testMode)
                return;

            // Simplest drawing - direct to Canvas context
            ctx.SetColor (Colors.Red);
            DrawFPS = TimedAction (delegate {
                DrawFocus (ctx, p);
            });

            // Check timings for copying off-screen images
            // Destination on canvas may be changed
            Rectangle srcRect = new Rectangle (0, 0, size, size);
            Rectangle dstRect = new Rectangle (80, 0, size, size);

            BitmapFPS = TimedAction (delegate {
                ctx.DrawImage (bitmap, srcRect, dstRect);
            });

            dstRect.X += 80;
            ImageFPS = TimedAction (delegate {
                ctx.DrawImage (vectorImage, srcRect, dstRect);
            });

            testMode = false;
            if (TestFinished != null)
                TestFinished (this, EventArgs.Empty);
        }
Пример #18
0
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            base.OnDraw(ctx, dirtyRect);

            ctx.DrawImage(renderedImage[(int) SelectedLogLevel], Point.Zero);
        }
		void DrawCheckBox (Context ctx, PackageViewModel packageViewModel, Rectangle cellArea)
		{
			CreateCheckboxImages ();

			Image image = GetCheckBoxImage (packageViewModel.IsChecked);
			double alpha = GetCheckBoxImageAlpha ();
			ctx.DrawImage (
				image,
				cellArea.Left + checkBoxPadding.Left,
				cellArea.Top + ((cellArea.Height - checkBoxImageSize.Height - 2) / 2),
				alpha);
		}
Пример #20
0
        /// <summary>
        /// Draw the the PlotSurface and contents (axes, drawables, and legend) using the
        /// Drawing Context supplied and the bounding rectangle for the PlotSurface to cover
        /// </summary>
        /// <param name="ctx">The Drawing Context with which to draw.</param>
        /// <param name="bounds">The rectangle within which to draw</param>
        public void Draw(Context ctx, Rectangle bounds)
        {
            Point titleOrigin = Point.Zero;

            ctx.Save ();

            // determine font sizes and tick scale factor.
            double scale = DetermineScaleFactor (bounds.Width, bounds.Height);

            // if there is nothing to plot, draw title and return.
            if (drawables.Count == 0) {
                // draw title
                //TODO: Title should be centred here - not its origin
                Point origin = Point.Zero;
                titleOrigin.X = bounds.Width/2;
                titleOrigin.Y = bounds.Height/2;
                DrawTitle (ctx, titleOrigin, scale);
                ctx.Restore ();
                return;
            }

            // determine the [non physical] axes to draw based on the axis properties set.
            Axis XAxis1 = null;
            Axis XAxis2 = null;
            Axis YAxis1 = null;
            Axis YAxis2 = null;
            DetermineAxesToDraw (out XAxis1, out XAxis2, out YAxis1, out YAxis2);

            // apply scale factor to axes as desired.

            if (XAxis1.AutoScaleTicks) {
                XAxis1.TickScale = scale;
            }
            if (XAxis1.AutoScaleText) {
                XAxis1.FontScale = scale;
            }
            if (YAxis1.AutoScaleTicks) {
                YAxis1.TickScale = scale;
            }
            if (YAxis1.AutoScaleText) {
                YAxis1.FontScale = scale;
            }
            if (XAxis2.AutoScaleTicks) {
                XAxis2.TickScale = scale;
            }
            if (XAxis2.AutoScaleText) {
                XAxis2.FontScale = scale;
            }
            if (YAxis2.AutoScaleTicks) {
                YAxis2.TickScale = scale;
            }
            if (YAxis2.AutoScaleText) {
                YAxis2.FontScale = scale;
            }

            // determine the default physical positioning of those axes.
            PhysicalAxis pXAxis1 = null;
            PhysicalAxis pYAxis1 = null;
            PhysicalAxis pXAxis2 = null;
            PhysicalAxis pYAxis2 = null;
            DeterminePhysicalAxesToDraw (
                bounds, XAxis1, XAxis2, YAxis1, YAxis2,
                out pXAxis1, out pXAxis2, out pYAxis1, out pYAxis2 );

            double oldXAxis2Height = pXAxis2.PhysicalMin.Y;

            // Apply axes constraints
            for (int i=0; i<axesConstraints.Count; ++i) {
                ((AxesConstraint)axesConstraints[i]).ApplyConstraint(
                    pXAxis1, pYAxis1, pXAxis2, pYAxis2 );
            }

            // draw legend if have one.
            // Note: this will update axes if necessary.
            Point legendPosition = new Point(0,0);
            if (legend != null) {
                legend.UpdateAxesPositions (
                    pXAxis1, pYAxis1, pXAxis2, pYAxis2,
                    drawables, scale, Padding, bounds,
                    out legendPosition );
            }

            double newXAxis2Height = pXAxis2.PhysicalMin.Y;
            double titleExtraOffset = oldXAxis2Height - newXAxis2Height;

            // now we are ready to define the clipping region
            plotAreaBoundingBoxCache = new Rectangle (
                Math.Min (pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMax.X),
                Math.Min (pYAxis1.PhysicalMax.Y, pYAxis1.PhysicalMin.Y),
                Math.Abs (pXAxis1.PhysicalMax.X - pXAxis1.PhysicalMin.X + 1),
                Math.Abs (pYAxis1.PhysicalMin.Y - pYAxis1.PhysicalMax.Y + 1)
            );
            bbXAxis1Cache = pXAxis1.GetBoundingBox ();
            bbXAxis2Cache = pXAxis2.GetBoundingBox ();
            bbYAxis1Cache = pYAxis1.GetBoundingBox ();
            bbYAxis2Cache = pYAxis2.GetBoundingBox ();

            Rectangle plotBounds = (Rectangle)plotAreaBoundingBoxCache;

            // set the clipping region.. (necessary for zoom)
            // Note: although clipping is enforced by the clip region, it is probably more efficient
            // for each Drawable to check against the plotBounds and not draw if points are outside.
            // This hasn't yet been implemented
            ctx.Save ();
            ctx.Rectangle (plotBounds);
            ctx.Clip ();

            // Fill in the plot background.
            if (plotBackImage != null) {
                // Ensure plotBounds has integer size for correct tiling/drawing
                plotBounds.Width = Math.Truncate (plotBounds.Width);
                plotBounds.Height = Math.Truncate (plotBounds.Height);
                ctx.DrawImage (Utils.TiledImage (plotBackImage , plotBounds.Size), plotBounds);
            }
            else if (plotBackGradient != null) {
                // Scale plotBackGradient to plotBounds
                double startX = plotBounds.X + (plotBackGradient.StartPoint.X * plotBounds.Width);
                double startY = plotBounds.Y + (plotBackGradient.StartPoint.Y * plotBounds.Height);
                double endX = plotBounds.X + (plotBackGradient.EndPoint.X * plotBounds.Width);
                double endY = plotBounds.Y + (plotBackGradient.EndPoint.Y * plotBounds.Height);
                LinearGradient g = new LinearGradient (startX, startY, endX, endY);
                g.AddColorStop (0, plotBackGradient.StartColor);
                g.AddColorStop (1, plotBackGradient.EndColor);
                ctx.Rectangle (plotBounds);
                ctx.Pattern = g;
                ctx.Fill ();
            }
            else {
                ctx.Rectangle (plotBounds);
                ctx.SetColor (plotBackColor);
                ctx.Fill ();
            }

            // draw title at centre of Physical X-axis and at top of plot

            titleOrigin.X = (pXAxis2.PhysicalMax.X + pXAxis2.PhysicalMin.X)/2.0;
            titleOrigin.Y = bounds.Top + Padding - titleExtraOffset;
            Size s = DrawTitle (ctx, titleOrigin, scale);

            bbTitleCache = new Rectangle (titleOrigin.X-s.Width/2, titleOrigin.Y, s.Width, s.Height);

            // draw drawables..
            bool legendDrawn = false;

            for (int i_o = 0; i_o < ordering.Count; ++i_o) {

                int i = (int)ordering.GetByIndex (i_o);
                double zOrder = (double)ordering.GetKey (i_o);
                if (zOrder > legendZOrder) {
                    // draw legend.
                    if (!legendDrawn && legend != null) {
                        legend.Draw (ctx, legendPosition, drawables, scale);
                        legendDrawn = true;
                    }
                }

                IDrawable drawable = (IDrawable)drawables[i];
                XAxisPosition xap = (XAxisPosition)xAxisPositions[i];
                YAxisPosition yap = (YAxisPosition)yAxisPositions[i];

                PhysicalAxis drawXAxis;
                PhysicalAxis drawYAxis;

                if (xap == XAxisPosition.Bottom) {
                    drawXAxis = pXAxis1;
                }
                else {
                    drawXAxis = pXAxis2;
                }

                if (yap == YAxisPosition.Left) {
                    drawYAxis = pYAxis1;
                }
                else {
                    drawYAxis = pYAxis2;
                }

                drawable.Draw (ctx, drawXAxis, drawYAxis);

            }

            if (!legendDrawn && legend != null) {
                legend.Draw (ctx, legendPosition, drawables, scale);
            }

            ctx.Restore ();		// end of clipping region

            // cache the physical axes we used on this draw;
            pXAxis1Cache = pXAxis1;
            pYAxis1Cache = pYAxis1;
            pXAxis2Cache = pXAxis2;
            pYAxis2Cache = pYAxis2;

            // now draw axes.
            Rectangle axisBounds;
            pXAxis1.Draw (ctx, out axisBounds);
            pXAxis2.Draw (ctx, out axisBounds);
            pYAxis1.Draw (ctx, out axisBounds);
            pYAxis2.Draw (ctx, out axisBounds);

            #if DEBUG_BOUNDING_BOXES
            ctx.SetColor (Colors.Orange);
            ctx.Rectangle ((Rectangle)bbXAxis1Cache);
            ctx.Rectangle ((Rectangle)bbXAxis2Cache);
            ctx.Rectangle ((Rectangle)bbYAxis1Cache);
            ctx.Rectangle ((Rectangle)bbYAxis2Cache);
            ctx.Stroke ();
            ctx.SetColor (Colors.Red);
            ctx.Rectangle ((Rectangle)plotAreaBoundingBoxCache);
            ctx.Rectangle ((Rectangle)bbTitleCache);
            ctx.Stroke ();
            #endif
            ctx.Restore ();
        }
Пример #21
0
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            base.OnDraw(ctx, dirtyRect);

            for (int i = 0; i < Size.Width / checkerboard.Width; i++)
            {
                for (int j = 0; j < Size.Height / checkerboard.Height; j++)
                {
                    ctx.DrawImage(checkerboard, i * checkerboard.Width, j * checkerboard.Height);
                }
            }

            ctx.SetLineWidth(1);

            ctx.SetColor(color);
            ctx.Rectangle(0, 0, Size.Width - 20, Size.Height);
            ctx.Fill();

            ctx.SetColor(DefaultColor);
            ctx.Rectangle(Size.Width - 20, 0, 20, Size.Height);
            ctx.Fill();

            ctx.SetColor(Colors.Black);
            ctx.Rectangle(0, 0, Size.Width, Size.Height);
            ctx.Stroke();

            //ctx.SetColor(Color.Brightness > .5 ? Colors.White : Colors.Black);
            ctx.SetColor(((-1 * Color.Brightness) + 1) * 1.15 + (Color.Alpha) > 1.2 ? Colors.White : Colors.Black);
            ctx.DrawTextLayout(new TextLayout(this) { Text = Color.ToHexString().ToUpper() }, 2, 3);

            if (mover && (IsDefaultColor || mx <= Size.Width - 20))
            {
                ctx.SetColor(new Color(1, 1, 1, .33));
                ctx.Rectangle(0, 0, Size.Width - (IsDefaultColor ? 0 : 20), Size.Height);
                ctx.Fill();
            }

            if (!IsDefaultColor)
            {
                if (mover && mx > Size.Width - 20)
                {
                    ctx.SetColor(new Color(1, 1, 1, .33));
                    ctx.Rectangle(Size.Width - 20, 0, 20, Size.Height);
                    ctx.Fill();
                }

                ctx.SetColor(Colors.Black);
                ctx.MoveTo(Size.Width - 19.5, 0);
                ctx.RelLineTo(0, Size.Height);
                ctx.Stroke();

                if (mover)
                    ctx.DrawImage(resetImage, Size.Width - 18, (Size.Height - 16) / 2, 16, 16);
            }
        }
Пример #22
0
 /// <summary>
 /// Draw a information on the ListView2Item
 /// </summary>
 /// <param name="What">What should be drawed</param>
 /// <param name="Where">Where (position by X) should be drawed</param>
 /// <param name="On">On what Drawing.Context the information should be drawed</param>
 /// <param name="MaxWidth">The limit of the picture's width</param>
 /// <param name="TextColor">The text foreground color</param>
 /// <param name="WhatFont">Which font is used to draw the onject</param>
 private void Draw(object What, double Where, Context On, double MaxWidth, Color TextColor, Font WhatFont)
 {
     if (What.GetType() != typeof (Image)
         &&
         What.GetType() != typeof (DirItem))
     {
         TextLayout tl = new TextLayout(this)
         {
             Text = What.ToString(),
             Font = WhatFont,
             Width = MaxWidth,
             Trimming = TextTrimming.WordElipsis
         };
         On.SetColor (TextColor);
         On.DrawTextLayout(tl, Where + 4, 0);
     }
     if (What is Image)
     {
         On.DrawImage(What as Image, Where + 2, 0);
     }
 }
Пример #23
0
 protected override void OnDraw(Context ctx, Rectangle dirtyRect)
 {
     // Update the display from the off-screen cache
     ctx.DrawImage (cache, dirtyRect, dirtyRect);
     // then add any Overlay content
     OnDrawOverlay (ctx, dirtyRect);
 }
Пример #24
0
        protected override sealed void OnDraw(Context ctx, Rectangle bounds)
        {
            var frame = GetFrame (ctx.ScaleFactor);
            var fixedWidth = frame.Bitmap.Width - 2 - frame.StretchableWidth;
            var fixedHeight = frame.Bitmap.Height - 2 - frame.StretchableHeight;
            double totalVariableWidth = bounds.Width - fixedWidth / frame.ScaleFactor;
            double totalVariableHeight = bounds.Height - fixedHeight / frame.ScaleFactor;
            double remainingVariableHeight = totalVariableHeight;

            double y = bounds.Y, yb = 1;
            int tileIndex = 0;

            ctx.Save ();
            if (totalVariableWidth < 0) {
                if (fixedWidth > 0)
                    ctx.Scale (bounds.Width / fixedWidth, 1);
                totalVariableWidth = 0;
            }
            if (totalVariableHeight < 0) {
                if (fixedHeight > 0)
                    ctx.Scale (1, bounds.Height / fixedHeight);
                totalVariableHeight = 0;
            }

            foreach (var vs in frame.VerticalSections) {

                double sh = CalcSectionSize (frame, vs, totalVariableHeight, frame.StretchableHeight, ref remainingVariableHeight);

                double x = bounds.X, xb = 1;
                double remainingVariableWidth = totalVariableWidth;

                foreach (var hs in frame.HorizontalSections) {
                    var sourceRegion = new Rectangle (xb, yb, hs.Size, vs.Size);
                    double sw = CalcSectionSize (frame, hs, totalVariableWidth, frame.StretchableWidth, ref remainingVariableWidth);
                    var targetRegion = new Rectangle (x, y, sw, sh);

                    if (vs.Mode != RenderMode.Tile && hs.Mode != RenderMode.Tile) {
                        var t = GetTile (frame, tileIndex, sourceRegion);
                        ctx.DrawImage (t, targetRegion);
                    } else {
                        double pw = hs.Size / frame.ScaleFactor;
                        double ph = vs.Size / frame.ScaleFactor;
                        if (hs.Mode == RenderMode.Stretch) {
                            pw = targetRegion.Width;
                        }
                        if (vs.Mode == RenderMode.Stretch) {
                            ph = targetRegion.Height;
                        }

                        ctx.Save ();
                        ctx.Translate (targetRegion.Location);
                        targetRegion.Location = Point.Zero;
                        ctx.Pattern = new ImagePattern (GetTile (frame, tileIndex, sourceRegion).WithSize (pw, ph));
                        ctx.NewPath ();
                        ctx.Rectangle (targetRegion);
                        ctx.Fill ();
                        ctx.Restore ();
                    }
                    x += sw;
                    xb += hs.Size;
                    tileIndex++;
                }
                yb += vs.Size;
                y += sh;
            }
            ctx.Restore ();
        }
Пример #25
0
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            base.OnDraw(ctx, dirtyRect);

            if (isDisabled) {
                ctx.DrawImage(bgDisabled.WithBoxSize(Size), Point.Zero);
            } else if (isPressed) {
                ctx.DrawImage(bgPressed.WithBoxSize(Size), Point.Zero);
            } else if (isHover) {
                ctx.DrawImage(bgHover.WithBoxSize(Size), Point.Zero);
            } else {
                ctx.DrawImage(bgNormal.WithBoxSize(Size), Point.Zero);
            }

            if (isDisabled) {
                ctx.DrawImage(icon.WithBoxSize(Size).WithAlpha(0.6), Point.Zero);
            } else {
                ctx.DrawImage(icon.WithBoxSize(Size), Point.Zero);
            }
        }
		void DrawPackageImage (Context ctx, Rectangle cellArea)
		{
			Image image = GetValue (ImageField);

			if (image == null) {
				image = defaultPackageImage;
			}

			if (PackageImageNeedsResizing (image)) {
				Point imageLocation = GetPackageImageLocation (maxPackageImageSize, cellArea);
				ctx.DrawImage (
					image,
					cellArea.Left + packageImagePadding.Left + checkBoxAreaWidth + imageLocation.X,
					Math.Round( cellArea.Top + packageImagePadding.Top + imageLocation.Y),
					maxPackageImageSize.Width,
					maxPackageImageSize.Height);
			} else {
				Point imageLocation = GetPackageImageLocation (image.Size, cellArea);
				ctx.DrawImage (
					image,
					cellArea.Left + packageImagePadding.Left + checkBoxAreaWidth + imageLocation.X,
					Math.Round (cellArea.Top + packageImagePadding.Top + imageLocation.Y));
			}
		}
Пример #27
0
        /// <summary>
        /// Draw the the PlotSurface2D and contents (axes, drawables, and legend) using the
        /// Drawing Context supplied and the bounding rectangle for the PlotSurface to cover
        /// </summary>
        /// <param name="ctx">The Drawing Context with which to draw.</param>
        /// <param name="bounds">The rectangle within which to draw</param>
        public void Draw(Context ctx, Rectangle bounds)
        {
            Point titleOrigin = Point.Zero;

            ctx.Save ();

            // determine font sizes and tick scale factor.
            double scale = DetermineScaleFactor (bounds.Width, bounds.Height);

            // if there is nothing to plot, draw title and return.
            if (drawables.Count == 0) {
                // draw title
                //TODO: Title should be centred here - not its origin
                Point origin = Point.Zero;
                titleOrigin.X = bounds.Width/2;
                titleOrigin.Y = bounds.Height/2;
                DrawTitle (ctx, titleOrigin, scale);
                ctx.Restore ();
                return;
            }

            // determine the [non physical] axes to draw based on the axis properties set.
            Axis xAxis1 = null;
            Axis xAxis2 = null;
            Axis yAxis1 = null;
            Axis yAxis2 = null;
            DetermineAxesToDraw (out xAxis1, out xAxis2, out yAxis1, out yAxis2);

            // apply scale factor to axes as desired.

            if (xAxis1.AutoScaleTicks) {
                xAxis1.TickScale = scale;
            }
            if (xAxis1.AutoScaleText) {
                xAxis1.FontScale = scale;
            }
            if (yAxis1.AutoScaleTicks) {
                yAxis1.TickScale = scale;
            }
            if (yAxis1.AutoScaleText) {
                yAxis1.FontScale = scale;
            }
            if (xAxis2.AutoScaleTicks) {
                xAxis2.TickScale = scale;
            }
            if (xAxis2.AutoScaleText) {
                xAxis2.FontScale = scale;
            }
            if (yAxis2.AutoScaleTicks) {
                yAxis2.TickScale = scale;
            }
            if (yAxis2.AutoScaleText) {
                yAxis2.FontScale = scale;
            }

            // determine the default physical positioning of those axes.
            PhysicalAxis pXAxis1 = null;
            PhysicalAxis pYAxis1 = null;
            PhysicalAxis pXAxis2 = null;
            PhysicalAxis pYAxis2 = null;
            DeterminePhysicalAxesToDraw (
                bounds, xAxis1, xAxis2, yAxis1, yAxis2,
                out pXAxis1, out pXAxis2, out pYAxis1, out pYAxis2 );

            double oldXAxis2Height = pXAxis2.PhysicalMin.Y;

            // Apply axes constraints
            for (int i=0; i<axesConstraints.Count; ++i) {
                ((AxesConstraint)axesConstraints[i]).ApplyConstraint(
                    pXAxis1, pYAxis1, pXAxis2, pYAxis2 );
            }

            // draw legend if have one.
            // Note: this will update axes if necessary.
            Point legendPosition = new Point(0,0);
            if (legend != null) {
                legend.UpdateAxesPositions (
                    pXAxis1, pYAxis1, pXAxis2, pYAxis2,
                    drawables, scale, padding, bounds,
                    out legendPosition );
            }

            double newXAxis2Height = pXAxis2.PhysicalMin.Y;
            double titleExtraOffset = oldXAxis2Height - newXAxis2Height;

            // now we are ready to define the bounding box for the plot area (to use in clipping
            // operations.
            plotAreaBoundingBoxCache = new Rectangle (
                Math.Min (pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMax.X),
                Math.Min (pYAxis1.PhysicalMax.Y, pYAxis1.PhysicalMin.Y),
                Math.Abs (pXAxis1.PhysicalMax.X - pXAxis1.PhysicalMin.X + 1),
                Math.Abs (pYAxis1.PhysicalMin.Y - pYAxis1.PhysicalMax.Y + 1)
            );
            bbXAxis1Cache = pXAxis1.GetBoundingBox ();
            bbXAxis2Cache = pXAxis2.GetBoundingBox ();
            bbYAxis1Cache = pYAxis1.GetBoundingBox ();
            bbYAxis2Cache = pYAxis2.GetBoundingBox ();

            // Fill in the background.
            if (plotBackImage != null) {
                Rectangle imageRect = (Rectangle)plotAreaBoundingBoxCache;
                ctx.DrawImage (Utils.TiledImage (plotBackImage , imageRect.Size), imageRect);
            }
            //else if (plotBackBrush_ != null) {
            //	g.FillRectangle(
            //		plotBackBrush_.Get( (Rectangle)plotAreaBoundingBoxCache ),
            //		(Rectangle)plotAreaBoundingBoxCache );
            //}
            else {
                ctx.SetColor (plotBackColor);
                ctx.Rectangle ((Rectangle)plotAreaBoundingBoxCache);
                ctx.Fill ();
            }

            // draw title at centre of Physical X-axis and at top of plot

            titleOrigin.X = (pXAxis2.PhysicalMax.X + pXAxis2.PhysicalMin.X)/2.0;
            titleOrigin.Y = bounds.Top + padding - titleExtraOffset;
            Size s = DrawTitle (ctx, titleOrigin, scale);

            bbTitleCache = new Rectangle (titleOrigin.X-s.Width/2, titleOrigin.Y, s.Width, s.Height);

            // draw drawables..
            bool legendDrawn = false;

            for (int i_o = 0; i_o < ordering.Count; ++i_o) {

                int i = (int)ordering.GetByIndex (i_o);
                double zOrder = (double)ordering.GetKey (i_o);
                if (zOrder > legendZOrder) {
                    // draw legend.
                    if (!legendDrawn && legend != null) {
                        legend.Draw (ctx, legendPosition, drawables, scale);
                        legendDrawn = true;
                    }
                }

                IDrawable drawable = (IDrawable)drawables[i];
                XAxisPosition xap = (XAxisPosition)xAxisPositions[i];
                YAxisPosition yap = (YAxisPosition)yAxisPositions[i];

                PhysicalAxis drawXAxis;
                PhysicalAxis drawYAxis;

                if (xap == XAxisPosition.Bottom) {
                    drawXAxis = pXAxis1;
                }
                else {
                    drawXAxis = pXAxis2;
                }

                if (yap == YAxisPosition.Left) {
                    drawYAxis = pYAxis1;
                }
                else {
                    drawYAxis = pYAxis2;
                }

                // set the clipping region.. (necessary for zoom)
                ///TODO:	g.Clip = new Region((Rectangle)plotAreaBoundingBoxCache);
                // plot.
                drawable.Draw (ctx, drawXAxis, drawYAxis);
                // reset it..
                //g.ResetClip();
            }

            if (!legendDrawn && legend != null) {
                legend.Draw (ctx, legendPosition, drawables, scale);
            }

            // cache the physical axes we used on this draw;
            pXAxis1Cache = pXAxis1;
            pYAxis1Cache = pYAxis1;
            pXAxis2Cache = pXAxis2;
            pYAxis2Cache = pYAxis2;

            // now draw axes.
            Rectangle axisBounds;
            pXAxis1.Draw (ctx, out axisBounds);
            pXAxis2.Draw (ctx, out axisBounds);
            pYAxis1.Draw (ctx, out axisBounds);
            pYAxis2.Draw (ctx, out axisBounds);

            #if DEBUG_BOUNDING_BOXES
            ctx.SetColor (Colors.Orange);
            ctx.Rectangle ((Rectangle)bbXAxis1Cache);
            ctx.Rectangle ((Rectangle)bbXAxis2Cache);
            ctx.Rectangle ((Rectangle)bbYAxis1Cache);
            ctx.Rectangle ((Rectangle)bbYAxis2Cache);
            ctx.Stroke ();
            ctx.SetColor (Colors.Red);
            ctx.Rectangle ((Rectangle)plotAreaBoundingBoxCache);
            ctx.Rectangle ((Rectangle)bbTitleCache);
            ctx.Stroke ();
            #endif
            ctx.Restore ();
        }
Пример #28
0
		protected override void OnDraw (Context ctx, Rectangle dirtyRect)
		{
			if (colorBox == null) {
				using (var ib = new ImageBuilder (size, size)) {
					for (int i=0; i<size; i++) {
						for (int j=0; j<size; j++) {
							ib.Context.Rectangle (i, j, 1, 1);
							ib.Context.SetColor (GetColor (i,j));
							ib.Context.Fill ();
						}
					}

					if (ParentWindow != null)
						colorBox = ib.ToBitmap (this); // take screen scale factor into account
					else
						colorBox = ib.ToBitmap ();
				}
			}
			ctx.DrawImage (colorBox, padding, padding);
			ctx.SetLineWidth (1);
			ctx.SetColor (Colors.Black);
			ctx.Rectangle (selection.X + padding - 2 + 0.5, selection.Y + padding - 2 + 0.5, 4, 4);
			ctx.Stroke ();
		}
Пример #29
0
        /// <summary>
        /// Raises the draw event.
        /// </summary>
        /// <param name="ctx">Context.</param>
        /// <param name="dirtyRect">Dirty rect.</param>
        protected override void OnDraw(Context ctx, Rectangle dirtyRect)
        {
            base.OnDraw(ctx, dirtyRect);

            ctx.SetLineWidth(1.0);

            if (previous != null && !previous.Active) {
                ctx.SetColor(deactiveColor);
                if (Multiple) {
                    ctx.Rectangle(0, 0, Lean.Dx * 2, Size.Height);
                    ctx.Fill();

                    ctx.SetColor(borderColor);
                    ctx.MoveTo(0, 0);
                    ctx.LineTo(Lean.Dx * 2, 0);
                    ctx.Stroke();
                } else {
                    ctx.MoveTo(0, 0);
                    ctx.CurveTo(
                        0, 0,
                        Lean.Dx, 0,
                        Lean.Dx, Lean.Dy);
                    ctx.LineTo(Lean.Dx, Size.Height - Lean.Dy);
                    ctx.CurveTo(
                        Lean.Dx, Size.Height - Lean.Dy,
                        Lean.Dx, Size.Height + 0.5,
                        Lean.Dx * 2, Size.Height + 0.5);
                    ctx.LineTo(0, Size.Height);

                    ctx.FillPreserve();

                    ctx.SetColor(borderColor);
                    ctx.Stroke();
                }
            }

            if (previous == null || Multiple || !previous.Active) {
                ctx.MoveTo(0, Size.Height + 0.5);
                ctx.CurveTo(
                    0, Size.Height + 0.5,
                    Lean.Dx, Size.Height + 0.5,
                    Lean.Dx, Size.Height - Lean.Dy);
            } else {
                ctx.MoveTo(Lean.Dx, Size.Height);
            }
            ctx.LineTo(Lean.Dx, Lean.Dy);
            ctx.CurveTo(
                Lean.Dx, Lean.Dy,
                Lean.Dx, 0,
                Lean.Dx * 2, 0);

            if (next == null) {
                ctx.LineTo(Size.Width - (Lean.Dx * 2), 0);
                ctx.CurveTo(
                    Size.Width - (Lean.Dx * 2), 0,
                    Size.Width - Lean.Dx, 0,
                    Size.Width - Lean.Dx, Lean.Dy);
                ctx.LineTo(Size.Width - Lean.Dx, Size.Height - Lean.Dy);
                ctx.CurveTo(
                    Size.Width - Lean.Dx, Size.Height - Lean.Dy,
                    Size.Width - Lean.Dx, Size.Height,
                    Size.Width, Size.Height);
            } else {
                ctx.LineTo(Size.Width, 0);
                ctx.LineTo(Size.Width, Size.Height);
            }

            ctx.SetColor(Active ? activeColor : deactiveColor);
            ctx.Fill();

            // border
            if (previous == null || Multiple || !previous.Active) {
                ctx.MoveTo(0, Size.Height + 0.5);
                ctx.CurveTo(
                    0, Size.Height + 0.5,
                    Lean.Dx, Size.Height + 0.5,
                    Lean.Dx, Size.Height - Lean.Dy);
            } else {
                ctx.MoveTo(Lean.Dx, Size.Height + 0.5 - Lean.Dy);
            }

            ctx.LineTo(Lean.Dx, Lean.Dy);
            ctx.CurveTo(
                Lean.Dx, Lean.Dy,
                Lean.Dx, 0,
                Lean.Dx * 2, 0);

            if (next == null) {
                ctx.LineTo(Size.Width - (Lean.Dx * 2), 0);
                ctx.CurveTo(
                    Size.Width - (Lean.Dx * 2), 0,
                    Size.Width - Lean.Dx, 0,
                    Size.Width - Lean.Dx, Lean.Dy);
                ctx.LineTo(Size.Width - Lean.Dx, Size.Height - Lean.Dy);
                ctx.CurveTo(
                    Size.Width - Lean.Dx, Size.Height - Lean.Dy,
                    Size.Width - Lean.Dx, Size.Height + 0.5,
                    Size.Width, Size.Height + 0.5);
            } else {
                ctx.LineTo(Size.Width, 0);
            }

            ctx.SetColor(borderColor);
            ctx.Stroke();

            if (previous != null && previous.Active) {
                ctx.SetColor(activeColor);
                if (Multiple) {
                    ctx.Rectangle(0, 0, Lean.Dx * 2, Size.Height);
                    ctx.Fill();

                    ctx.SetColor(borderColor);
                    ctx.MoveTo(0, 0);
                    ctx.LineTo(Lean.Dx * 2, 0);
                    ctx.Stroke();
                } else {
                    ctx.MoveTo(0, 0);
                    ctx.CurveTo(
                        0, 0,
                        Lean.Dx, 0,
                        Lean.Dx, Lean.Dy);
                    ctx.LineTo(Lean.Dx, Size.Height - Lean.Dy);
                    ctx.CurveTo(
                        Lean.Dx, Size.Height - Lean.Dy,
                        Lean.Dx, Size.Height + 0.5,
                        Lean.Dx * 2, Size.Height + 0.5);
                    ctx.LineTo(0, Size.Height);

                    ctx.FillPreserve();

                    ctx.SetColor(borderColor);
                    ctx.Stroke();
                }
            }

            // text
            ctx.SetColor(Active ? Colors.AliceBlue : deactiveTextColor);
            ctx.DrawTextLayout(text, new Point(padding.Left + Lean.Dx + 2, padding.Top));

            // close button
            if (Closeable) {
                ctx.DrawImage(Hovered ? closeSelected : (Active ? closeNormalInv : closeNormal),
                    new Point(
                        Size.Width - closeNormal.Width - (next == null ? padding.Right + Lean.Dx : 0),
                        (Size.Height - closeNormal.Height) / 2
                    )
                );
            }
        }