Skip to content

Commit cc9dc60

Browse files
committed
Refactor feedback sample playback logic
1 parent 6cadcc2 commit cc9dc60

File tree

1 file changed

+57
-63
lines changed

1 file changed

+57
-63
lines changed

osu.Game/Graphics/UserInterface/OsuTextBox.cs

+57-63
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
22
// See the LICENCE file in the repository root for full licence text.
33

4+
using System;
5+
using System.Collections.Generic;
46
using System.Linq;
57
using osu.Framework.Allocation;
68
using osu.Framework.Audio;
@@ -40,30 +42,26 @@ public class OsuTextBox : BasicTextBox
4042
Margin = new MarginPadding { Left = 2 },
4143
};
4244

43-
private readonly Sample?[] textAddedSamples = new Sample[4];
44-
private Sample? capsTextAddedSample;
45-
private Sample? textRemovedSample;
46-
private Sample? textCommittedSample;
47-
private Sample? caretMovedSample;
48-
49-
private Sample? selectCharSample;
50-
private Sample? selectWordSample;
51-
private Sample? selectAllSample;
52-
private Sample? deselectSample;
53-
5445
private OsuCaret? caret;
5546

5647
private bool selectionStarted;
5748
private double sampleLastPlaybackTime;
5849

59-
private enum SelectionSampleType
50+
private enum FeedbackSampleType
6051
{
61-
Character,
62-
Word,
63-
All,
52+
TextAdd,
53+
TextAddCaps,
54+
TextRemove,
55+
TextConfirm,
56+
CaretMove,
57+
SelectCharacter,
58+
SelectWord,
59+
SelectAll,
6460
Deselect
6561
}
6662

63+
private Dictionary<FeedbackSampleType, Sample?[]> sampleMap = new Dictionary<FeedbackSampleType, Sample?[]>();
64+
6765
public OsuTextBox()
6866
{
6967
Height = 40;
@@ -87,18 +85,22 @@ private void load(OverlayColourProvider? colourProvider, OsuColour colour, Audio
8785

8886
Placeholder.Colour = colourProvider?.Foreground1 ?? new Color4(180, 180, 180, 255);
8987

88+
var textAddedSamples = new Sample?[4];
9089
for (int i = 0; i < textAddedSamples.Length; i++)
9190
textAddedSamples[i] = audio.Samples.Get($@"Keyboard/key-press-{1 + i}");
9291

93-
capsTextAddedSample = audio.Samples.Get(@"Keyboard/key-caps");
94-
textRemovedSample = audio.Samples.Get(@"Keyboard/key-delete");
95-
textCommittedSample = audio.Samples.Get(@"Keyboard/key-confirm");
96-
caretMovedSample = audio.Samples.Get(@"Keyboard/key-movement");
97-
98-
selectCharSample = audio.Samples.Get(@"Keyboard/select-char");
99-
selectWordSample = audio.Samples.Get(@"Keyboard/select-word");
100-
selectAllSample = audio.Samples.Get(@"Keyboard/select-all");
101-
deselectSample = audio.Samples.Get(@"Keyboard/deselect");
92+
sampleMap = new Dictionary<FeedbackSampleType, Sample?[]>
93+
{
94+
{ FeedbackSampleType.TextAdd, textAddedSamples },
95+
{ FeedbackSampleType.TextAddCaps, new[] { audio.Samples.Get(@"Keyboard/key-caps") } },
96+
{ FeedbackSampleType.TextRemove, new[] { audio.Samples.Get(@"Keyboard/key-delete") } },
97+
{ FeedbackSampleType.TextConfirm, new[] { audio.Samples.Get(@"Keyboard/key-confirm") } },
98+
{ FeedbackSampleType.CaretMove, new[] { audio.Samples.Get(@"Keyboard/key-movement") } },
99+
{ FeedbackSampleType.SelectCharacter, new[] { audio.Samples.Get(@"Keyboard/select-char") } },
100+
{ FeedbackSampleType.SelectWord, new[] { audio.Samples.Get(@"Keyboard/select-word") } },
101+
{ FeedbackSampleType.SelectAll, new[] { audio.Samples.Get(@"Keyboard/select-all") } },
102+
{ FeedbackSampleType.Deselect, new[] { audio.Samples.Get(@"Keyboard/deselect") } }
103+
};
102104
}
103105

104106
private Color4 selectionColour;
@@ -110,31 +112,31 @@ protected override void OnUserTextAdded(string added)
110112
base.OnUserTextAdded(added);
111113

112114
if (added.Any(char.IsUpper) && AllowUniqueCharacterSamples)
113-
capsTextAddedSample?.Play();
115+
playSample(FeedbackSampleType.TextAddCaps);
114116
else
115-
playTextAddedSample();
117+
playSample(FeedbackSampleType.TextAdd);
116118
}
117119

118120
protected override void OnUserTextRemoved(string removed)
119121
{
120122
base.OnUserTextRemoved(removed);
121123

122-
textRemovedSample?.Play();
124+
playSample(FeedbackSampleType.TextRemove);
123125
}
124126

125127
protected override void OnTextCommitted(bool textChanged)
126128
{
127129
base.OnTextCommitted(textChanged);
128130

129-
textCommittedSample?.Play();
131+
playSample(FeedbackSampleType.TextConfirm);
130132
}
131133

132134
protected override void OnCaretMoved(bool selecting)
133135
{
134136
base.OnCaretMoved(selecting);
135137

136138
if (!selecting)
137-
caretMovedSample?.Play();
139+
playSample(FeedbackSampleType.CaretMove);
138140
}
139141

