Пример #1
0
        protected override bool OnDrawn(Cairo.Context cr)
        {
            if (this.isDirty)
            {
                this.Rebuild();
            }

            bool baseDrawnResult = base.OnDrawn(cr);

            cr.SetFontSize(FONT_HEIGHT);
            cr.SelectFontFace("Mono", FontSlant.Normal, FontWeight.Normal);

            cr.Rectangle(0.0, 0.0, this.allocRect.Width, this.allocRect.Height);
            cr.SetSourceRGB(1, 1, 1);
            cr.Fill();

            var gradient = new LinearGradient(0.0, 0.0, 0.0, this.allocRect.Height);

            gradient.AddColorStopRgb(0.0, new Color(0.4, 0.4, 0.4));
            gradient.AddColorStopRgb(0.1, new Color(1.0, 1.0, 1.0));
            gradient.AddColorStopRgb(0.2, new Color(0.6, 0.6, 0.6));
            gradient.AddColorStopRgb(1.0, new Color(0.1, 0.1, 0.1));

            cr.LineWidth = 1;

            foreach (var box in this.boxen)
            {
                this.RoundedRect(cr, box.Rect, 4.0);
                cr.SetSource(gradient);
                cr.FillPreserve();
                cr.SetSourceRGB(0, 0, 0);
                cr.Stroke();


                int x = (int)(box.Rect.X + TAGBOX_PADDING * 2 + TAGBOX_XSIZE);
                int y = (int)(box.Rect.Y + box.Rect.Height / 2 + cr.FontExtents.Height / 2 - cr.FontExtents.Descent / 2);
                cr.MoveTo(x, y);
                cr.TextPath(box.Tag);
                cr.SetSourceRGB(1.0, 1.0, 1.0);
                cr.Fill();

                cr.MoveTo(box.Rect.X + TAGBOX_PADDING + TAGBOX_XOFFSET, box.Rect.Y + TAGBOX_PADDING + TAGBOX_XOFFSET);
                cr.RelLineTo(TAGBOX_XSIZE - TAGBOX_XOFFSET * 2, TAGBOX_XSIZE - TAGBOX_XOFFSET * 2);
                cr.MoveTo(box.Rect.X + TAGBOX_PADDING + TAGBOX_XOFFSET, box.Rect.Y + TAGBOX_PADDING + TAGBOX_XSIZE - TAGBOX_XOFFSET);
                cr.RelLineTo(TAGBOX_XSIZE - TAGBOX_XOFFSET * 2, -TAGBOX_XSIZE + TAGBOX_XOFFSET * 2);
                cr.Stroke();
            }

            return(baseDrawnResult);
        }
Пример #2
0
        private void DrawState(Context c)
        {
            State s = CheckState();

            LinearGradient GradientOutline = new LinearGradient(x + sx - 1, y + sy - 3, x + sx + 1, y + sy + 3);

            GradientOutline.AddColorStopRgb(0, new Color(0.06, 0.06, 0.627));
            GradientOutline.AddColorStopRgb(1, new Color(0.06, 0.06, 0.25));

            LinearGradient GradientInside = new LinearGradient(x + sx - 2, y + sy - 2, x + sx - 1, y + sy + 1);

            if (s == State.NotReady)
            {
                GradientInside.AddColorStopRgb(0, new Color(0.5, 0.5, 0.5));
                GradientInside.AddColorStopRgb(1, new Color(0.06, 0.06, 0.06));
            }
            else if (s == State.Bad)
            {
                GradientInside.AddColorStopRgb(0, new Color(1, 0.25, 0.25));
                GradientInside.AddColorStopRgb(1, new Color(0.627, 0.03, 0.03));
            }
            else if (s == State.Good)
            {
                GradientInside.AddColorStopRgb(0, new Color(0.5, 1, 0.5));
                GradientInside.AddColorStopRgb(1, new Color(0.25, 0.75, 0.25));
            }
            else
            {
                GradientInside.AddColorStopRgb(0, new Color(1, 0.75, 0));
                GradientInside.AddColorStopRgb(1, new Color(1, 0.5, 0));
            }

            c.Pattern = GradientInside;
            c.Arc(x + sx, y + sy, 4, 0, 2 * Math.PI);
            c.FillPreserve();

            c.Pattern = GradientOutline;
            c.Stroke();

            c.Color = new Color(1, 1, 1, 0.25);
            c.Arc(x + sx, y + sy, 3, 0, 2 * Math.PI);
            c.Stroke();
        }
