private static double[] GetVerticalOffsets(VerticalPlacement verticalPlacement, double popupHeight, double targetHeight, double offsetHeight) { var verticalOffsets = Enumerable.Repeat <double>(offsetHeight, 2).ToArray(); switch (verticalPlacement) { case VerticalPlacement.Top: verticalOffsets[0] += -popupHeight; verticalOffsets[1] += targetHeight; break; case VerticalPlacement.Center: verticalOffsets[0] += targetHeight / 2 - popupHeight / 2; verticalOffsets[1] += verticalOffsets[0]; break; case VerticalPlacement.Bottom: verticalOffsets[0] += targetHeight; verticalOffsets[1] += -popupHeight; break; default: throw new Exception("Invalid Vertical Placement"); } return(verticalOffsets); }
public void Update(TimeSpan lifetime, Animation animation, Thickness margin, Size size, HorizontalPlacement horizontalPlacement, VerticalPlacement verticalPlacement) { lock (_lock) { Parallel.Invoke( () => { Settings.Default.Lifetime = lifetime; Settings.Default.Animation = animation; Settings.Default.Margin = margin; Settings.Default.Size = size; Settings.Default.HorizontalPlacement = horizontalPlacement; Settings.Default.VerticalPlacement = verticalPlacement; Settings.Default.Save(); }, () => { _lifetimeCache = lifetime; _animationCache = animation; _marginCache = margin; _sizeCache = size; _horizontalPlacementCache = horizontalPlacement; _verticalPlacementCache = verticalPlacement; }); } }
private static double GetVerticalOffset(Size popupSize, Size targetSize, VerticalPlacement verticalPlacement) { switch (verticalPlacement) { case VerticalPlacement.Top: return(-popupSize.Height); case VerticalPlacement.Bottom: return(targetSize.Height); case VerticalPlacement.Center: return(-(popupSize.Height / 2) + targetSize.Height / 2); } throw new ArgumentOutOfRangeException("verticalPlacement"); }
private void DrawSlurs(ScoreRendererBase renderer, Note element, double notePositionY) { if (element.Slur == null) { return; } VerticalPlacement slurPlacement; if (element.Slur.Placement.HasValue) { slurPlacement = element.Slur.Placement.Value; } else { slurPlacement = element.StemDirection == VerticalDirection.Up ? VerticalPlacement.Below : VerticalPlacement.Above; } if (element.Slur.Type == NoteSlurType.Start) { slurStartPlacement = slurPlacement; if (slurPlacement == VerticalPlacement.Above) { measurementService.SlurStartPoint = new Point(scoreService.CursorPositionX, element.StemDirection == VerticalDirection.Down ? notePositionY : notePositionY + element.StemDefaultY); } else { measurementService.SlurStartPoint = new Point(scoreService.CursorPositionX, notePositionY); } } else if (element.Slur.Type == NoteSlurType.Stop) { if (slurStartPlacement == VerticalPlacement.Above) { renderer.DrawBezier(measurementService.SlurStartPoint.X + 10, measurementService.SlurStartPoint.Y + 18, measurementService.SlurStartPoint.X + 12, measurementService.SlurStartPoint.Y + 9, scoreService.CursorPositionX + 8, (element.StemDirection == VerticalDirection.Up ? element.StemDefaultY + scoreService.Systems.Take(scoreService.CurrentSystemNo - 1).Sum(s => s.Height) : notePositionY + 9), scoreService.CursorPositionX + 10, (element.StemDirection == VerticalDirection.Up ? element.StemDefaultY + scoreService.Systems.Take(scoreService.CurrentSystemNo - 1).Sum(s => s.Height) + 9 : notePositionY + 18), element); } else if (slurStartPlacement == VerticalPlacement.Below) { renderer.DrawBezier(measurementService.SlurStartPoint.X + 10, measurementService.SlurStartPoint.Y + 30, measurementService.SlurStartPoint.X + 12, measurementService.SlurStartPoint.Y + 44, scoreService.CursorPositionX + 8, notePositionY + 44, scoreService.CursorPositionX + 10, notePositionY + 30, element); } } }
private Point GetMostExtremePoint(IEnumerable <Note> notes, VerticalPlacement slurStartPlacement) { if (slurStartPlacement == VerticalPlacement.Above) { var mostExtremeStemEnd = notes.First(n => n.StemEndLocation.Y == notes.Min(nus => nus.StemEndLocation.Y)).StemEndLocation; var mostExtremeNotehead = notes.First(n => n.TextBlockLocation.Y == notes.Min(nus => nus.TextBlockLocation.Y)).TextBlockLocation; mostExtremeNotehead += new Point(0, -8); return(mostExtremeStemEnd.Y < mostExtremeNotehead.Y ? mostExtremeStemEnd : mostExtremeNotehead); } else { var mostExtremeStemEnd = notes.First(n => n.StemEndLocation.Y == notes.Max(nus => nus.StemEndLocation.Y)).StemEndLocation; var mostExtremeNotehead = notes.First(n => n.TextBlockLocation.Y == notes.Max(nus => nus.TextBlockLocation.Y)).TextBlockLocation; mostExtremeNotehead += new Point(0, 8); return(mostExtremeStemEnd.Y > mostExtremeNotehead.Y ? mostExtremeStemEnd : mostExtremeNotehead); } }
private static double GetVerticalOffset(VerticalPlacement verticalPlacement, double popupHeight, double targetHeight, double offsetHeight) { var verticalOffset = offsetHeight; switch (verticalPlacement) { case VerticalPlacement.Top: verticalOffset += -popupHeight; break; case VerticalPlacement.Center: verticalOffset += targetHeight / 2 - popupHeight / 2; break; case VerticalPlacement.Bottom: verticalOffset += targetHeight; break; default: throw new Exception("Invalid Vertical Placement"); } return(verticalOffset); }
public PlacementOptions(HorizontalPlacement horizontal, VerticalPlacement vertical, double offset) { this.Vertical = vertical; this.Horizontal = horizontal; this.Offset = offset; }
/// <summary> /// Draws of performs additional logic at slur end /// </summary> /// <param name="renderer">Score renderer</param> /// <param name="slur">Slur</param> /// <param name="element">Element with a slur</param> /// <param name="notePositionY">Y position of element with a slur</param> /// <param name="slurStartInfo">Information about slur start point</param> /// <param name="slurPlacement">Information about slur placement</param> protected abstract void ProcessSlurEnd(ScoreRendererBase renderer, Slur slur, Note element, double notePositionY, SlurInfo slurStartInfo, VerticalPlacement slurPlacement);
/// <summary> /// Initializes a new instance of the <see cref="PlacementOptions"/> class. /// </summary> /// <param name="horizontal">The <see cref="HorizontalPlacement"/>.</param> /// <param name="vertical">The <see cref="VerticalPlacement"/>.</param> /// <param name="offset">The offset.</param> public PlacementOptions(HorizontalPlacement horizontal, VerticalPlacement vertical, double offset) { this.Vertical = vertical; this.Horizontal = horizontal; this.Offset = offset; }
/// <summary> /// Usage: In XAML, add the following to your tooltip: /// Placement="Custom" CustomPopupPlacementCallback="CustomPopupPlacementCallback" /// and call this method from the CustomPopupPlacementCallback. /// </summary> public static CustomPopupPlacement[] PlacePopup(Size popupSize, Size targetSize, Point offset, VerticalPlacement verticalPlacement, HorizontalPlacement horizontalPlacement) { Point p = new Point { X = GetHorizontalOffset(popupSize, targetSize, horizontalPlacement), Y = GetVerticalOffset(popupSize, targetSize, verticalPlacement) }; return(new[] { new CustomPopupPlacement(p, PopupPrimaryAxis.Horizontal) }); }
private static bool TryParsePlacements(string arg1, string arg2, out HorizontalPlacement horizontal, out VerticalPlacement vertical) { vertical = default(VerticalPlacement); return((Enum.TryParse(arg1, ignoreCase: true, result: out horizontal) && Enum.TryParse(arg2, ignoreCase: true, result: out vertical)) || (Enum.TryParse(arg2, ignoreCase: true, result: out horizontal) && Enum.TryParse(arg1, ignoreCase: true, result: out vertical))); }
/// <summary> /// Draws or performs additional logic at slur start /// </summary> /// <param name="renderer">Score renderer</param> /// <param name="slur">Slur</param> /// <param name="element">Element with a slur</param> /// <param name="notePositionY"></param> /// <param name="slurStartInfo">Information about slur start point</param> /// <param name="slurPlacement">Information about slur placement</param> protected override void ProcessSlurStart(ScoreRendererBase renderer, Slur slur, Note element, double notePositionY, SlurInfo slurStartInfo, VerticalPlacement slurPlacement) { slurStartInfo.StartPlacement = slurPlacement; slurStartInfo.StartPointStemDirection = element.StemDirection; var polihymniaFix = renderer.LinespacesToPixels(element.GetNoteheadWidthLs(renderer) * 0.5); if (slurPlacement == VerticalPlacement.Above) { bool hasFlagOrBeam = element.BaseDuration.Denominator > 4; //If note has a flag or beam start the slur above the note. If not, start a bit to the right and down. var xShiftConcerningStemDirectionStart = slurStartInfo.StartPointStemDirection == VerticalDirection.Up ? (hasFlagOrBeam ? 5 : 10) : 1; slurStartInfo.StartPoint = new Point(scoreService.CursorPositionX + xShiftConcerningStemDirectionStart + polihymniaFix, element.StemDirection == VerticalDirection.Down ? notePositionY - 7 : element.StemEndLocation.Y + (hasFlagOrBeam ? -3 : 8)); } else { slurStartInfo.StartPoint = new Point(scoreService.CursorPositionX + 3 + polihymniaFix, notePositionY + 5); } }
private static double CorrectOrnamentYPositionToAvoidIntersection(ScoreRendererBase renderer, VerticalPlacement placement, double ornamentHeight, double yPosition, Note element, double notePositionY) { if (placement == VerticalPlacement.Above && yPosition + ornamentHeight > element.StemEndLocation.Y) { yPosition = element.StemEndLocation.Y - ornamentHeight - renderer.Settings.LineSpacing; } if (placement == VerticalPlacement.Above && yPosition + ornamentHeight > notePositionY) { yPosition = notePositionY - ornamentHeight - renderer.Settings.LineSpacing; } if (placement == VerticalPlacement.Below && yPosition + ornamentHeight < element.StemEndLocation.Y) { yPosition = element.StemEndLocation.Y + ornamentHeight + renderer.Settings.LineSpacing; } if (placement == VerticalPlacement.Below && yPosition + ornamentHeight < notePositionY) { yPosition = notePositionY + ornamentHeight + renderer.Settings.LineSpacing; } return(yPosition); }
/// <summary> /// Draws or performs additional logic at slur start /// </summary> /// <param name="renderer">Score renderer</param> /// <param name="slur">Slur</param> /// <param name="element">Element with a slur</param> /// <param name="notePositionY"></param> /// <param name="slurStartInfo">Information about slur start point</param> /// <param name="slurPlacement">Information about slur placement</param> protected override void ProcessSlurStart(ScoreRendererBase renderer, Slur slur, Note element, double notePositionY, SlurInfo slurStartInfo, VerticalPlacement slurPlacement) { slurStartInfo.StartPoint = RelativeToAbsolute(renderer, renderer.TenthsToPixels(slur.BezierControlPoint), notePositionY); slurStartInfo.BezierStartControlPoint = RelativeToAbsolute(renderer, renderer.TenthsToPixels(slur.BezierStartOrEndPoint), notePositionY); }
private static bool TryParsePlacements(string arg1, string arg2, out HorizontalPlacement horizontal, out VerticalPlacement vertical) { vertical = default(VerticalPlacement); return (Enum.TryParse(arg1, true, out horizontal) && Enum.TryParse(arg2, true, out vertical)) || (Enum.TryParse(arg2, true, out horizontal) && Enum.TryParse(arg1, true, out vertical)); }
/// <summary> /// Draws of performs additional logic at slur end /// </summary> /// <param name="renderer">Score renderer</param> /// <param name="slur">Slur</param> /// <param name="element">Element with a slur</param> /// <param name="notePositionY">Y position of element with a slur</param> /// <param name="slurStartInfo">Information about slur start point</param> /// <param name="slurPlacement">Information about slur placement</param> protected override void ProcessSlurEnd(ScoreRendererBase renderer, Slur slur, Note element, double notePositionY, SlurInfo slurStartInfo, VerticalPlacement slurPlacement) { Point endPoint; var noteheadWidth = element.GetNoteheadWidthPx(renderer); if (slurStartInfo.StartPlacement == VerticalPlacement.Above) { var xShiftConcerningStemDirectionEnd = noteheadWidth / 2; bool hasFlagOrBeam = element.BaseDuration.Denominator > 4; endPoint = new Point(scoreService.CursorPositionX + xShiftConcerningStemDirectionEnd, (element.StemDirection == VerticalDirection.Up ? element.StemEndLocation.Y + (hasFlagOrBeam ? -2 : 0) : notePositionY - 7)); } else if (slurStartInfo.StartPlacement == VerticalPlacement.Below) { var xShiftConcerningStemDirectionEnd = noteheadWidth / 2; endPoint = new Point(scoreService.CursorPositionX + xShiftConcerningStemDirectionEnd, notePositionY + 5); } else { throw new Exception("Unsupported placement type."); } var slurHeight = DetermineSlurHeight(element, slur, slurStartInfo, endPoint); for (int i = 0; i < 3; i++) //Draw a few curves one by one to simulate a curve with variable thickness. It will be replaced by a path in future releases. { var controlPoints = GetBezierControlPoints(slurStartInfo.StartPoint, endPoint, slurStartInfo.StartPlacement, slurHeight + i); renderer.DrawBezier(slurStartInfo.StartPoint, controlPoints.Item1, controlPoints.Item2, endPoint, element); } //DrawSlurFrame(renderer, startPoint, controlPoints.Item1, controlPoints.Item2, endPoint, element); }
private static Tuple <Point, Point> GetBezierControlPoints(Point start, Point end, VerticalPlacement placement, double height) { var factor = placement == VerticalPlacement.Above ? -1 : 1; var angle = UsefulMath.BeamAngle(start.X, start.Y, end.X, end.Y); var angle2 = angle + (Math.PI / 2) * factor; var distance = Point.Distance(start, end); var startPointForControlPoints = start.TranslateByAngleOld(angle2, height); var control1 = startPointForControlPoints.TranslateByAngleOld(angle, distance * 0.25); var control2 = startPointForControlPoints.TranslateByAngleOld(angle, distance * 0.75); return(new Tuple <Point, Point>(control1, control2)); }