1
1
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2
2
// See the LICENCE file in the repository root for full licence text.
3
3
4
+ using System ;
5
+ using System . Collections . Generic ;
4
6
using System . Linq ;
5
7
using osu . Framework . Allocation ;
6
8
using osu . Framework . Audio ;
@@ -40,30 +42,26 @@ public class OsuTextBox : BasicTextBox
40
42
Margin = new MarginPadding { Left = 2 } ,
41
43
} ;
42
44
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
-
54
45
private OsuCaret ? caret ;
55
46
56
47
private bool selectionStarted ;
57
48
private double sampleLastPlaybackTime ;
58
49
59
- private enum SelectionSampleType
50
+ private enum FeedbackSampleType
60
51
{
61
- Character ,
62
- Word ,
63
- All ,
52
+ TextAdd ,
53
+ TextAddCaps ,
54
+ TextRemove ,
55
+ TextConfirm ,
56
+ CaretMove ,
57
+ SelectCharacter ,
58
+ SelectWord ,
59
+ SelectAll ,
64
60
Deselect
65
61
}
66
62
63
+ private Dictionary < FeedbackSampleType , Sample ? [ ] > sampleMap = new Dictionary < FeedbackSampleType , Sample ? [ ] > ( ) ;
64
+
67
65
public OsuTextBox ( )
68
66
{
69
67
Height = 40 ;
@@ -87,18 +85,22 @@ private void load(OverlayColourProvider? colourProvider, OsuColour colour, Audio
87
85
88
86
Placeholder . Colour = colourProvider ? . Foreground1 ?? new Color4 ( 180 , 180 , 180 , 255 ) ;
89
87
88
+ var textAddedSamples = new Sample ? [ 4 ] ;
90
89
for ( int i = 0 ; i < textAddedSamples . Length ; i ++ )
91
90
textAddedSamples [ i ] = audio . Samples . Get ( $@ "Keyboard/key-press-{ 1 + i } ") ;
92
91
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
+ } ;
102
104
}
103
105
104
106
private Color4 selectionColour ;
@@ -110,31 +112,31 @@ protected override void OnUserTextAdded(string added)
110
112
base . OnUserTextAdded ( added ) ;
111
113
112
114
if ( added . Any ( char . IsUpper ) && AllowUniqueCharacterSamples )
113
- capsTextAddedSample ? . Play ( ) ;
115
+ playSample ( FeedbackSampleType . TextAddCaps ) ;
114
116
else
115
- playTextAddedSample ( ) ;
117
+ playSample ( FeedbackSampleType . TextAdd ) ;
116
118
}
117
119
118
120
protected override void OnUserTextRemoved ( string removed )
119
121
{
120
122
base . OnUserTextRemoved ( removed ) ;
121
123
122
- textRemovedSample ? . Play ( ) ;
124
+ playSample ( FeedbackSampleType . TextRemove ) ;
123
125
}
124
126
125
127
protected override void OnTextCommitted ( bool textChanged )
126
128
{
127
129
base . OnTextCommitted ( textChanged ) ;
128
130
129
- textCommittedSample ? . Play ( ) ;
131
+ playSample ( FeedbackSampleType . TextConfirm ) ;
130
132
}
131
133
132
134
protected override void OnCaretMoved ( bool selecting )
133
135
{
134
136
base . OnCaretMoved ( selecting ) ;
135
137
136
138
if ( ! selecting )
137
- caretMovedSample ? . Play ( ) ;
139
+ playSample ( FeedbackSampleType . CaretMove ) ;
138
140
}
139
141
140
142
protected override void OnTextSelectionChanged ( TextSelectionType selectionType )
@@ -144,15 +146,15 @@ protected override void OnTextSelectionChanged(TextSelectionType selectionType)
144
146
switch ( selectionType )
145
147
{
146
148
case TextSelectionType . Character :
147
- playSelectSample ( SelectionSampleType . Character ) ;
149
+ playSample ( FeedbackSampleType . SelectCharacter ) ;
148
150
break ;
149
151
150
152
case TextSelectionType . Word :
151
- playSelectSample ( selectionStarted ? SelectionSampleType . Character : SelectionSampleType . Word ) ;
153
+ playSample ( selectionStarted ? FeedbackSampleType . SelectCharacter : FeedbackSampleType . SelectWord ) ;
152
154
break ;
153
155
154
156
case TextSelectionType . All :
155
- playSelectSample ( SelectionSampleType . All ) ;
157
+ playSample ( FeedbackSampleType . SelectAll ) ;
156
158
break ;
157
159
}
158
160
@@ -165,7 +167,7 @@ protected override void OnTextDeselected()
165
167
166
168
if ( ! selectionStarted ) return ;
167
169
168
- playSelectSample ( SelectionSampleType . Deselect ) ;
170
+ playSample ( FeedbackSampleType . Deselect ) ;
169
171
170
172
selectionStarted = false ;
171
173
}
@@ -184,36 +186,36 @@ protected override void OnImeComposition(string newComposition, int removedTextL
184
186
185
187
case 1 :
186
188
// composition probably ended by pressing backspace, or was cancelled.
187
- textRemovedSample ? . Play ( ) ;
189
+ playSample ( FeedbackSampleType . TextRemove ) ;
188
190
return ;
189
191
190
192
default :
191
193
// longer text removed, composition ended because it was cancelled.
192
194
// could be a different sample if desired.
193
- textRemovedSample ? . Play ( ) ;
195
+ playSample ( FeedbackSampleType . TextRemove ) ;
194
196
return ;
195
197
}
196
198
}
197
199
198
200
if ( addedTextLength > 0 )
199
201
{
200
202
// some text was added, probably due to typing new text or by changing the candidate.
201
- playTextAddedSample ( ) ;
203
+ playSample ( FeedbackSampleType . TextAdd ) ;
202
204
return ;
203
205
}
204
206
205
207
if ( removedTextLength > 0 )
206
208
{
207
209
// text was probably removed by backspacing.
208
210
// it's also possible that a candidate that only removed text was changed to.
209
- textRemovedSample ? . Play ( ) ;
211
+ playSample ( FeedbackSampleType . TextRemove ) ;
210
212
return ;
211
213
}
212
214
213
215
if ( caretMoved )
214
216
{
215
217
// only the caret/selection was moved.
216
- caretMovedSample ? . Play ( ) ;
218
+ playSample ( FeedbackSampleType . CaretMove ) ;
217
219
}
218
220
}
219
221
@@ -224,13 +226,13 @@ protected override void OnImeResult(string result, bool successful)
224
226
if ( successful )
225
227
{
226
228
// composition was successfully completed, usually by pressing the enter key.
227
- textCommittedSample ? . Play ( ) ;
229
+ playSample ( FeedbackSampleType . TextConfirm ) ;
228
230
}
229
231
else
230
232
{
231
233
// composition was prematurely ended, eg. by clicking inside the textbox.
232
234
// could be a different sample if desired.
233
- textCommittedSample ? . Play ( ) ;
235
+ playSample ( FeedbackSampleType . TextConfirm ) ;
234
236
}
235
237
}
236
238
@@ -259,43 +261,35 @@ protected override void OnFocusLost(FocusLostEvent e)
259
261
SelectionColour = SelectionColour ,
260
262
} ;
261
263
262
- private void playSelectSample ( SelectionSampleType selectionType )
264
+ private SampleChannel ? getSampleChannel ( FeedbackSampleType feedbackSampleType )
263
265
{
264
- if ( Time . Current < sampleLastPlaybackTime + 15 ) return ;
266
+ var samples = sampleMap [ feedbackSampleType ] ;
265
267
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 ;
274
270
275
- case SelectionSampleType . Word :
276
- channel = selectWordSample ? . GetChannel ( ) ;
277
- break ;
271
+ return samples [ RNG . Next ( 0 , samples . Length ) ] ? . GetChannel ( ) ;
272
+ }
278
273
279
- case SelectionSampleType . Deselect :
280
- channel = deselectSample ? . GetChannel ( ) ;
281
- break ;
274
+ private void playSample ( FeedbackSampleType feedbackSample )
275
+ {
276
+ if ( Time . Current < sampleLastPlaybackTime + 15 ) return ;
282
277
283
- default :
284
- channel = selectCharSample ? . GetChannel ( ) ;
285
- pitch += ( SelectedText . Length / ( double ) Text . Length ) * 0.15f ;
286
- break ;
287
- }
278
+ SampleChannel ? channel = getSampleChannel ( feedbackSample ) ;
288
279
289
280
if ( channel == null ) return ;
290
281
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
+
291
287
channel . Frequency . Value = pitch ;
292
288
channel . Play ( ) ;
293
289
294
290
sampleLastPlaybackTime = Time . Current ;
295
291
}
296
292
297
- private void playTextAddedSample ( ) => textAddedSamples [ RNG . Next ( 0 , textAddedSamples . Length ) ] ? . Play ( ) ;
298
-
299
293
private class OsuCaret : Caret
300
294
{
301
295
private const float caret_move_time = 60 ;
0 commit comments