diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs
index 8865bf31ea..5550c6a748 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs
@@ -6,10 +6,13 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
+using osu.Framework.Input.Events;
+using osu.Framework.Threading;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osuTK;
using osuTK.Graphics;
+using osuTK.Input;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
@@ -52,6 +55,45 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
HoverColour = OsuColour.Gray(0.25f);
FlashColour = OsuColour.Gray(0.5f);
}
+
+ private ScheduledDelegate repeatSchedule;
+
+ ///
+ /// The initial delay before mouse down repeat begins.
+ ///
+ private const int repeat_initial_delay = 250;
+
+ ///
+ /// The delay between mouse down repeats after the initial repeat.
+ ///
+ private const int repeat_tick_rate = 70;
+
+ protected override bool OnClick(ClickEvent e)
+ {
+ // don't actuate a click since we are manually handling repeats.
+ return true;
+ }
+
+ protected override bool OnMouseDown(MouseDownEvent e)
+ {
+ if (e.Button == MouseButton.Left)
+ {
+ Action clickAction = () => base.OnClick(new ClickEvent(e.CurrentState, e.Button));
+
+ // run once for initial down
+ clickAction();
+
+ Scheduler.Add(repeatSchedule = new ScheduledDelegate(clickAction, Clock.CurrentTime + repeat_initial_delay, repeat_tick_rate));
+ }
+
+ return base.OnMouseDown(e);
+ }
+
+ protected override void OnMouseUp(MouseUpEvent e)
+ {
+ repeatSchedule?.Cancel();
+ base.OnMouseUp(e);
+ }
}
}
}