Exemplo n.º 1
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();
                    }
                }
            }
        }
Exemplo n.º 2
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 ();
        }
Exemplo n.º 3
0
		void DrawSerie (Context ctx, Serie serie)
		{
			ctx.NewPath ();
			ctx.Rectangle (left, top, width + 1, height + 1);
			ctx.Clip ();
			
			ctx.NewPath ();
			ctx.SetColor (serie.Color);
			ctx.SetLineWidth (serie.LineWidth);
			
			bool first = true;
			bool blockMode = serie.DisplayMode == DisplayMode.BlockLine;
			
			double lastY = 0;
			
			foreach (Data d in serie.GetData (startX, endX)) {
				double x, y;
				GetPoint (d.X, d.Y, out x, out y);
				if (first) {
					ctx.MoveTo (x, y);
					lastY = y;
					first = false;
				} else {
					if (blockMode) {
						if (lastY != y)
							ctx.LineTo (x, lastY);
						ctx.LineTo (x, y);
					} else
						ctx.LineTo (x, y);
				}
				lastY = y;
			}
			
			ctx.Stroke ();
		}
Exemplo n.º 4
0
        void DrawProgress(Context ctx)
        {
            int threadsRunning = progress.Keys.Count;

            Rectangle clipBound = bound.Inflate(-1, -1);
            clipBound.Bottom = clipBound.Top + contentOffset.Y;

            double height = threadsRunning == 0 ? clipBound.Height : clipBound.Height / threadsRunning;
            double width = clipBound.Width;
            clipBound.Bottom = clipBound.Top + height;

            List<int> toRemove = new List<int>();
            foreach (var singleProgress in progress) {
                int progressForThread = singleProgress.Value;
                ctx.Save();

                clipBound.Width = width * (progressForThread / 100.0);

                ctx.Rectangle(clipBound);
                ctx.Clip();
                ctx.RoundRectangle(bound.Inflate(-1, -1), NodeRadius);
                ctx.SetColor(NodeColorProgress);
                ctx.Fill();

                ctx.Restore();

                clipBound.Top += height;

                if (progressForThread >= 100 && progress.ContainsKey(singleProgress.Key)) {
                    toRemove.Add(singleProgress.Key);
                }
            }

            foreach (int removeID in toRemove) {
                progress.Remove(removeID);
            }
        }