140142
protected override void OnTextSelectionChanged(TextSelectionType selectionType)
@@ -144,15 +146,15 @@ protected override void OnTextSelectionChanged(TextSelectionType selectionType)
144146
switch (selectionType)
145147
{
146148
case TextSelectionType.Character:
147-
playSelectSample(SelectionSampleType.Character);
149+
playSample(FeedbackSampleType.SelectCharacter);
148150
break;
149151

150152
case TextSelectionType.Word:
151-
playSelectSample(selectionStarted ? SelectionSampleType.Character : SelectionSampleType.Word);
153+
playSample(selectionStarted ? FeedbackSampleType.SelectCharacter : FeedbackSampleType.SelectWord);
152154
break;
153155

154156
case TextSelectionType.All:
155-
playSelectSample(SelectionSampleType.All);
157+
playSample(FeedbackSampleType.SelectAll);
156158
break;
157159
}
158160

@@ -165,7 +167,7 @@ protected override void OnTextDeselected()
165167

166168
if (!selectionStarted) return;
167169

168-
playSelectSample(SelectionSampleType.Deselect);
170+
playSample(FeedbackSampleType.Deselect);
169171

170172
selectionStarted = false;
171173
}
@@ -184,36 +186,36 @@ protected override void OnImeComposition(string newComposition, int removedTextL
184186

185187
case 1:
186188
// composition probably ended by pressing backspace, or was cancelled.
187-
textRemovedSample?.Play();
189+
playSample(FeedbackSampleType.TextRemove);
188190
return;
189191

190192
default:
191193
// longer text removed, composition ended because it was cancelled.
192194
// could be a different sample if desired.
193-
textRemovedSample?.Play();
195+
playSample(FeedbackSampleType.TextRemove);
194196
return;
195197
}
196198
}
197199

198200
if (addedTextLength > 0)
199201
{
200202
// some text was added, probably due to typing new text or by changing the candidate.
201-
playTextAddedSample();
203+
playSample(FeedbackSampleType.TextAdd);
202204
return;
203205
}
204206

205207
if (removedTextLength > 0)
206208
{
207209
// text was probably removed by backspacing.
208210
// it's also possible that a candidate that only removed text was changed to.
209-
textRemovedSample?.Play();
211+
playSample(FeedbackSampleType.TextRemove);
210212
return;
211213
}
212214

213215
if (caretMoved)
214216
{
215217
// only the caret/selection was moved.
216-
caretMovedSample?.Play();
218+
playSample(FeedbackSampleType.CaretMove);
217219
}
218220
}
219221

@@ -224,13 +226,13 @@ protected override void OnImeResult(string result, bool successful)
224226
if (successful)
225227
{
226228
// composition was successfully completed, usually by pressing the enter key.
227-
textCommittedSample?.Play();
229+
playSample(FeedbackSampleType.TextConfirm);
228230
}
229231
else
230232
{
231233
// composition was prematurely ended, eg. by clicking inside the textbox.
232234
// could be a different sample if desired.
233-
textCommittedSample?.Play();
235+
playSample(FeedbackSampleType.TextConfirm);
234236
}
235237
}
236238

@@ -259,43 +261,35 @@ protected override void OnFocusLost(FocusLostEvent e)
259261
SelectionColour = SelectionColour,
260262
};
261263

262-
private void playSelectSample(SelectionSampleType selectionType)
264+
private SampleChannel? getSampleChannel(FeedbackSampleType feedbackSampleType)
263265
{
264-
if (Time.Current < sampleLastPlaybackTime + 15) return;
266+
var samples = sampleMap[feedbackSampleType];
265267

266-
SampleChannel? channel;
267-
double pitch = 0.98 + RNG.NextDouble(0.04);
268-
269-
switch (selectionType)
270-
{
271-
case SelectionSampleType.All:
272-
channel = selectAllSample?.GetChannel();
273-
break;
268+
if (samples == null || samples.Length == 0)
269+
return null;
274270

275-
case SelectionSampleType.Word:
276-
channel = selectWordSample?.GetChannel();
277-
break;
271+
return samples[RNG.Next(0, samples.Length)]?.GetChannel();
272+
}
278273

279-
case SelectionSampleType.Deselect:
280-
channel = deselectSample?.GetChannel();
281-
break;
274+
private void playSample(FeedbackSampleType feedbackSample)
275+
{
276+
if (Time.Current < sampleLastPlaybackTime + 15) return;
282277

283-
default:
284-
channel = selectCharSample?.GetChannel();
285-
pitch += (SelectedText.Length / (double)Text.Length) * 0.15f;
286-
break;
287-
}
278+
SampleChannel? channel = getSampleChannel(feedbackSample);
288279

289280
if (channel == null) return;
290281

282+
double pitch = 0.98 + RNG.NextDouble(0.04);
283+
284+
if (feedbackSample == FeedbackSampleType.SelectCharacter)
285+
pitch += ((double)SelectedText.Length / Math.Max(1, Text.Length)) * 0.15f;
286+
291287
channel.Frequency.Value = pitch;
292288
channel.Play();
293289

294290
sampleLastPlaybackTime = Time.Current;
295291
}
296292

297-
private void playTextAddedSample() => textAddedSamples[RNG.Next(0, textAddedSamples.Length)]?.Play();
298-
299293
private class OsuCaret : Caret
300294
{
301295
private const float caret_move_time = 60;

0 commit comments

Comments
 (0)