Пример #3
0
        private void DoDraw(Gdk.Window window, Rectangle[] rects, double borderWidth)
        {
            Context cr = Gdk.CairoHelper.Create(window);

            // draw progress
            Color color1 = ChangeColorBrightness(this.ForeColor, 0.25f);
            Color color2 = ChangeColorBrightness(this.ForeColor, -0.25f);
            // a linear gradient for progress bar fill
            var grd = new LinearGradient(0, 0, _direction == DirectionMode.Horizontal ? 1 : Allocation.Width, _direction == DirectionMode.Horizontal ? Allocation.Height : 1);

            grd.AddColorStopRgb(0, color1);
            grd.AddColorStopRgb(1, color2);


            if (_direction == DirectionMode.Horizontal)
            {
                DrawRectangleH(cr, 0, Allocation.Height, grd);
            }
            else
            {
                DrawRectangleV(cr, 0, Allocation.Width, grd);
            }

            grd.Dispose();


            // draw border around widget
            // - sets line width to 2 points
            cr.LineWidth = 2;
            // - set brush/source color
            cr.SetSourceRGBA(0, 0, 0, 1);
            // - draw a virtual rect
            cr.Rectangle(new Rectangle(cr.LineWidth, cr.LineWidth, Allocation.Width - cr.LineWidth, Allocation.Height - cr.LineWidth));
            // - stroke it.
            cr.Stroke();

            cr.GetTarget().Dispose();
            cr.Dispose();
        }
Пример #4
0
        protected override void PaintWidget(Cairo.Context ctx, int w, int h)
        {
            ctx.SetFill(0.0d, 0.0d, 0.0d);
            ctx.Rectangle(0.0d, Offset, w, h - Offset);
            ctx.Fill();
            ctx.SetFill(BlueprintStyle.BluePrint);
            ctx.Rectangle(0.0d, 0.0d, w, Offset);
            ctx.Fill();
            double wr = w - 2.0d * Offset;
            double ew = wr / (max - min + 1 + shaft * (max - min));

            this.flapWidth = ew;
            double xc = Offset;

            for (int i = min; i <= max; i++)
            {
                if (i != current)
                {
                    ctx.Rectangle(xc, Offset, ew, h - 2.0d * Offset);
                }
                xc += (1.0d + shaft) * ew;
            }
            ctx.FillPreserve();
            LinearGradient p    = new LinearGradient(0.0d, Offset, 0.0d, Offset + 10.0d);
            double         fctr = 0.5d;

            for (double y = 0.0d; y <= 1.0d; y += 0.1d)
            {
                p.AddColorStopRgb(y, new Color(fctr * BlueprintStyle.BluePrintShadow.R, fctr * BlueprintStyle.BluePrintShadow.G, fctr * BlueprintStyle.BluePrintShadow.B));
                fctr += 0.05d;
            }
            ctx.SetFill(p);
            ctx.Fill();
            ctx.Rectangle(Offset + (1.0d + shaft) * ew * (current - min), Offset, ew, h - 2.0d * Offset);
            ctx.SetFill(BlueprintStyle.BluePrint);
            ctx.Fill();
            xc = Offset;
            ctx.SetFill(BlueprintStyle.HardWhite);
            ctx.MoveTo(0.0d, Offset);
            ctx.LineTo(Offset, Offset);
            for (int i = min; i <= max; i++)
            {
                ctx.LineTo(xc, h - Offset);
                ctx.LineTo(xc + ew, h - Offset);
                ctx.LineTo(xc + ew, Offset);
                xc += (1.0d + shaft) * ew;
                if (i < max)
                {
                    ctx.LineTo(xc, Offset);
                }
            }
            ctx.LineTo(w - Offset, Offset);
            ctx.LineTo(w, Offset);
            ctx.MoveTo(Offset, Offset);
            ctx.LineTo(Offset + (1.0d + shaft) * ew * (current - min), Offset);
            ctx.MoveTo(w - Offset, Offset);
            ctx.LineTo(w - Offset + (1.0d + shaft) * ew * (current - max), Offset);
            ctx.Stroke();
            xc = Offset + 0.5d * ew;
            IEnumerable <string> namei = this.names.Skip(this.min);
            IEnumerator <string> enume = namei.GetEnumerator();

            for (int i = min; i <= max && enume.MoveNext(); i++)
            {
                string name = enume.Current;
                if (name != null)
                {
                                        #if PANGO
                    Pango.Layout pglay = Pango.CairoHelper.CreateLayout(ctx);
                    pglay.SetText(name);
                    Pango.Rectangle ra, rb;
                    pglay.GetExtents(out ra, out rb);
                    double tew = rb.Width / 1024.0d;
                    double teh = rb.Height / 1024.0d;
                                        #else
                    TextExtents te  = ctx.TextExtents(name);
                    double      tew = te.Width;
                    double      teh = te.Height;
                                        #endif
                    ctx.MoveTo(xc - 0.5d * tew, 0.5d * (h + teh));
                    ctx.ShowText(name);
                    xc += (1.0d + shaft) * ew;
                }
            }
        }
