public /* Interface KGuiControl */ void GuiChartSnap() { if (NSThread.IsMain) { CGBitmapContext theCanvas = null; // store the canvas internally generated by GenPainter for use by DoPaste Func <Colorer> GenColorer = () => { return(new CGColorer()); }; Func <SKSize, ChartPainter> GenPainter = (SKSize canvasSize) => { CGBitmapContext canvas = CG.Bitmap((int)canvasSize.Width, (int)canvasSize.Height); CG.FlipCoordinateSystem(canvas); theCanvas = canvas; return(new CGChartPainter(canvas)); }; Action <CGBitmapContext> DoPaste = (CGBitmapContext canvas) => { var pasteboard = NSPasteboard.GeneralPasteboard; pasteboard.ClearContents(); pasteboard.WriteObjects(new NSImage[] { new NSImage(canvas.ToImage(), new CGSize(canvas.Width, canvas.Height)) }); }; CGSize cgChartSize = this.kaemikaChart.Frame.Size; Export.Snap(GenColorer, GenPainter, new SKSize((float)cgChartSize.Width, (float)cgChartSize.Height)); try { DoPaste(theCanvas); } catch { } } else { _ = BeginInvokeOnMainThreadAsync(() => { GuiChartSnap(); return(ack); }).Result; } }
public void SetLegendImage(KSeries series) { NSImage nsImage; int thickness = (series.lineStyle == KLineStyle.Thick) ? 3 : (series.lineMode == KLineMode.Line) ? 1 : 8; const int height = 16; const int width = 50; const int padding = 1; const int frame = 3; const int left = 0; int framedH = thickness + 2 * frame; int framedY = (height - 2 * padding - framedH) / 2; int framedW = width - 2 * padding; int framedX = left + padding; using (CGBitmapContext bitmap = CG.Bitmap(left + width, height)) { CG.DrawRect(bitmap, new CGRect(0, 0, left + width, height), CG.Color(new SKColor(0, 0, 0, 0))); // transparent if (series.visible) { CG.DrawRect(bitmap, new CGRect(framedX, framedY, framedW, framedH), CG.Color(SKColors.White)); CG.DrawRect(bitmap, new CGRect(framedX + frame, framedY + frame, framedW - 2 * frame, thickness), CG.Color(series.color)); } using (CGImage cgImage = bitmap.ToImage()) { nsImage = new NSImage(cgImage, new CGSize(cgImage.Width, cgImage.Height)); } } this.imageDM = nsImage; this.imageLM = nsImage; this.button.Image = nsImage; }
public /*interface DevicePainter*/ void Draw(KDeviceHandler.KDevice device, int canvasX, int canvasY, int canvasWidth, int canvasHeight) { (float margin, float padRadius, float deviceWidth, float deviceHeight) = device.FittedDimensions(canvasWidth, canvasHeight); float strokeWidth = padRadius / 10.0f; float accentStrokeWidth = 1.5f * strokeWidth; float textStrokeWidth = accentStrokeWidth / 2.0f; float deviceX = canvasX + (canvasWidth - deviceWidth) / 2.0f; float deviceY = canvasY + (canvasHeight - deviceHeight) / 2.0f; // don't lock device here, it will dedlock if (device.sizeChanged || cachedBackground == null || cachedBackground.Width != canvasWidth || cachedBackground.Height != canvasHeight) { cachedBackground = CG.Bitmap(canvasWidth, canvasHeight); DrawDevice(device, cachedBackground, canvasX, canvasY, canvasWidth, canvasHeight, deviceX, deviceY, deviceWidth, deviceHeight, padRadius, margin, device.pinchPan); device.sizeChanged = false; } if (!device.sizeChanged) { // copy cachedBackground to canvas DOH! canvas.AsBitmapContext().DrawImage(new CGRect(0, 0, cachedBackground.Width, cachedBackground.Height), cachedBackground.ToImage()); // do not apply pinchPan: background bitmap is alread scaled by it } if (device.displayPinchOrigin) { // same as: GraphSharp.GraphLayout.CanvasDrawCircle(canvas, pinchOrigin, 20, false, SKColors.LightGray); // same as: using (var paint = FillPaint(SKColors.LightGray)) { painter.DrawCircle(pinchOrigin, 20, paint); } //using (var paint = new SKPaint()) { // paint.TextSize = 10; paint.IsAntialias = true; paint.Color = SKColors.LightGray; paint.IsStroke = false; // canvas.DrawCircle(device.pinchOrigin.X, device.pinchOrigin.Y, 20, paint); //} } using (var dropletFillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = device.dropletColor, IsAntialias = true }) using (var dropletBiggieFillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = device.dropletBiggieColor, IsAntialias = true }) { KDeviceHandler.Place[,] places = device.places; KDeviceHandler.Placement placement = device.placement; for (int row = 0; row < places.GetLength(0); row++) { for (int col = 0; col < places.GetLength(1); col++) { KDeviceHandler.Place place = places[row, col]; if (place != null && placement.IsOccupied(place)) { SampleValue sample = placement.SampleOf(place); float volumeRadius = padRadius * (float)Math.Sqrt((sample.Volume()) * 1000000.0); // normal radius = 1μL float diameter = 2 * padRadius; SKPaint fillPaint = dropletFillPaint; bool biggie = false; if (volumeRadius > 2 * padRadius) { biggie = true; volumeRadius = 2 * padRadius; fillPaint = dropletBiggieFillPaint; } SKPoint here = new SKPoint(deviceX + margin + padRadius + col * diameter, deviceY + margin + padRadius + row * diameter); SKPoint rht = new SKPoint(deviceX + margin + padRadius + (col + 1) * diameter, deviceY + margin + padRadius + row * diameter); SKPoint lft = new SKPoint(deviceX + margin + padRadius + (col - 1) * diameter, deviceY + margin + padRadius + row * diameter); SKPoint bot = new SKPoint(deviceX + margin + padRadius + col * diameter, deviceY + margin + padRadius + (row + 1) * diameter); SKPoint top = new SKPoint(deviceX + margin + padRadius + col * diameter, deviceY + margin + padRadius + (row - 1) * diameter); string label = sample.symbol.Raw(); // sample.FormatSymbol(placement.StyleOf(sample, style)) if (place.IsAnimation(KDeviceHandler.Animation.None)) { DrawDroplet(canvas, label, biggie, here, padRadius, volumeRadius, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SizeHalf)) { DrawDroplet(canvas, label, biggie, here, padRadius, volumeRadius / 2, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SizeQuarter)) { DrawDroplet(canvas, label, biggie, here, padRadius, volumeRadius / 4, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.PullRht)) { DrawDropletPulledHor(canvas, label, biggie, here, rht, KDeviceHandler.Direction.Rht, padRadius, volumeRadius * 5 / 6, volumeRadius * 5 / 12, volumeRadius * 1 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SplitRht)) { DrawDropletPulledHor(canvas, label, biggie, here, rht, KDeviceHandler.Direction.Rht, padRadius, volumeRadius * 2 / 3, volumeRadius * 1 / 3, volumeRadius * 2 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.PullLft)) { DrawDropletPulledHor(canvas, label, biggie, lft, here, KDeviceHandler.Direction.Lft, padRadius, volumeRadius * 1 / 3, volumeRadius * 5 / 12, volumeRadius * 5 / 6, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SplitLft)) { DrawDropletPulledHor(canvas, label, biggie, lft, here, KDeviceHandler.Direction.Lft, padRadius, volumeRadius * 2 / 3, volumeRadius * 1 / 3, volumeRadius * 2 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.PullBot)) { DrawDropletPulledVer(canvas, label, biggie, here, bot, KDeviceHandler.Direction.Bot, padRadius, volumeRadius * 5 / 6, volumeRadius * 5 / 12, volumeRadius * 1 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SplitBot)) { DrawDropletPulledVer(canvas, label, biggie, here, bot, KDeviceHandler.Direction.Bot, padRadius, volumeRadius * 2 / 3, volumeRadius * 1 / 3, volumeRadius * 2 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.PullTop)) { DrawDropletPulledVer(canvas, label, biggie, top, here, KDeviceHandler.Direction.Top, padRadius, volumeRadius * 1 / 3, volumeRadius * 5 / 12, volumeRadius * 5 / 6, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } if (place.IsAnimation(KDeviceHandler.Animation.SplitTop)) { DrawDropletPulledVer(canvas, label, biggie, top, here, KDeviceHandler.Direction.Top, padRadius, volumeRadius * 2 / 3, volumeRadius * 1 / 3, volumeRadius * 2 / 3, textStrokeWidth, fillPaint, strokeWidth, accentStrokeWidth, device.pinchPan); } } } } } canvas.Flush(); }