// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using JetBrains.Annotations; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; using osu.Game.Input.Bindings; namespace osu.Game.Skinning.Editor { /// /// A container which handles loading a skin editor on user request for a specified target. /// This also handles the scaling / positioning adjustment of the target. /// public class SkinEditorOverlay : CompositeDrawable, IKeyBindingHandler { private readonly ScalingContainer target; [CanBeNull] private SkinEditor skinEditor; public const float VISIBLE_TARGET_SCALE = 0.8f; public SkinEditorOverlay(ScalingContainer target) { this.target = target; RelativeSizeAxes = Axes.Both; } public bool OnPressed(KeyBindingPressEvent e) { switch (e.Action) { case GlobalAction.Back: if (skinEditor?.State.Value != Visibility.Visible) break; Hide(); return true; case GlobalAction.ToggleSkinEditor: Toggle(); return true; } return false; } public void Toggle() { if (skinEditor == null) Show(); else skinEditor.ToggleVisibility(); } public override void Hide() { // base call intentionally omitted. skinEditor?.Hide(); } public override void Show() { // base call intentionally omitted as we have custom behaviour. if (skinEditor != null) { skinEditor.Show(); return; } var editor = new SkinEditor(target); editor.State.BindValueChanged(editorVisibilityChanged); skinEditor = editor; // Schedule ensures that if `Show` is called before this overlay is loaded, // it will not throw (LoadComponentAsync requires the load target to be in a loaded state). Schedule(() => { if (editor != skinEditor) return; LoadComponentAsync(editor, _ => { if (editor != skinEditor) return; AddInternal(editor); }); }); } private void editorVisibilityChanged(ValueChangedEvent visibility) { if (visibility.NewValue == Visibility.Visible) { target.SetCustomRect(new RectangleF(0.18f, 0.1f, VISIBLE_TARGET_SCALE, VISIBLE_TARGET_SCALE), true); } else { target.SetCustomRect(null); } } public void OnReleased(KeyBindingReleaseEvent e) { } /// /// Exit any existing skin editor due to the game state changing. /// public void Reset() { skinEditor?.Save(); skinEditor?.Hide(); skinEditor?.Expire(); skinEditor = null; } } }