Skip to content

Commit 9bf60fd

Browse files
committed
feat: 节拍编辑
1 parent 5db14b2 commit 9bf60fd

File tree

9 files changed

+360
-62
lines changed

9 files changed

+360
-62
lines changed

TuneLab/Data/ITimeSignature.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
using System.Text;
55
using System.Text.RegularExpressions;
66
using System.Threading.Tasks;
7+
using TuneLab.Base.Data;
8+
using TuneLab.Extensions.Formats.DataInfo;
79

810
namespace TuneLab.Data;
911

10-
internal interface ITimeSignature : IMeter
12+
internal interface ITimeSignature : IDataObject<TimeSignatureInfo>, IMeter
1113
{
1214
int BarIndex { get; }
1315
int GlobalBeatIndex { get; }

TuneLab/Data/ITimeSignatureManager.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,33 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using TuneLab.Base.Data;
4+
using TuneLab.Base.Utils;
5+
using TuneLab.Extensions.Formats.DataInfo;
36

47
namespace TuneLab.Data;
58

6-
internal interface ITimeSignatureManager
9+
internal interface ITimeSignatureManager : IDataObject<List<TimeSignatureInfo>>
710
{
11+
IProject Project { get; } // TODO: Remove this
812
IReadOnlyList<ITimeSignature> TimeSignatures { get; }
913

10-
void AddTimeSignature(int barIndex, int numerator, int denominator);
14+
int AddTimeSignature(int barIndex, int numerator, int denominator);
1115
void RemoveTimeSignatureAt(int index);
12-
void SetNumeratorAndDenominator(int index, int numerator, int denominator);
16+
void SetMeter(int index, int numerator, int denominator);
1317
}
1418

1519
internal static class ITimeSignatureManagerExtension
1620
{
21+
public static void RemoveTimeSignature(this ITimeSignatureManager manager, ITimeSignature timeSignature)
22+
{
23+
manager.RemoveTimeSignatureAt(manager.TimeSignatures.IndexOf(timeSignature));
24+
}
25+
26+
public static void SetMeter(this ITimeSignatureManager manager, ITimeSignature timeSignature, int numerator, int denominator)
27+
{
28+
manager.SetMeter(manager.TimeSignatures.IndexOf(timeSignature), numerator, denominator);
29+
}
30+
1731
public static MeterStatus[] GetMeterStatus(this ITimeSignatureManager manager, IReadOnlyList<double> ticks)
1832
{
1933
MeterStatus[] meters = new MeterStatus[ticks.Count];

TuneLab/Data/Project.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ internal class Project : DataObject, IProject
2222
public Project() : this(new ProjectInfo()) { }
2323
public Project(ProjectInfo info)
2424
{
25+
mTimeSignatureManager = new(this);
2526
mTempoManager = new(this);
2627
mTracks = new(this);
2728

@@ -53,12 +54,10 @@ public ProjectInfo GetInfo()
5354
return info;
5455
}
5556

56-
[MemberNotNull(nameof(mTimeSignatureManager))]
5757
void IDataObject<ProjectInfo>.SetInfo(ProjectInfo info)
5858
{
59-
// TODO: 两个manager都改成dataobject
6059
IDataObject<ProjectInfo>.SetInfo(mTempoManager, info.Tempos);
61-
mTimeSignatureManager = new TimeSignatureManager(info.TimeSignatures);
60+
IDataObject<ProjectInfo>.SetInfo(mTimeSignatureManager, info.TimeSignatures);
6261
IDataObject<ProjectInfo>.SetInfo(mTracks, info.Tracks.Convert(CreateTrack).ToArray());
6362
}
6463

TuneLab/Data/TempoManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public TempoManager(IProject project, List<TempoInfo> tempos) : base(project)
2222
{
2323
mTempos = new(this);
2424
mProject = project;
25-
IDataObject<IReadOnlyList<TempoInfo>>.SetInfo(this, tempos);
25+
IDataObject<List<TempoInfo>>.SetInfo(this, tempos);
2626
}
2727

2828
public int AddTempo(double pos, double bpm)
@@ -125,7 +125,7 @@ void IDataObject<List<TempoInfo>>.SetInfo(List<TempoInfo> info)
125125
if (info.Count == 0)
126126
info = [new() { Pos = 0, Bpm = DefaultBpm }];
127127

128-
IDataObject<IReadOnlyList<TempoInfo>>.SetInfo(mTempos, info.Convert(t => new TempoForTempoManager(t)).ToArray());
128+
IDataObject<List<TempoInfo>>.SetInfo(mTempos, info.Convert(t => new TempoForTempoManager(t)).ToArray());
129129
CorrectStatusFrom(0);
130130
}
131131

TuneLab/Data/TimeSignatureManager.cs

Lines changed: 73 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,66 +3,82 @@
33
using System.Linq;
44
using System.Text;
55
using System.Threading.Tasks;
6+
using TuneLab.Base.Data;
7+
using TuneLab.Base.Structures;
68
using TuneLab.Base.Utils;
79
using TuneLab.Extensions.Formats.DataInfo;
810

911
namespace TuneLab.Data;
1012

11-
internal class TimeSignatureManager : ITimeSignatureManager
13+
internal class TimeSignatureManager : DataObject, ITimeSignatureManager
1214
{
15+
public IProject Project => mProject;
1316
public IReadOnlyList<ITimeSignature> TimeSignatures => mTimeSignatures;
1417

1518
public const int DefaultNumerator = 4;
1619
public const int DefaultDenominator = 4;
17-
public TimeSignatureManager() : this(DefaultNumerator, DefaultDenominator) { }
18-
public TimeSignatureManager(int numerator, int denominator) : this(new TimeSignatureInfo[] { new TimeSignatureInfo { BarIndex = 0, Numerator = numerator, Denominator = denominator } }) { }
20+
public TimeSignatureManager(IProject project) : this(project, DefaultNumerator, DefaultDenominator) { }
21+
public TimeSignatureManager(IProject project, int numerator, int denominator) : this(project, [new TimeSignatureInfo { BarIndex = 0, Numerator = numerator, Denominator = denominator }]) { }
1922

20-
public TimeSignatureManager(IReadOnlyList<TimeSignatureInfo> timeSignatures)
23+
public TimeSignatureManager(IProject project, List<TimeSignatureInfo> timeSignatures) : base(project)
2124
{
22-
if (timeSignatures == null || timeSignatures.Count == 0)
23-
timeSignatures = new TimeSignatureInfo[] { new TimeSignatureInfo { BarIndex = 0, Numerator = DefaultNumerator, Denominator = DefaultDenominator } };
24-
25-
foreach (var timeSignature in timeSignatures)
26-
{
27-
mTimeSignatures.Add(new TimeSignature(timeSignature.BarIndex, timeSignature.Numerator, timeSignature.Denominator));
28-
}
29-
CorrectStatusFrom(0);
25+
mTimeSignatures = new(this);
26+
mProject = project;
27+
IDataObject<List<TimeSignatureInfo>>.SetInfo(this, timeSignatures);
3028
}
3129

32-
public void AddTimeSignature(int barIndex, int numerator, int denominator)
30+
public int AddTimeSignature(int barIndex, int numerator, int denominator)
3331
{
32+
barIndex = Math.Max(barIndex, TimeSignatures[0].BarIndex);
33+
34+
BeginMergeNotify();
3435
int i = mTimeSignatures.Count - 1;
3536
for (; i >= 0; --i)
3637
{
3738
if (mTimeSignatures[i].BarIndex <= barIndex)
3839
break;
3940
}
4041

42+
int result;
4143
if (mTimeSignatures[i].BarIndex == barIndex)
42-
mTimeSignatures[i] = new TimeSignature(barIndex, numerator, denominator) { GlobalBeatIndex = mTimeSignatures[i].GlobalBeatIndex, Pos = mTimeSignatures[i].Pos };
44+
{
45+
var timeSignature = mTimeSignatures[i];
46+
timeSignature.Numerator.Set(numerator);
47+
timeSignature.Denominator.Set(denominator);
48+
result = i;
49+
}
4350
else
44-
mTimeSignatures.Insert(i + 1, new TimeSignature(barIndex, numerator, denominator));
51+
{
52+
mTimeSignatures.Insert(i + 1, new TimeSignature(new() { BarIndex = barIndex, Numerator = numerator, Denominator = denominator }));
53+
result = i + 1;
54+
}
4555

4656
CorrectStatusFrom(i + 1);
57+
EndMergeNotify();
58+
return result;
4759
}
4860

4961
public void RemoveTimeSignatureAt(int index)
5062
{
5163
if (index < 0 || index >= mTimeSignatures.Count)
5264
return;
5365

66+
BeginMergeNotify();
5467
mTimeSignatures.RemoveAt(index);
5568
CorrectStatusFrom(index);
69+
EndMergeNotify();
5670
}
5771

58-
public void SetNumeratorAndDenominator(int index, int numerator, int denominator)
72+
public void SetMeter(int index, int numerator, int denominator)
5973
{
6074
if (index < 0 || index >= TimeSignatures.Count)
6175
return;
6276

63-
mTimeSignatures[index].Numerator = numerator;
64-
mTimeSignatures[index].Denominator = denominator;
77+
BeginMergeNotify();
78+
mTimeSignatures[index].Numerator.Set(numerator);
79+
mTimeSignatures[index].Denominator.Set(denominator);
6580
CorrectStatusFrom(index + 1);
81+
EndMergeNotify();
6682
}
6783

6884
void CorrectStatusFrom(int index)
@@ -87,25 +103,52 @@ void CorrectStatusFrom(int index)
87103
}
88104
}
89105

90-
readonly List<TimeSignature> mTimeSignatures = new();
91-
class TimeSignature : ITimeSignature
106+
public List<TimeSignatureInfo> GetInfo()
107+
{
108+
return mTimeSignatures.GetInfo().ToInfo();
109+
}
110+
111+
void IDataObject<List<TimeSignatureInfo>>.SetInfo(List<TimeSignatureInfo> info)
92112
{
93-
public int BarIndex { get => mBarIndex; set => mBarIndex = value; }
94-
public int Numerator { get => mNumerator; set => mNumerator = value; }
95-
public int Denominator { get => mDenominator; set => mDenominator = value; }
113+
if (info.Count == 0)
114+
info = [new() { BarIndex = 0, Numerator = DefaultNumerator, Denominator = DefaultDenominator }];
115+
116+
IDataObject<List<TimeSignatureInfo>>.SetInfo(mTimeSignatures, info.Convert(t => new TimeSignature(t)).ToArray());
117+
CorrectStatusFrom(0);
118+
}
119+
120+
readonly DataObjectList<TimeSignature> mTimeSignatures;
121+
readonly IProject mProject;
122+
123+
class TimeSignature : DataObject, ITimeSignature
124+
{
125+
public DataStruct<int> BarIndex { get; }
126+
public DataStruct<int> Numerator { get; }
127+
public DataStruct<int> Denominator { get; }
96128
public int GlobalBeatIndex { get => mBeatIndex; set => mBeatIndex = value; }
97129
public double Pos { get => mPos; set => mPos = value; }
98130

99-
public TimeSignature(int barIndex, int numerator, int denominator)
131+
int ITimeSignature.BarIndex => BarIndex;
132+
int IMeter.Numerator => Numerator;
133+
int IMeter.Denominator => Denominator;
134+
135+
public TimeSignature(TimeSignatureInfo info)
136+
{
137+
BarIndex = new(this);
138+
Numerator = new(this);
139+
Denominator = new(this);
140+
IDataObject<TimeSignatureInfo>.SetInfo(this, info);
141+
}
142+
143+
public TimeSignatureInfo GetInfo() => new() { BarIndex = BarIndex.Value, Numerator = Numerator.Value, Denominator = Denominator.Value };
144+
145+
void IDataObject<TimeSignatureInfo>.SetInfo(TimeSignatureInfo info)
100146
{
101-
mBarIndex = barIndex;
102-
mNumerator = numerator;
103-
mDenominator = denominator;
147+
IDataObject<TimeSignatureInfo>.SetInfo(BarIndex, info.BarIndex);
148+
IDataObject<TimeSignatureInfo>.SetInfo(Numerator, info.Numerator);
149+
IDataObject<TimeSignatureInfo>.SetInfo(Denominator, info.Denominator);
104150
}
105151

106-
int mBarIndex;
107-
int mNumerator;
108-
int mDenominator;
109152
int mBeatIndex;
110153
double mPos;
111154
}

TuneLab/UI/MainWindow/Editor/PianoWindow/PianoScrollView/PianoScrollView.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ public PianoScrollView(IDependency dependency)
8787
mDependency.PartProvider.When(p => p.Pitch.Modified).Subscribe(InvalidateVisual, s);
8888
mDependency.PartProvider.When(p => p.Track.Project.Tracks.Any(track => track.AsRefer.Modified)).Subscribe(InvalidateVisual, s);
8989
mDependency.PartProvider.When(p => p.Track.Project.Tracks.Any(track => track.Color.Modified)).Subscribe(InvalidateVisual, s);
90+
mDependency.PartProvider.When(p => p.TempoManager.Modified).Subscribe(InvalidateVisual, s);
91+
mDependency.PartProvider.When(p => p.TimeSignatureManager.Modified).Subscribe(InvalidateVisual, s);
9092
mDependency.WaveformBottomChanged.Subscribe(InvalidateVisual, s);
9193
mDependency.PianoTool.Modified.Subscribe(InvalidateVisual, s);
9294
TickAxis.AxisChanged += Update;

0 commit comments

Comments
 (0)