mirror of
https://github.com/osukey/osukey.git
synced 2025-05-06 14:17:27 +09:00
Refactor feedback sample playback logic
This commit is contained in:
parent
6cadcc206b
commit
cc9dc604a0
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
@ -40,30 +42,26 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Margin = new MarginPadding { Left = 2 },
|
Margin = new MarginPadding { Left = 2 },
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Sample?[] textAddedSamples = new Sample[4];
|
|
||||||
private Sample? capsTextAddedSample;
|
|
||||||
private Sample? textRemovedSample;
|
|
||||||
private Sample? textCommittedSample;
|
|
||||||
private Sample? caretMovedSample;
|
|
||||||
|
|
||||||
private Sample? selectCharSample;
|
|
||||||
private Sample? selectWordSample;
|
|
||||||
private Sample? selectAllSample;
|
|
||||||
private Sample? deselectSample;
|
|
||||||
|
|
||||||
private OsuCaret? caret;
|
private OsuCaret? caret;
|
||||||
|
|
||||||
private bool selectionStarted;
|
private bool selectionStarted;
|
||||||
private double sampleLastPlaybackTime;
|
private double sampleLastPlaybackTime;
|
||||||
|
|
||||||
private enum SelectionSampleType
|
private enum FeedbackSampleType
|
||||||
{
|
{
|
||||||
Character,
|
TextAdd,
|
||||||
Word,
|
TextAddCaps,
|
||||||
All,
|
TextRemove,
|
||||||
|
TextConfirm,
|
||||||
|
CaretMove,
|
||||||
|
SelectCharacter,
|
||||||
|
SelectWord,
|
||||||
|
SelectAll,
|
||||||
Deselect
|
Deselect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<FeedbackSampleType, Sample?[]> sampleMap = new Dictionary<FeedbackSampleType, Sample?[]>();
|
||||||
|
|
||||||
public OsuTextBox()
|
public OsuTextBox()
|
||||||
{
|
{
|
||||||
Height = 40;
|
Height = 40;
|
||||||
@ -87,18 +85,22 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
Placeholder.Colour = colourProvider?.Foreground1 ?? new Color4(180, 180, 180, 255);
|
Placeholder.Colour = colourProvider?.Foreground1 ?? new Color4(180, 180, 180, 255);
|
||||||
|
|
||||||
|
var textAddedSamples = new Sample?[4];
|
||||||
for (int i = 0; i < textAddedSamples.Length; i++)
|
for (int i = 0; i < textAddedSamples.Length; i++)
|
||||||
textAddedSamples[i] = audio.Samples.Get($@"Keyboard/key-press-{1 + i}");
|
textAddedSamples[i] = audio.Samples.Get($@"Keyboard/key-press-{1 + i}");
|
||||||
|
|
||||||
capsTextAddedSample = audio.Samples.Get(@"Keyboard/key-caps");
|
sampleMap = new Dictionary<FeedbackSampleType, Sample?[]>
|
||||||
textRemovedSample = audio.Samples.Get(@"Keyboard/key-delete");
|
{
|
||||||
textCommittedSample = audio.Samples.Get(@"Keyboard/key-confirm");
|
{ FeedbackSampleType.TextAdd, textAddedSamples },
|
||||||
caretMovedSample = audio.Samples.Get(@"Keyboard/key-movement");
|
{ FeedbackSampleType.TextAddCaps, new[] { audio.Samples.Get(@"Keyboard/key-caps") } },
|
||||||
|
{ FeedbackSampleType.TextRemove, new[] { audio.Samples.Get(@"Keyboard/key-delete") } },
|
||||||
selectCharSample = audio.Samples.Get(@"Keyboard/select-char");
|
{ FeedbackSampleType.TextConfirm, new[] { audio.Samples.Get(@"Keyboard/key-confirm") } },
|
||||||
selectWordSample = audio.Samples.Get(@"Keyboard/select-word");
|
{ FeedbackSampleType.CaretMove, new[] { audio.Samples.Get(@"Keyboard/key-movement") } },
|
||||||
selectAllSample = audio.Samples.Get(@"Keyboard/select-all");
|
{ FeedbackSampleType.SelectCharacter, new[] { audio.Samples.Get(@"Keyboard/select-char") } },
|
||||||
deselectSample = audio.Samples.Get(@"Keyboard/deselect");
|
{ FeedbackSampleType.SelectWord, new[] { audio.Samples.Get(@"Keyboard/select-word") } },
|
||||||
|
{ FeedbackSampleType.SelectAll, new[] { audio.Samples.Get(@"Keyboard/select-all") } },
|
||||||
|
{ FeedbackSampleType.Deselect, new[] { audio.Samples.Get(@"Keyboard/deselect") } }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color4 selectionColour;
|
private Color4 selectionColour;
|
||||||
@ -110,23 +112,23 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
base.OnUserTextAdded(added);
|
base.OnUserTextAdded(added);
|
||||||
|
|
||||||
if (added.Any(char.IsUpper) && AllowUniqueCharacterSamples)
|
if (added.Any(char.IsUpper) && AllowUniqueCharacterSamples)
|
||||||
capsTextAddedSample?.Play();
|
playSample(FeedbackSampleType.TextAddCaps);
|
||||||
else
|
else
|
||||||
playTextAddedSample();
|
playSample(FeedbackSampleType.TextAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUserTextRemoved(string removed)
|
protected override void OnUserTextRemoved(string removed)
|
||||||
{
|
{
|
||||||
base.OnUserTextRemoved(removed);
|
base.OnUserTextRemoved(removed);
|
||||||
|
|
||||||
textRemovedSample?.Play();
|
playSample(FeedbackSampleType.TextRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnTextCommitted(bool textChanged)
|
protected override void OnTextCommitted(bool textChanged)
|
||||||
{
|
{
|
||||||
base.OnTextCommitted(textChanged);
|
base.OnTextCommitted(textChanged);
|
||||||
|
|
||||||
textCommittedSample?.Play();
|
playSample(FeedbackSampleType.TextConfirm);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnCaretMoved(bool selecting)
|
protected override void OnCaretMoved(bool selecting)
|
||||||
@ -134,7 +136,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
base.OnCaretMoved(selecting);
|
base.OnCaretMoved(selecting);
|
||||||
|
|
||||||
if (!selecting)
|
if (!selecting)
|
||||||
caretMovedSample?.Play();
|
playSample(FeedbackSampleType.CaretMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnTextSelectionChanged(TextSelectionType selectionType)
|
protected override void OnTextSelectionChanged(TextSelectionType selectionType)
|
||||||
@ -144,15 +146,15 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
switch (selectionType)
|
switch (selectionType)
|
||||||
{
|
{
|
||||||
case TextSelectionType.Character:
|
case TextSelectionType.Character:
|
||||||
playSelectSample(SelectionSampleType.Character);
|
playSample(FeedbackSampleType.SelectCharacter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TextSelectionType.Word:
|
case TextSelectionType.Word:
|
||||||
playSelectSample(selectionStarted ? SelectionSampleType.Character : SelectionSampleType.Word);
|
playSample(selectionStarted ? FeedbackSampleType.SelectCharacter : FeedbackSampleType.SelectWord);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TextSelectionType.All:
|
case TextSelectionType.All:
|
||||||
playSelectSample(SelectionSampleType.All);
|
playSample(FeedbackSampleType.SelectAll);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +167,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
if (!selectionStarted) return;
|
if (!selectionStarted) return;
|
||||||
|
|
||||||
playSelectSample(SelectionSampleType.Deselect);
|
playSample(FeedbackSampleType.Deselect);
|
||||||
|
|
||||||
selectionStarted = false;
|
selectionStarted = false;
|
||||||
}
|
}
|
||||||
@ -184,13 +186,13 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// composition probably ended by pressing backspace, or was cancelled.
|
// composition probably ended by pressing backspace, or was cancelled.
|
||||||
textRemovedSample?.Play();
|
playSample(FeedbackSampleType.TextRemove);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// longer text removed, composition ended because it was cancelled.
|
// longer text removed, composition ended because it was cancelled.
|
||||||
// could be a different sample if desired.
|
// could be a different sample if desired.
|
||||||
textRemovedSample?.Play();
|
playSample(FeedbackSampleType.TextRemove);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +200,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
if (addedTextLength > 0)
|
if (addedTextLength > 0)
|
||||||
{
|
{
|
||||||
// some text was added, probably due to typing new text or by changing the candidate.
|
// some text was added, probably due to typing new text or by changing the candidate.
|
||||||
playTextAddedSample();
|
playSample(FeedbackSampleType.TextAdd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,14 +208,14 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
// text was probably removed by backspacing.
|
// text was probably removed by backspacing.
|
||||||
// it's also possible that a candidate that only removed text was changed to.
|
// it's also possible that a candidate that only removed text was changed to.
|
||||||
textRemovedSample?.Play();
|
playSample(FeedbackSampleType.TextRemove);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (caretMoved)
|
if (caretMoved)
|
||||||
{
|
{
|
||||||
// only the caret/selection was moved.
|
// only the caret/selection was moved.
|
||||||
caretMovedSample?.Play();
|
playSample(FeedbackSampleType.CaretMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,13 +226,13 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
if (successful)
|
if (successful)
|
||||||
{
|
{
|
||||||
// composition was successfully completed, usually by pressing the enter key.
|
// composition was successfully completed, usually by pressing the enter key.
|
||||||
textCommittedSample?.Play();
|
playSample(FeedbackSampleType.TextConfirm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// composition was prematurely ended, eg. by clicking inside the textbox.
|
// composition was prematurely ended, eg. by clicking inside the textbox.
|
||||||
// could be a different sample if desired.
|
// could be a different sample if desired.
|
||||||
textCommittedSample?.Play();
|
playSample(FeedbackSampleType.TextConfirm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,43 +261,35 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
SelectionColour = SelectionColour,
|
SelectionColour = SelectionColour,
|
||||||
};
|
};
|
||||||
|
|
||||||
private void playSelectSample(SelectionSampleType selectionType)
|
private SampleChannel? getSampleChannel(FeedbackSampleType feedbackSampleType)
|
||||||
|
{
|
||||||
|
var samples = sampleMap[feedbackSampleType];
|
||||||
|
|
||||||
|
if (samples == null || samples.Length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return samples[RNG.Next(0, samples.Length)]?.GetChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playSample(FeedbackSampleType feedbackSample)
|
||||||
{
|
{
|
||||||
if (Time.Current < sampleLastPlaybackTime + 15) return;
|
if (Time.Current < sampleLastPlaybackTime + 15) return;
|
||||||
|
|
||||||
SampleChannel? channel;
|
SampleChannel? channel = getSampleChannel(feedbackSample);
|
||||||
double pitch = 0.98 + RNG.NextDouble(0.04);
|
|
||||||
|
|
||||||
switch (selectionType)
|
|
||||||
{
|
|
||||||
case SelectionSampleType.All:
|
|
||||||
channel = selectAllSample?.GetChannel();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SelectionSampleType.Word:
|
|
||||||
channel = selectWordSample?.GetChannel();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SelectionSampleType.Deselect:
|
|
||||||
channel = deselectSample?.GetChannel();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
channel = selectCharSample?.GetChannel();
|
|
||||||
pitch += (SelectedText.Length / (double)Text.Length) * 0.15f;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel == null) return;
|
if (channel == null) return;
|
||||||
|
|
||||||
|
double pitch = 0.98 + RNG.NextDouble(0.04);
|
||||||
|
|
||||||
|
if (feedbackSample == FeedbackSampleType.SelectCharacter)
|
||||||
|
pitch += ((double)SelectedText.Length / Math.Max(1, Text.Length)) * 0.15f;
|
||||||
|
|
||||||
channel.Frequency.Value = pitch;
|
channel.Frequency.Value = pitch;
|
||||||
channel.Play();
|
channel.Play();
|
||||||
|
|
||||||
sampleLastPlaybackTime = Time.Current;
|
sampleLastPlaybackTime = Time.Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playTextAddedSample() => textAddedSamples[RNG.Next(0, textAddedSamples.Length)]?.Play();
|
|
||||||
|
|
||||||
private class OsuCaret : Caret
|
private class OsuCaret : Caret
|
||||||
{
|
{
|
||||||
private const float caret_move_time = 60;
|
private const float caret_move_time = 60;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user