Пример #5
0
        private void DrawClock(Context c)
        {
            LinearGradient g;

            c.LineWidth = 1;

            c.Save();
            c.Translate(x + cx, y + cy);

            // shadow
            c.Color = new Color(0, 0, 0, 0.1);
            c.Arc(0, 0, 14, 0, 2 * Math.PI);
            c.Fill();
            c.Arc(0, 0, 13, 0, 2 * Math.PI);
            c.Fill();

            // background
            c.Arc(0, 0, 12, 0, 2 * Math.PI);
            c.Color = new Color(0.525, 0.525, 0.525);
            c.FillPreserve();
            c.Color = new Color(0.455, 0.455, 0.455);
            c.Stroke();

            // outline
            c.Color = new Color(1, 1, 1, 0.25);
            c.Arc(0, 0, 11, 0, 2 * Math.PI);
            c.Stroke();

            // clock face
            c.Arc(0, 0, 8, 0, 2 * Math.PI);
            g = new LinearGradient(7, 7, -7, -7);
            g.AddColorStopRgb(0, new Color(0.796, 0.796, 0.796));
            g.AddColorStopRgb(1, new Color(1, 1, 1));
            c.Pattern = g;
            c.FillPreserve();
            g = new LinearGradient(7, 7, -7, -7);
            g.AddColorStopRgb(0, new Color(1, 1, 1));
            g.AddColorStopRgb(1, new Color(0.627, 0.627, 0.627));
            c.Pattern = g;
            c.Stroke();

            // hand center
            c.LineWidth = 0.5;
            c.Arc(0.5, 0.5, 1.25, 0, 2 * Math.PI);
            c.Color = new Color(0.95, 0.95, 0.95);
            c.FillPreserve();
            c.Color = new Color(0.1, 0.1, 0.1);
            c.Stroke();

            // minute hand
            c.MoveTo(0.5 + Math.Sin(-1.15) * 1.5, 0.5 + Math.Cos(-1.15) * 1.5);
            c.LineTo(0.5 + Math.Sin(-1.15) * 6.5, 0.5 + Math.Cos(-1.15) * 6.5);
            c.Stroke();

            // hour hand
            c.LineWidth = 0.75;

            c.MoveTo(0.5 + Math.Sin(1.15) * 1.5, 0.5 + Math.Cos(1.15) * 1.5);
            c.LineTo(0.5 + Math.Sin(1.15) * 5, 0.5 + Math.Cos(1.15) * 5);
            c.Stroke();

            // hour markers
            c.LineWidth = 1;

            c.Arc(0.5, 6.5, 0.75, 0, 2 * Math.PI);
            c.Color = new Color(0.058, 0.058, 0.058);
            c.Fill();

            c.Arc(0.5, -5.5, 0.75, 0, 2 * Math.PI);
            c.Color = new Color(0.44, 0.44, 0.44);
            c.Fill();

            c.Arc(6.5, 0.5, 0.75, 0, 2 * Math.PI);
            c.Color = new Color(0.113, 0.113, 0.113);
            c.Fill();

            c.Arc(-5.5, 0.5, 0.75, 0, 2 * Math.PI);
            c.Color = new Color(0.38, 0.38, 0.38);
            c.Fill();

            c.Restore();
        }
