public static void DrawOnDemandAvailabilityStatus(CGContext context, OnDemandScreening screening, nfloat side, bool selected) { // Establish some base dimensions. const int maxDaysInRuler = 5; const int margin = 2; nfloat w = side - 2 * margin; nfloat h = side - 2 * margin; nfloat x = margin; nfloat y = margin; var windowSeconds = (screening.WindowEndTime - screening.WindowStartTime).TotalSeconds; var passedSeconds = (screening.StartTime - screening.WindowStartTime).TotalSeconds; nfloat wPassed = w * (nfloat)passedSeconds / (nfloat)windowSeconds; nfloat wLeft = w - wPassed; // Initlialize core graphics settings. context.SetStrokeColor(ClickPadTextColor(selected).CGColor); context.SetLineWidth(1); // Draw the passed time part of the progres bar. using (var passedPath = new CGPath()) { context.SetFillColor(ClickPadTextColor(selected).CGColor); passedPath.AddRect(new CGRect(x, y + h * 1 / 16, wPassed, h * 2 / 16)); passedPath.CloseSubpath(); context.AddPath(passedPath); } context.DrawPath(CGPathDrawingMode.FillStroke); // Draw the left time part of the progress bar. using (var leftPath = new CGPath()) { context.SetFillColor((selected ? ClickPadBackgroundColor(selected) : NSColor.White).CGColor); leftPath.AddRect(new CGRect(x + wPassed, y + h * 1 / 16, wLeft, h * 2 / 16)); leftPath.CloseSubpath(); context.AddPath(leftPath); } context.DrawPath(CGPathDrawingMode.FillStroke); // Draw verticle needle lines to indicate availability days. var daySeconds = ViewController.DaySpan.TotalSeconds; nfloat days = (nfloat)windowSeconds / (nfloat)daySeconds; nfloat wPeriod = w / days; if (days <= maxDaysInRuler) { using (var needlePath = new CGPath()) { for (int i = 1; i < days; i++) { needlePath.AddLines(new CGPoint[] { new CGPoint(i * wPeriod, y + h * 1 / 16), new CGPoint(i * wPeriod, y + h * 3 / 16) }); } context.AddPath(needlePath); } } context.DrawPath(CGPathDrawingMode.FillStroke); }
private bool FitOnDemandScreening(string filmFan, OnDemandScreening onDemandScreening) { // Define helper functions. bool fits(OnDemandScreening odScreening) => odScreening.IsPlannable && !odScreening.HasTimeOverlap && odScreening.FitsAvailability; bool canMove(OnDemandScreening odScreening) => odScreening.AttendingFilmFans.Count == 0; // No moving if the screening already fits. if (fits(onDemandScreening)) { return(true); } // Try to fit the screening by moving it. bool stop = false; bool found = false; bool tryNextDay = false; if (canMove(onDemandScreening)) { // Start at the first allowed start time of the screening. _controller.MoveToWindowStart(onDemandScreening); if (fits(onDemandScreening)) { return(true); } // Try to fit moving forward. while (!stop) { TimeSpan span = _controller.GetSpanToAutomaticallyFit(onDemandScreening); if (span == TimeSpan.Zero) { tryNextDay = true; } else { _controller.MoveOnDemandScreeningAutomatically(onDemandScreening, span); found = fits(onDemandScreening); stop = found; } if (tryNextDay) { if (_controller.TryMoveForwardOvernight(onDemandScreening)) { found = fits(onDemandScreening); stop = found; } else { stop = true; } } } } // Screening can't be fitted. if (!found && canMove(onDemandScreening)) { _controller.MoveToWindowStart(onDemandScreening); } return(found); }