From d246f469bc929a7697c2e661eb3af4f619c4a232 Mon Sep 17 00:00:00 2001 From: Farex-GH Date: Sun, 11 Sep 2022 22:54:36 -0700 Subject: [PATCH 1/2] mainform: circleview: Split and decouple some elements This moves circleview rendering and mouse updating into the circleView class. The goal of this is to start to decouple circleView from needing direct access to GUI elements, and to also help remove some non-GUI logic from MainForm. Most of the logic is left untouched. There are some small changes, mostly with the if statements when checking if we need to pay attention to certain mouse movement, but the underlying behavior is left as-is. --- BAKKA-Editor/CircleView.cs | 349 ++++++++++++++++++++++++++++++++- BAKKA-Editor/MainForm.cs | 389 ++++++------------------------------- 2 files changed, 407 insertions(+), 331 deletions(-) diff --git a/BAKKA-Editor/CircleView.cs b/BAKKA-Editor/CircleView.cs index 22c8e7b..f298592 100644 --- a/BAKKA-Editor/CircleView.cs +++ b/BAKKA-Editor/CircleView.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Drawing.Drawing2D; using System.Threading.Tasks; namespace BAKKA_Editor @@ -33,6 +34,17 @@ namespace BAKKA_Editor private int SelectTransparency = 110; private int FlairTransparency = 75; + // Graphics. + BufferedGraphicsContext gfxContext = BufferedGraphicsManager.Current; + BufferedGraphics bufGraphics; + + // Mouse information. Public so other GUI elements can be updated with their values. + public int mouseDownPos = -1; + public Point mouseDownPt; + public int lastMousePos = -1; + public bool rolloverPos = false; + public bool rolloverNeg = false; + public CircleView(SizeF size) { Update(size); @@ -61,7 +73,7 @@ namespace BAKKA_Editor FlairPen = new Pen(Color.FromArgb(FlairTransparency, Color.Yellow), PanelSize.Width * 8.0f / 600.0f); } - public ArcInfo GetScaledRect(float objectTime) + private ArcInfo GetScaledRect(float objectTime) { ArcInfo info = new(); float notescaleInit = 1 - ((objectTime - CurrentMeasure) * (1 / TotalMeasureShowNotes)); // Scale from 0-1 @@ -76,7 +88,7 @@ namespace BAKKA_Editor return info; } - public ArcInfo GetArcInfo(Note note) + private ArcInfo GetArcInfo(Note note) { ArcInfo info = GetScaledRect(note.Measure); info.StartAngle = -note.Position * 6; @@ -89,6 +101,339 @@ namespace BAKKA_Editor return info; } + // Updates the mouse down position within the circle, and returns the new position. + public void UpdateMouseDown(float xCen, float yCen, Point mousePt) + { + float theta = (float)(Math.Atan2(yCen, xCen) * 180.0f / Math.PI); + if (theta < 0) + theta += 360.0f; + // Left click moves the cursor + mouseDownPos = (int)(theta / 6.0f); + mouseDownPt = mousePt; + lastMousePos = -1; + rolloverPos = false; + rolloverNeg = false; + } + + public void UpdateMouseUp() + { + if (mouseDownPos <= -1) + { + return; + } + + // Reset position and point. + mouseDownPos = -1; + mouseDownPt = new Point(); + } + + // Updates the mouse position and returns the new position in degrees. + public int UpdateMouseMove(float xCen, float yCen) + { + float thetaCalc = (float)(Math.Atan2(yCen, xCen) * 180.0f / Math.PI); + if (thetaCalc < 0) + thetaCalc += 360.0f; + int theta = (int)(thetaCalc / 6.0f); + + int delta = theta - lastMousePos; + // Handle rollover + if (delta == -59) + { + if (rolloverNeg) + rolloverNeg = false; + else + rolloverPos = true; + } + else if (delta == 59) + { + if (rolloverPos) + rolloverPos = false; + else + rolloverNeg = true; + } + lastMousePos = theta; + + return theta; + } + + public void DrawBackground(int width, int height, Color color) + { + Rectangle panelRect = new Rectangle(0, 0, width, height); + + // Set drawing mode + bufGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; + // Draw background + bufGraphics.Graphics.FillRectangle(new SolidBrush(color), panelRect); + } + + public void DrawMasks(Chart chart) + { + var masks = chart.Notes.Where( + x => x.Measure <= CurrentMeasure + && x.IsMask).ToList(); + foreach (var mask in masks) + { + if (mask.NoteType == NoteType.MaskAdd) + { + // Check if there's a MaskRemove that counters the MaskAdd (unless the MaskAdd is later) + var rem = masks.FirstOrDefault(x => x.NoteType == NoteType.MaskRemove && + x.Position == mask.Position && x.Size == mask.Size); + if (rem == null || rem.Measure < mask.Measure) + bufGraphics.Graphics.FillPie(MaskBrush, DrawRect.ToInt(), -mask.Position * 6.0f, -mask.Size * 6.0f); + } + } + } + + public void DrawCircle() + { + // Switch drawing modes + bufGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + + // Draw measure circle + for (float meas = (float)Math.Ceiling(CurrentMeasure); (meas - CurrentMeasure) < TotalMeasureShowNotes; meas += 1.0f) + { + var info = GetScaledRect(meas); + if (info.Rect.Width >= 1) + { + bufGraphics.Graphics.DrawEllipse(BeatPen, info.Rect); + } + } + + // Draw base circle + bufGraphics.Graphics.DrawEllipse(TickMediumPen, DrawRect); + } + + public void DrawDegreeLines() + { + for (int i = 0; i < 360; i += 6) + { + PointF startPoint = new PointF( + (float)(Radius * Math.Cos(Utils.DegToRad(i))) + CenterPoint.X, + (float)(Radius * Math.Sin(Utils.DegToRad(i))) + CenterPoint.Y); + float tickLength = PanelSize.Width * 10.0f / 285.0f; + float innerRad = Radius - tickLength; + Pen activePen; + if (i % 90 == 0) + { + innerRad = Radius - (tickLength * 3.5f); + activePen = TickMajorPen; + } + else if (i % 30 == 0) + { + innerRad = Radius - (tickLength * 2.5f); + activePen = TickMediumPen; + } + else + { + activePen = TickMinorPen; + } + PointF endPoint = new PointF( + (float)(innerRad * Math.Cos(Utils.DegToRad(i))) + CenterPoint.X, + (float)(innerRad * Math.Sin(Utils.DegToRad(i))) + CenterPoint.Y); + + bufGraphics.Graphics.DrawLine(activePen, startPoint, endPoint); + } + } + + public void DrawHolds(Chart chart, bool highlightSelectedNote, int selectedNoteIndex) + { + ArcInfo currentInfo = GetScaledRect(CurrentMeasure); + ArcInfo endInfo = GetScaledRect(CurrentMeasure + TotalMeasureShowNotes); + + // First, draw holes that start before the viewpoint and have nodes that end after + List holdNotes = chart.Notes.Where( + x => x.Measure < CurrentMeasure + && x.NextNote != null + && x.NextNote.Measure > (CurrentMeasure + TotalMeasureShowNotes) + && x.IsHold).ToList(); + foreach (var note in holdNotes) + { + ArcInfo info = GetArcInfo(note); + ArcInfo nextInfo = GetArcInfo((Note)note.NextNote); + //GraphicsPath path = new GraphicsPath(); + //path.AddArc(endInfo.Rect, info.StartAngle, info.ArcLength); + //path.AddArc(currentInfo.Rect, info.StartAngle + info.ArcLength, -info.ArcLength); + //bufGraphics.Graphics.FillPath(HoldBrush, path); + + float ratio = (currentInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width); + float startNoteAngle = nextInfo.StartAngle; + float endNoteAngle = info.StartAngle; + if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) + { + startNoteAngle -= 360; + } + else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) + { + endNoteAngle -= 360; + } + float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle; + float endAngle = ratio * ((endNoteAngle - info.ArcLength) - (startNoteAngle - nextInfo.ArcLength)) + + (startNoteAngle - nextInfo.ArcLength); + float arcLength = startAngle - endAngle; + + float ratio2 = (endInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width); + float startNoteAngle2 = nextInfo.StartAngle; + float endNoteAngle2 = info.StartAngle; + if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) + { + startNoteAngle2 -= 360; + } + else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) + { + endNoteAngle2 -= 360; + } + float startAngle2 = ratio2 * (endNoteAngle2 - startNoteAngle2) + startNoteAngle2; + float endAngle2 = ratio2 * ((endNoteAngle2 - info.ArcLength) - (startNoteAngle2 - nextInfo.ArcLength)) + + (startNoteAngle2 - nextInfo.ArcLength); + float arcLength2 = startAngle2 - endAngle2; + + GraphicsPath path = new GraphicsPath(); + path.AddArc(currentInfo.Rect, startAngle, arcLength); + path.AddArc(endInfo.Rect, startAngle2 + arcLength2, -arcLength2); + bufGraphics.Graphics.FillPath(HoldBrush, path); + } + + // Second, draw all the notes on-screen + holdNotes = chart.Notes.Where( + x => x.Measure >= CurrentMeasure + && x.Measure <= (CurrentMeasure + TotalMeasureShowNotes) + && x.IsHold).ToList(); + foreach (var note in holdNotes) + { + ArcInfo info = GetArcInfo(note); + + // If the previous note is off-screen, this case handles that + if (note.PrevNote != null && note.PrevNote.Measure < CurrentMeasure) + { + ArcInfo prevInfo = GetArcInfo((Note)note.PrevNote); + float ratio = (currentInfo.Rect.Width - info.Rect.Width) / (prevInfo.Rect.Width - info.Rect.Width); + float startNoteAngle = info.StartAngle; + float endNoteAngle = prevInfo.StartAngle; + if (info.StartAngle > prevInfo.StartAngle && (Math.Abs(info.StartAngle - prevInfo.StartAngle) > 180)) + { + startNoteAngle -= 360; + } + else if (prevInfo.StartAngle > info.StartAngle && (Math.Abs(info.StartAngle - prevInfo.StartAngle) > 180)) + { + endNoteAngle -= 360; + } + float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle; + float endAngle = ratio * ((endNoteAngle - prevInfo.ArcLength) - (startNoteAngle - info.ArcLength)) + + (startNoteAngle - info.ArcLength); + float arcLength = startAngle - endAngle; + + GraphicsPath path = new GraphicsPath(); + path.AddArc(info.Rect, info.StartAngle, info.ArcLength); + path.AddArc(currentInfo.Rect, startAngle + arcLength, -arcLength); + bufGraphics.Graphics.FillPath(HoldBrush, path); + } + + // If the next note is on-screen, this case handles that + if (note.NextNote != null && note.NextNote.Measure <= (CurrentMeasure + TotalMeasureShowNotes)) + { + ArcInfo nextInfo = GetArcInfo((Note)note.NextNote); + GraphicsPath path = new GraphicsPath(); + path.AddArc(info.Rect, info.StartAngle, info.ArcLength); + path.AddArc(nextInfo.Rect, nextInfo.StartAngle + nextInfo.ArcLength, -nextInfo.ArcLength); + bufGraphics.Graphics.FillPath(HoldBrush, path); + } + + // If the next note is off-screen, this case handles that + if (note.NextNote != null && note.NextNote.Measure > (CurrentMeasure + TotalMeasureShowNotes)) + { + ArcInfo nextInfo = GetArcInfo((Note)note.NextNote); + float ratio = (endInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width); + float startNoteAngle = nextInfo.StartAngle; + float endNoteAngle = info.StartAngle; + if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) + { + startNoteAngle -= 360; + } + else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) + { + endNoteAngle -= 360; + } + float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle; + float endAngle = ratio * ((endNoteAngle - info.ArcLength) - (startNoteAngle - nextInfo.ArcLength)) + + (startNoteAngle - nextInfo.ArcLength); + float arcLength = startAngle - endAngle; + + GraphicsPath path = new GraphicsPath(); + path.AddArc(endInfo.Rect, startAngle, arcLength); + path.AddArc(info.Rect, info.StartAngle + info.ArcLength, -info.ArcLength); + bufGraphics.Graphics.FillPath(HoldBrush, path); + } + + // Draw note + if (info.Rect.Width >= 1) + { + bufGraphics.Graphics.DrawArc(GetPen(note), info.Rect, info.StartAngle, info.ArcLength); + + // Draw bonus + if (note.IsFlair) + bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4); + + // Plot highlighted + if (highlightSelectedNote) + { + if (selectedNoteIndex != -1 && note == chart.Notes[selectedNoteIndex]) + { + bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4); + } + } + } + } + } + + public void DrawNotes(Chart chart, bool highlightSelectedNote, int selectedNoteIndex) + { + List drawNotes = chart.Notes.Where( + x => x.Measure >= CurrentMeasure + && x.Measure <= (CurrentMeasure + TotalMeasureShowNotes) + && !x.IsHold && !x.IsMask).ToList(); + foreach (var note in drawNotes) + { + ArcInfo info = GetArcInfo(note); + + if (info.Rect.Width >= 1) + { + bufGraphics.Graphics.DrawArc(GetPen(note, info.NoteScale), info.Rect, info.StartAngle, info.ArcLength); + if (note.IsFlair) + { + bufGraphics.Graphics.DrawArc(FlairPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4); + } + // Plot highlighted + if (highlightSelectedNote) + { + if (selectedNoteIndex != -1 && note == chart.Notes[selectedNoteIndex]) + { + bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4); + } + } + } + } + } + + public void DrawCursor(NoteType noteType, float startAngle, float sweepAngle) + { + bufGraphics.Graphics.DrawArc( + GetPen(noteType), + DrawRect, + -(float)startAngle * 6.0f, + -(float)sweepAngle * 6.0f); + } + + public void Render(Graphics graphics) + { + bufGraphics.Render(graphics); + } + + public void SetBufferedGraphicsContext(int width, int height, Graphics graphics) + { + gfxContext.MaximumBuffer = new Size(width + 1, height + 1); + bufGraphics = gfxContext.Allocate(graphics, new Rectangle(0, 0, width, height)); + } + public Pen GetPen(Note note, float noteScale = 1.0f) { return new Pen(note.Color, PanelSize.Width * 8.0f * noteScale / 600.0f); diff --git a/BAKKA-Editor/MainForm.cs b/BAKKA-Editor/MainForm.cs index 37a539f..d3d5af8 100644 --- a/BAKKA-Editor/MainForm.cs +++ b/BAKKA-Editor/MainForm.cs @@ -17,9 +17,7 @@ namespace BAKKA_Editor // Operations OperationManager opManager = new OperationManager(); - // Graphics - BufferedGraphicsContext gfxContext = BufferedGraphicsManager.Current; - BufferedGraphics bufGraphics; + // Playfield CircleView circleView = new CircleView(new SizeF(611, 611)); // Note Selection @@ -30,13 +28,6 @@ namespace BAKKA_Editor int selectedNoteIndex = -1; Note lastNote; - // Mouse - int mouseDownPos = -1; - Point mouseDownPt; - int lastMousePos = -1; - bool rolloverPos = false; - bool rolloverNeg = false; - // Music ISoundEngine soundEngine = new ISoundEngine(); ISound currentSong; @@ -172,13 +163,6 @@ namespace BAKKA_Editor Text = $"{save}BAKKA Editor {fileVersion} - [{name}]"; } - private void SetBufferedGraphicsContext() - { - gfxContext.MaximumBuffer = new Size(circlePanel.Width + 1, circlePanel.Height + 1); - bufGraphics = gfxContext.Allocate(circlePanel.CreateGraphics(), - new Rectangle(0, 0, circlePanel.Width, circlePanel.Height)); - } - /// /// Prompts for a save if the chart is not currently saved. /// @@ -503,256 +487,26 @@ namespace BAKKA_Editor private void circlePanel_Paint(object sender, PaintEventArgs e) { - Rectangle panelRect = new Rectangle(0, 0, circlePanel.Width, circlePanel.Height); - - // Set drawing mode - bufGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; - // Draw background - bufGraphics.Graphics.FillRectangle(new SolidBrush(this.BackColor), panelRect); - - // Set hi-speed + circleView.DrawBackground(circlePanel.Width, circlePanel.Height, this.BackColor); // Draw masks - var masks = chart.Notes.Where( - x => x.Measure <= circleView.CurrentMeasure - && x.IsMask).ToList(); - foreach (var mask in masks) - { - if (mask.NoteType == NoteType.MaskAdd) - { - // Check if there's a MaskRemove that counters the MaskAdd (unless the MaskAdd is later) - var rem = masks.FirstOrDefault(x => x.NoteType == NoteType.MaskRemove && x.Position == mask.Position && x.Size == mask.Size); - if (rem == null || rem.Measure < mask.Measure) - bufGraphics.Graphics.FillPie(circleView.MaskBrush, circleView.DrawRect.ToInt(), -mask.Position * 6.0f, -mask.Size * 6.0f); - } - } + circleView.DrawMasks(chart); - // Draw selected mask - - // Switch drawing modes - bufGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; - - // Draw measure circle - for (float meas = (float)Math.Ceiling(circleView.CurrentMeasure); (meas - circleView.CurrentMeasure) < circleView.TotalMeasureShowNotes; meas += 1.0f) - { - var info = circleView.GetScaledRect(meas); - if (info.Rect.Width >= 1) - { - bufGraphics.Graphics.DrawEllipse(circleView.BeatPen, info.Rect); - } - } - - // Draw base circle - bufGraphics.Graphics.DrawEllipse(circleView.TickMediumPen, circleView.DrawRect); + // Draw base and measure circle. + circleView.DrawCircle(); // Draw degree lines - for (int i = 0; i < 360; i += 6) - { - PointF startPoint = new PointF( - (float)(circleView.Radius * Math.Cos(Utils.DegToRad(i))) + circleView.CenterPoint.X, - (float)(circleView.Radius * Math.Sin(Utils.DegToRad(i))) + circleView.CenterPoint.Y); - float tickLength = circleView.PanelSize.Width * 10.0f / 285.0f; - float innerRad = circleView.Radius - tickLength; - Pen activePen; - if (i % 90 == 0) - { - innerRad = circleView.Radius - (tickLength * 3.5f); - activePen = circleView.TickMajorPen; - } - else if (i % 30 == 0) - { - innerRad = circleView.Radius - (tickLength * 2.5f); - activePen = circleView.TickMediumPen; - } - else - { - activePen = circleView.TickMinorPen; - } - PointF endPoint = new PointF( - (float)(innerRad * Math.Cos(Utils.DegToRad(i))) + circleView.CenterPoint.X, - (float)(innerRad * Math.Sin(Utils.DegToRad(i))) + circleView.CenterPoint.Y); - - bufGraphics.Graphics.DrawLine(activePen, startPoint, endPoint); - } - - // Some variables for use later - ArcInfo currentInfo = circleView.GetScaledRect(circleView.CurrentMeasure); - ArcInfo endInfo = circleView.GetScaledRect(circleView.CurrentMeasure + circleView.TotalMeasureShowNotes); + circleView.DrawDegreeLines(); // Draw holds - // First, draw holes that start before the viewpoint and have nodes that end after - List holdNotes = chart.Notes.Where( - x => x.Measure < circleView.CurrentMeasure - && x.NextNote != null - && x.NextNote.Measure > (circleView.CurrentMeasure + circleView.TotalMeasureShowNotes) - && x.IsHold).ToList(); - foreach (var note in holdNotes) - { - ArcInfo info = circleView.GetArcInfo(note); - ArcInfo nextInfo = circleView.GetArcInfo((Note)note.NextNote); - //GraphicsPath path = new GraphicsPath(); - //path.AddArc(endInfo.Rect, info.StartAngle, info.ArcLength); - //path.AddArc(currentInfo.Rect, info.StartAngle + info.ArcLength, -info.ArcLength); - //bufGraphics.Graphics.FillPath(circleView.HoldBrush, path); - - float ratio = (currentInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width); - float startNoteAngle = nextInfo.StartAngle; - float endNoteAngle = info.StartAngle; - if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) - { - startNoteAngle -= 360; - } - else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) - { - endNoteAngle -= 360; - } - float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle; - float endAngle = ratio * ((endNoteAngle - info.ArcLength) - (startNoteAngle - nextInfo.ArcLength)) + - (startNoteAngle - nextInfo.ArcLength); - float arcLength = startAngle - endAngle; - - float ratio2 = (endInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width); - float startNoteAngle2 = nextInfo.StartAngle; - float endNoteAngle2 = info.StartAngle; - if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) - { - startNoteAngle2 -= 360; - } - else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) - { - endNoteAngle2 -= 360; - } - float startAngle2 = ratio2 * (endNoteAngle2 - startNoteAngle2) + startNoteAngle2; - float endAngle2 = ratio2 * ((endNoteAngle2 - info.ArcLength) - (startNoteAngle2 - nextInfo.ArcLength)) + - (startNoteAngle2 - nextInfo.ArcLength); - float arcLength2 = startAngle2 - endAngle2; - - GraphicsPath path = new GraphicsPath(); - path.AddArc(currentInfo.Rect, startAngle, arcLength); - path.AddArc(endInfo.Rect, startAngle2 + arcLength2, -arcLength2); - bufGraphics.Graphics.FillPath(circleView.HoldBrush, path); - } - // Second, draw all the notes on-screen - holdNotes = chart.Notes.Where( - x => x.Measure >= circleView.CurrentMeasure - && x.Measure <= (circleView.CurrentMeasure + circleView.TotalMeasureShowNotes) - && x.IsHold).ToList(); - foreach (var note in holdNotes) - { - ArcInfo info = circleView.GetArcInfo(note); - - // If the previous note is off-screen, this case handles that - if (note.PrevNote != null && note.PrevNote.Measure < circleView.CurrentMeasure) - { - ArcInfo prevInfo = circleView.GetArcInfo((Note)note.PrevNote); - float ratio = (currentInfo.Rect.Width - info.Rect.Width) / (prevInfo.Rect.Width - info.Rect.Width); - float startNoteAngle = info.StartAngle; - float endNoteAngle = prevInfo.StartAngle; - if (info.StartAngle > prevInfo.StartAngle && (Math.Abs(info.StartAngle - prevInfo.StartAngle) > 180)) - { - startNoteAngle -= 360; - } - else if (prevInfo.StartAngle > info.StartAngle && (Math.Abs(info.StartAngle - prevInfo.StartAngle) > 180)) - { - endNoteAngle -= 360; - } - float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle; - float endAngle = ratio * ((endNoteAngle - prevInfo.ArcLength) - (startNoteAngle - info.ArcLength)) + - (startNoteAngle - info.ArcLength); - float arcLength = startAngle - endAngle; - - GraphicsPath path = new GraphicsPath(); - path.AddArc(info.Rect, info.StartAngle, info.ArcLength); - path.AddArc(currentInfo.Rect, startAngle + arcLength, -arcLength); - bufGraphics.Graphics.FillPath(circleView.HoldBrush, path); - } - - // If the next note is on-screen, this case handles that - if (note.NextNote != null && note.NextNote.Measure <= (circleView.CurrentMeasure + circleView.TotalMeasureShowNotes)) - { - ArcInfo nextInfo = circleView.GetArcInfo((Note)note.NextNote); - GraphicsPath path = new GraphicsPath(); - path.AddArc(info.Rect, info.StartAngle, info.ArcLength); - path.AddArc(nextInfo.Rect, nextInfo.StartAngle + nextInfo.ArcLength, -nextInfo.ArcLength); - bufGraphics.Graphics.FillPath(circleView.HoldBrush, path); - } - - // If the next note is off-screen, this case handles that - if (note.NextNote != null && note.NextNote.Measure > (circleView.CurrentMeasure + circleView.TotalMeasureShowNotes)) - { - ArcInfo nextInfo = circleView.GetArcInfo((Note)note.NextNote); - float ratio = (endInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width); - float startNoteAngle = nextInfo.StartAngle; - float endNoteAngle = info.StartAngle; - if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) - { - startNoteAngle -= 360; - } - else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180)) - { - endNoteAngle -= 360; - } - float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle; - float endAngle = ratio * ((endNoteAngle - info.ArcLength) - (startNoteAngle - nextInfo.ArcLength)) + - (startNoteAngle - nextInfo.ArcLength); - float arcLength = startAngle - endAngle; - - GraphicsPath path = new GraphicsPath(); - path.AddArc(endInfo.Rect, startAngle, arcLength); - path.AddArc(info.Rect, info.StartAngle + info.ArcLength, -info.ArcLength); - bufGraphics.Graphics.FillPath(circleView.HoldBrush, path); - } - - // Draw note - if (info.Rect.Width >= 1) - { - bufGraphics.Graphics.DrawArc(circleView.GetPen(note), info.Rect, info.StartAngle, info.ArcLength); - - // Draw bonus - if (note.IsFlair) - bufGraphics.Graphics.DrawArc(circleView.HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4); - - // Plot highlighted - if (highlightViewedNoteToolStripMenuItem.Checked) - { - if (selectedNoteIndex != -1 && note == chart.Notes[selectedNoteIndex]) - { - bufGraphics.Graphics.DrawArc(circleView.HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4); - } - } - } - } + circleView.DrawHolds(chart, highlightViewedNoteToolStripMenuItem.Checked, selectedNoteIndex); // Draw notes - List drawNotes = chart.Notes.Where( - x => x.Measure >= circleView.CurrentMeasure - && x.Measure <= (circleView.CurrentMeasure + circleView.TotalMeasureShowNotes) - && !x.IsHold && !x.IsMask).ToList(); - foreach (var note in drawNotes) - { - ArcInfo info = circleView.GetArcInfo(note); - - if (info.Rect.Width >= 1) - { - bufGraphics.Graphics.DrawArc(circleView.GetPen(note, info.NoteScale), info.Rect, info.StartAngle, info.ArcLength); - if (note.IsFlair) - { - bufGraphics.Graphics.DrawArc(circleView.FlairPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4); - } - // Plot highlighted - if (highlightViewedNoteToolStripMenuItem.Checked) - { - if (selectedNoteIndex != -1 && note == chart.Notes[selectedNoteIndex]) - { - bufGraphics.Graphics.DrawArc(circleView.HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4); - } - } - } - } + circleView.DrawNotes(chart, highlightViewedNoteToolStripMenuItem.Checked, selectedNoteIndex); // Determine if cursor should be showing - bool showCursor = showCursorToolStripMenuItem.Checked || mouseDownPos != -1; + bool showCursor = showCursorToolStripMenuItem.Checked || circleView.mouseDownPos != -1; if (currentSong != null && !currentSong.Paused) { showCursor = showCursorDuringPlaybackToolStripMenuItem.Checked; @@ -761,14 +515,11 @@ namespace BAKKA_Editor // Draw cursor if (showCursor) { - bufGraphics.Graphics.DrawArc( - circleView.GetPen(currentNoteType), - circleView.DrawRect, - -(float)positionNumeric.Value * 6.0f, - -(float)sizeNumeric.Value * 6.0f); + circleView.DrawCursor(currentNoteType, (float)positionNumeric.Value, (float)sizeNumeric.Value); } - bufGraphics.Render(e.Graphics); + // Everything has been drawn, render it. + circleView.Render(e.Graphics); } private void measureNumeric_ValueChanged(object sender, EventArgs e) @@ -1204,92 +955,72 @@ namespace BAKKA_Editor private void circlePanel_MouseDown(object sender, MouseEventArgs e) { - // Determine the location of mouse click inside the circle + if (e.Button != MouseButtons.Left) + { + return; + } + // X and Y are relative to the upper left of the panel float xCen = e.X - (circlePanel.Width / 2); float yCen = -(e.Y - (circlePanel.Height / 2)); - float theta = (float)(Math.Atan2(yCen, xCen) * 180.0f / Math.PI); - if (theta < 0) - theta += 360.0f; - // Left click moves the cursor - if (e.Button == MouseButtons.Left) - { - positionNumeric.Value = (int)(theta / 6.0f); - mouseDownPos = (int)positionNumeric.Value; - mouseDownPt = e.Location; - lastMousePos = -1; - rolloverPos = false; - rolloverNeg = false; - circlePanel.Invalidate(); - } + // Update the location of mouse click inside the circle + circleView.UpdateMouseDown(xCen, yCen, e.Location); + positionNumeric.Value = circleView.mouseDownPos; + circlePanel.Invalidate(); } private void circlePanel_MouseUp(object sender, MouseEventArgs e) { - if (e.Button == MouseButtons.Left && mouseDownPos > -1) + // Mouse down position wasn't within the window or wasn't a left click, do nothing. + if (e.Button != MouseButtons.Left || circleView.mouseDownPos <= -1) { - var dist = Utils.GetDist(e.Location, mouseDownPt); - if (dist > 5.0f) - InsertObject(); - mouseDownPos = -1; - mouseDownPt = new Point(); - circlePanel.Invalidate(); + return; } + + var dist = Utils.GetDist(e.Location, circleView.mouseDownPt); + if (dist > 5.0f) + InsertObject(); + circleView.UpdateMouseUp(); + circlePanel.Invalidate(); } private void circlePanel_MouseMove(object sender, MouseEventArgs e) { - // Determine the location of mouse click inside the circle + // Mouse down position wasn't within the window or wasn't a left click, do nothing. + if (e.Button != MouseButtons.Left || circleView.mouseDownPos <= -1) + { + return; + } + // X and Y are relative to the upper left of the panel float xCen = e.X - (circlePanel.Width / 2); float yCen = -(e.Y - (circlePanel.Height / 2)); - float thetaCalc = (float)(Math.Atan2(yCen, xCen) * 180.0f / Math.PI); - if (thetaCalc < 0) - thetaCalc += 360.0f; - int theta = (int)(thetaCalc / 6.0f); + // Update the location of mouse click inside the circle. + int theta = circleView.UpdateMouseMove(xCen, yCen); // Left click will alter the note width and possibly position depending on which direction we move - if (e.Button == MouseButtons.Left && mouseDownPos != -1) + if (theta == circleView.mouseDownPos) { - int delta = theta - lastMousePos; - // Handle rollover - if (delta == -59) - { - if (rolloverNeg) - rolloverNeg = false; - else - rolloverPos = true; - } - else if (delta == 59) - { - if (rolloverPos) - rolloverPos = false; - else - rolloverNeg = true; - } - if (theta == mouseDownPos) - { - positionNumeric.Value = mouseDownPos; - sizeNumeric.Value = 1; - } - else if ((theta > mouseDownPos || rolloverPos) && !rolloverNeg) - { - positionNumeric.Value = mouseDownPos; - if (rolloverPos) - sizeNumeric.Value = (int)Math.Min(theta + 60 - mouseDownPos + 1, 60); - else - sizeNumeric.Value = theta - mouseDownPos + 1; - } - else if (theta < mouseDownPos || rolloverNeg) - { - positionNumeric.Value = theta; - if (rolloverNeg) - sizeNumeric.Value = (int)Math.Min(mouseDownPos + 60 - theta + 1, 60); - else - sizeNumeric.Value = mouseDownPos - theta + 1; - } - lastMousePos = theta; - circlePanel.Invalidate(); + positionNumeric.Value = circleView.mouseDownPos; + sizeNumeric.Value = 1; } + else if ((theta > circleView.mouseDownPos || circleView.rolloverPos) && !circleView.rolloverNeg) + { + positionNumeric.Value = circleView.mouseDownPos; + if (circleView.rolloverPos) + sizeNumeric.Value = (int)Math.Min(theta + 60 - circleView.mouseDownPos + 1, 60); + else + sizeNumeric.Value = theta - circleView.mouseDownPos + 1; + } + else if (theta < circleView.mouseDownPos || circleView.rolloverNeg) + { + positionNumeric.Value = theta; + if (circleView.rolloverNeg) + sizeNumeric.Value = (int)Math.Min(circleView.mouseDownPos + 60 - theta + 1, 60); + else + sizeNumeric.Value = circleView.mouseDownPos - theta + 1; + } + + circlePanel.Invalidate(); } private void visualHispeedNumeric_ValueChanged(object sender, EventArgs e) @@ -2024,7 +1755,7 @@ namespace BAKKA_Editor } int paddingLeft = (zoneWidth - circlePanel.Width) / 2; circlePanel.Left = gimmickTypeGroupBox.Right + 6 + paddingLeft; - SetBufferedGraphicsContext(); + circleView.SetBufferedGraphicsContext(circlePanel.Width, circlePanel.Height, circlePanel.CreateGraphics()); circleView.Update(circlePanel.Size); circlePanel.Invalidate(); } -- 2.54.0 From 6f5bdaddd956c8408fa22ce7b1182b7adff58147 Mon Sep 17 00:00:00 2001 From: veroxzik <43590004+veroxzik@users.noreply.github.com> Date: Fri, 4 Nov 2022 22:51:35 -0400 Subject: [PATCH 2/2] Fixing a single tab like a madman. --- BAKKA-Editor/MainForm.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BAKKA-Editor/MainForm.cs b/BAKKA-Editor/MainForm.cs index 128def1..c595a8c 100644 --- a/BAKKA-Editor/MainForm.cs +++ b/BAKKA-Editor/MainForm.cs @@ -1854,7 +1854,7 @@ namespace BAKKA_Editor circlePanel.Invalidate(); } - private void MainForm_Resize(object sender, EventArgs e) + private void MainForm_Resize(object sender, EventArgs e) { var zoneWidth = noteViewGroupBox.Left - gimmickTypeGroupBox.Right - 12; var zoneHeight = playbackGroupBox.Top - gimmickTypeGroupBox.Top - 6; -- 2.54.0