Пример #6
0
        public static void GenerateGraph(List <ResultDbEntry> resultList, string filename)
        {
            // FIXME Exception if more than 50 results...

            ImageSurface surface = new ImageSurface(Format.Rgb24, 103, 52);
            Context      context = new Context(surface);

            // Fill with grad
            LinearGradient grad = new LinearGradient(0.0, 0.0, 0.0, 52.0);

            grad.AddColorStopRgb(0.0, new Color(1.0, 1.0, 1.0));
            grad.AddColorStopRgb(1.0, new Color(0.8, 0.8, 0.9));
            context.Pattern = grad;
            context.Paint();

            // Frame
            context.SetSourceRGB(0, 0, 0);
            context.LineWidth = 1.0;
            context.Rectangle(0.5, 0.5, 102.0, 51.0);
            context.Stroke();

            long denominator = (long)(FindBiggestResult(resultList) * 1.2);

            context.LineWidth = 1.5;

            // FIXME Reverse to copy
            resultList.Reverse();

            double x             = 100.5 - ((resultList.Count - 1) * 2.0);
            bool   hasPrevResult = false;
            long   prevResult    = 0;

            foreach (ResultDbEntry entry in resultList)
            {
                if (entry.Failure)
                {
                    x += 2.0;
                    continue;
                }

                double sz = ((double)entry.Time / denominator) * 50.0;

                if (hasPrevResult && UtilFu.GetValueDifference(prevResult, entry.Time) > 0.1)
                {
                    context.SetSourceRGB(1.0, 0.0, 0.0);
                }
                else if (hasPrevResult && UtilFu.GetValueDifference(prevResult, entry.Time) < -0.1)
                {
                    context.SetSourceRGB(0.0, 1.0, 0.0);
                }
                else
                {
                    context.SetSourceRGB(0.4, 0.4, 0.4);
                }

                context.MoveTo(x, 51);
                context.LineTo(x, 51 - sz);
                context.Stroke();

                x += 2.0;

                hasPrevResult = true;
                prevResult    = entry.Time;
            }

            surface.WriteToPng(filename);

            resultList.Reverse();
            ((IDisposable)context).Dispose();
            ((IDisposable)surface).Dispose();
        }
