// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Framework.Threading; using osu.Game.Screens.Play.HUD; using osuTK; namespace osu.Game.Extensions { public static class DrawableExtensions { public const double REPEAT_INTERVAL = 70; public const double INITIAL_DELAY = 250; /// /// Helper method that is used while doesn't support repetitions of . /// Simulates repetitions by continually invoking a delegate according to the default key repeat rate. /// /// /// The returned delegate can be cancelled to stop repeat events from firing (usually in ). /// /// The which is handling the repeat. /// The to schedule repetitions on. /// The to be invoked once immediately and with every repetition. /// The delay imposed on the first repeat. Defaults to . /// A which can be cancelled to stop the repeat events from firing. public static ScheduledDelegate BeginKeyRepeat(this IKeyBindingHandler handler, Scheduler scheduler, Action action, double initialRepeatDelay = INITIAL_DELAY) { action(); ScheduledDelegate repeatDelegate = new ScheduledDelegate(action, handler.Time.Current + initialRepeatDelay, REPEAT_INTERVAL); scheduler.Add(repeatDelegate); return repeatDelegate; } /// /// Accepts a delta vector in screen-space coordinates and converts it to one which can be applied to this drawable's position. /// /// The drawable. /// A delta in screen-space coordinates. /// The delta vector in Parent's coordinates. public static Vector2 ScreenSpaceDeltaToParentSpace(this Drawable drawable, Vector2 delta) => drawable.Parent.ToLocalSpace(drawable.Parent.ToScreenSpace(Vector2.Zero) + delta); public static SkinnableInfo CreateSerialisedInformation(this Drawable component) => new SkinnableInfo(component); public static void ApplySerialisedInformation(this Drawable component, SkinnableInfo info) { // todo: can probably make this better via deserialisation directly using a common interface. component.Position = info.Position; component.Rotation = info.Rotation; component.Scale = info.Scale; component.Anchor = info.Anchor; if (component is Container container) { foreach (var child in info.Children) container.Add(child.CreateInstance()); } } } }