public void AddItem(string identifier, string title) { var layer = new CATextLayer(); layer.String = title; layer.SetFont("SF UI Text Bold"); layer.FontSize = 12; layer.ForegroundColor = NSColor.FromRgb(80, 80, 80).CGColor; layer.ContentsScale = NSScreen.MainScreen.BackingScaleFactor; var attrs = new NSStringAttributes(); attrs.Font = NSFont.FromFontName("SF UI Text Bold", 12); var stringSize = NSStringDrawing.StringSize(layer.String, attrs); var frame = new CGRect(new CGPoint(0, 0), stringSize); layer.Frame = frame; layer.AnchorPoint = new CGPoint(0, 0.5f); items.Add(new BreadcrumbViewItem { Identifier = identifier, Title = title, Layer = layer }); Layer.AddSublayer(layer); NeedsDisplay = true; }
public void MainQueueDispatch() { #if !DEBUG || OPTIMIZEALL Assert.Ignore("UIKitThreadAccessException is not throw, by default, on release builds (removed by the linker)"); #endif if (RunningOnSnowLeopard) { Assert.Ignore("this test crash when executed with the iOS simulator on Snow Leopard"); } bool hit = false; // We need to check the UIKitThreadAccessException, but there are very few API // with that check on WatchOS. NSStringDrawing.WeakDrawString is one example, here we pass // it null for the parameter so that it immediately returns with an ArgumentNullException // instead of trying to load an image (which is not what we're testing). There // is also a test to ensure UIKitThreadAccessException is thrown if not on // the UI thread (so that we'll notice if the UIKitThreadAccessException is ever // removed from NSStringDrawing.WeakDrawString). var uiThread = Thread.CurrentThread; Thread queueThread = null; Thread mainQthread = null; Exception ex = null; Exception queue_ex = null; var defaultQ = DispatchQueue.GetGlobalQueue(DispatchQueuePriority.Default); defaultQ.DispatchAsync(delegate { try { NSStringDrawing.WeakDrawString(null, PointF.Empty, null); } catch (Exception e) { queue_ex = e; } queueThread = Thread.CurrentThread; var mainQ = DispatchQueue.MainQueue; mainQ.DispatchAsync(delegate { mainQthread = Thread.CurrentThread; try { NSStringDrawing.WeakDrawString(null, PointF.Empty, null); } catch (Exception e) { ex = e; } finally { hit = true; } }); }); // Now wait for the above to actually run while (hit == false) { NSRunLoop.Current.RunUntil(NSDate.FromTimeIntervalSinceNow(0.5)); } Assert.IsNotNull(ex, "main ex"); Assert.That(ex.GetType(), Is.SameAs(typeof(ArgumentNullException)), "no thread check hit"); Assert.IsNotNull(queue_ex, "queue ex"); Assert.That(queue_ex.GetType(), Is.SameAs(typeof(UIKitThreadAccessException)), "thread check hit"); Assert.That(uiThread, Is.EqualTo(mainQthread), "mainq thread is equal to uithread"); Assert.That(queueThread, Is.Not.EqualTo(mainQthread), "queueThread is not the same as the UI thread"); }
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- public override void Draw(CGRect rect) { DateTime t1 = DateTime.Now; base.Draw(rect); var context = UIGraphics.GetCurrentContext(); var path = new CGPath(); CGPoint [] pointsBuff; CGPoint [] points; float width = (float)Frame.Size.Width - leftBorder - rightBorder; float height = (float)Frame.Size.Height - downBorder; //X-Y axis points = new CGPoint [9]; points [0] = new CGPoint(leftBorder - 3, 3); points [1] = new CGPoint(leftBorder, 0); points [2] = new CGPoint(leftBorder + 3, 3); points [3] = new CGPoint(leftBorder, 0); points [4] = new CGPoint(leftBorder, height + 2); points [5] = new CGPoint(leftBorder + width + rightBorder / 2, height + 2); points [6] = new CGPoint(leftBorder + width + rightBorder / 2 - 3, height + 2 - 3); points [7] = new CGPoint(leftBorder + width + rightBorder / 2, height + 2); points [8] = new CGPoint(leftBorder + width + rightBorder / 2 - 3, height + 2 + 3); path.AddLines(points); context.AddPath(path); context.SetLineWidth(1);; context.SetStrokeColor(new CGColor(0, 0, 0, 1)); context.DrawPath(CGPathDrawingMode.Stroke); NSStringDrawing.DrawString(new NSString(timeStart.ToString("HH:mm")), new CGPoint(leftBorder, height + 5), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(12) }); NSStringDrawing.DrawString(new NSString(timeStart.ToString("dd.MM.yy")), new CGPoint(leftBorder, height + 17), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(7) }); NSStringDrawing.DrawString(new NSString(timeEnd.ToString("HH:mm")), new CGPoint(leftBorder + width - 25, height + 5), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(12) }); NSStringDrawing.DrawString(new NSString(timeEnd.ToString("dd.MM.yy")), new CGPoint(leftBorder + width - 25, height + 17), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(7) }); if ((historyList == null) || (historyList.Count == 0)) { return; } context.SetStrokeColor(UIColor.LightGray.CGColor); context.SetLineWidth(2); float period = (float)(timeEnd - timeStart).Ticks; double minValue = initialMinValue; double maxValue = initialMaxValue; for (int s = 0; s < historyList.Count; s++) { if (historyList [s].value < minValue) { minValue = historyList [s].value; } if (historyList [s].value > maxValue) { maxValue = historyList [s].value; } } initialMinValue = minValue; initialMaxValue = maxValue; double valueRange = maxValue - minValue; path = new CGPath(); pointsBuff = new CGPoint [(int)width]; //double lastX = 0; int pointX = 0; for (int s = 0; s < historyList.Count; s++) { if ((historyList[s].time < timeStart) || (historyList[s].time > timeEnd)) { continue; } double X = leftBorder + (double)(historyList [s].time - timeStart).Ticks / period * width; double Y = height + 2 - ((historyList [s].value - minValue) / valueRange * height); /*if ((Math.Abs (lastX - X) < 1)) * continue; * * lastX = X;*/ if (pointX == (int)width) { break; } pointsBuff [pointX] = new CGPoint(X, Y); pointX++; //Console.WriteLine (points [s].ToString ()); } points = new CGPoint[pointX]; Array.Copy(pointsBuff, points, pointX); path.AddLines(points); context.AddPath(path); context.DrawPath(CGPathDrawingMode.Stroke); //X axis agendaa DateTime quartDate = timeStart + new TimeSpan(((timeEnd - timeStart).Ticks / 4)); DateTime mediumDate = timeStart + new TimeSpan(((timeEnd - timeStart).Ticks / 2)); DateTime threeQuartDate = timeStart + new TimeSpan(((timeEnd - timeStart).Ticks * 3 / 4)); NSStringDrawing.DrawString(new NSString(quartDate.ToString("HH:mm")), new CGPoint(leftBorder + width / 4 - 15, height + 5), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(12) }); NSStringDrawing.DrawString(new NSString(quartDate.ToString("dd.MM.yy")), new CGPoint(leftBorder + width / 4 - 15, height + 17), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(7) }); NSStringDrawing.DrawString(new NSString(mediumDate.ToString("HH:mm")), new CGPoint(leftBorder + width / 2 - 15, height + 5), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(12) }); NSStringDrawing.DrawString(new NSString(mediumDate.ToString("dd.MM.yy")), new CGPoint(leftBorder + width / 2 - 15, height + 17), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(7) }); NSStringDrawing.DrawString(new NSString(threeQuartDate.ToString("HH:mm")), new CGPoint(leftBorder + width * 3 / 4 - 15, height + 5), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(12) }); NSStringDrawing.DrawString(new NSString(threeQuartDate.ToString("dd.MM.yy")), new CGPoint(leftBorder + width * 3 / 4 - 15, height + 17), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(7) }); path = new CGPath(); points = new CGPoint [2]; points [0] = new CGPoint(leftBorder + width / 4, height + 2 - 3); points [1] = new CGPoint(leftBorder + width / 4, height + 2 + 3); path.AddLines(points); points [0] = new CGPoint(leftBorder + width / 2, height + 2 - 3); points [1] = new CGPoint(leftBorder + width / 2, height + 2 + 3); path.AddLines(points); points [0] = new CGPoint(leftBorder + width * 3 / 4, height + 2 - 3); points [1] = new CGPoint(leftBorder + width * 3 / 4, height + 2 + 3); path.AddLines(points); context.AddPath(path); context.SetLineWidth(1);; context.SetStrokeColor(new CGColor(0, 0, 0, 1)); context.DrawPath(CGPathDrawingMode.Stroke); //Y axis agenda double quartValue = minValue + ((maxValue - minValue) / 4); double mediumValue = minValue + ((maxValue - minValue) / 2); double threeQuartValue = minValue + ((maxValue - minValue) * 3 / 4); NSMutableParagraphStyle paragraphStyle = new NSMutableParagraphStyle(); paragraphStyle.Alignment = UITextAlignment.Right; NSStringDrawing.DrawString(new NSString(minValue.ToString("F1")), new CGRect(2, height - 12, leftBorder - 6, 12), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(11), ParagraphStyle = paragraphStyle }); NSStringDrawing.DrawString(new NSString(quartValue.ToString("F1")), new CGRect(2, height - 6 - height / 4, leftBorder - 6, 12), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(11), ParagraphStyle = paragraphStyle }); NSStringDrawing.DrawString(new NSString(mediumValue.ToString("F1")), new CGRect(2, height - 6 - height / 2, leftBorder - 6, 12), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(11), ParagraphStyle = paragraphStyle }); NSStringDrawing.DrawString(new NSString(threeQuartValue.ToString("F1")), new CGRect(2, height - 6 - height * 3 / 4, leftBorder - 6, 12), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(11), ParagraphStyle = paragraphStyle }); NSStringDrawing.DrawString(new NSString(maxValue.ToString("F1")), new CGRect(2, 0, leftBorder - 6, 12), new UIStringAttributes() { ForegroundColor = UIColor.Black, Font = UIFont.SystemFontOfSize(11), ParagraphStyle = paragraphStyle }); points = new CGPoint [2]; points [0] = new CGPoint(leftBorder - 3, height + 2 - height / 4); points [1] = new CGPoint(leftBorder + 3, height + 2 - height / 4); path.AddLines(points); points [0] = new CGPoint(leftBorder - 3, height + 2 - height / 2); points [1] = new CGPoint(leftBorder + 3, height + 2 - height / 2); path.AddLines(points); points [0] = new CGPoint(leftBorder - 3, height + 2 - height * 3 / 4); points [1] = new CGPoint(leftBorder + 3, height + 2 - height * 3 / 4); path.AddLines(points); context.AddPath(path); context.DrawPath(CGPathDrawingMode.Stroke); Console.WriteLine("Redraw in " + (DateTime.Now - t1).TotalMilliseconds + " ms."); }