Пример #7
0
        /// <summary>Draws a button.</summary>
        public void DrawButton(Context cr, Rectangle bodyAllocation, ButtonState state, double roundSize, double lineWidth, double arrowSize, double arrowPadding, bool drawSeparator, BaseButton widget)
        {
            double lineWidth05 = lineWidth / 2;
            double lineWidth15 = lineWidth05 * 3;

            bool upLeft = true, upRight = true, downRight = true, downLeft = true;

            switch (widget.GroupStyle)
            {
            case GroupStyle.Left:
                upRight = downRight = false;
                break;

            case GroupStyle.Center:
                upLeft = downLeft = upRight = downRight = false;
                break;

            case GroupStyle.Right:
                upLeft = downLeft = false;
                break;
            }

            cr.LineWidth = lineWidth;

            if (state == ButtonState.Pressed || state == ButtonState.Hover)
            {
                LinearGradient bodyPattern, innerBorderPattern;
                Color          borderColor;

                if (state == ButtonState.Pressed)
                {
                    bodyPattern = new LinearGradient(bodyAllocation.X, bodyAllocation.Y, bodyAllocation.X, bodyAllocation.Y + bodyAllocation.Height);
                    bodyPattern.AddColorStopRgb(0.0, new Color(0.996, 0.847, 0.667));
                    bodyPattern.AddColorStopRgb(0.37, new Color(0.984, 0.710, 0.396));
                    bodyPattern.AddColorStopRgb(0.43, new Color(0.980, 0.616, 0.204));
                    bodyPattern.AddColorStopRgb(1.0, new Color(0.992, 0.933, 0.667));

                    innerBorderPattern = new LinearGradient(bodyAllocation.X, bodyAllocation.Y, bodyAllocation.X + bodyAllocation.Width, bodyAllocation.Y + bodyAllocation.Height);
                    innerBorderPattern.AddColorStop(0.0, new Color(0.876, 0.718, 0.533, 1));
                    innerBorderPattern.AddColorStop(1.0, new Color(0.876, 0.718, 0.533, 0));

                    borderColor = new Color(0.671, 0.631, 0.549);
                }
                else
                {
                    bodyPattern = new LinearGradient(bodyAllocation.X, bodyAllocation.Y, bodyAllocation.X, bodyAllocation.Y + bodyAllocation.Height);
                    bodyPattern.AddColorStopRgb(0.0, new Color(1, 0.996, 0.890));
                    bodyPattern.AddColorStopRgb(0.37, new Color(1, 0.906, 0.592));
                    bodyPattern.AddColorStopRgb(0.43, new Color(1, 0.843, 0.314));
                    bodyPattern.AddColorStopRgb(1.0, new Color(1, 0.906, 0.588));

                    innerBorderPattern = new LinearGradient(bodyAllocation.X, bodyAllocation.Y, bodyAllocation.X + bodyAllocation.Width, bodyAllocation.Y + bodyAllocation.Height);
                    innerBorderPattern.AddColorStop(0.0, new Color(1, 1, 0.969, 1));
                    innerBorderPattern.AddColorStop(1.0, new Color(1, 1, 0.969, 0));

                    borderColor = new Color(0.824, 0.753, 0.553);
                }

                double x0 = bodyAllocation.X + lineWidth05, y0 = bodyAllocation.Y + lineWidth05;
                double x1 = bodyAllocation.X + bodyAllocation.Width - lineWidth05, y1 = bodyAllocation.Y + bodyAllocation.Height - lineWidth05;

                if (upLeft)
                {
                    cr.MoveTo(x0 + roundSize, y0);
                }
                else
                {
                    cr.MoveTo(x0, y0);
                }
                if (upRight)
                {
                    cr.Arc(x1 - roundSize, y0 + roundSize, roundSize, 1.5 * Math.PI, 0);
                }
                else
                {
                    cr.LineTo(x1, y0);
                }
                if (downRight)
                {
                    cr.Arc(x1 - roundSize, y1 - roundSize, roundSize, 0, 0.5 * Math.PI);
                }
                else
                {
                    cr.LineTo(x1, y1);
                }
                if (downLeft)
                {
                    cr.Arc(x0 + roundSize, y1 - roundSize, roundSize, 0.5 * Math.PI, Math.PI);
                }
                else
                {
                    cr.LineTo(x0, y1);
                }
                if (upLeft)
                {
                    cr.Arc(x0 + roundSize, y0 + roundSize, roundSize, Math.PI, 1.5 * Math.PI);
                }
                else
                {
                    cr.LineTo(x0, y0);
                }

                cr.Pattern = bodyPattern;
                cr.Fill();

                x0 = bodyAllocation.X + lineWidth15; y0 = bodyAllocation.Y + lineWidth15;
                x1 = bodyAllocation.X + bodyAllocation.Width - lineWidth15; y1 = bodyAllocation.Y + bodyAllocation.Height - lineWidth15;

                double roundSizeMinusLineWidth = roundSize - lineWidth;

                if (widget.GroupStyle != GroupStyle.Left)
                {
                    x0 -= lineWidth;
                }

                if (upLeft)
                {
                    cr.MoveTo(x0 + roundSizeMinusLineWidth, y0);
                }
                else
                {
                    cr.MoveTo(x0, y0);
                }
                if (upRight)
                {
                    cr.Arc(x1 - roundSizeMinusLineWidth, y0 + roundSizeMinusLineWidth, roundSizeMinusLineWidth, 1.5 * Math.PI, 0);
                }
                else
                {
                    cr.LineTo(x1, y0);
                }
                if (downRight)
                {
                    cr.Arc(x1 - roundSizeMinusLineWidth, y1 - roundSizeMinusLineWidth, roundSizeMinusLineWidth, 0, 0.5 * Math.PI);
                }
                else
                {
                    cr.LineTo(x1, y1);
                }
                if (downLeft)
                {
                    cr.Arc(x0 + roundSizeMinusLineWidth, y1 - roundSizeMinusLineWidth, roundSizeMinusLineWidth, 0.5 * Math.PI, Math.PI);
                }
                else
                {
                    cr.LineTo(x0, y1);
                }
                if (upLeft)
                {
                    cr.Arc(x0 + roundSizeMinusLineWidth, y0 + roundSizeMinusLineWidth, roundSizeMinusLineWidth, Math.PI, 1.5 * Math.PI);
                }
                else
                {
                    cr.LineTo(x0, y0);
                }

                if (widget.GroupStyle != GroupStyle.Left)
                {
                    x0 += lineWidth;
                }

                cr.Pattern = innerBorderPattern;
                cr.Stroke();

                x0 = bodyAllocation.X + lineWidth05; y0 = bodyAllocation.Y + lineWidth05;
                x1 = bodyAllocation.X + bodyAllocation.Width - lineWidth05; y1 = bodyAllocation.Y + bodyAllocation.Height - lineWidth05;

                if (upLeft)
                {
                    cr.MoveTo(x0 + roundSize, y0);
                }
                else
                {
                    cr.MoveTo(x0, y0);
                }
                if (upRight)
                {
                    cr.Arc(x1 - roundSize, y0 + roundSize, roundSize, 1.5 * Math.PI, 0);
                }
                else
                {
                    cr.LineTo(x1, y0);
                }
                if (downRight)
                {
                    cr.Arc(x1 - roundSize, y1 - roundSize, roundSize, 0, 0.5 * Math.PI);
                }
                else
                {
                    cr.LineTo(x1, y1);
                }
                if (downLeft)
                {
                    cr.Arc(x0 + roundSize, y1 - roundSize, roundSize, 0.5 * Math.PI, Math.PI);
                }
                else
                {
                    cr.LineTo(x0, y1);
                }
                if (widget.GroupStyle == GroupStyle.Left)
                {
                    if (upLeft)
                    {
                        cr.Arc(x0 + roundSize, y0 + roundSize, roundSize, Math.PI, 1.5 * Math.PI);
                    }
                    else
                    {
                        cr.LineTo(x0, y0);
                    }
                }

                cr.Color = borderColor;
                cr.Stroke();
            }
            else if (widget.DrawBackground)
            {
                LinearGradient bodyPattern = new LinearGradient(bodyAllocation.X, bodyAllocation.Y, bodyAllocation.X, bodyAllocation.Y + bodyAllocation.Height);
                bodyPattern.AddColorStop(0.0, new Color(1, 1, 1, 0.7));
                bodyPattern.AddColorStop(0.37, new Color(1, 1, 1, 0.2));
                bodyPattern.AddColorStop(0.43, new Color(1, 1, 1, 0.2));
                bodyPattern.AddColorStop(1.0, new Color(1, 1, 1, 0.7));

                double x0 = bodyAllocation.X + lineWidth05, y0 = bodyAllocation.Y + lineWidth05;
                double x1 = bodyAllocation.X + bodyAllocation.Width - lineWidth05, y1 = bodyAllocation.Y + bodyAllocation.Height - lineWidth05;

                if (upLeft)
                {
                    cr.MoveTo(x0 + roundSize, y0);
                }
                else
                {
                    cr.MoveTo(x0, y0);
                }
                if (upRight)
                {
                    cr.Arc(x1 - roundSize, y0 + roundSize, roundSize, 1.5 * Math.PI, 0);
                }
                else
                {
                    cr.LineTo(x1, y0);
                }
                if (downRight)
                {
                    cr.Arc(x1 - roundSize, y1 - roundSize, roundSize, 0, 0.5 * Math.PI);
                }
                else
                {
                    cr.LineTo(x1, y1);
                }
                if (downLeft)
                {
                    cr.Arc(x0 + roundSize, y1 - roundSize, roundSize, 0.5 * Math.PI, Math.PI);
                }
                else
                {
                    cr.LineTo(x0, y1);
                }
                if (upLeft)
                {
                    cr.Arc(x0 + roundSize, y0 + roundSize, roundSize, Math.PI, 1.5 * Math.PI);
                }
                else
                {
                    cr.LineTo(x0, y0);
                }

                cr.Pattern = bodyPattern;
                cr.Fill();

                if (widget.GroupStyle != GroupStyle.Left)
                {
                    if (downLeft)
                    {
                        cr.Arc(x0 + roundSize, y1 - roundSize, roundSize, 0.5 * Math.PI, Math.PI);
                    }
                    else
                    {
                        cr.MoveTo(x0, y1);
                    }
                    if (upLeft)
                    {
                        cr.Arc(x0 + roundSize, y0 + roundSize, roundSize, Math.PI, 1.5 * Math.PI);
                    }
                    else
                    {
                        cr.LineTo(x0, y0);
                    }

                    cr.Color = new Color(1, 1, 1, 0.8);
                    cr.Stroke();
                }

                if (upLeft)
                {
                    cr.Arc(x0 + roundSize, y0 + roundSize, roundSize, Math.PI, 1.5 * Math.PI);
                }
                else
                {
                    cr.MoveTo(x0, y0);
                }
                if (upRight)
                {
                    cr.Arc(x1 - roundSize, y0 + roundSize, roundSize, 1.5 * Math.PI, 0);
                }
                else
                {
                    cr.LineTo(x1, y0);
                }
                if (downRight)
                {
                    cr.Arc(x1 - roundSize, y1 - roundSize, roundSize, 0, 0.5 * Math.PI);
                }
                else
                {
                    cr.LineTo(x1, y1);
                }
                if (downLeft)
                {
                    cr.Arc(x0 + roundSize, y1 - roundSize, roundSize, 0.5 * Math.PI, Math.PI);
                }
                else
                {
                    cr.LineTo(x0, y1);
                }
                if (widget.GroupStyle == GroupStyle.Left)
                {
                    if (upLeft)
                    {
                        cr.LineTo(x0, y0 + roundSize);
                    }
                    else
                    {
                        cr.LineTo(x0, y0);
                    }
                }

                cr.Color = new Color(0, 0, 0, 0.2);
                cr.Stroke();
            }

            if (arrowSize > 0)
            {
                double x, y;

                switch (widget.ImagePosition)
                {
                case Gtk.PositionType.Bottom:
                case Gtk.PositionType.Top:
                    x = bodyAllocation.X + (bodyAllocation.Width - arrowSize) / 2.0;
                    y = bodyAllocation.Y + bodyAllocation.Height - 2 * lineWidth - arrowSize - 2 * arrowPadding;

                    if (drawSeparator)
                    {
                        double left = bodyAllocation.X + 2 * lineWidth, right = bodyAllocation.X + bodyAllocation.Width - 2 * lineWidth;

                        cr.MoveTo(left, y - lineWidth / 2);
                        cr.LineTo(right, y - lineWidth / 2);
                        cr.Color = new Color(0, 0, 0, 0.1);
                        cr.Stroke();

                        cr.MoveTo(left, y + lineWidth / 2);
                        cr.LineTo(right, y + lineWidth / 2);
                        cr.Color = new Color(1, 1, 1, 0.6);
                        cr.Stroke();
                    }

                    y += arrowPadding;
                    break;

                default:
                    x = bodyAllocation.X + bodyAllocation.Width - 2 * lineWidth - arrowSize - 2 * arrowPadding;
                    y = bodyAllocation.Y + (bodyAllocation.Height - arrowSize) / 2.0;

                    if (drawSeparator)
                    {
                        double top = bodyAllocation.Y + 2 * lineWidth, bottom = bodyAllocation.Y + bodyAllocation.Height - 2 * lineWidth;
                        cr.MoveTo(x - lineWidth / 2, top);
                        cr.LineTo(x - lineWidth / 2, bottom);
                        cr.Color = new Color(0, 0, 0, 0.1);
                        cr.Stroke();

                        cr.MoveTo(x + lineWidth / 2, top);
                        cr.LineTo(x + lineWidth / 2, bottom);
                        cr.Color = new Color(1, 1, 1, 0.6);
                        cr.Stroke();
                    }

                    x += arrowPadding;
                    break;
                }

                y += arrowSize / 4.0 + lineWidth / 2.0;
                cr.MoveTo(x, y);
                cr.LineTo(x + arrowSize, y);
                cr.LineTo(x + arrowSize / 2.0, y + arrowSize / 2.0);
                cr.LineTo(x, y);
                cr.Color = new Color(0, 0, 0);
                cr.Fill();
            }
        }