1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 18:45:37 +08:00
osu-lazer/osu.Game/Skinning/Editor/SkinEditor.cs
2021-05-11 18:39:14 +09:00

177 lines
5.7 KiB
C#

// 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.
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play.HUD;
using osuTK;
namespace osu.Game.Skinning.Editor
{
public class SkinEditor : FocusedOverlayContainer
{
public const double TRANSITION_DURATION = 500;
private readonly Drawable targetScreen;
private OsuTextFlowContainer headerText;
protected override bool StartHidden => true;
[Resolved]
private SkinManager skins { get; set; }
public SkinEditor(Drawable targetScreen)
{
this.targetScreen = targetScreen;
RelativeSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
InternalChild = new OsuContextMenuContainer
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
headerText = new OsuTextFlowContainer
{
TextAnchor = Anchor.TopCentre,
Padding = new MarginPadding(20),
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X
},
new SkinBlueprintContainer(targetScreen),
new SkinComponentToolbox(600)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RequestPlacement = placeComponent
},
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Spacing = new Vector2(5),
Padding = new MarginPadding
{
Top = 10,
Left = 10,
},
Margin = new MarginPadding
{
Right = 10,
Bottom = 10,
},
Children = new Drawable[]
{
new TriangleButton
{
Text = "Save Changes",
Width = 140,
Action = save,
},
new DangerousTriangleButton
{
Text = "Revert to default",
Width = 140,
Action = revert,
},
}
},
}
};
headerText.AddParagraph("Skin editor (preview)", cp => cp.Font = OsuFont.Default.With(size: 24));
headerText.AddParagraph("This is a preview of what is to come. Changes are lost on changing screens.", cp =>
{
cp.Font = OsuFont.Default.With(size: 12);
cp.Colour = colours.Yellow;
});
}
private void placeComponent(Type type)
{
Drawable instance = (Drawable)Activator.CreateInstance(type);
getTarget(SkinnableTarget.MainHUDComponents)?.Add(instance);
}
private ISkinnableTarget getTarget(SkinnableTarget target)
{
return targetScreen.ChildrenOfType<ISkinnableTarget>().FirstOrDefault(c => c.Target == target);
}
protected override void LoadComplete()
{
base.LoadComplete();
Show();
}
private void revert()
{
var currentSkin = skins.CurrentSkin.Value;
var legacySkin = currentSkin as LegacySkin;
if (legacySkin == null)
return;
SkinnableElementTargetContainer[] targetContainers = targetScreen.ChildrenOfType<SkinnableElementTargetContainer>().ToArray();
foreach (var t in targetContainers)
{
legacySkin.ResetDrawableTarget(t);
// add back default components
getTarget(t.Target).Reload();
}
}
private void save()
{
var currentSkin = skins.CurrentSkin.Value;
var legacySkin = currentSkin as LegacySkin;
if (legacySkin == null)
return;
SkinnableElementTargetContainer[] targetContainers = targetScreen.ChildrenOfType<SkinnableElementTargetContainer>().ToArray();
foreach (var t in targetContainers)
legacySkin.UpdateDrawableTarget(t);
skins.Save(skins.CurrentSkin.Value);
}
protected override bool OnHover(HoverEvent e) => true;
protected override bool OnMouseDown(MouseDownEvent e) => true;
protected override void PopIn()
{
this.FadeIn(TRANSITION_DURATION, Easing.OutQuint);
}
protected override void PopOut()
{
this.FadeOut(TRANSITION_DURATION, Easing.OutQuint);
}
}
}