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.
This commit is contained in:
Farex-GH
2022-09-11 22:54:36 -07:00
parent afc86e9c46
commit d246f469bc
2 changed files with 407 additions and 331 deletions
+347 -2
View File
@@ -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<Note> 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<Note> 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);
+60 -329
View File
@@ -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));
}
/// <summary>
/// Prompts for a save if the chart is not currently saved.
/// </summary>
@@ -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<Note> 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<Note> 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();
}